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));
152 =item C<PMC * key_new_pmc(PARROT_INTERP, PMC *value)>
154 Returns a new PMC C<Key> PMC with value C<value>.
161 PARROT_CANNOT_RETURN_NULL
162 PARROT_WARN_UNUSED_RESULT
164 key_new_pmc(PARROT_INTERP
, ARGIN(PMC
*value
))
166 ASSERT_ARGS(key_new_pmc
)
167 PMC
* const key
= Parrot_pmc_new(interp
, enum_class_Key
);
169 PObj_get_FLAGS(key
) |= KEY_pmc_FLAG
;
170 Parrot_ex_throw_from_c_args(interp
, NULL
, 1, "this is broken - see slice.pmc");
176 =item C<void key_set_integer(PARROT_INTERP, PMC *key, INTVAL value)>
178 Set the integer C<value> in C<key>.
186 key_set_integer(PARROT_INTERP
, ARGMOD(PMC
*key
), INTVAL value
)
188 ASSERT_ARGS(key_set_integer
)
189 PObj_get_FLAGS(key
) &= ~KEY_type_FLAGS
;
190 PObj_get_FLAGS(key
) |= KEY_integer_FLAG
;
191 SETATTR_Key_int_key(interp
, key
, value
);
199 =item C<void key_set_register(PARROT_INTERP, PMC *key, INTVAL value, INTVAL
202 Set the register C<value> in C<key>.
210 key_set_register(PARROT_INTERP
, ARGMOD(PMC
*key
), INTVAL value
, INTVAL flag
)
212 ASSERT_ARGS(key_set_register
)
213 PObj_get_FLAGS(key
) &= ~KEY_type_FLAGS
;
214 PObj_get_FLAGS(key
) |= KEY_register_FLAG
| flag
;
215 SETATTR_Key_int_key(interp
, key
, value
);
223 =item C<void key_set_number(PARROT_INTERP, PMC *key, FLOATVAL value)>
225 Set the number C<value> in C<key>.
233 key_set_number(PARROT_INTERP
, ARGMOD(PMC
*key
), FLOATVAL value
)
235 ASSERT_ARGS(key_set_number
)
236 PObj_get_FLAGS(key
) &= ~KEY_type_FLAGS
;
237 PObj_get_FLAGS(key
) |= KEY_number_FLAG
;
238 SETATTR_Key_num_key(interp
, key
, value
);
246 =item C<void key_set_string(PARROT_INTERP, PMC *key, STRING *value)>
248 Set the string C<value> in C<key>.
256 key_set_string(PARROT_INTERP
, ARGMOD(PMC
*key
), ARGIN(STRING
*value
))
258 ASSERT_ARGS(key_set_string
)
259 PObj_get_FLAGS(key
) &= ~KEY_type_FLAGS
;
260 PObj_get_FLAGS(key
) |= KEY_string_FLAG
;
261 SETATTR_Key_str_key(interp
, key
, value
);
269 =item C<void key_set_pmc(PARROT_INTERP, PMC *key, PMC *value)>
271 Set the PMC C<value> in C<key>.
279 key_set_pmc(PARROT_INTERP
, ARGMOD(PMC
*key
), ARGIN(PMC
*value
))
281 ASSERT_ARGS(key_set_pmc
)
282 PObj_get_FLAGS(key
) &= ~KEY_type_FLAGS
;
283 PObj_get_FLAGS(key
) |= KEY_pmc_FLAG
;
287 * what for is this indirection?
289 Parrot_ex_throw_from_c_args(interp
, NULL
, 1, "this is broken - see slice.pmc");
295 =item C<INTVAL key_type(PARROT_INTERP, const PMC *key)>
297 Returns the type of C<key>.
305 PARROT_WARN_UNUSED_RESULT
307 key_type(SHIM_INTERP
, ARGIN(const PMC
*key
))
309 ASSERT_ARGS(key_type
)
310 return (PObj_get_FLAGS(key
) & KEY_type_FLAGS
) & ~KEY_register_FLAG
;
316 =item C<INTVAL key_integer(PARROT_INTERP, PMC *key)>
318 Translates a key value into an integer.
319 Takes an interpreter name and pointer to a key.
320 Returns an integer value corresponding to the key.
327 PARROT_WARN_UNUSED_RESULT
329 key_integer(PARROT_INTERP
, ARGIN(PMC
*key
))
331 ASSERT_ARGS(key_integer
)
336 switch (PObj_get_FLAGS(key
) & KEY_type_FLAGS
) {
337 case KEY_integer_FLAG
:
338 GETATTR_Key_int_key(interp
, key
, int_key
);
340 case KEY_integer_FLAG
| KEY_register_FLAG
:
341 GETATTR_Key_int_key(interp
, key
, int_key
);
342 return REG_INT(interp
, int_key
);
344 case KEY_number_FLAG
:
345 GETATTR_Key_num_key(interp
, key
, num_key
);
346 return (INTVAL
)num_key
;
347 case KEY_number_FLAG
| KEY_register_FLAG
:
348 GETATTR_Key_int_key(interp
, key
, int_key
);
349 return (INTVAL
)REG_NUM(interp
, int_key
);
351 case KEY_pmc_FLAG
| KEY_register_FLAG
:
354 GETATTR_Key_int_key(interp
, key
, int_key
);
355 reg
= REG_PMC(interp
, int_key
);
356 return VTABLE_get_integer(interp
, reg
);
359 case KEY_string_FLAG
:
360 GETATTR_Key_str_key(interp
, key
, str_key
);
361 return Parrot_str_to_int(interp
, str_key
);
362 case KEY_string_FLAG
| KEY_register_FLAG
:
365 GETATTR_Key_int_key(interp
, key
, int_key
);
366 s_reg
= REG_STR(interp
, int_key
);
367 return Parrot_str_to_int(interp
, s_reg
);
374 return VTABLE_get_integer(interp
, key
);
380 =item C<FLOATVAL key_number(PARROT_INTERP, PMC *key)>
382 Translates a key value into a number.
383 Takes an interpreter name and pointer to a key.
384 Returns a number value corresponding to the key.
385 Throws an exception if the key is not a valid number.
392 PARROT_WARN_UNUSED_RESULT
394 key_number(PARROT_INTERP
, ARGIN(PMC
*key
))
396 ASSERT_ARGS(key_number
)
400 switch (PObj_get_FLAGS(key
) & KEY_type_FLAGS
) {
401 case KEY_number_FLAG
:
402 GETATTR_Key_num_key(interp
, key
, num_key
);
404 case KEY_number_FLAG
| KEY_register_FLAG
:
405 GETATTR_Key_int_key(interp
, key
, int_key
);
406 return REG_NUM(interp
, int_key
);
408 return VTABLE_get_number(interp
, key
);
409 case KEY_pmc_FLAG
| KEY_register_FLAG
:
412 GETATTR_Key_int_key(interp
, key
, int_key
);
413 reg
= REG_PMC(interp
, int_key
);
414 return VTABLE_get_number(interp
, reg
);
417 Parrot_ex_throw_from_c_args(interp
, NULL
, EXCEPTION_INVALID_OPERATION
,
418 "Key not a number!\n");
425 =item C<STRING * key_string(PARROT_INTERP, PMC *key)>
427 Translates a key value into a string. Takes an interpreter name and pointer to
428 a key. Returns a string value corresponding to the key.
434 PARROT_WARN_UNUSED_RESULT
435 PARROT_CAN_RETURN_NULL
437 key_string(PARROT_INTERP
, ARGIN(PMC
*key
))
439 ASSERT_ARGS(key_string
)
441 switch (PObj_get_FLAGS(key
) & KEY_type_FLAGS
) {
442 /* remember to COW strings instead of returning them directly */
443 case KEY_string_FLAG
:
446 GETATTR_Key_str_key(interp
, key
, s
);
449 case KEY_string_FLAG
| KEY_register_FLAG
:
452 GETATTR_Key_int_key(interp
, key
, int_key
);
453 return REG_STR(interp
, int_key
);
455 case KEY_pmc_FLAG
| KEY_register_FLAG
:
459 GETATTR_Key_int_key(interp
, key
, int_key
);
460 reg
= REG_PMC(interp
, int_key
);
461 return VTABLE_get_string(interp
, reg
);
463 case KEY_integer_FLAG
:
466 GETATTR_Key_int_key(interp
, key
, int_key
);
467 return Parrot_str_from_int(interp
, int_key
);
469 case KEY_integer_FLAG
| KEY_register_FLAG
:
472 GETATTR_Key_int_key(interp
, key
, int_key
);
473 return Parrot_str_from_int(interp
, REG_INT(interp
, int_key
));
475 case KEY_number_FLAG
:
478 GETATTR_Key_num_key(interp
, key
, num_key
);
479 return Parrot_str_from_num(interp
, num_key
);
481 case KEY_number_FLAG
| KEY_register_FLAG
:
484 GETATTR_Key_int_key(interp
, key
, int_key
);
485 return Parrot_str_from_num(interp
, REG_NUM(interp
, int_key
));
489 return VTABLE_get_string(interp
, key
);
496 =item C<PMC * key_pmc(PARROT_INTERP, PMC *key)>
498 These functions return the integer/number/string/PMC values of C<key> if
499 possible. Otherwise they throw exceptions.
506 PARROT_CANNOT_RETURN_NULL
507 PARROT_WARN_UNUSED_RESULT
509 key_pmc(PARROT_INTERP
, ARGIN(PMC
*key
))
514 switch (PObj_get_FLAGS(key
) & KEY_type_FLAGS
) {
515 case KEY_pmc_FLAG
| KEY_register_FLAG
:
516 GETATTR_Key_int_key(interp
, key
, int_key
);
517 return REG_PMC(interp
, int_key
);
526 =item C<PMC * key_next(PARROT_INTERP, PMC *key)>
528 Returns the next key if C<key> is in a sequence of linked keys.
535 PARROT_CAN_RETURN_NULL
536 PARROT_WARN_UNUSED_RESULT
538 key_next(PARROT_INTERP
, ARGIN(PMC
*key
))
540 ASSERT_ARGS(key_next
)
542 if (VTABLE_isa(interp
, key
, CONST_STRING(interp
, "Key"))) {
544 GETATTR_Key_next_key(interp
, key
, next_key
);
554 =item C<PMC * key_append(PARROT_INTERP, PMC *key1, PMC *key2)>
556 Appends C<key2> to C<key1>.
558 Note that if C<key1> is not the last key in a sequence of linked keys then the
559 last key will be found and C<key2> appended to that.
568 PARROT_CANNOT_RETURN_NULL
569 PARROT_IGNORABLE_RESULT
571 key_append(PARROT_INTERP
, ARGMOD(PMC
*key1
), ARGIN(PMC
*key2
))
573 ASSERT_ARGS(key_append
)
577 GETATTR_Key_next_key(interp
, tail
, tail_next
);
581 GETATTR_Key_next_key(interp
, tail
, tail_next
);
584 SETATTR_Key_next_key(interp
, tail
, key2
);
592 =item C<void key_mark(PARROT_INTERP, PMC *key)>
594 Marks C<key> as live.
602 key_mark(PARROT_INTERP
, ARGIN(PMC
*key
))
604 ASSERT_ARGS(key_mark
)
606 const UINTVAL flags
= PObj_get_FLAGS(key
) & KEY_type_FLAGS
;
608 if (flags
== KEY_string_FLAG
) {
610 GETATTR_Key_str_key(interp
, key
, str_key
);
611 Parrot_gc_mark_STRING_alive(interp
, str_key
);
615 if ((flags
== KEY_string_FLAG
) || (flags
== KEY_pmc_FLAG
)) {
616 GETATTR_Key_next_key(interp
, key
, next_key
);
617 Parrot_gc_mark_PMC_alive(interp
, next_key
);
625 =item C<STRING * key_set_to_string(PARROT_INTERP, PMC *key)>
627 Translates a series of key values into strings, quoted or bracketed if
628 appropriate. Takes an interpreter name and pointer to a key. Returns a
629 string value corresponding to the key.
636 PARROT_CANNOT_RETURN_NULL
637 PARROT_WARN_UNUSED_RESULT
639 key_set_to_string(PARROT_INTERP
, ARGIN_NULLOK(PMC
*key
))
641 ASSERT_ARGS(key_set_to_string
)
642 STRING
* const semicolon
= CONST_STRING(interp
, " ; ");
643 STRING
* const quote
= CONST_STRING(interp
, "'");
644 STRING
*value
= Parrot_str_new(interp
, "[ ", 2);
649 while (key
!= NULL
) {
650 switch (PObj_get_FLAGS(key
) & KEY_type_FLAGS
) {
651 case KEY_integer_FLAG
:
652 GETATTR_Key_int_key(interp
, key
, int_key
);
653 value
= Parrot_str_concat(interp
, value
,
654 Parrot_str_from_int(interp
, int_key
));
656 case KEY_number_FLAG
:
657 GETATTR_Key_int_key(interp
, key
, int_key
);
658 value
= Parrot_str_concat(interp
, value
,
659 Parrot_str_from_num(interp
, (FLOATVAL
)int_key
));
661 case KEY_string_FLAG
:
662 GETATTR_Key_str_key(interp
, key
, str_key
);
663 value
= Parrot_str_concat(interp
, value
, quote
);
664 value
= Parrot_str_concat(interp
, value
, str_key
);
665 value
= Parrot_str_concat(interp
, value
, quote
);
668 value
= Parrot_str_concat(interp
, value
,
669 VTABLE_get_string(interp
, key
));
671 case KEY_integer_FLAG
| KEY_register_FLAG
:
672 GETATTR_Key_int_key(interp
, key
, int_key
);
673 value
= Parrot_str_concat(interp
, value
,
674 Parrot_str_from_int(interp
,
675 REG_INT(interp
, int_key
)));
677 case KEY_number_FLAG
| KEY_register_FLAG
:
678 GETATTR_Key_int_key(interp
, key
, int_key
);
679 value
= Parrot_str_concat(interp
, value
,
680 Parrot_str_from_num(interp
,
681 REG_NUM(interp
, int_key
)));
683 case KEY_string_FLAG
| KEY_register_FLAG
:
684 value
= Parrot_str_concat(interp
, value
, quote
);
685 GETATTR_Key_int_key(interp
, key
, int_key
);
686 value
= Parrot_str_concat(interp
, value
,
687 REG_STR(interp
, int_key
));
688 value
= Parrot_str_concat(interp
, value
, quote
);
690 case KEY_pmc_FLAG
| KEY_register_FLAG
:
693 GETATTR_Key_int_key(interp
, key
, int_key
);
694 reg
= REG_PMC(interp
, int_key
);
695 value
= Parrot_str_concat(interp
, value
,
696 VTABLE_get_string(interp
, reg
));
700 value
= Parrot_str_concat(interp
, value
, CONST_STRING(interp
, "Key type unknown"));
704 GETATTR_Key_next_key(interp
, key
, next_key
);
706 value
= Parrot_str_concat(interp
, value
, semicolon
);
708 GETATTR_Key_next_key(interp
, key
, key
);
711 value
= Parrot_str_concat(interp
, value
, Parrot_str_new(interp
, " ]", 2));
721 F<include/parrot/key.h>.
730 * c-file-style: "parrot"
732 * vim: expandtab shiftwidth=4: