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.
382 PARROT_WARN_UNUSED_RESULT
383 PARROT_CAN_RETURN_NULL
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
:
394 GETATTR_Key_str_key(interp
, key
, s
);
397 case KEY_string_FLAG
| KEY_register_FLAG
:
400 GETATTR_Key_int_key(interp
, key
, int_key
);
401 return REG_STR(interp
, int_key
);
403 case KEY_pmc_FLAG
| KEY_register_FLAG
:
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
:
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
:
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
:
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
:
432 GETATTR_Key_int_key(interp
, key
, int_key
);
433 return Parrot_str_from_num(interp
, REG_NUM(interp
, int_key
));
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.
454 PARROT_CANNOT_RETURN_NULL
455 PARROT_WARN_UNUSED_RESULT
457 key_pmc(PARROT_INTERP
, ARGIN(PMC
*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
);
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.
483 PARROT_CAN_RETURN_NULL
484 PARROT_WARN_UNUSED_RESULT
486 key_next(PARROT_INTERP
, ARGIN(PMC
*key
))
488 ASSERT_ARGS(key_next
)
490 if (VTABLE_isa(interp
, key
, CONST_STRING(interp
, "Key"))) {
492 GETATTR_Key_next_key(interp
, key
, next_key
);
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.
516 PARROT_CANNOT_RETURN_NULL
517 PARROT_IGNORABLE_RESULT
519 key_append(PARROT_INTERP
, ARGMOD(PMC
*key1
), ARGIN(PMC
*key2
))
521 ASSERT_ARGS(key_append
)
525 GETATTR_Key_next_key(interp
, tail
, tail_next
);
529 GETATTR_Key_next_key(interp
, tail
, tail_next
);
532 SETATTR_Key_next_key(interp
, tail
, key2
);
540 =item C<void key_mark(PARROT_INTERP, PMC *key)>
542 Marks C<key> as live.
550 key_mark(PARROT_INTERP
, ARGIN(PMC
*key
))
552 ASSERT_ARGS(key_mark
)
554 const UINTVAL flags
= PObj_get_FLAGS(key
) & KEY_type_FLAGS
;
556 if (flags
== KEY_string_FLAG
) {
558 GETATTR_Key_str_key(interp
, key
, str_key
);
559 Parrot_gc_mark_STRING_alive(interp
, str_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.
584 PARROT_CANNOT_RETURN_NULL
585 PARROT_WARN_UNUSED_RESULT
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);
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
));
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
));
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
);
616 value
= Parrot_str_concat(interp
, value
,
617 VTABLE_get_string(interp
, key
));
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
)));
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
)));
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
);
638 case KEY_pmc_FLAG
| KEY_register_FLAG
:
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
));
648 value
= Parrot_str_concat(interp
, value
, CONST_STRING(interp
, "Key type unknown"));
652 GETATTR_Key_next_key(interp
, key
, 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));
669 F<include/parrot/key.h>.
678 * c-file-style: "parrot"
680 * vim: expandtab shiftwidth=4: