add generated_hello.pbc to examples-clean
[parrot.git] / src / key.c
blob479bd638a87929802cddef7f09b166ec436302df
1 /*
2 Copyright (C) 2001-2010, Parrot 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"
24 #include "pmc/pmc_key.h"
25 #include "pmc/pmc_callcontext.h"
27 /* HEADERIZER HFILE: include/parrot/key.h */
31 =item C<PMC * key_new(PARROT_INTERP)>
33 Returns a new C<Key> PMC.
35 =cut
39 PARROT_EXPORT
40 PARROT_CANNOT_RETURN_NULL
41 PARROT_WARN_UNUSED_RESULT
42 PMC *
43 key_new(PARROT_INTERP)
45 ASSERT_ARGS(key_new)
46 return Parrot_pmc_new(interp, enum_class_Key);
52 =item C<PMC * key_new_integer(PARROT_INTERP, INTVAL value)>
54 Returns a new integer C<Key> PMC with value C<value>.
56 =cut
60 PARROT_EXPORT
61 PARROT_CANNOT_RETURN_NULL
62 PARROT_WARN_UNUSED_RESULT
63 PMC *
64 key_new_integer(PARROT_INTERP, INTVAL value)
66 ASSERT_ARGS(key_new_integer)
67 PMC * const key = Parrot_pmc_new(interp, enum_class_Key);
69 PObj_get_FLAGS(key) |= KEY_integer_FLAG;
70 SETATTR_Key_int_key(interp, key, value);
72 return key;
78 =item C<PMC * key_new_number(PARROT_INTERP, FLOATVAL value)>
80 Returns a new number C<Key> PMC with value C<value>.
82 =cut
86 PARROT_EXPORT
87 PARROT_CANNOT_RETURN_NULL
88 PARROT_WARN_UNUSED_RESULT
89 PMC *
90 key_new_number(PARROT_INTERP, FLOATVAL value)
92 ASSERT_ARGS(key_new_number)
93 PMC * const key = Parrot_pmc_new(interp, enum_class_Key);
95 PObj_get_FLAGS(key) |= KEY_number_FLAG;
96 SETATTR_Key_num_key(interp, key, value);
98 return key;
104 =item C<PMC * key_new_string(PARROT_INTERP, STRING *value)>
106 Returns a new string C<Key> PMC with value C<value>.
108 =cut
112 PARROT_EXPORT
113 PARROT_CANNOT_RETURN_NULL
114 PARROT_WARN_UNUSED_RESULT
115 PMC *
116 key_new_string(PARROT_INTERP, ARGIN(STRING *value))
118 ASSERT_ARGS(key_new_string)
119 PMC * const key = Parrot_pmc_new(interp, enum_class_Key);
121 PObj_get_FLAGS(key) |= KEY_string_FLAG;
122 SETATTR_Key_str_key(interp, key, value);
124 return key;
130 =item C<PMC * key_new_cstring(PARROT_INTERP, const char *value)>
132 Returns a new string C<Key> PMC with value C<value> converted to a
133 C<STRING>.
135 =cut
139 PARROT_EXPORT
140 PARROT_CANNOT_RETURN_NULL
141 PARROT_WARN_UNUSED_RESULT
142 PMC *
143 key_new_cstring(PARROT_INTERP, ARGIN_NULLOK(const char *value))
145 ASSERT_ARGS(key_new_cstring)
146 return key_new_string(interp, Parrot_str_new(interp, value, 0));
151 =item C<void key_set_integer(PARROT_INTERP, PMC *key, INTVAL value)>
153 Set the integer C<value> in C<key>.
155 =cut
159 PARROT_EXPORT
160 void
161 key_set_integer(PARROT_INTERP, ARGMOD(PMC *key), INTVAL value)
163 ASSERT_ARGS(key_set_integer)
164 PObj_get_FLAGS(key) &= ~KEY_type_FLAGS;
165 PObj_get_FLAGS(key) |= KEY_integer_FLAG;
166 SETATTR_Key_int_key(interp, key, value);
168 return;
174 =item C<void key_set_register(PARROT_INTERP, PMC *key, INTVAL value, INTVAL
175 flag)>
177 Set the register C<value> in C<key>.
179 =cut
183 PARROT_EXPORT
184 void
185 key_set_register(PARROT_INTERP, ARGMOD(PMC *key), INTVAL value, INTVAL flag)
187 ASSERT_ARGS(key_set_register)
188 PObj_get_FLAGS(key) &= ~KEY_type_FLAGS;
189 PObj_get_FLAGS(key) |= KEY_register_FLAG | flag;
190 SETATTR_Key_int_key(interp, key, value);
192 return;
198 =item C<void key_set_number(PARROT_INTERP, PMC *key, FLOATVAL value)>
200 Set the number C<value> in C<key>.
202 =cut
206 PARROT_EXPORT
207 void
208 key_set_number(PARROT_INTERP, ARGMOD(PMC *key), FLOATVAL value)
210 ASSERT_ARGS(key_set_number)
211 PObj_get_FLAGS(key) &= ~KEY_type_FLAGS;
212 PObj_get_FLAGS(key) |= KEY_number_FLAG;
213 SETATTR_Key_num_key(interp, key, value);
215 return;
221 =item C<void key_set_string(PARROT_INTERP, PMC *key, STRING *value)>
223 Set the string C<value> in C<key>.
225 =cut
229 PARROT_EXPORT
230 void
231 key_set_string(PARROT_INTERP, ARGMOD(PMC *key), ARGIN(STRING *value))
233 ASSERT_ARGS(key_set_string)
234 PObj_get_FLAGS(key) &= ~KEY_type_FLAGS;
235 PObj_get_FLAGS(key) |= KEY_string_FLAG;
236 SETATTR_Key_str_key(interp, key, value);
238 return;
243 =item C<INTVAL key_type(PARROT_INTERP, const PMC *key)>
245 Returns the type of C<key>.
247 =cut
251 PARROT_EXPORT
252 PARROT_PURE_FUNCTION
253 PARROT_WARN_UNUSED_RESULT
254 INTVAL
255 key_type(SHIM_INTERP, ARGIN(const PMC *key))
257 ASSERT_ARGS(key_type)
258 return (PObj_get_FLAGS(key) & KEY_type_FLAGS) & ~KEY_register_FLAG;
264 =item C<INTVAL key_integer(PARROT_INTERP, PMC *key)>
266 Translates a key value into an integer.
267 Takes an interpreter name and pointer to a key.
268 Returns an integer value corresponding to the key.
270 =cut
274 PARROT_EXPORT
275 PARROT_WARN_UNUSED_RESULT
276 INTVAL
277 key_integer(PARROT_INTERP, ARGIN(PMC *key))
279 ASSERT_ARGS(key_integer)
280 INTVAL int_key;
281 STRING *str_key;
282 FLOATVAL num_key;
284 switch (PObj_get_FLAGS(key) & KEY_type_FLAGS) {
285 case KEY_integer_FLAG:
286 GETATTR_Key_int_key(interp, key, int_key);
287 return int_key;
288 case KEY_integer_FLAG | KEY_register_FLAG:
289 GETATTR_Key_int_key(interp, key, int_key);
290 return REG_INT(interp, int_key);
292 case KEY_number_FLAG:
293 GETATTR_Key_num_key(interp, key, num_key);
294 return (INTVAL)num_key;
295 case KEY_number_FLAG | KEY_register_FLAG:
296 GETATTR_Key_int_key(interp, key, int_key);
297 return (INTVAL)REG_NUM(interp, int_key);
299 case KEY_pmc_FLAG | KEY_register_FLAG:
301 PMC *reg;
302 GETATTR_Key_int_key(interp, key, int_key);
303 reg = REG_PMC(interp, int_key);
304 return VTABLE_get_integer(interp, reg);
307 case KEY_string_FLAG:
308 GETATTR_Key_str_key(interp, key, str_key);
309 return Parrot_str_to_int(interp, str_key);
310 case KEY_string_FLAG | KEY_register_FLAG:
312 STRING *s_reg;
313 GETATTR_Key_int_key(interp, key, int_key);
314 s_reg = REG_STR(interp, int_key);
315 return Parrot_str_to_int(interp, s_reg);
318 default:
319 break;
322 return VTABLE_get_integer(interp, key);
328 =item C<FLOATVAL key_number(PARROT_INTERP, PMC *key)>
330 Translates a key value into a number.
331 Takes an interpreter name and pointer to a key.
332 Returns a number value corresponding to the key.
333 Throws an exception if the key is not a valid number.
335 =cut
339 PARROT_EXPORT
340 PARROT_WARN_UNUSED_RESULT
341 FLOATVAL
342 key_number(PARROT_INTERP, ARGIN(PMC *key))
344 ASSERT_ARGS(key_number)
345 INTVAL int_key;
346 FLOATVAL num_key;
348 switch (PObj_get_FLAGS(key) & KEY_type_FLAGS) {
349 case KEY_number_FLAG:
350 GETATTR_Key_num_key(interp, key, num_key);
351 return num_key;
352 case KEY_number_FLAG | KEY_register_FLAG:
353 GETATTR_Key_int_key(interp, key, int_key);
354 return REG_NUM(interp, int_key);
355 case KEY_pmc_FLAG:
356 return VTABLE_get_number(interp, key);
357 case KEY_pmc_FLAG | KEY_register_FLAG:
359 PMC *reg;
360 GETATTR_Key_int_key(interp, key, int_key);
361 reg = REG_PMC(interp, int_key);
362 return VTABLE_get_number(interp, reg);
364 default:
365 Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
366 "Key not a number!\n");
373 =item C<STRING * key_string(PARROT_INTERP, PMC *key)>
375 Translates a key value into a string. Takes an interpreter name and pointer to
376 a key. Returns a string value corresponding to the key.
378 =cut
382 PARROT_WARN_UNUSED_RESULT
383 PARROT_CAN_RETURN_NULL
384 STRING *
385 key_string(PARROT_INTERP, ARGIN(PMC *key))
387 ASSERT_ARGS(key_string)
389 switch (PObj_get_FLAGS(key) & KEY_type_FLAGS) {
390 /* remember to COW strings instead of returning them directly */
391 case KEY_string_FLAG:
393 STRING *s;
394 GETATTR_Key_str_key(interp, key, s);
395 return s;
397 case KEY_string_FLAG | KEY_register_FLAG:
399 INTVAL int_key;
400 GETATTR_Key_int_key(interp, key, int_key);
401 return REG_STR(interp, int_key);
403 case KEY_pmc_FLAG | KEY_register_FLAG:
405 INTVAL int_key;
406 PMC *reg;
407 GETATTR_Key_int_key(interp, key, int_key);
408 reg = REG_PMC(interp, int_key);
409 return VTABLE_get_string(interp, reg);
411 case KEY_integer_FLAG:
413 INTVAL int_key;
414 GETATTR_Key_int_key(interp, key, int_key);
415 return Parrot_str_from_int(interp, int_key);
417 case KEY_integer_FLAG | KEY_register_FLAG:
419 INTVAL int_key;
420 GETATTR_Key_int_key(interp, key, int_key);
421 return Parrot_str_from_int(interp, REG_INT(interp, int_key));
423 case KEY_number_FLAG:
425 FLOATVAL num_key;
426 GETATTR_Key_num_key(interp, key, num_key);
427 return Parrot_str_from_num(interp, num_key);
429 case KEY_number_FLAG | KEY_register_FLAG:
431 INTVAL int_key;
432 GETATTR_Key_int_key(interp, key, int_key);
433 return Parrot_str_from_num(interp, REG_NUM(interp, int_key));
435 default:
436 case KEY_pmc_FLAG:
437 return VTABLE_get_string(interp, key);
444 =item C<PMC * key_pmc(PARROT_INTERP, PMC *key)>
446 These functions return the integer/number/string/PMC values of C<key> if
447 possible. Otherwise they throw exceptions.
449 =cut
453 PARROT_EXPORT
454 PARROT_CANNOT_RETURN_NULL
455 PARROT_WARN_UNUSED_RESULT
456 PMC *
457 key_pmc(PARROT_INTERP, ARGIN(PMC *key))
459 ASSERT_ARGS(key_pmc)
460 INTVAL int_key;
462 switch (PObj_get_FLAGS(key) & KEY_type_FLAGS) {
463 case KEY_pmc_FLAG | KEY_register_FLAG:
464 GETATTR_Key_int_key(interp, key, int_key);
465 return REG_PMC(interp, int_key);
466 default:
467 return key;
474 =item C<PMC * key_next(PARROT_INTERP, PMC *key)>
476 Returns the next key if C<key> is in a sequence of linked keys.
478 =cut
482 PARROT_EXPORT
483 PARROT_CAN_RETURN_NULL
484 PARROT_WARN_UNUSED_RESULT
485 PMC *
486 key_next(PARROT_INTERP, ARGIN(PMC *key))
488 ASSERT_ARGS(key_next)
490 if (VTABLE_isa(interp, key, CONST_STRING(interp, "Key"))) {
491 PMC *next_key;
492 GETATTR_Key_next_key(interp, key, next_key);
493 return next_key;
496 return NULL;
502 =item C<PMC * key_append(PARROT_INTERP, PMC *key1, PMC *key2)>
504 Appends C<key2> to C<key1>.
506 Note that if C<key1> is not the last key in a sequence of linked keys then the
507 last key will be found and C<key2> appended to that.
509 Returns C<key1>.
511 =cut
515 PARROT_EXPORT
516 PARROT_CANNOT_RETURN_NULL
517 PARROT_IGNORABLE_RESULT
518 PMC *
519 key_append(PARROT_INTERP, ARGMOD(PMC *key1), ARGIN(PMC *key2))
521 ASSERT_ARGS(key_append)
522 PMC *tail = key1;
523 PMC *tail_next;
525 GETATTR_Key_next_key(interp, tail, tail_next);
527 while (tail_next) {
528 tail = tail_next;
529 GETATTR_Key_next_key(interp, tail, tail_next);
532 SETATTR_Key_next_key(interp, tail, key2);
534 return key1;
540 =item C<void key_mark(PARROT_INTERP, PMC *key)>
542 Marks C<key> as live.
544 =cut
548 PARROT_EXPORT
549 void
550 key_mark(PARROT_INTERP, ARGIN(PMC *key))
552 ASSERT_ARGS(key_mark)
553 PMC *next_key;
554 const UINTVAL flags = PObj_get_FLAGS(key) & KEY_type_FLAGS;
556 if (flags == KEY_string_FLAG) {
557 STRING *str_key;
558 GETATTR_Key_str_key(interp, key, str_key);
559 Parrot_gc_mark_STRING_alive(interp, str_key);
562 /* Mark next key */
563 if ((flags == KEY_string_FLAG) || (flags == KEY_pmc_FLAG)) {
564 GETATTR_Key_next_key(interp, key, next_key);
565 Parrot_gc_mark_PMC_alive(interp, next_key);
573 =item C<STRING * key_set_to_string(PARROT_INTERP, PMC *key)>
575 Translates a series of key values into strings, quoted or bracketed if
576 appropriate. Takes an interpreter name and pointer to a key. Returns a
577 string value corresponding to the key.
579 =cut
583 PARROT_EXPORT
584 PARROT_CANNOT_RETURN_NULL
585 PARROT_WARN_UNUSED_RESULT
586 STRING *
587 key_set_to_string(PARROT_INTERP, ARGIN_NULLOK(PMC *key))
589 ASSERT_ARGS(key_set_to_string)
590 STRING * const semicolon = CONST_STRING(interp, " ; ");
591 STRING * const quote = CONST_STRING(interp, "'");
592 STRING *value = Parrot_str_new(interp, "[ ", 2);
593 PMC *next_key;
594 INTVAL int_key;
595 STRING *str_key;
597 while (key != NULL) {
598 switch (PObj_get_FLAGS(key) & KEY_type_FLAGS) {
599 case KEY_integer_FLAG:
600 GETATTR_Key_int_key(interp, key, int_key);
601 value = Parrot_str_concat(interp, value,
602 Parrot_str_from_int(interp, int_key));
603 break;
604 case KEY_number_FLAG:
605 GETATTR_Key_int_key(interp, key, int_key);
606 value = Parrot_str_concat(interp, value,
607 Parrot_str_from_num(interp, (FLOATVAL)int_key));
608 break;
609 case KEY_string_FLAG:
610 GETATTR_Key_str_key(interp, key, str_key);
611 value = Parrot_str_concat(interp, value, quote);
612 value = Parrot_str_concat(interp, value, str_key);
613 value = Parrot_str_concat(interp, value, quote);
614 break;
615 case KEY_pmc_FLAG:
616 value = Parrot_str_concat(interp, value,
617 VTABLE_get_string(interp, key));
618 break;
619 case KEY_integer_FLAG | KEY_register_FLAG:
620 GETATTR_Key_int_key(interp, key, int_key);
621 value = Parrot_str_concat(interp, value,
622 Parrot_str_from_int(interp,
623 REG_INT(interp, int_key)));
624 break;
625 case KEY_number_FLAG | KEY_register_FLAG:
626 GETATTR_Key_int_key(interp, key, int_key);
627 value = Parrot_str_concat(interp, value,
628 Parrot_str_from_num(interp,
629 REG_NUM(interp, int_key)));
630 break;
631 case KEY_string_FLAG | KEY_register_FLAG:
632 value = Parrot_str_concat(interp, value, quote);
633 GETATTR_Key_int_key(interp, key, int_key);
634 value = Parrot_str_concat(interp, value,
635 REG_STR(interp, int_key));
636 value = Parrot_str_concat(interp, value, quote);
637 break;
638 case KEY_pmc_FLAG | KEY_register_FLAG:
640 PMC *reg;
641 GETATTR_Key_int_key(interp, key, int_key);
642 reg = REG_PMC(interp, int_key);
643 value = Parrot_str_concat(interp, value,
644 VTABLE_get_string(interp, reg));
646 break;
647 default:
648 value = Parrot_str_concat(interp, value, CONST_STRING(interp, "Key type unknown"));
649 break;
652 GETATTR_Key_next_key(interp, key, next_key);
653 if (next_key)
654 value = Parrot_str_concat(interp, value, semicolon);
656 GETATTR_Key_next_key(interp, key, key);
659 value = Parrot_str_concat(interp, value, Parrot_str_new(interp, " ]", 2));
660 return value;
665 =back
667 =head1 SEE ALSO
669 F<include/parrot/key.h>.
671 =cut
677 * Local variables:
678 * c-file-style: "parrot"
679 * End:
680 * vim: expandtab shiftwidth=4: