fix codetest failure - ASSERT_ARGS does not have a ; after and
[parrot.git] / src / dynpmc / dynlexpad.pmc
blob7381ea23bf8ca09967e65ef1282b8456067a464d
1 /*
2 Copyright (C) 2005-2010, Parrot Foundation.
3 $Id$
5 =head1 NAME
7 src/dynpmc/dynlexpad.pmc - DynLexPad PMC
9 =head1 DESCRIPTION
11 DynLexPad provides a more dynamic lexpad that allows the addition of
12 lexicals at runtime.
14 =head2 Functions
16 =over 4
18 =cut
22 pmclass DynLexPad dynpmc provides lexpad auto_attrs {
23     ATTR Hash *hash;
24     ATTR PMC  *init; /* the PMC used to initialize this DynLexPad */
26     VTABLE void init() {
27         Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_INVALID_OPERATION,
28             "don't create me like this");
29     }
33 =item C<init_pmc(PMC *lexinfo)>
35 Initialize the LexPad PMC and remember the associate
36 lexinfo.
38 =cut
41     VTABLE void init_pmc(PMC* lexinfo) {
42         Hash *hash;
44         Parrot_DynLexPad_attributes *attrs =
45             (Parrot_DynLexPad_attributes *) PMC_data(SELF);
47         if (VTABLE_elements(INTERP, lexinfo)) {
48             attrs->init = Parrot_pmc_new_init(INTERP, enum_class_LexPad, lexinfo);
49         }
50         else
51             attrs->init = NULL;
53         hash             = parrot_new_hash(INTERP);
54         attrs->hash      = hash;
55         PObj_custom_mark_destroy_SETALL(SELF);
56     }
60 =item C<void set_pointer(void *)>
62 Initialize the LexPad PMC and remember the associate context.
64 =cut
67     VTABLE void set_pointer(void* ctx) {
68         PMC *std_pad = PARROT_DYNLEXPAD(SELF)->init;
69         if (std_pad)
70             VTABLE_set_pointer(INTERP, std_pad, ctx);
71     }
75 =item C<INTVAL elements()>
77 Returns the number of elements in the hash.
79 =cut
82     VTABLE INTVAL elements() {
83         return parrot_hash_size(INTERP, PARROT_DYNLEXPAD(SELF)->hash);
84     }
88 =item C<INTVAL exists_keyed(PMC *name)>
90 =item C<INTVAL exists_keyed_str(STRING *name)>
92 Returns whether a lexical C<name> exists in the hash.
94 =cut
98     VTABLE INTVAL exists_keyed(PMC* name) {
99         STRING *s = VTABLE_get_string(INTERP, name);
100         return SELF.exists_keyed_str(s);
101     }
103     VTABLE INTVAL exists_keyed_str(STRING* name) {
104         PMC *std_pad;
105         if (parrot_hash_exists(INTERP, PARROT_DYNLEXPAD(SELF)->hash, name))
106             return 1;
107         std_pad = PARROT_DYNLEXPAD(SELF)->init;
108         if (std_pad)
109             return VTABLE_exists_keyed_str(INTERP, std_pad, name);
110         return 0;
111     }
115 =item C<PMC *get_pmc_keyed_str(STRING *name)>
117 =item C<PMC *get_pmc_keyed(PMC *name)>
119 Return the lexical with the given name, or NULL (not PMCNULL), if the
120 lexical doesn't exist.
122 =cut
125     VTABLE PMC* get_pmc_keyed_str(STRING* name) {
126         HashBucket *b = parrot_hash_get_bucket(INTERP,
127             PARROT_DYNLEXPAD(SELF)->hash, name);
129         if (!b) {
130             PMC *std_pad = PARROT_DYNLEXPAD(SELF)->init;
132             if (std_pad)
133                 return VTABLE_get_pmc_keyed_str(INTERP, std_pad, name);
135             return PMCNULL;
136         }
138         return (PMC *)b->value;
139     }
141     VTABLE PMC* get_pmc_keyed(PMC* name) {
142         STRING *s = VTABLE_get_string(INTERP, name);
143         return SELF.get_pmc_keyed_str(s);
144     }
149 =item C<void set_pmc_keyed(PMC *name, PMC *value)>
151 =item C<void set_pmc_keyed_str(STRING *name, PMC *value)>
153 Set the lexical with the given name to value. If the lexical name
154 doesn't exist, it is created.
156 =cut
160     VTABLE void set_pmc_keyed(PMC* name, PMC* value) {
161         STRING *s = VTABLE_get_string(INTERP, name);
162         SELF.set_pmc_keyed_str(s, value);
163     }
165     VTABLE void set_pmc_keyed_str(STRING* name, PMC* value) {
166         PMC *std_pad = PARROT_DYNLEXPAD(SELF)->init;
168         if (PObj_constant_TEST(SELF)) {
169             if (!PObj_constant_TEST((PObj *)name))
170                 Parrot_ex_throw_from_c_args(INTERP, NULL,
171                     EXCEPTION_INVALID_OPERATION,
172                     "Used non-constant STRING key in constant hash.");
173             if (!PObj_constant_TEST((PObj *)value))
174                 Parrot_ex_throw_from_c_args(INTERP, NULL,
175                     EXCEPTION_INVALID_OPERATION,
176                     "Used non-constant PMC value in constant hash.");
177         }
179         if (std_pad && VTABLE_exists_keyed_str(INTERP, std_pad, name))
180             VTABLE_set_pmc_keyed_str(INTERP, std_pad, name, value);
182         parrot_hash_put(INTERP, PARROT_DYNLEXPAD(SELF)->hash, name, value);
183     }
187 =item C<void destroy()>
189 Destroy DynLexPad.
191 =cut
195     VTABLE void destroy() {
196         if (PARROT_DYNLEXPAD(SELF)->hash) {
197             parrot_hash_destroy(INTERP, PARROT_DYNLEXPAD(SELF)->hash);
198             PARROT_DYNLEXPAD(SELF)->hash = NULL;
199         }
200     }
203 =item C<void mark()>
205 Marks the lexpad hash as live.
207 =cut
211     VTABLE void mark() {
212         PMC *std_pad = PARROT_DYNLEXPAD(SELF)->init;
213         Parrot_gc_mark_PMC_alive(INTERP, std_pad);
214         if (PARROT_DYNLEXPAD(SELF)->hash)
215             parrot_mark_hash(INTERP, PARROT_DYNLEXPAD(SELF)->hash);
216     }
224 =back
226 =head1 SEE ALSO
228 F<docs/pdds/pdd20_lexical_vars.pod>, F<src/pmc/lexpad.pmc>,
229 F<src/pmc/lexinfo.pmc>.
231 =cut
236  * Local variables:
237  *   c-file-style: "parrot"
238  * End:
239  * vim: expandtab shiftwidth=4:
240  */