fix codetest failure - ASSERT_ARGS does not have a ; after and
[parrot.git] / compilers / pct / src / PCT / Node.pir
blob023ae39482950d8a1f29b96b8ed4e30333173d3e
1 # $Id$
3 =head1 NAME
5 PCT::Node - base class for PAST and POST nodes
7 =head1 DESCRIPTION
9 This file implements the base class for abstract syntax tree (PAST)
10 and opcode syntax tree (POST) nodes in the Parrot Compiler Toolkit.
12 =cut
14 .namespace [ 'PCT';'Node' ]
16 .sub 'onload' :anon :load :init
17     ##   create the PCT::Node base class
18     .local pmc p6meta
19     p6meta = new 'P6metaclass'
20     p6meta.'new_class'('PCT::Node', 'parent'=>'Capture')
22     $P0 = box 10
23     set_hll_global ['PCT';'Node'], '$!serno', $P0
25     .return ()
26 .end
28 =head1 PCT::Node
30 C<PCT::Node> is the base class for all PAST and POST nodes.  It's
31 derived from class C<Capture>, so that it has both array and hash
32 components.  The array component is used to maintain a node's children,
33 while the hash component contains the attributes of the node.  In general
34 we provide and use accessor methods for a node's attributes, instead
35 of accessing the hash component directly.
37 Every PAST/POST node has C<name>, C<source>, and C<pos> attributes.
38 The C<name> attribute is the node's name, if any, while C<source>
39 and C<pos> are used to identify the location in the original source
40 code for the node.  The C<source> and C<pos> values are generally
41 set by the C<node> method below.
43 Other node attributes are generally defined by subclasses of C<PCT::Node>.
45 =over 4
47 =item init([child1, child2, ..., ] [attr1=>val1, attr2=>val2, ... ])
49 Initialize a node with the given children and attributes.
50 Adds each child to the node (using the C<push> method, below) and
51 calls the appropriate accessor method for each attribute.
52 And returns the node.
54 =cut
56 .sub 'init' :method
57     .param pmc children        :slurpy
58     .param pmc adverbs         :slurpy :named
60     .local pmc it
61     it = iter children
62   children_loop:
63     unless it goto children_end
64     $P0 = shift it
65     push self, $P0
66     goto children_loop
67   children_end:
69     it = iter adverbs
70   adverbs_loop:
71     unless it goto adverbs_end
72     $S0 = shift it
73     $P0 = it[$S0]
74     $P1 = find_method self, $S0
75     self.$P1($P0)
76     goto adverbs_loop
77   adverbs_end:
78   end:
79     .return (self)
80 .end
83 =item new([child1, child2, ..., ] [attr1=>val1, attr2=>val2, ...])
85 Create a new PAST node of initialized with the given
86 children and attributes.  Returns the newly created node.
88 =cut
90 .sub 'new' :method
91     .param pmc children        :slurpy
92     .param pmc adverbs         :slurpy :named
94     $P0 = self.'HOW'()
95     $P0 = getattribute $P0, 'parrotclass'
96     $P1 = new $P0
97     $P1.'init'(children :flat, adverbs :flat :named)
98     .return ($P1)
99 .end
102 =item clone()
104 Clone the node.
106 =cut
108 .sub 'clone' :method
109     $P0 = clone self
110     .return ($P0)
111 .end
114 =item unshift(child)
116 Add C<child> to the beginning of the invocant's list of children.
118 =item shift()
120 Remove the first child from the invocant's list of children.
121 Returns the child.
123 =item push(child)
125 Add C<child> to the end of the invocant's list of children.
127 =item pop()
129 Remove the last child from the invocant's list of children.
130 Returns the child.
132 =cut
134 .sub 'unshift' :method
135     .param pmc value
136     unshift self, value
137 .end
139 .sub 'shift' :method
140     $P0 = shift self
141     .return ($P0)
142 .end
144 .sub 'push' :method
145     .param pmc value
146     push self, value
147 .end
149 .sub 'pop' :method
150     $P0 = pop self
151     .return ($P0)
152 .end
155 =item push_new(class, [child1, child2, ..., ] [attr1=>val1, attr2=>val2, ...])
157 (Deprecated.)  Creates a new node of type C<class>, initializes it with the
158 given children and attributes, and adds it to the end of the invocant's
159 array of children.  Returns the newly created node.
161 =cut
163 .sub 'push_new' :method
164     .param string class
165     .param pmc children        :slurpy
166     .param pmc adverbs         :slurpy :named
167     $P0 = split '::', class
168     $P0 = new $P0
169     $P0.'init'(children :flat, adverbs :flat :named)
170     push self, $P0
171     .return ($P0)
172 .end
175 =item iterator( )
177 Returns a newly initialized iterator for the invocant's list of
178 children.
180 =cut
182 .sub 'iterator' :method
183     .local pmc it
184     $P0 = self.'list'()
185     it = iter $P0
186     .return (it)
187 .end
190 =item node([val])
192 Sets the invocant's C<source> and C<pos> attributes to those
193 of C<val>.  If C<val> is another PAST node, then C<source> and C<pos>
194 are simply copied from that node, otherwise C<val> is assumed to be
195 a C<Match> object and obtains source/position information from that.
197 =cut
199 .sub 'node' :method
200     .param pmc node
202     if null node goto done
203     $I0 = isa node, ['PGE';'Match']
204     if $I0 goto node_match
205     $I0 = isa node, ['PCT';'Node']
206     if $I0 goto node_pct
207   node_misc:
208     $I0 = can node, 'orig'
209     unless $I0 goto err_unknown
210     $I0 = can node, 'from'
211     unless $I0 goto err_unknown
212     .local pmc source, pos
213     source = node.'orig'()
214     pos = node.'from'()
215     goto node_done
216   node_match:
217     source = getattribute node, '$.target'
218     pos    = node.'from'()
219     goto node_done
220   node_pct:
221     source = node['source']
222     pos    = node['pos']
223   node_done:
224     self['source'] = source
225     self['pos']    = pos
226   done:
227     .return ()
229   err_unknown:
230     $S0 = typeof node
231     $S0 = concat "Don't know how to save info from node of type ", $S0
232     die $S0
233 .end
236 =item name([value])
238 Accessor method -- sets/returns the C<name> attribute of the invocant.
240 =cut
242 .sub 'name' :method
243     .param pmc value           :optional
244     .param int has_value       :opt_flag
245     .tailcall self.'attr'('name', value, has_value)
246 .end
249 =item attr(STR attrname, PMC value, INT has_value)
251 Helper method for accessors.  If C<has_value> is true then set
252 the invocant's value of C<attrname> to C<value>.  Returns the
253 (resulting) value of C<attrname> in the invocant.
255 =cut
257 .sub 'attr' :method
258     .param string attrname
259     .param pmc value
260     .param int has_value
261     .param pmc default         :optional
262     .param int has_default     :opt_flag
263     if has_value goto setattr
264     value = self[attrname]
265     unless null value goto value_done
266     unless has_default goto value_undef
267     .return (default)
268   value_undef:
269     value = new 'Undef'
270   value_done:
271     .return (value)
272   setattr:
273     self[attrname] = value
274     .return (value)
275 .end
278 =item unique([STR fmt])
280 Generate a unique number that can be used as an identifier.
281 If C<fmt> is provided, then it will be used as a prefix to the
282 unique number.
284 =cut
286 .sub 'unique' :method
287     .param string fmt          :optional
288     .param int has_fmt         :opt_flag
290     if has_fmt goto unique_1
291     fmt = ''
292   unique_1:
293     $P0 = get_global '$!serno'
294     $S0 = $P0
295     $S0 = concat fmt, $S0
296     inc $P0
297     .return ($S0)
298 .end
301 =item isa([type])
303 Ask the current object's metaclass if C<self> is a C<type>, through its C<isa>
304 method. If so, return 1, else return 0.
306 =cut
308 .sub 'isa' :method
309     .param pmc type
310     $P0 = self.'HOW'()
311     $I0 = $P0.'isa'(self, type)
312     .return ($I0)
313 .end
316 =item VTABLE get_bool()
318 Return true since the node is defined.
320 =cut
322 .sub '' :vtable('get_bool') :method
323     .return (1)
324 .end
327 =back
329 =head1 AUTHOR
331 Patrick Michaud <pmichaud@pobox.com> is the author and maintainer.
332 Please send patches and suggestions to the Parrot porters or
333 Perl 6 compilers mailing lists.
335 =head1 HISTORY
337 2006-11-20  Patrick Michaud added first draft of POD documentation.
338 2007-11-21  Re-implementation with pdd26 compliance, compiler toolkit
339 2007-12-07  Refactor PAST::Node into separate PCT::Node component.
341 =head1 COPYRIGHT
343 Copyright (C) 2006-2008, Parrot Foundation.
345 =cut
347 # Local Variables:
348 #   mode: pir
349 #   fill-column: 100
350 # End:
351 # vim: expandtab shiftwidth=4 ft=pir: