2 Copyright (C) 2001-2008, Parrot Foundation.
7 src/key.c - Base vtable calling functions
11 The base vtable calling functions.
21 #include "parrot/parrot.h"
22 #include "parrot/key.h"
24 #include "pmc/pmc_key.h"
26 /* HEADERIZER HFILE: include/parrot/key.h */
30 =item C<PMC * key_new(PARROT_INTERP)>
32 Returns a new C<Key> PMC.
39 PARROT_CANNOT_RETURN_NULL
40 PARROT_WARN_UNUSED_RESULT
42 key_new(PARROT_INTERP
)
45 return pmc_new(interp
, enum_class_Key
);
51 =item C<PMC * key_new_integer(PARROT_INTERP, INTVAL value)>
53 Returns a new integer C<Key> PMC with value C<value>.
60 PARROT_CANNOT_RETURN_NULL
61 PARROT_WARN_UNUSED_RESULT
63 key_new_integer(PARROT_INTERP
, INTVAL value
)
65 ASSERT_ARGS(key_new_integer
)
66 PMC
* const key
= pmc_new(interp
, enum_class_Key
);
68 PObj_get_FLAGS(key
) |= KEY_integer_FLAG
;
69 SETATTR_Key_int_key(interp
, key
, value
);
77 =item C<PMC * key_new_number(PARROT_INTERP, FLOATVAL value)>
79 Returns a new number C<Key> PMC with value C<value>.
86 PARROT_CANNOT_RETURN_NULL
87 PARROT_WARN_UNUSED_RESULT
89 key_new_number(PARROT_INTERP
, FLOATVAL value
)
91 ASSERT_ARGS(key_new_number
)
92 PMC
* const key
= pmc_new(interp
, enum_class_Key
);
94 PObj_get_FLAGS(key
) |= KEY_number_FLAG
;
95 SETATTR_Key_num_key(interp
, key
, value
);
103 =item C<PMC * key_new_string(PARROT_INTERP, STRING *value)>
105 Returns a new string C<Key> PMC with value C<value>.
112 PARROT_CANNOT_RETURN_NULL
113 PARROT_WARN_UNUSED_RESULT
115 key_new_string(PARROT_INTERP
, ARGIN(STRING
*value
))
117 ASSERT_ARGS(key_new_string
)
118 PMC
* const key
= pmc_new(interp
, enum_class_Key
);
120 PObj_get_FLAGS(key
) |= KEY_string_FLAG
;
121 SETATTR_Key_str_key(interp
, key
, value
);
129 =item C<PMC * key_new_cstring(PARROT_INTERP, const char *value)>
131 Returns a new string C<Key> PMC with value C<value> converted to a
139 PARROT_CANNOT_RETURN_NULL
140 PARROT_WARN_UNUSED_RESULT
142 key_new_cstring(PARROT_INTERP
, ARGIN_NULLOK(const char *value
))
144 ASSERT_ARGS(key_new_cstring
)
145 return key_new_string(interp
, Parrot_str_new(interp
, value
, 0));
151 =item C<PMC * key_new_pmc(PARROT_INTERP, PMC *value)>
153 Returns a new PMC C<Key> PMC with value C<value>.
160 PARROT_CANNOT_RETURN_NULL
161 PARROT_WARN_UNUSED_RESULT
163 key_new_pmc(PARROT_INTERP
, ARGIN(PMC
*value
))
165 ASSERT_ARGS(key_new_pmc
)
166 PMC
* const key
= pmc_new(interp
, enum_class_Key
);
168 PObj_get_FLAGS(key
) |= KEY_pmc_FLAG
;
169 Parrot_ex_throw_from_c_args(interp
, NULL
, 1, "this is broken - see slice.pmc");
175 =item C<void key_set_integer(PARROT_INTERP, PMC *key, INTVAL value)>
177 Set the integer C<value> in C<key>.
185 key_set_integer(PARROT_INTERP
, ARGMOD(PMC
*key
), INTVAL value
)
187 ASSERT_ARGS(key_set_integer
)
188 PObj_get_FLAGS(key
) &= ~KEY_type_FLAGS
;
189 PObj_get_FLAGS(key
) |= KEY_integer_FLAG
;
190 SETATTR_Key_int_key(interp
, key
, value
);
198 =item C<void key_set_register(PARROT_INTERP, PMC *key, INTVAL value, INTVAL
201 Set the register C<value> in C<key>.
209 key_set_register(PARROT_INTERP
, ARGMOD(PMC
*key
), INTVAL value
, INTVAL flag
)
211 ASSERT_ARGS(key_set_register
)
212 PObj_get_FLAGS(key
) &= ~KEY_type_FLAGS
;
213 PObj_get_FLAGS(key
) |= KEY_register_FLAG
| flag
;
214 SETATTR_Key_int_key(interp
, key
, value
);
222 =item C<void key_set_number(PARROT_INTERP, PMC *key, FLOATVAL value)>
224 Set the number C<value> in C<key>.
232 key_set_number(PARROT_INTERP
, ARGMOD(PMC
*key
), FLOATVAL value
)
234 ASSERT_ARGS(key_set_number
)
235 PObj_get_FLAGS(key
) &= ~KEY_type_FLAGS
;
236 PObj_get_FLAGS(key
) |= KEY_number_FLAG
;
237 SETATTR_Key_num_key(interp
, key
, value
);
245 =item C<void key_set_string(PARROT_INTERP, PMC *key, STRING *value)>
247 Set the string C<value> in C<key>.
255 key_set_string(PARROT_INTERP
, ARGMOD(PMC
*key
), ARGIN(STRING
*value
))
257 ASSERT_ARGS(key_set_string
)
258 PObj_get_FLAGS(key
) &= ~KEY_type_FLAGS
;
259 PObj_get_FLAGS(key
) |= KEY_string_FLAG
;
260 SETATTR_Key_str_key(interp
, key
, value
);
268 =item C<void key_set_pmc(PARROT_INTERP, PMC *key, PMC *value)>
270 Set the PMC C<value> in C<key>.
278 key_set_pmc(PARROT_INTERP
, ARGMOD(PMC
*key
), ARGIN(PMC
*value
))
280 ASSERT_ARGS(key_set_pmc
)
281 PObj_get_FLAGS(key
) &= ~KEY_type_FLAGS
;
282 PObj_get_FLAGS(key
) |= KEY_pmc_FLAG
;
286 * what for is this indirection?
288 Parrot_ex_throw_from_c_args(interp
, NULL
, 1, "this is broken - see slice.pmc");
294 =item C<INTVAL key_type(PARROT_INTERP, const PMC *key)>
296 Returns the type of C<key>.
303 PARROT_WARN_UNUSED_RESULT
305 key_type(SHIM_INTERP
, ARGIN(const PMC
*key
))
307 ASSERT_ARGS(key_type
)
308 return (PObj_get_FLAGS(key
) & KEY_type_FLAGS
) & ~KEY_register_FLAG
;
314 =item C<INTVAL key_integer(PARROT_INTERP, PMC *key)>
316 Translates a key value into an integer.
317 Takes an interpreter name and pointer to a key.
318 Returns an integer value corresponding to the key.
325 PARROT_WARN_UNUSED_RESULT
327 key_integer(PARROT_INTERP
, ARGIN(PMC
*key
))
329 ASSERT_ARGS(key_integer
)
334 switch (PObj_get_FLAGS(key
) & KEY_type_FLAGS
) {
335 case KEY_integer_FLAG
:
336 GETATTR_Key_int_key(interp
, key
, int_key
);
338 case KEY_integer_FLAG
| KEY_register_FLAG
:
339 GETATTR_Key_int_key(interp
, key
, int_key
);
340 return REG_INT(interp
, int_key
);
342 case KEY_number_FLAG
:
343 GETATTR_Key_num_key(interp
, key
, num_key
);
344 return (INTVAL
)num_key
;
345 case KEY_number_FLAG
| KEY_register_FLAG
:
346 GETATTR_Key_int_key(interp
, key
, int_key
);
347 return (INTVAL
)REG_NUM(interp
, int_key
);
349 case KEY_pmc_FLAG
| KEY_register_FLAG
:
352 GETATTR_Key_int_key(interp
, key
, int_key
);
353 reg
= REG_PMC(interp
, int_key
);
354 return VTABLE_get_integer(interp
, reg
);
357 case KEY_string_FLAG
:
358 GETATTR_Key_str_key(interp
, key
, str_key
);
359 return Parrot_str_to_int(interp
, str_key
);
360 case KEY_string_FLAG
| KEY_register_FLAG
:
363 GETATTR_Key_int_key(interp
, key
, int_key
);
364 s_reg
= REG_STR(interp
, int_key
);
365 return Parrot_str_to_int(interp
, s_reg
);
372 return VTABLE_get_integer(interp
, key
);
378 =item C<FLOATVAL key_number(PARROT_INTERP, PMC *key)>
380 Translates a key value into a number.
381 Takes an interpreter name and pointer to a key.
382 Returns a number value corresponding to the key.
383 Throws an exception if the key is not a valid number.
390 PARROT_WARN_UNUSED_RESULT
392 key_number(PARROT_INTERP
, ARGIN(PMC
*key
))
394 ASSERT_ARGS(key_number
)
398 switch (PObj_get_FLAGS(key
) & KEY_type_FLAGS
) {
399 case KEY_number_FLAG
:
400 GETATTR_Key_num_key(interp
, key
, num_key
);
402 case KEY_number_FLAG
| KEY_register_FLAG
:
403 GETATTR_Key_int_key(interp
, key
, int_key
);
404 return REG_NUM(interp
, int_key
);
406 return VTABLE_get_number(interp
, key
);
407 case KEY_pmc_FLAG
| KEY_register_FLAG
:
410 GETATTR_Key_int_key(interp
, key
, int_key
);
411 reg
= REG_PMC(interp
, int_key
);
412 return VTABLE_get_number(interp
, reg
);
415 Parrot_ex_throw_from_c_args(interp
, NULL
, EXCEPTION_INVALID_OPERATION
,
416 "Key not a number!\n");
423 =item C<STRING * key_string(PARROT_INTERP, PMC *key)>
425 Translates a key value into a string. Takes an interpreter name and pointer to
426 a key. Returns a string value corresponding to the key.
432 PARROT_WARN_UNUSED_RESULT
433 PARROT_CAN_RETURN_NULL
435 key_string(PARROT_INTERP
, ARGIN(PMC
*key
))
437 ASSERT_ARGS(key_string
)
439 switch (PObj_get_FLAGS(key
) & KEY_type_FLAGS
) {
440 /* remember to COW strings instead of returning them directly */
441 case KEY_string_FLAG
:
444 GETATTR_Key_str_key(interp
, key
, s
);
446 s
= Parrot_str_new_COW(interp
, s
);
449 case KEY_string_FLAG
| KEY_register_FLAG
:
453 GETATTR_Key_int_key(interp
, key
, int_key
);
454 s
= REG_STR(interp
, int_key
);
456 s
= Parrot_str_new_COW(interp
, s
);
459 case KEY_pmc_FLAG
| KEY_register_FLAG
:
463 GETATTR_Key_int_key(interp
, key
, int_key
);
464 reg
= REG_PMC(interp
, int_key
);
465 return VTABLE_get_string(interp
, reg
);
467 case KEY_integer_FLAG
:
470 GETATTR_Key_int_key(interp
, key
, int_key
);
471 return Parrot_str_from_int(interp
, int_key
);
473 case KEY_integer_FLAG
| KEY_register_FLAG
:
476 GETATTR_Key_int_key(interp
, key
, int_key
);
477 return Parrot_str_from_int(interp
, REG_INT(interp
, int_key
));
479 case KEY_number_FLAG
:
482 GETATTR_Key_num_key(interp
, key
, num_key
);
483 return Parrot_str_from_num(interp
, num_key
);
485 case KEY_number_FLAG
| KEY_register_FLAG
:
488 GETATTR_Key_int_key(interp
, key
, int_key
);
489 return Parrot_str_from_num(interp
, REG_NUM(interp
, int_key
));
493 return VTABLE_get_string(interp
, key
);
500 =item C<PMC * key_pmc(PARROT_INTERP, PMC *key)>
502 These functions return the integer/number/string/PMC values of C<key> if
503 possible. Otherwise they throw exceptions.
510 PARROT_CANNOT_RETURN_NULL
511 PARROT_WARN_UNUSED_RESULT
513 key_pmc(PARROT_INTERP
, ARGIN(PMC
*key
))
518 switch (PObj_get_FLAGS(key
) & KEY_type_FLAGS
) {
519 case KEY_pmc_FLAG
| KEY_register_FLAG
:
520 GETATTR_Key_int_key(interp
, key
, int_key
);
521 return REG_PMC(interp
, int_key
);
530 =item C<PMC * key_next(PARROT_INTERP, PMC *key)>
532 Returns the next key if C<key> is in a sequence of linked keys.
539 PARROT_CAN_RETURN_NULL
540 PARROT_WARN_UNUSED_RESULT
542 key_next(PARROT_INTERP
, ARGIN(PMC
*key
))
544 ASSERT_ARGS(key_next
)
547 if (VTABLE_isa(interp
, key
, CONST_STRING(interp
, "Key")) && key
->pmc_ext
) {
548 GETATTR_Key_next_key(interp
, key
, next_key
);
558 =item C<PMC * key_append(PARROT_INTERP, PMC *key1, PMC *key2)>
560 Appends C<key2> to C<key1>.
562 Note that if C<key1> is not the last key in a sequence of linked keys then the
563 last key will be found and C<key2> appended to that.
572 PARROT_CANNOT_RETURN_NULL
573 PARROT_IGNORABLE_RESULT
575 key_append(PARROT_INTERP
, ARGMOD(PMC
*key1
), ARGIN(PMC
*key2
))
577 ASSERT_ARGS(key_append
)
581 GETATTR_Key_next_key(interp
, tail
, tail_next
);
585 GETATTR_Key_next_key(interp
, tail
, tail_next
);
588 SETATTR_Key_next_key(interp
, tail
, key2
);
596 =item C<void key_mark(PARROT_INTERP, PMC *key)>
598 Marks C<key> as live.
606 key_mark(PARROT_INTERP
, ARGIN(PMC
*key
))
608 ASSERT_ARGS(key_mark
)
610 const UINTVAL flags
= PObj_get_FLAGS(key
) & KEY_type_FLAGS
;
612 if (flags
== KEY_string_FLAG
) {
614 GETATTR_Key_str_key(interp
, key
, str_key
);
616 /* XXX str_key can be NULL from GETATTR_Key_str_key, */
617 /* so shouldn't be marked. */
618 Parrot_gc_mark_PObj_alive(interp
, (PObj
*)str_key
);
622 if ((flags
== KEY_string_FLAG
) || (flags
== KEY_pmc_FLAG
)) {
623 GETATTR_Key_next_key(interp
, key
, next_key
);
625 Parrot_gc_mark_PObj_alive(interp
, (PObj
*)next_key
);
633 =item C<STRING * key_set_to_string(PARROT_INTERP, PMC *key)>
635 Translates a series of key values into strings, quoted or bracketed if
636 appropriate. Takes an interpreter name and pointer to a key. Returns a
637 string value corresponding to the key.
644 PARROT_CANNOT_RETURN_NULL
645 PARROT_WARN_UNUSED_RESULT
647 key_set_to_string(PARROT_INTERP
, ARGIN_NULLOK(PMC
*key
))
649 ASSERT_ARGS(key_set_to_string
)
650 STRING
* const semicolon
= CONST_STRING(interp
, " ; ");
651 STRING
* const quote
= CONST_STRING(interp
, "'");
652 STRING
*value
= Parrot_str_new(interp
, "[ ", 2);
657 while (key
!= NULL
) {
658 switch (PObj_get_FLAGS(key
) & KEY_type_FLAGS
) {
659 case KEY_integer_FLAG
:
660 GETATTR_Key_int_key(interp
, key
, int_key
);
661 value
= Parrot_str_append(interp
, value
,
662 Parrot_str_from_int(interp
, int_key
));
664 case KEY_number_FLAG
:
665 GETATTR_Key_int_key(interp
, key
, int_key
);
666 value
= Parrot_str_append(interp
, value
,
667 Parrot_str_from_num(interp
, (FLOATVAL
)int_key
));
669 case KEY_string_FLAG
:
670 GETATTR_Key_str_key(interp
, key
, str_key
);
671 value
= Parrot_str_append(interp
, value
, quote
);
672 value
= Parrot_str_append(interp
, value
, str_key
);
673 value
= Parrot_str_append(interp
, value
, quote
);
676 value
= Parrot_str_append(interp
, value
,
677 VTABLE_get_string(interp
, key
));
679 case KEY_integer_FLAG
| KEY_register_FLAG
:
680 GETATTR_Key_int_key(interp
, key
, int_key
);
681 value
= Parrot_str_append(interp
, value
,
682 Parrot_str_from_int(interp
,
683 REG_INT(interp
, int_key
)));
685 case KEY_number_FLAG
| KEY_register_FLAG
:
686 GETATTR_Key_int_key(interp
, key
, int_key
);
687 value
= Parrot_str_append(interp
, value
,
688 Parrot_str_from_num(interp
,
689 REG_NUM(interp
, int_key
)));
691 case KEY_string_FLAG
| KEY_register_FLAG
:
692 value
= Parrot_str_append(interp
, value
, quote
);
693 GETATTR_Key_int_key(interp
, key
, int_key
);
694 value
= Parrot_str_append(interp
, value
,
695 REG_STR(interp
, int_key
));
696 value
= Parrot_str_append(interp
, value
, quote
);
698 case KEY_pmc_FLAG
| KEY_register_FLAG
:
701 GETATTR_Key_int_key(interp
, key
, int_key
);
702 reg
= REG_PMC(interp
, int_key
);
703 value
= Parrot_str_append(interp
, value
,
704 VTABLE_get_string(interp
, reg
));
708 value
= Parrot_str_append(interp
, value
, CONST_STRING(interp
, "Key type unknown"));
712 GETATTR_Key_next_key(interp
, key
, next_key
);
714 value
= Parrot_str_append(interp
, value
, semicolon
);
716 GETATTR_Key_next_key(interp
, key
, key
);
719 value
= Parrot_str_append(interp
, value
, Parrot_str_new(interp
, " ]", 2));
729 F<include/parrot/key.h>.
733 Initial version by Jeff G. on 2001.12.05.
742 * c-file-style: "parrot"
744 * vim: expandtab shiftwidth=4: