1 grammar TclExpr::PIR::Grammar is TGE::Grammar;
3 transform result (ROOT) {
5 .return tree.get('pir', node, $S0)
8 transform pir (PAST::Expr) {
10 pir = new 'CodeString'
14 $P0 = tree.get('pir', value)
21 label = pir.unique('expr_is_string')
23 pir.emit(<<'END_PIR', ret, label)
25 __number = get_root_global ['_tcl'], '__number'
35 transform pir (PAST::Program) {
37 pir = new 'CodeString'
40 .local pmc colons, split, epoch
41 colons = get_root_global ['_tcl'], 'colons'
42 split = get_root_global ['parrot'; 'PGE::Util'], 'split'
43 epoch = get_root_global ['_tcl'], 'epoch'
46 .local pmc iter, child
47 iter = node.'child_iter'()
51 $P0 = tree.'get'('pir', child)
61 transform pir (PAST::Val) {
66 pir = new 'CodeString'
67 ret = pir.unique('$P')
69 pir.emit(" %0 = new '%1'", ret, class)
71 if class == "TclFloat" goto assign_float
72 if class == "TclString" goto assign_string
75 $I0 = index $S0, '.' # RT#40690: '.' hack due to
76 if $I0 >= 0 goto assign_val # parrotbug #38896
78 if $I0 >= 0 goto assign_val
80 if $I0 >= 0 goto assign_val
86 pir.emit(' assign %0, %1', ret, $S0)
93 transform pir (PAST::Var) {
95 pir = new 'CodeString'
96 ret = pir.unique('$P')
103 $I0 = exists node['index']
106 pir.emit(<<'END_PIR', ret, name)
108 __read = get_root_global ['_tcl'], '__read'
115 index = node['index']
117 $P0 = tree.get('pir', index)
120 pir.emit(<<'END_PIR', ret, name, $S0)
122 __read = get_root_global ['_tcl'], '__read'
131 transform pir (PAST::Op) {
132 .local pmc args,iter,pir
133 .local pmc return_register
135 pir = new 'CodeString'
136 args = new 'ResizablePMCArray'
137 iter = node.'child_iter'()
139 unless iter goto iter_done
141 $P0 = tree.get('pir', $P1)
142 return_register = $P1['ret']
143 push args, return_register
149 retval = pir.unique('$P')
151 pir .= " = get_hll_global '"
159 $S0 = join ", ", args
166 transform pir (PAST::MathFunc) {
167 .local pmc args,iter,pir
168 .local pmc return_register
170 pir = new 'CodeString'
171 args = new 'ResizablePMCArray'
172 iter = node.'child_iter'()
174 unless iter goto iter_done
176 $P0 = tree.get('pir', $P1)
177 return_register = $P1['ret']
178 push args, return_register
184 retval = pir.unique('$P')
185 $S0 = node['mathfunc']
186 pir.emit("%0 = get_hll_global ['tcl'; 'mathfunc'], '&%1'", retval, $S0)
191 $S0 = join ", ", args
198 transform pir (PAST::StaticCommand) {
199 .local pmc args, children, iter, pir
202 pir = new 'CodeString'
203 args = new 'ResizablePMCArray'
204 children = node.'get_children'()
205 iter = new 'Iterator', children
211 .local int has_expand
215 unless iter goto iter_done
217 $P0 = tree.get('pir', $P1)
222 if $S0 == 'PAST::Expand' goto iter_expand
223 unless $S0 == 'PAST::Var' goto iter_loop
224 pir.emit(" %0 = clone %0", reg)
231 retval = pir.unique('$P')
233 .local string invalid_, done_, exec_
234 invalid_ = pir.unique('invalid_')
235 done_ = pir.unique('done_')
236 exec_ = pir.unique('exec_')
240 if has_expand goto dynamic
241 $P1 = get_root_global ['_tcl'; 'builtins'], $S0
242 if null $P1 goto dynamic
244 $P0 = $P1(retval, children,args)
245 if null $P0 goto dynamic
248 epoch = get_root_global ['_tcl'], 'epoch'
249 $S0 = pir.unique('dynamic_')
250 pir.emit(' if epoch != %0 goto %1', epoch, $S0)
252 pir.emit(' goto %0', done_)
258 $S0 = join ", ", args
259 $I0 = index name, "::"
260 if $I0 == -1 goto no_ns
262 .local pmc split, colons
263 split = get_root_global ['parrot'; 'PGE::Util'], 'split'
264 colons = get_root_global ['_tcl'], 'colons'
265 $P0 = split(colons, name)
269 $S1 = pir.escape($S1)
272 if $S2 == "" goto root_ns
274 ns = join "'; '", $P0
279 root_ = pir.unique('root_')
280 pir.emit(<<'END_PIR', retval, ns, $S1, root_, exec_)
281 %0 = get_global %1 %2
291 if $I0 == 0 goto root_ns_emit
293 ns = join "'; '", $P0
298 pir.emit(<<'END_PIR', retval, ns, $S1, invalid_, exec_)
299 %0 = get_hll_global %1 %2
307 $S1 = pir.escape($S1)
308 pir.emit(<<'END_PIR', retval, $S1, invalid_)
314 $S3 = pir.escape(name)
315 pir.emit(<<'END_PIR', retval, $S3, $S0, invalid_, done_)
319 tcl_error 'invalid command name %1'
326 transform pir (PAST::DynamicCommand) {
327 .local pmc args, children, iter, pir, reg
329 pir = new 'CodeString'
330 args = new 'ResizablePMCArray'
331 children = node.'get_children'()
332 iter = new 'Iterator', children
334 unless iter goto iter_done
336 $P0 = tree.get('pir', $P1)
340 pir.emit("%0 = clone %0", reg)
343 .local pmc retval, name
344 retval = pir.unique('$P')
347 $S1 = pir.unique('invalid_')
348 $S2 = pir.unique('done_')
352 $S0 = join ", ", args
353 $S4 = pir.unique('curr_namespace')
354 $S5 = pir.unique('root_namespace')
355 pir.emit(<<'END_PIR', retval, name, $S0, $S1, $S2, $S4, $S5)
357 $P0 = split(colons, $S0)
367 %0 = get_hll_namespace $P0
375 %0 = get_namespace $P0
379 if null %0 goto %6 # try the root namespace if it's not in the current
383 tcl_error 'invalid command name %1'
390 transform pir (PAST::Expand) {
391 .local pmc pir, value
392 pir = new 'CodeString'
393 value = node['value']
395 $S0 = tree.get('pir', value)
399 $S1 = pir.'unique'('$P')
400 $S2 = pir.'unique'('loop_')
401 $S3 = pir.'unique'('end_')
402 pir.emit(<<'END_PIR', $S0)
404 __list = get_root_global ['_tcl'], '__list'
413 transform pir (PAST::Cond) {
414 .local pmc args, pir, ret, label
415 .local pmc children, cond, then, else
416 .local string cond_result, then_result, else_result
418 pir = new 'CodeString'
419 pir.emit(' .local pmc __boolean')
420 pir.emit(' __boolean = get_root_global ["_tcl"], "__boolean"')
422 # This node has 3 children. generate PIR so that:
423 # if node1 then node2 else node3
425 # pick a unique register to store our result in.
426 ret = pir.unique('$P')
428 # pick a unique number for our labels..
429 label = pir.unique('label_')
431 children = node.'get_children'()
434 $S0 = tree.get('pir', cond)
436 cond_result = cond['ret']
438 pir.emit(" %0 = __boolean(%0)", cond_result)
439 pir.emit(" unless %0 goto else_%1", cond_result, label)
442 $S0 = tree.get('pir', then)
444 then_result = then['ret']
446 pir.emit(' %0 = %1', ret, then_result)
447 pir.emit(" goto end_if_%0", label)
449 #set the result register to the answer from this section
451 #then jump to custom end label..
453 pir.emit(" else_%0:",label)
456 $S0 = tree.get('pir', else)
458 else_result = else['ret']
460 pir.emit(' %0 = %1', ret, else_result)
462 #set the result register to the answer from this section
464 pir.emit(" end_if_%0:",label)