tagged release 0.7.1
[parrot.git] / compilers / pct / src / PCT / Node.pir
blob0624d51febc2dbd9b14faf6a40296c01c83da738
1 =head1 NAME
3 PCT::Node - base class for PAST and POST nodes
5 =head1 DESCRIPTION
7 This file implements the base class for abstract syntax tree (PAST)
8 and opcode syntax tree (POST) nodes in the Parrot Compiler Toolkit.
10 =cut
12 .namespace [ 'PCT::Node' ]
14 .sub 'onload' :anon :load :init
15     ##   create the PCT::Node base class
16     ##   FIXME: Eventually we want this to be a subclass of
17     ##   Capture, but as of now Capture isn't working so we
18     ##   use the Capture_PIR class for now.
19     load_bytecode 'Parrot/Capture_PIR.pbc'
21     .local pmc p6meta
22     p6meta = new 'P6metaclass'
23     p6meta.'new_class'('PCT::Node', 'parent'=>'Capture_PIR')
25     $P0 = new 'Integer'
26     $P0 = 10
27     set_hll_global ['PCT::Node'], '$!serno', $P0
29     .return ()
30 .end
32 =head1 PCT::Node
34 C<PCT::Node> is the base class for all PAST and POST nodes.  It's
35 derived from class C<Capture>, so that it has both array and hash
36 components.  The array component is used to maintain a node's children,
37 while the hash component contains the attributes of the node.  In general
38 we provide and use accessor methods for a node's attributes, instead
39 of accessing the hash component directly.
41 Every PAST/POST node has C<name>, C<source>, and C<pos> attributes.
42 The C<name> attribute is the node's name, if any, while C<source>
43 and C<pos> are used to identify the location in the original source
44 code for the node.  The C<source> and C<pos> values are generally
45 set by the C<node> method below.
47 Other node attributes are generally defined by subclasses of C<PCT::Node>.
49 =over 4
51 =item init([child1, child2, ..., ] [attr1=>val1, attr2=>val2, ... ])
53 Initialize a node with the given children and attributes.
54 Adds each child to the node (using the C<push> method, below) and
55 calls the appropriate accessor method for each attribute.
56 And returns the node.
58 =cut
60 .sub 'init' :method
61     .param pmc children        :slurpy
62     .param pmc adverbs         :slurpy :named
64     .local pmc iter
65     iter = new 'Iterator', children
66   children_loop:
67     unless iter goto children_end
68     $P0 = shift iter
69     push self, $P0
70     goto children_loop
71   children_end:
73     iter = new 'Iterator', adverbs
74   adverbs_loop:
75     unless iter goto adverbs_end
76     $S0 = shift iter
77     $P0 = iter[$S0]
78     $P1 = find_method self, $S0
79     self.$P1($P0)
80     goto adverbs_loop
81   adverbs_end:
82   end:
83     .return (self)
84 .end
87 =item new([child1, child2, ..., ] [attr1=>val1, attr2=>val2, ...])
89 Create a new PAST node of initialized with the given
90 children and attributes.  Returns the newly created node.
92 =cut
94 .sub 'new' :method
95     .param pmc children        :slurpy
96     .param pmc adverbs         :slurpy :named
98     $P0 = self.'HOW'()
99     $P0 = getattribute $P0, 'parrotclass'
100     $P1 = new $P0
101     $P1.'init'(children :flat, adverbs :flat :named)
102     .return ($P1)
103 .end
106 =item clone
108 Create and returns a clone of a PAST node.
110 =cut
112 .sub 'clone' :vtable :method
113     .local pmc res
114     $S0 = typeof self
115     res = new $S0
116     .local pmc iter
117     iter = self.'iterator'()
118   iter_child_loop:
119     unless iter goto iter_child_end
120     $P0 = shift iter
121     $P1 = clone $P0
122     res.'push'($P1)
123     goto iter_child_loop
124   iter_child_end:
125     iter = new 'Iterator', self
126   iter_attr_loop:
127     unless iter goto iter_attr_end
128     $S0 = shift iter
129     $P0 = iter[$S0]
130     res[$S0] = $P0
131     goto iter_attr_loop
132   iter_attr_end:
133     .return (res)
134 .end
137 =item unshift(child)
139 Add C<child> to the beginning of the invocant's list of children.
141 =item shift()
143 Remove the first child from the invocant's list of children.
144 Returns the child.
146 =item push(child)
148 Add C<child> to the end of the invocant's list of children.
150 =item pop()
152 Remove the last child from the invocant's list of children.
153 Returns the child.
155 =cut
157 .sub 'unshift' :method
158     .param pmc value
159     unshift self, value
160 .end
162 .sub 'shift' :method
163     $P0 = shift self
164     .return ($P0)
165 .end
167 .sub 'push' :method
168     .param pmc value
169     push self, value
170 .end
172 .sub 'pop' :method
173     $P0 = pop self
174     .return ($P0)
175 .end
178 =item push_new(class, [child1, child2, ..., ] [attr1=>val1, attr2=>val2, ...])
180 (Deprecated.)  Creates a new node of type C<class>, initializes it with the
181 given children and attributes, and adds it to the end of the invocant's
182 array of children.  Returns the newly created node.
184 =cut
186 .sub 'push_new' :method
187     .param string class
188     .param pmc children        :slurpy
189     .param pmc adverbs         :slurpy :named
190     $P0 = new class
191     $P0.'init'(children :flat, adverbs :flat :named)
192     push self, $P0
193     .return ($P0)
194 .end
197 =item iterator( )
199 Returns a newly initialized iterator for the invocant's list of
200 children.
202 =cut
204 .sub 'iterator' :method
205     .local pmc iter
206     $P0 = self.'list'()
207     iter = new 'Iterator', $P0
208     iter = 0
209     .return (iter)
210 .end
213 =item node([val])
215 Sets the invocant's C<source> and C<pos> attributes to those
216 of C<val>.  If C<val> is another PAST node, then C<source> and C<pos>
217 are simply copied from that node, otherwise C<val> is assumed to be
218 a C<Match> object and obtains source/position information from that.
220 =cut
222 .sub 'node' :method
223     .param pmc node
224     $I0 = isa node, 'PAST::Node'
225     if $I0 goto clone_past
226   clone_pge:
227     $S0 = node
228     $I0 = node.'from'()
229     self['source'] = $S0
230     self['pos'] = $I0
231     .return ()
232   clone_past:
233     $P0 = node['source']
234     $P1 = node['pos']
235     self['source'] = $P0
236     self['pos'] = $P1
237     .return ()
238 .end
241 =item name([value])
243 Accessor method -- sets/returns the C<name> attribute of the invocant.
245 =cut
247 .sub 'name' :method
248     .param pmc value           :optional
249     .param int has_value       :opt_flag
250     .return self.'attr'('name', value, has_value)
251 .end
254 =item attr(STR attrname, PMC value, INT has_value)
256 Helper method for accessors.  If C<has_value> is true then set
257 the invocant's value of C<attrname> to C<value>.  Returns the
258 (resulting) value of C<attrname> in the invocant.
260 =cut
262 .sub 'attr' :method
263     .param string attrname
264     .param pmc value
265     .param int has_value
266     .param pmc default         :optional
267     .param int has_default     :opt_flag
268     if has_value goto setattr
269     value = self[attrname]
270     unless null value goto value_done
271     unless has_default goto value_undef
272     .return (default)
273   value_undef:
274     value = new 'Undef'
275   value_done:
276     .return (value)
277   setattr:
278     self[attrname] = value
279     .return (value)
280 .end
283 =item unique([STR fmt])
285 Generate a unique number that can be used as an identifier.
286 If C<fmt> is provided, then it will be used as a prefix to the
287 unique number.
289 =cut
291 .sub 'unique' :method
292     .param string fmt          :optional
293     .param int has_fmt         :opt_flag
295     if has_fmt goto unique_1
296     fmt = ''
297   unique_1:
298     $P0 = get_global '$!serno'
299     $S0 = $P0
300     $S0 = concat fmt, $S0
301     inc $P0
302     .return ($S0)
303 .end
306 =back
308 =head1 AUTHOR
310 Patrick Michaud <pmichaud@pobox.com> is the author and maintainer.
311 Please send patches and suggestions to the Parrot porters or
312 Perl 6 compilers mailing lists.
314 =head1 HISTORY
316 2006-11-20  Patrick Michaud added first draft of POD documentation.
317 2007-11-21  Re-implementation with pdd26 compliance, compiler toolkit
318 2007-12-07  Refactor PAST::Node into separate PCT::Node component.
320 =head1 COPYRIGHT
322 Copyright (C) 2006-2008, The Perl Foundation.
324 =cut
326 # Local Variables:
327 #   mode: pir
328 #   fill-column: 100
329 # End:
330 # vim: expandtab shiftwidth=4 ft=pir: