3 POST::Compiler - Compiler for POST trees
7 POST::Compiler defines a compiler that converts a POST tree into
8 PIR or an Eval PMC (bytecode).
16 .namespace [ 'POST::Compiler' ]
18 .sub '__onload' :load :init
19 .local pmc p6meta, cproto
20 p6meta = new 'P6metaclass'
21 cproto = p6meta.'new_class'('POST::Compiler', 'parent'=>'PCT::HLLCompiler')
22 cproto.'language'('POST')
23 $P1 = split ' ', 'pir evalpmc'
26 $P0 = new 'ResizablePMCArray'
27 set_global '@!subcode', $P0
30 set_global '$?NAMESPACE', $P0
37 .param pmc adverbs :slurpy :named
40 newself = new 'POST::Compiler'
42 ## start with empty code
43 .local pmc subcode, code
44 subcode = get_global '@!subcode'
45 code = new 'CodeString'
48 ## if the root node isn't a Sub, wrap it
49 $I0 = isa post, 'POST::Sub'
51 $P0 = get_hll_global ['POST'], 'Sub'
52 post = $P0.'new'(post, 'name'=>'anon')
55 ## now generate the pir
58 ## and return whatever code was generated
64 =item pir_children(node)
66 Return generated PIR for C<node> and all of its children.
70 .sub 'pir_children' :method
73 code = new 'CodeString'
74 iter = node.'iterator'()
76 unless iter goto iter_end
79 $P0 = self.'pir'(cpost)
89 Return generated pir for any POST::Node. Returns
90 the generated pir of C<node>'s children.
94 .sub 'pir' :method :multi(_,_)
96 .return self.'pir_children'(node)
100 =item pir(POST::Op node)
102 Return pir for an operation node.
106 .sub 'pir' :method :multi(_,['POST::Op'])
109 ## determine the type of operation
111 pirop = node.'pirop'()
113 ## determine if we're storing result
115 result = node.'result'()
116 unless result goto have_result
120 ## get list of arguments to operation
122 arglist = node.'list'()
124 ## get format and arguments based on pirop
125 .local string fmt, name, invocant
126 if pirop == 'call' goto pirop_call
127 if pirop == 'callmethod' goto pirop_callmethod
128 if pirop == 'return' goto pirop_return
129 if pirop == 'tailcall' goto pirop_tailcall
130 if pirop == 'inline' goto pirop_inline
145 invocant = shift arglist
149 fmt = " .return (%,)"
154 fmt = ' .return %n(%,)'
158 fmt = node.'inline'()
159 result = node.'result'()
164 code = new 'CodeString'
165 code.'emit'(fmt, arglist :flat, 'r'=>result, 'n'=>name, 'i'=>invocant, 't'=>result)
170 =item pir(POST::Label node)
176 .sub 'pir' :method :multi(_, ['POST::Label'])
178 .local string code, value
179 value = node.'result'()
187 =item pir(POST::Sub node)
189 Generate PIR for C<node>, storing the result into the compiler's
190 C<$!code> attribute and returning any code needed to look up
195 .sub 'pir' :method :multi(_, ['POST::Sub'])
199 subcode = get_global '@!subcode'
200 $P0 = new 'CodeString'
204 code = new 'CodeString'
206 .local string name, pirflags
208 pirflags = node.'pirflags'()
211 $I0 = index pirflags, ':lexid('
212 if $I0 >= 0 goto pirflags_lexid_done
214 lexid = code.'unique'()
216 pirflags = concat pirflags, ' :lexid("'
222 $I0 = index pirflags, ':method'
223 if $I0 >= 0 goto pirflags_method_done
224 $S0 = node.'blocktype'()
225 if $S0 != 'method' goto pirflags_method_done
226 pirflags = concat pirflags, ' :method'
227 pirflags_method_done:
229 .local pmc outerpost, outername
230 outername = new 'Undef'
231 outerpost = node.'outer'()
232 if null outerpost goto pirflags_done
233 unless outerpost goto pirflags_done
234 outername = outerpost.'lexid'()
235 $S0 = code.'escape'(outername)
236 pirflags = concat pirflags, ' :outer('
241 .local pmc outerns, ns, nskey
242 outerns = get_global '$?NAMESPACE'
244 ns = node.'namespace'()
245 unless ns goto have_ns
246 nskey = code.'key'(ns)
247 set_global '$?NAMESPACE', nskey
251 $P0 = node.'compiler'()
252 unless $P0 goto subpir_post
254 $P0 = node.'compiler_args'()
255 if $P0 goto have_compiler_args
258 $P0 = self.'hll_pir'(node, 'name'=>name, 'namespace'=>ns, 'pirflags'=>pirflags, $P0 :named :flat)
263 code.'emit'("\n.namespace %0", nskey)
264 $S0 = code.'escape'(name)
265 code.'emit'(".sub %0 %1", $S0, pirflags)
267 paramlist = node['paramlist']
268 if null paramlist goto paramlist_done
270 iter = new 'Iterator', paramlist
272 unless iter goto paramlist_done
274 if null $P0 goto param_loop
279 $P0 = self.'pir_children'(node)
281 code.'emit'(".end\n\n")
289 set_global '$?NAMESPACE', outerns
291 code = new 'CodeString'
296 .sub 'hll_pir' :method
298 .param pmc options :slurpy :named
300 options['target'] = 'pir'
301 options['grammar'] = ''
302 .local pmc source, compiler, pir
304 $S0 = node.'compiler'()
305 compiler = compreg $S0
306 $I0 = isa compiler, 'Sub'
307 if $I0 goto compiler_sub
308 .return compiler.'compile'(source, options :flat :named)
310 .return compiler(source, options :flat :named)
317 Patrick Michaud <pmichaud@pobox.com> is the author and maintainer.
318 Please send patches and suggestions to the Parrot porters or
319 Perl 6 compilers mailing lists.
323 2007-11-21 Significant refactor as part of Parrot Compiler Toolkit
327 Copyright (C) 2006-2008, The Perl Foundation.
335 # vim: expandtab shiftwidth=4 ft=pir: