tagged release 0.7.1
[parrot.git] / src / pmc / pair.pmc
blobb50a681e338a05c21c7783d52a53b0d2216ca527
1 /*
2 Copyright (C) 2005-2008, The Perl Foundation.
3 $Id$
5 =head1 NAME
7 src/pmc/pair.pmc - Pair PMC
9 =head1 DESCRIPTION
11 A Pair PMC represents one key => value mapping like a one element hash.
13 =head2 Functions
15 =over 4
17 =cut
21 #include "parrot/parrot.h"
22 #include "pmc_pair.h"
24 pmclass Pair need_ext {
25     ATTR PMC *key;
26     ATTR PMC *value;
30 =item C<void init()>
32 Initializes the instance.
34 =item C<PMC *instantiate(PMC *sig)>
36 Class method to construct an Integer according to passed arguments.
38 =cut
42     VTABLE void init() {
43         PMC_data(SELF) = mem_allocate_zeroed_typed(Parrot_Pair_attributes);
44         PObj_custom_mark_SET(SELF);
45     }
47     VTABLE PMC *instantiate(PMC *sig) {
48         return PMCNULL;
50         /* TODO -- really create this thing */
51 #if 0
52         PMC * const  _class = REG_PMC(interp, 2);
53         Parrot_Pair_attributes *pair   = PARROT_PAIR(SELF);
54         const int    argcP  = REG_INT(interp, 3);
55         const int    argcS  = REG_INT(interp, 2);
57         SELF = pmc_new(INTERP, _class->vtable->base_type);
58         if (argcS == 1 && argcP == 1) {
59             PObj_key_is_string_SET(SELF);
60             pair->key   = REG_STR(interp, 5);
61             pair->value = REG_PMC(interp, 5);
62         }
63         else if (argcP == 2) {
64             pair->key   = REG_PMC(interp, 5);
65             pair->value = REG_PMC(interp, 6);
66         }
67         else
68             Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_INVALID_OPERATION,
69                 "wrong argument count for Pair creation");
71         return SELF;
72 #endif
73     }
76 =item C<void mark()>
78 Marks the hash as live.
80 =cut
84     VTABLE void mark() {
85         Parrot_Pair_attributes * const pair = PARROT_PAIR(SELF);
87         if (pair->key)
88             pobject_lives(INTERP, (PObj *)pair->key);
90         if (pair->value)
91             pobject_lives(INTERP, (PObj *)pair->value);
92     }
96 =item C<PMC *get_pmc_keyed_str(STRING *key)>
98 =item C<PMC *get_pmc_keyed(PMC *key)>
100 =cut
104     VTABLE PMC *get_pmc_keyed_str(STRING *key) {
105         Parrot_Pair_attributes * const pair = PARROT_PAIR(SELF);
106         /* check key ? */
107         return pair->value;
108     }
110     VTABLE PMC *get_pmc_keyed(PMC *key) {
111         Parrot_Pair_attributes * const pair = PARROT_PAIR(SELF);
112         /* check key ? */
113         return pair->value;
114     }
118 =item C<void set_pmc_keyed(PMC *key, PMC *value)>
120 =item C<void set_pmc_keyed_str(STRING *key, PMC *value)>
122 Set key and value. The key can only set once.
124 =item C<void assign_pmc(PMC *value)>
126 Set the value of the Pair.
128 =cut
132     VTABLE void set_pmc_keyed(PMC *key, PMC *value) {
133         Parrot_Pair_attributes * const pair = PARROT_PAIR(SELF);
135         if (pair->key)
136             Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_INVALID_OPERATION,
137                 "attempt to set existing Pair key");
140         pair->key   = key;
141         pair->value = value;
142     }
145     VTABLE void set_pmc_keyed_str(STRING *key, PMC *value) {
146         Parrot_Pair_attributes * const pair = PARROT_PAIR(SELF);
147         PMC                *key_pmc;
149         if (pair->key)
150             Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_INVALID_OPERATION,
151                 "attempt to set existing Pair key");
154         key_pmc = pmc_new(interp, enum_class_String);
155         VTABLE_set_string_native(interp, key_pmc, key);
157         pair->key   = key_pmc;
158         pair->value = value;
159     }
161     VTABLE void assign_pmc(PMC *value) {
162         Parrot_Pair_attributes * const pair = PARROT_PAIR(SELF);
163         pair->value              = value;
164     }
168 =item C<void set_pmc(PMC *pair)>
170 Sets this pair to hold the value of another.
172 =cut
176     void set_pmc(PMC *pair) {
177         if (pair->vtable->base_type == enum_class_Pair) {
178             Parrot_Pair_attributes * const from = PARROT_PAIR(SELF);
179             Parrot_Pair_attributes * const to   = PARROT_PAIR(SELF);
181             to->key   = from->key;
182             to->value = from->value;
183         }
184         else
185             Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_INVALID_OPERATION,
186                 "Can only set a pair to another pair.");
187     }
191 =item C<INTVAL is_equal(PMC *value)>
193 The C<==> operation.
195 Check if two Pairs hold the same keys and values.
197 =cut
201     VTABLE INTVAL is_equal(PMC *value) {
202         Parrot_Pair_attributes * const from = PARROT_PAIR(SELF);
203         Parrot_Pair_attributes * const to   = PARROT_PAIR(SELF);
204         PMC *p1, *p2;
205         PMC *k1, *k2;
207         if (value->vtable->base_type != SELF->vtable->base_type)
208             return 0;
210         k1 = from->key;
211         k2 = to->key;
213         if (!mmd_dispatch_i_pp(INTERP, k1, k2, MMD_EQ))
214             return 0;
216         p1 = from->value;
217         p2 = to->value;
219         if (!p1 && !p2)
220             return 1;
221         else
222             return 0;
223     }
227 =item C<void visit(visit_info *info)>
229 Used during archiving to visit the elements in the pair.
231 =item C<void freeze(visit_info *info)>
233 Used to archive the Pair.
235 =item C<void thaw(visit_info *info)>
237 Used to unarchive the Pair.
239 =cut
243     VTABLE void visit(visit_info *info) {
244         PMC               **pos;
245         Parrot_Pair_attributes * const pair     = PARROT_PAIR(SELF);
246         IMAGE_IO    * const io       = info->image_io;
247         DPOINTER   ** const temp_pos = (DPOINTER **)pair->key;
248         info->thaw_ptr               = (PMC **)temp_pos;
249         (info->visit_pmc_now)(INTERP, (PMC *)temp_pos, info);
251         pos            = &pair->value;
252         info->thaw_ptr = pos;
254         (info->visit_pmc_now)(INTERP, *pos, info);
256         SUPER(info);
257     }
259     VTABLE void freeze(visit_info *info) {
260         Parrot_Pair_attributes * const pair = PARROT_PAIR(SELF);
261         IMAGE_IO    * const io   = info->image_io;
262         SUPER(info);
263         VTABLE_push_pmc(INTERP, io, pair->key);
264         VTABLE_push_pmc(INTERP, io, pair->value);
265     }
267     VTABLE void thaw(visit_info *info) {
268         Parrot_Pair_attributes * const pair = PARROT_PAIR(SELF);
269         IMAGE_IO    * const io   = info->image_io;
271         SUPER(info);
273         pair->key   = VTABLE_shift_pmc(interp, io);
274         pair->value = VTABLE_shift_pmc(interp, io);
275     }
278 =back
280 =head2 Methods
282 =over 4
284 =item C<METHOD key()>
286 Return the key of the pair.
288 =cut
292     METHOD key() {
293         Parrot_Pair_attributes * const pair = PARROT_PAIR(SELF);
294         PMC                *key  = pair->key;
296         RETURN(PMC *key);
297     }
301 =item C<METHOD value()>
303 Return the value of the pair.
305 =cut
309     METHOD value() {
310         Parrot_Pair_attributes * const pair  = PARROT_PAIR(SELF);
311         PMC         * const value = pair->value;
312         RETURN(PMC *value);
313     }
317 =item C<METHOD kv()>
319 Return a tuple of (key, value) for the pair.
321 =cut
325     METHOD kv() {
326         Parrot_Pair_attributes * const pair = PARROT_PAIR(SELF);
327         PMC         * const t    = pmc_new(INTERP,
328             Parrot_get_ctx_HLL_type(INTERP, enum_class_FixedPMCArray));
330         VTABLE_set_integer_native(INTERP, t, 2);
331         VTABLE_set_pmc_keyed_int(INTERP, t, 0, pair->key);
333         VTABLE_set_pmc_keyed_int(INTERP, t, 1, pair->value);
334         RETURN(PMC *t);
335     }
340 =back
342 =cut
347  * Local variables:
348  *   c-file-style: "parrot"
349  * End:
350  * vim: expandtab shiftwidth=4:
351  */