* t/op/lexicals-2.t (added), MANIFEST:
[parrot.git] / src / key.c
blobca563f375aa4c17a1f1828287088dfcedb893b55
1 /*
2 Copyright (C) 2001-2008, The Perl Foundation.
3 $Id$
5 =head1 NAME
7 src/key.c - Base vtable calling functions
9 =head1 DESCRIPTION
11 The base vtable calling functions.
13 =head2 Functions
15 =over 4
17 =cut
21 #include "parrot/parrot.h"
22 #include "parrot/key.h"
23 #include "key.str"
25 /* HEADERIZER HFILE: include/parrot/key.h */
29 =item C<PMC * key_new>
31 Returns a new C<Key> PMC.
33 =cut
37 PARROT_API
38 PARROT_CANNOT_RETURN_NULL
39 PARROT_WARN_UNUSED_RESULT
40 PMC *
41 key_new(PARROT_INTERP)
43 return pmc_new(interp, enum_class_Key);
49 =item C<PMC * key_new_integer>
51 Returns a new integer C<Key> PMC with value C<value>.
53 =cut
57 PARROT_API
58 PARROT_CANNOT_RETURN_NULL
59 PARROT_WARN_UNUSED_RESULT
60 PMC *
61 key_new_integer(PARROT_INTERP, INTVAL value)
63 PMC * const key = pmc_new(interp, enum_class_Key);
65 PObj_get_FLAGS(key) |= KEY_integer_FLAG;
66 PMC_int_val(key) = value;
68 return key;
74 =item C<PMC * key_new_number>
76 Returns a new number C<Key> PMC with value C<value>.
78 =cut
82 PARROT_API
83 PARROT_CANNOT_RETURN_NULL
84 PARROT_WARN_UNUSED_RESULT
85 PMC *
86 key_new_number(PARROT_INTERP, FLOATVAL value)
88 PMC * const key = pmc_new(interp, enum_class_Key);
90 PObj_get_FLAGS(key) |= KEY_number_FLAG;
91 PMC_num_val(key) = value;
93 return key;
99 =item C<PMC * key_new_string>
101 Returns a new string C<Key> PMC with value C<value>.
103 =cut
107 PARROT_API
108 PARROT_CANNOT_RETURN_NULL
109 PARROT_WARN_UNUSED_RESULT
110 PMC *
111 key_new_string(PARROT_INTERP, ARGIN(STRING *value))
113 PMC * const key = pmc_new(interp, enum_class_Key);
115 PObj_get_FLAGS(key) |= KEY_string_FLAG;
116 PMC_str_val(key) = value;
118 return key;
124 =item C<PMC * key_new_cstring>
126 Returns a new string C<Key> PMC with value C<value> converted to a
127 C<STRING>.
129 =cut
133 PARROT_API
134 PARROT_CANNOT_RETURN_NULL
135 PARROT_WARN_UNUSED_RESULT
136 PMC *
137 key_new_cstring(PARROT_INTERP, ARGIN_NULLOK(const char *value))
139 return key_new_string(interp, string_from_cstring(interp, value, 0));
145 =item C<PMC * key_new_pmc>
147 Returns a new PMC C<Key> PMC with value C<value>.
149 =cut
153 PARROT_API
154 PARROT_CANNOT_RETURN_NULL
155 PARROT_WARN_UNUSED_RESULT
156 PMC *
157 key_new_pmc(PARROT_INTERP, ARGIN(PMC *value))
159 PMC * const key = pmc_new(interp, enum_class_Key);
161 PObj_get_FLAGS(key) |= KEY_pmc_FLAG;
162 real_exception(interp, NULL, 1, "this is broken - see slice.pmc");
168 =item C<void key_set_integer>
170 Set the integer C<value> in C<key>.
172 =cut
176 PARROT_API
177 void
178 key_set_integer(SHIM_INTERP, ARGMOD(PMC *key), INTVAL value)
180 PObj_get_FLAGS(key) &= ~KEY_type_FLAGS;
181 PObj_get_FLAGS(key) |= KEY_integer_FLAG;
182 PMC_int_val(key) = value;
184 return;
190 =item C<void key_set_register>
192 Set the register C<value> in C<key>.
194 =cut
198 PARROT_API
199 void
200 key_set_register(SHIM_INTERP, ARGMOD(PMC *key), INTVAL value, INTVAL flag)
202 PObj_get_FLAGS(key) &= ~KEY_type_FLAGS;
203 PObj_get_FLAGS(key) |= KEY_register_FLAG | flag;
204 PMC_int_val(key) = value;
206 return;
212 =item C<void key_set_number>
214 Set the number C<value> in C<key>.
216 =cut
220 PARROT_API
221 void
222 key_set_number(SHIM_INTERP, ARGMOD(PMC *key), FLOATVAL value)
224 PObj_get_FLAGS(key) &= ~KEY_type_FLAGS;
225 PObj_get_FLAGS(key) |= KEY_number_FLAG;
226 PMC_num_val(key) = value;
228 return;
234 =item C<void key_set_string>
236 Set the string C<value> in C<key>.
238 =cut
242 PARROT_API
243 void
244 key_set_string(SHIM_INTERP, ARGMOD(PMC *key), ARGIN(STRING *value))
246 PObj_get_FLAGS(key) &= ~KEY_type_FLAGS;
247 PObj_get_FLAGS(key) |= KEY_string_FLAG;
248 PMC_str_val(key) = value;
250 return;
256 =item C<void key_set_pmc>
258 Set the PMC C<value> in C<key>.
260 =cut
264 PARROT_API
265 void
266 key_set_pmc(PARROT_INTERP, ARGMOD(PMC *key), ARGIN(PMC *value))
268 PObj_get_FLAGS(key) &= ~KEY_type_FLAGS;
269 PObj_get_FLAGS(key) |= KEY_pmc_FLAG;
272 * XXX leo
273 * what for is this indirection?
275 real_exception(interp, NULL, 1, "this is broken - see slice.pmc");
281 =item C<INTVAL key_type>
283 Returns the type of C<key>.
285 =cut
289 PARROT_API
290 PARROT_WARN_UNUSED_RESULT
291 INTVAL
292 key_type(SHIM_INTERP, ARGIN(const PMC *key))
294 return (PObj_get_FLAGS(key) & KEY_type_FLAGS) & ~KEY_register_FLAG;
300 =item C<INTVAL key_integer>
302 Translates a key value into an integer.
303 Takes an interpreter name and pointer to a key.
304 Returns an integer value corresponding to the key.
306 =cut
310 PARROT_API
311 PARROT_WARN_UNUSED_RESULT
312 INTVAL
313 key_integer(PARROT_INTERP, ARGIN(PMC *key))
315 if (VTABLE_isa(interp, key, CONST_STRING(interp, "Key"))) {
316 switch (PObj_get_FLAGS(key) & KEY_type_FLAGS) {
317 case KEY_hash_iterator_FLAGS:
318 case KEY_integer_FLAG:
319 return PMC_int_val(key);
320 case KEY_integer_FLAG | KEY_register_FLAG:
321 return REG_INT(interp, PMC_int_val(key));
322 case KEY_pmc_FLAG | KEY_register_FLAG:
324 PMC * const reg = REG_PMC(interp, PMC_int_val(key));
325 return VTABLE_get_integer(interp, reg);
327 case KEY_string_FLAG:
328 return string_to_int(interp, PMC_str_val(key));
329 case KEY_string_FLAG | KEY_register_FLAG:
331 STRING * const s_reg = REG_STR(interp, PMC_int_val(key));
332 return string_to_int(interp, s_reg);
334 case KEY_string_FLAG | KEY_start_slice_FLAG:
335 case KEY_string_FLAG | KEY_inf_slice_FLAG:
337 STRING * const s_key = VTABLE_get_string(interp, key);
338 return string_to_int(interp, s_key);
340 case KEY_start_slice_FLAG:
341 case KEY_inf_slice_FLAG:
342 default:
343 break;
347 return VTABLE_get_integer(interp, key);
353 =item C<FLOATVAL key_number>
355 Translates a key value into a number.
356 Takes an interpreter name and pointer to a key.
357 Returns a number value corresponding to the key.
358 Throws an exception if the key is not a valid number.
360 =cut
364 PARROT_API
365 PARROT_WARN_UNUSED_RESULT
366 FLOATVAL
367 key_number(PARROT_INTERP, ARGIN(PMC *key))
369 switch (PObj_get_FLAGS(key) & KEY_type_FLAGS) {
370 case KEY_number_FLAG:
371 return PMC_num_val(key);
372 case KEY_number_FLAG | KEY_register_FLAG:
373 return REG_NUM(interp, PMC_int_val(key));
374 case KEY_pmc_FLAG:
375 return VTABLE_get_number(interp, key);
376 /* PMC_pmc_val(key)); */
377 case KEY_pmc_FLAG | KEY_register_FLAG:
379 PMC * const reg = REG_PMC(interp, PMC_int_val(key));
380 return VTABLE_get_number(interp, reg);
382 default:
383 real_exception(interp, NULL, INVALID_OPERATION, "Key not a number!\n");
390 =item C<STRING * key_string>
392 Translates a key value into a string.
393 Takes an interpreter name and pointer to a key.
394 Returns a string value corresponding to the key.
396 =cut
400 PARROT_API
401 PARROT_WARN_UNUSED_RESULT
402 PARROT_CANNOT_RETURN_NULL
403 STRING *
404 key_string(PARROT_INTERP, ARGIN(PMC *key))
406 switch (PObj_get_FLAGS(key) & KEY_type_FLAGS) {
407 case KEY_string_FLAG:
408 return PMC_str_val(key);
409 case KEY_string_FLAG | KEY_register_FLAG:
410 return REG_STR(interp, PMC_int_val(key));
411 /* PMC_pmc_val(key)); */
412 case KEY_pmc_FLAG | KEY_register_FLAG:
414 PMC * const reg = REG_PMC(interp, PMC_int_val(key));
415 return VTABLE_get_string(interp, reg);
417 case KEY_integer_FLAG:
418 return string_from_int(interp, PMC_int_val(key));
419 case KEY_integer_FLAG | KEY_register_FLAG:
420 return string_from_int(interp, REG_INT(interp, PMC_int_val(key)));
421 default:
422 case KEY_pmc_FLAG:
423 return VTABLE_get_string(interp, key);
430 =item C<PMC * key_pmc>
432 These functions return the integer/number/string/PMC values of C<key> if
433 possible. Otherwise they throw exceptions.
435 =cut
439 PARROT_API
440 PARROT_CANNOT_RETURN_NULL
441 PARROT_WARN_UNUSED_RESULT
442 PMC *
443 key_pmc(PARROT_INTERP, ARGIN(PMC *key))
445 switch (PObj_get_FLAGS(key) & KEY_type_FLAGS) {
446 case KEY_pmc_FLAG | KEY_register_FLAG:
447 return REG_PMC(interp, PMC_int_val(key));
448 default:
449 return key; /* PMC_pmc_val(key); */
456 =item C<PMC * key_next>
458 Returns the next key if C<key> is in a sequence of linked keys.
460 =cut
464 PARROT_API
465 PARROT_CAN_RETURN_NULL
466 PARROT_WARN_UNUSED_RESULT
467 PMC *
468 key_next(PARROT_INTERP, ARGIN(PMC *key))
470 return VTABLE_isa(interp, key, CONST_STRING(interp, "Key")) && key->pmc_ext
471 ? (PMC *)PMC_data(key)
472 : NULL;
478 =item C<PMC * key_append>
480 Appends C<key2> to C<key1>.
482 Note that if C<key1> is not the last key in a sequence of linked keys then the
483 last key will be found and C<key2> appended to that.
485 Returns C<key1>.
487 =cut
491 PARROT_API
492 PARROT_CANNOT_RETURN_NULL
493 PARROT_IGNORABLE_RESULT
494 PMC *
495 key_append(SHIM_INTERP, ARGMOD(PMC *key1), ARGIN(PMC *key2))
497 PMC *tail = key1;
499 while (PMC_data(tail)) {
500 tail = (PMC *)PMC_data(tail);
503 PMC_data(tail) = key2;
505 return key1;
511 =item C<void key_mark>
513 Marks C<key> as live.
515 =cut
519 PARROT_API
520 void
521 key_mark(PARROT_INTERP, ARGIN(PMC *key))
523 const UINTVAL flags = PObj_get_FLAGS(key) & KEY_type_FLAGS;
525 if (flags == KEY_string_FLAG)
526 pobject_lives(interp, (PObj *)PMC_str_val(key));
529 * KEY_hash_iterator_FLAGS denote a hash key iteration, PMC_data() is
530 * the bucket_index and not the next key component
532 if (flags == KEY_hash_iterator_FLAGS)
533 return;
535 /* if iteration hasn't started, above flag isn't set yet */
536 if (PMC_data(key) && PMC_data(key) != (void *)INITBucketIndex)
537 pobject_lives(interp, (PObj *)PMC_data(key));
544 =item C<STRING * key_set_to_string>
546 Translates a series of key values into strings, quoted or bracketed if
547 appropriate. Takes an interpreter name and pointer to a key. Returns a
548 string value corresponding to the key.
550 =cut
554 PARROT_API
555 PARROT_CANNOT_RETURN_NULL
556 PARROT_WARN_UNUSED_RESULT
557 STRING *
558 key_set_to_string(PARROT_INTERP, ARGIN_NULLOK(PMC *key))
560 STRING * const semicolon = string_from_cstring(interp, " ; ", 3);
561 STRING * const quote = string_from_cstring(interp, "'", 1);
562 STRING *value = string_from_cstring(interp, "[ ", 2);
564 for (; key; key = (PMC *)PMC_data(key)) {
565 switch (PObj_get_FLAGS(key) & KEY_type_FLAGS) {
566 case KEY_integer_FLAG:
567 value = string_append(interp, value,
568 string_from_int(interp, PMC_int_val(key)));
569 break;
570 case KEY_string_FLAG:
571 value = string_append(interp, value, quote);
572 value = string_append(interp, value, PMC_str_val(key));
573 value = string_append(interp, value, quote);
574 break;
575 case KEY_pmc_FLAG:
576 value = string_append(interp, value,
577 VTABLE_get_string(interp, key));
578 break;
579 case KEY_integer_FLAG | KEY_register_FLAG:
580 value = string_append(interp, value,
581 string_from_int(interp,
582 REG_INT(interp, PMC_int_val(key))));
583 break;
584 case KEY_string_FLAG | KEY_register_FLAG:
585 value = string_append(interp, value, quote);
586 value = string_append(interp, value,
587 REG_STR(interp, PMC_int_val(key)));
588 value = string_append(interp, value, quote);
589 break;
590 case KEY_pmc_FLAG | KEY_register_FLAG:
592 PMC * const reg = REG_PMC(interp, PMC_int_val(key));
593 value = string_append(interp, value,
594 VTABLE_get_string(interp, reg));
596 break;
597 default:
598 value = string_append(interp, value, CONST_STRING(interp, "Key type unknown"));
599 break;
602 if (PMC_data(key))
603 value = string_append(interp, value, semicolon);
606 value = string_append(interp, value, string_from_cstring(interp, " ]", 2));
607 return value;
612 =back
614 =head1 SEE ALSO
616 F<include/parrot/key.h>.
618 =head1 HISTORY
620 Initial version by Jeff G. on 2001.12.05.
622 =cut
628 * Local variables:
629 * c-file-style: "parrot"
630 * End:
631 * vim: expandtab shiftwidth=4: