2 Copyright (C) 2001-2010, 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"
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.
40 PARROT_CANNOT_RETURN_NULL
41 PARROT_WARN_UNUSED_RESULT
43 key_new(PARROT_INTERP
)
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>.
61 PARROT_CANNOT_RETURN_NULL
62 PARROT_WARN_UNUSED_RESULT
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
);
78 =item C<PMC * key_new_number(PARROT_INTERP, FLOATVAL value)>
80 Returns a new number C<Key> PMC with value C<value>.
87 PARROT_CANNOT_RETURN_NULL
88 PARROT_WARN_UNUSED_RESULT
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
);
104 =item C<PMC * key_new_string(PARROT_INTERP, STRING *value)>
106 Returns a new string C<Key> PMC with value C<value>.
113 PARROT_CANNOT_RETURN_NULL
114 PARROT_WARN_UNUSED_RESULT
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
);
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
140 PARROT_CANNOT_RETURN_NULL
141 PARROT_WARN_UNUSED_RESULT
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>.
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
);
174 =item C<void key_set_register(PARROT_INTERP, PMC *key, INTVAL value, INTVAL
177 Set the register C<value> in C<key>.
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
);
198 =item C<void key_set_number(PARROT_INTERP, PMC *key, FLOATVAL value)>
200 Set the number C<value> in C<key>.
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
);
221 =item C<void key_set_string(PARROT_INTERP, PMC *key, STRING *value)>
223 Set the string C<value> in C<key>.
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
);
243 =item C<INTVAL key_type(PARROT_INTERP, const PMC *key)>
245 Returns the type of C<key>.
253 PARROT_WARN_UNUSED_RESULT
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.
275 PARROT_WARN_UNUSED_RESULT
277 key_integer(PARROT_INTERP
, ARGIN(PMC
*key
))
279 ASSERT_ARGS(key_integer
)
284 switch (PObj_get_FLAGS(key
) & KEY_type_FLAGS
) {
285 case KEY_integer_FLAG
:
286 GETATTR_Key_int_key(interp
, key
, 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
:
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
:
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
);
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.
340 PARROT_WARN_UNUSED_RESULT
342 key_number(PARROT_INTERP
, ARGIN(PMC
*key
))
344 ASSERT_ARGS(key_number
)
348 switch (PObj_get_FLAGS(key
) & KEY_type_FLAGS
) {
349 case KEY_number_FLAG
:
350 GETATTR_Key_num_key(interp
, key
, 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
);
356 return VTABLE_get_number(interp
, key
);
357 case KEY_pmc_FLAG
| KEY_register_FLAG
:
360 GETATTR_Key_int_key(interp
, key
, int_key
);
361 reg
= REG_PMC(interp
, int_key
);
362 return VTABLE_get_number(interp
, reg
);
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.
383 PARROT_WARN_UNUSED_RESULT
384 PARROT_CAN_RETURN_NULL
386 key_string(PARROT_INTERP
, ARGIN(PMC
*key
))
388 ASSERT_ARGS(key_string
)
390 switch (PObj_get_FLAGS(key
) & KEY_type_FLAGS
) {
391 /* remember to COW strings instead of returning them directly */
392 case KEY_string_FLAG
:
395 GETATTR_Key_str_key(interp
, key
, s
);
398 case KEY_string_FLAG
| KEY_register_FLAG
:
401 GETATTR_Key_int_key(interp
, key
, int_key
);
402 return REG_STR(interp
, int_key
);
404 case KEY_pmc_FLAG
| KEY_register_FLAG
:
408 GETATTR_Key_int_key(interp
, key
, int_key
);
409 reg
= REG_PMC(interp
, int_key
);
410 return VTABLE_get_string(interp
, reg
);
412 case KEY_integer_FLAG
:
415 GETATTR_Key_int_key(interp
, key
, int_key
);
416 return Parrot_str_from_int(interp
, int_key
);
418 case KEY_integer_FLAG
| KEY_register_FLAG
:
421 GETATTR_Key_int_key(interp
, key
, int_key
);
422 return Parrot_str_from_int(interp
, REG_INT(interp
, int_key
));
424 case KEY_number_FLAG
:
427 GETATTR_Key_num_key(interp
, key
, num_key
);
428 return Parrot_str_from_num(interp
, num_key
);
430 case KEY_number_FLAG
| KEY_register_FLAG
:
433 GETATTR_Key_int_key(interp
, key
, int_key
);
434 return Parrot_str_from_num(interp
, REG_NUM(interp
, int_key
));
438 return VTABLE_get_string(interp
, key
);
445 =item C<PMC * key_pmc(PARROT_INTERP, PMC *key)>
447 These functions return the integer/number/string/PMC values of C<key> if
448 possible. Otherwise they throw exceptions.
455 PARROT_CANNOT_RETURN_NULL
456 PARROT_WARN_UNUSED_RESULT
458 key_pmc(PARROT_INTERP
, ARGIN(PMC
*key
))
463 switch (PObj_get_FLAGS(key
) & KEY_type_FLAGS
) {
464 case KEY_pmc_FLAG
| KEY_register_FLAG
:
465 GETATTR_Key_int_key(interp
, key
, int_key
);
466 return REG_PMC(interp
, int_key
);
475 =item C<PMC * key_next(PARROT_INTERP, PMC *key)>
477 Returns the next key if C<key> is in a sequence of linked keys.
484 PARROT_CAN_RETURN_NULL
485 PARROT_WARN_UNUSED_RESULT
487 key_next(PARROT_INTERP
, ARGIN(PMC
*key
))
489 ASSERT_ARGS(key_next
)
491 if (VTABLE_isa(interp
, key
, CONST_STRING(interp
, "Key"))) {
493 GETATTR_Key_next_key(interp
, key
, next_key
);
503 =item C<PMC * key_append(PARROT_INTERP, PMC *key1, PMC *key2)>
505 Appends C<key2> to C<key1>.
507 Note that if C<key1> is not the last key in a sequence of linked keys then the
508 last key will be found and C<key2> appended to that.
517 PARROT_CANNOT_RETURN_NULL
518 PARROT_IGNORABLE_RESULT
520 key_append(PARROT_INTERP
, ARGMOD(PMC
*key1
), ARGIN(PMC
*key2
))
522 ASSERT_ARGS(key_append
)
526 GETATTR_Key_next_key(interp
, tail
, tail_next
);
530 GETATTR_Key_next_key(interp
, tail
, tail_next
);
533 SETATTR_Key_next_key(interp
, tail
, key2
);
541 =item C<void key_mark(PARROT_INTERP, PMC *key)>
543 Marks C<key> as live.
551 key_mark(PARROT_INTERP
, ARGIN(PMC
*key
))
553 ASSERT_ARGS(key_mark
)
555 const UINTVAL flags
= PObj_get_FLAGS(key
) & KEY_type_FLAGS
;
557 if (flags
== KEY_string_FLAG
) {
559 GETATTR_Key_str_key(interp
, key
, str_key
);
560 Parrot_gc_mark_STRING_alive(interp
, str_key
);
564 if ((flags
== KEY_string_FLAG
) || (flags
== KEY_pmc_FLAG
)) {
565 GETATTR_Key_next_key(interp
, key
, next_key
);
566 Parrot_gc_mark_PMC_alive(interp
, next_key
);
574 =item C<STRING * key_set_to_string(PARROT_INTERP, PMC *key)>
576 Translates a series of key values into strings, quoted or bracketed if
577 appropriate. Takes an interpreter name and pointer to a key. Returns a
578 string value corresponding to the key.
585 PARROT_CANNOT_RETURN_NULL
586 PARROT_WARN_UNUSED_RESULT
588 key_set_to_string(PARROT_INTERP
, ARGIN_NULLOK(PMC
*key
))
590 ASSERT_ARGS(key_set_to_string
)
591 STRING
* const semicolon
= CONST_STRING(interp
, " ; ");
592 STRING
* const quote
= CONST_STRING(interp
, "'");
593 STRING
*value
= Parrot_str_new(interp
, "[ ", 2);
598 while (key
!= NULL
) {
599 switch (PObj_get_FLAGS(key
) & KEY_type_FLAGS
) {
600 case KEY_integer_FLAG
:
601 GETATTR_Key_int_key(interp
, key
, int_key
);
602 value
= Parrot_str_concat(interp
, value
,
603 Parrot_str_from_int(interp
, int_key
));
605 case KEY_number_FLAG
:
606 GETATTR_Key_int_key(interp
, key
, int_key
);
607 value
= Parrot_str_concat(interp
, value
,
608 Parrot_str_from_num(interp
, (FLOATVAL
)int_key
));
610 case KEY_string_FLAG
:
611 GETATTR_Key_str_key(interp
, key
, str_key
);
612 value
= Parrot_str_concat(interp
, value
, quote
);
613 value
= Parrot_str_concat(interp
, value
, str_key
);
614 value
= Parrot_str_concat(interp
, value
, quote
);
617 value
= Parrot_str_concat(interp
, value
,
618 VTABLE_get_string(interp
, key
));
620 case KEY_integer_FLAG
| KEY_register_FLAG
:
621 GETATTR_Key_int_key(interp
, key
, int_key
);
622 value
= Parrot_str_concat(interp
, value
,
623 Parrot_str_from_int(interp
,
624 REG_INT(interp
, int_key
)));
626 case KEY_number_FLAG
| KEY_register_FLAG
:
627 GETATTR_Key_int_key(interp
, key
, int_key
);
628 value
= Parrot_str_concat(interp
, value
,
629 Parrot_str_from_num(interp
,
630 REG_NUM(interp
, int_key
)));
632 case KEY_string_FLAG
| KEY_register_FLAG
:
633 value
= Parrot_str_concat(interp
, value
, quote
);
634 GETATTR_Key_int_key(interp
, key
, int_key
);
635 value
= Parrot_str_concat(interp
, value
,
636 REG_STR(interp
, int_key
));
637 value
= Parrot_str_concat(interp
, value
, quote
);
639 case KEY_pmc_FLAG
| KEY_register_FLAG
:
642 GETATTR_Key_int_key(interp
, key
, int_key
);
643 reg
= REG_PMC(interp
, int_key
);
644 value
= Parrot_str_concat(interp
, value
,
645 VTABLE_get_string(interp
, reg
));
649 value
= Parrot_str_concat(interp
, value
, CONST_STRING(interp
, "Key type unknown"));
653 GETATTR_Key_next_key(interp
, key
, next_key
);
655 value
= Parrot_str_concat(interp
, value
, semicolon
);
657 GETATTR_Key_next_key(interp
, key
, key
);
660 value
= Parrot_str_concat(interp
, value
, Parrot_str_new(interp
, " ]", 2));
670 F<include/parrot/key.h>.
679 * c-file-style: "parrot"
681 * vim: expandtab shiftwidth=4: