hi, attached an update for ASTGrammar.tg for languages/PIR
In order to print the past tree to screen, set 'target' to 'past' in pirc.pir. Currently, it is set to 'parse' in order to pass the tests.
regards, klaas-jan
Index: languages/PIR/lib/ASTGrammar.tg =================================================================== --- languages/PIR/lib/ASTGrammar.tg (revision 16922) +++ languages/PIR/lib/ASTGrammar.tg (working copy) @@ -1,506 +1,330 @@ grammar ASTGrammar is TGE::Grammar; -transform past (ROOT) :language('PIR') { - # Ask the child node for its result - .local pmc child - .local pmc result - - - result = new 'PAST::Block' - result.'init'('node'=>node, 'name'=>'anon') - - #.return(result) - - $I0 = defined node["program"] - unless $I0 goto err_no_tree - $P0 = node["program"] - print "\nSuccess!\n" - #printerr "SOURCE:\n" - #$S0 = node["source"] - #printerr $S0 - #printerr "\n========================\n" - child = tree.get('past', $P0, 'PIRGrammar::program') - print "Back from tree\n\n" - result.'push'(child) - .return (result) - - err_no_tree: - print "The top-level node doesn't contain a 'program' match.\n" - end +# past (ROOT) +# +# Transform the 'program' rule into a PAST::Block. +# +transform past (ROOT) :language('PIR') { + .local pmc past + past = new 'PAST::Block' + past.'init'('node'=>node, 'name'=>'anon') + + .local pmc childnode, childpast + childnode = node['program'] + childpast = tree.'get'('past', childnode, 'PIRGrammar::program') + past.'push'(childpast) + .return (past) } - +# past (PIRGrammar::program) +# +# Store each of the compilation units into a PAST::Stmts node. +# transform past (PIRGrammar::program) :language('PIR') { - .local pmc result - result = new 'PAST::Stmts' - result.'init'('node'=>node) + .local pmc past + past = new 'PAST::Stmts' + past.'init'('node'=>node) - $S0 = node["source"] - printerr "SOURCE:\n" - printerr $S0 - printerr "\n========================\n" - - # Ask the child node for its result - .local pmc child - $I0 = defined node["compilation_unit"] - unless $I0 goto err_no_tree - $P0 = node["compilation_unit"] - print $P0 .local pmc iter - iter = new Iterator, $P0 # setup iterator for node - iter = 0 - - iter_loop: - unless iter, iter_end # while (entries) ... - shift $P2, iter - $P3 = tree.get('past', $P2, 'PIRGrammar::compilation_unit') - result.'push'($P3) - goto iter_loop + $P0 = node['compilation_unit'] + if null $P0 goto iter_end + iter = new .Iterator, $P0 + iter_loop: + unless iter goto iter_end + .local pmc cnode, cpast + cnode = shift iter + cpast = tree.'get'('past', cnode, 'PIRGrammar::compilation_unit') + past.'push'(cpast) + goto iter_loop iter_end: - - .return (result) - err_no_tree: - print "The 'program' node doesn't contain a 'compilation_unit' match.\n" - .return (result) + .return (past) } +# past (PIRGrammar::compilation_unit) +# +# Call the appropiate transform rule depending on the type of compilation unit. +# transform past (PIRGrammar::compilation_unit) :language('PIR') { - .local pmc result - result = new .ResizablePMCArray + global_def: + $P0 = node['global_def'] + if null $P0 goto sub_def + .return tree.'get'('past', $P0, 'PIRGrammar::global_def') + sub_def: + $P0 = node['sub_def'] + if null $P0 goto const_def + .return tree.'get'('past', $P0, 'PIRGrammar::sub_def') + const_def: + $P0 = node['const_def'] + if null $P0 goto macro_def + .return tree.'get'('past', $P0, 'PIRGrammar::const_def') + macro_def: + $P0 = node['macro_def'] + if null $P0 goto pragma + .return tree.'get'('past', $P0, 'PIRGrammar::macro_def') + pragma: + $P0 = node['pragma'] + if null $P0 goto emit + .return tree.'get'('past', $P0, 'PIRGrammar::pragma') + emit: + $P0 = node['emit'] + if null $P0 goto const_def + .return tree.'get'('past', $P0, 'PIRGrammar::emit') +} - .local pmc iter - iter = new Iterator, node # setup iterator for node - iter = 0 - iter_loop: - unless iter, iter_end # while (entries) ... - shift $S1, iter # get the key of the iterator - $P2 = iter[$S1] - $S1 = concat 'PIRGrammar::', $S1 - $P3 = tree.get('past', $P2, $S1) - if null $P3 goto iter_loop - push result, $P3 - goto iter_loop - iter_end: - $I0 = elements result - if $I0 != 1 goto err_too_many - $P4 = result[0] - - .return ($P4) - err_too_many: - print "A 'line' node can only have one child.\n" - end - .return(result) +transform past (PIRGrammar::global_def) :language('PIR') { + } -transform past (PIRGrammar::class_def) :language('PIR') { +# past (PIRGrammar::sub_def) +# +# Transform a sub_def into a PAST::Block node. +# +transform past (PIRGrammar::sub_def) :language('PIR') { + printerr "subdef\n" .local pmc result - result = new .ResizablePMCArray - printerr "class def\n" - $P0 = node['sub_def'] - tree.get('past', $P0, 'PIRGrammar::sub_def') - - # .local pmc iter - # iter = new Iterator, node # setup iterator for node - # iter = 0 - # iter_loop: - # unless iter, iter_end # while (entries) ... - # shift $S1, iter # get the key of the iterator - # - # $P2 = iter[$S1] - # print $S1 - # print " = " - # print $P2 - # print "\n" - # $S1 = concat 'PIRGrammar::', $S1 - # $P3 = tree.get('past', $P2, $S1) - # if null $P3 goto iter_loop - # push result, $P3 - # goto iter_loop - # iter_end: - # $I0 = elements result - # if $I0 != 1 goto err_too_many - # $P4 = result[0] - # .return ($P4) - # #.return (result) - # err_too_many: - # print "A 'line' node can only have one child.\n" - # end - .return(result) + result = new 'PAST::Block' + .local string name + name = node['sub_id'] + result.'init'('node'=>node, 'name'=> name, 'blocktype'=>'sub') + .local pmc child + + # TODO: parameters + + $P1 = node['body'] + child = tree.'get'('past', $P1, 'PIRGrammar::body') + result.'push'(child) + .return(result) } transform past (PIRGrammar::const_def) :language('PIR') { - .local pmc result - result = new .ResizablePMCArray - print "const def\n" - - # .local pmc iter - # iter = new Iterator, node # setup iterator for node - # iter = 0 - #iter_loop: - # unless iter, iter_end # while (entries) ... - # shift $S1, iter # get the key of the iterator - # - # $P2 = iter[$S1] - # print $S1 - # print " = " - # print $P2 - # print "\n" - # #$S1 = concat 'PIRGrammar::', $S1 - # #$P3 = tree.get('past', $P2, $S1) - # #if null $P3 goto iter_loop - # #push result, $P3 - # goto iter_loop - #iter_end: - # #$I0 = elements result - # #if $I0 != 1 goto err_too_many - # #$P4 = result[0] - # #.return ($P4) - # .return (result) - #err_too_many: - # print "A 'line' node can only have one child.\n" - # end - - .return(result) + .local pmc past + past = new 'PASM::Op' + # FIX: + past.'init'('node'=>node, 'pasttype'=>'pirop', 'pirop'=>'const') + .return (past) } -transform past (PIRGrammar::global_def) :language('PIR') { - .local pmc result - result = new .ResizablePMCArray - print "global def\n" - - # .local pmc iter - # iter = new Iterator, node # setup iterator for node - # iter = 0 - # iter_loop: - # unless iter, iter_end # while (entries) ... - # shift $S1, iter # get the key of the iterator - # - # $P2 = iter[$S1] - # print $S1 - # print " = " - # print $P2 - # print "\n" - # #$S1 = concat 'PIRGrammar::', $S1 - # #$P3 = tree.get('past', $P2, $S1) - # #if null $P3 goto iter_loop - # #push result, $P3 - # goto iter_loop - # iter_end: - # #$I0 = elements result - # #if $I0 != 1 goto err_too_many - # #$P4 = result[0] - # #.return ($P4) - # .return (result) - # err_too_many: - # print "A 'line' node can only have one child.\n" - # end - - .return(result) +transform past (PIRGrammar::macro_def) :language('PIR') { + } -transform past (PIRGrammar::sub_def) :language('PIR') { - .local pmc result - result = new .ResizablePMCArray - print "sub def\n" - - $P0 = node['sub_id'] - printerr $P0 - .return($P0) - #printerr $S0 - # .local pmc iter - # iter = new Iterator, node # setup iterator for node - # iter = 0 - # iter_loop: - # unless iter, iter_end # while (entries) ... - # shift $S1, iter # get the key of the iterator - # - # $P2 = iter[$S1] - # print $S1 - # print " = " - # print $P2 - # print "\n" - # #$S1 = concat 'PIRGrammar::', $S1 - # #$P3 = tree.get('past', $P2, $S1) - # #if null $P3 goto iter_loop - # #push result, $P3 - # goto iter_loop - # iter_end: - # #$I0 = elements result - # #if $I0 != 1 goto err_too_many - # #$P4 = result[0] - # #.return ($P4) - # .return (result) - # err_too_many: - # print "A 'line' node can only have one child.\n" - # end - .return(result) +transform past (PIRGrammar::pragma_def) :language('PIR') { + .local pmc past + past = new 'PASM::Op' + past.'init'('node'=>node, 'pasttype'=>'pirop', 'pirop'=>'.pragma') + .return (past) } -transform past (PIRGrammar::pragma) :language('PIR') { - .local pmc result - result = new .ResizablePMCArray - print "pragma\n" +transform past (PIRGrammar::emit) :language('PIR') { - # .local pmc iter - # iter = new Iterator, node # setup iterator for node - # iter = 0 - # iter_loop: - # unless iter, iter_end # while (entries) ... - # shift $S1, iter # get the key of the iterator - # - # $P2 = iter[$S1] - # print $S1 - # print " = " - # print $P2 - # print "\n" - # #$S1 = concat 'PIRGrammar::', $S1 - # #$P3 = tree.get('past', $P2, $S1) - # #if null $P3 goto iter_loop - # #push result, $P3 - # goto iter_loop - # iter_end: - # #$I0 = elements result - # #if $I0 != 1 goto err_too_many - # #$P4 = result[0] - # #.return ($P4) - # .return (result) - # err_too_many: - # print "A 'line' node can only have one child.\n" - # end - - .return(result) } +#transform past (PIRGrammar::param) :language('PIR') { +# +#} +# past (PIRGrammar::body) +# +# Store each of the instructions in a body node in a PAST::Stmts node. +# transform past (PIRGrammar::body) :language('PIR') { - .local pmc result - result = new ResizablePMCArray + printerr "body\n" + .local pmc past + past = new 'PAST::Stmts' + past.'init'('node'=>node) - .local pmc iter - iter = new Iterator, node # setup iterator for node - iter = 0 + .local pmc iter + $P0 = node['labeled_pir_instr'] + if null $P0 goto iter_end + iter = new .Iterator, $P0 iter_loop: - unless iter, iter_end # while (entries) ... - shift $S1, iter # get the key of the iterator - $P2 = iter[$S1] - print $P2 - #$S1 = concat 'PIRGrammar::', $S1 - #$P3 = tree.get('past', $P2, $S1) - #if null $P3 goto iter_loop - #push result, $P3 - goto iter_loop + unless iter goto iter_end + .local pmc cnode, cpast + cnode = shift iter + cpast = tree.'get'('past', cnode, 'PIRGrammar::labeled_pir_instr') + past.'push'(cpast) + goto iter_loop iter_end: - #$I0 = elements result - #if $I0 != 1 goto err_too_many - #$P4 = result[0] - .return(result) + .return (past) } -transform past (PIRGrammar::id) :language('PIR') { - .local pmc result - result = new .ResizablePMCArray - $S0 = node["name"] - printerr $S0 - printerr "\n\n" - # $P1 = node.get_hash() - # $P0 = new Iterator, $P1 # setup iterator for node - # set $P0, 0 # reset iterator, begin at start - # iter_loop: - # unless $P0, iter_end # while (entries) ... - # shift $S2, $P0 # get key for next entry - # $P2 = $P0[$S2] # get entry at current key - # $S2 = concat 'PunieGrammar::', $S2 - # $P3 = tree.get('past', $P2, $S2) - # if null $P3 goto iter_loop - # push result, $P3 - # goto iter_loop - # iter_end: - # $I0 = elements result - # if $I0 != 1 goto err_too_many - # $P4 = result[0] - # - # .return ($P4) - # err_too_many: - # print "An 'expr' node can only have one child.\n" - # end - .return(result) + +transform past (PIRGrammar::local_decl) :language('PIR') { + } -transform past (PIRGrammar::extensions) :language('PIR') { - .local pmc result - result = new 'PAST::Op' - $S1 = node[0] - result.'name'($S1) +transform past (PIRGrammar::lexical_decl) :language('PIR') { + +} - # $P1 = node.get_hash() - # $P0 = new Iterator, $P1 # setup iterator for node - # set $P0, 0 # reset iterator, begin at start - #iter_loop: - # unless $P0, iter_end # while (entries) ... - # shift $S2, $P0 # get key for next entry - # $P2 = $P0[$S2] # get entry at current key - # $S2 = concat 'PunieGrammar::', $S2 - # $P3 = tree.get('past', $P2, $S2) - # if null $P3 goto iter_loop - # $S0 = $P3.'name'() - # if $S0 == 'infix:,' goto flatten_comma - # result.'init'($P3, 'node'=>node) - # goto iter_loop - # flatten_comma: - # $P4 = $P3.'get_array'() - # result.'init'($P4 :flat, 'node'=>node) - # goto iter_loop - #iter_end: - # - .return (result) +transform past (PIRGrammar::const_def) :language('PIR') { + } -transform past (PIRGrammar::nl) :language('PIR') { - .return() +transform past (PIRGrammar::assignment_stat) :language('PIR') { + } -transform past (PIRGrammar::class_member) :language('PIR') { - .return() +transform past (PIRGrammar::open_namespace) :language('PIR') { + .local pmc past + past = new 'PASM::Op' + past.'init'('node'=>node, 'pasttype'=>'pirop', 'pirop'=>'.namespace') + .return (past) } + +transform past (PIRGrammar::close_namespace) :language('PIR') { + .local pmc past + past = new 'PASM::Op' + past.'init'('node'=>node, 'pasttype'=>'pirop', 'pirop'=>'.endnamespace') + .return (past) +} + +transform past (PIRGrammar::return_stat) :language('PIR') { +} +transform past (PIRGrammar::sub_invocation) :language('PIR') { + +} -transform past (PunieGrammar::cond) :language('PIR') { - .local pmc result - result = new 'PAST::Op' - result.'init'('node'=>node) - $S1 = node[0] - result.'name'($S1) - result.'pasttype'($S1) +transform past (PIRGrammar::macro_invocation) :language('PIR') { + +} - $P1 = node.get_hash() - .local pmc iter - iter = new Iterator, $P1 # setup iterator for node - set iter, 0 # reset iterator, begin at start - iter_loop: - unless iter, iter_end # while (entries) ... - shift $S2, iter # get key for next entry - $P2 = iter[$S2] # get entry at current key - $S2 = concat 'PunieGrammar::', $S2 - $P3 = tree.get('past', $P2, $S2) - if null $P3 goto iter_loop - result.'push'($P3) - goto iter_loop - iter_end: +transform past (PIRGrammar::jump_stat) :language('PIR') { + .local pmc past + past = new 'PASM::Op' + past.'init'('node'=>node, 'pasttype'=>'pirop', 'pirop'=>'goto') + .return (past) +} - .return (result) +transform past (PIRGrammar::source_info) :language('PIR') { + } -transform past (PunieGrammar::else) :language('PIR') { - .local pmc result, onechild - onechild = node[0] - unless onechild goto no_child - .local string opname - opname = onechild[0] - unless opname == 'else' goto is_else_if - $P1 = onechild['block'] - result = tree.get('past', $P1, 'PunieGrammar::block') - goto transform_complete +transform past (PIRGrammar::instr) :language('PIR') { + printerr "instr\n" + $P0 = node['pir_instr'] + if null $P0 goto pasm_instr + pir_instr: + .return tree.'get'('past', $P0, 'PIRGrammar::pir_instr') + pasm_instr: + $P0 = node['pasm_instr'] + .return tree.'get'('past', $P0, 'PIRGrammar::pasm_instr') +} - is_else_if: - result = new 'PAST::Op' - result.'init'('node'=>onechild, 'name'=>opname, 'pasttype'=>'if') +transform past (PIRGrammar::labeled_pir_instr) :language('PIR') { + $P0 = node['instr'] + if null $P0 goto end + .return tree.'get'('past', $P0, 'PIRGrammar::instr') + end: +} - $P1 = onechild.get_hash() - .local pmc iter - iter = new Iterator, $P1 # setup iterator for node - set iter, 0 # reset iterator, begin at start - iter_loop: - unless iter, iter_end # while (entries) ... - shift $S2, iter # get key for next entry - $P2 = iter[$S2] # get entry at current key - $S2 = concat 'PunieGrammar::', $S2 - $P3 = tree.get('past', $P2, $S2) - if null $P3 goto iter_loop - result.'push'($P3) - goto iter_loop - iter_end: - transform_complete: - .return (result) - no_child: - .return () +# past (PIRGrammar::pir_instr) +# +# Return the transformed tree of a PIR instruction. +# +transform past (PIRGrammar::pir_instr) :language('PIR') { + local_decl: + $P0 = node['local_decl'] + if null $P0 goto lexical_decl + .return tree.'get'('past', $P0, 'PIRGrammar::local_decl') + lexical_decl: + $P0 = node['local_decl'] + if null $P0 goto const_def + .return tree.'get'('past', $P0, 'PIRGrammar::lexical_decl') + const_def: + $P0 = node['const_def'] + if null $P0 goto assignment_stat + .return tree.'get'('past', $P0, 'PIRGrammar::const_def') + assignment_stat: + $P0 = node['assignment_stat'] + if null $P0 goto open_namespace + .return tree.'get'('past', $P0, 'PIRGrammar::assignment_stat') + open_namespace: + $P0 = node['open_namespace'] + if null $P0 goto close_namespace + .return tree.'get'('past', $P0, 'PIRGrammar::open_namespace') + close_namespace: + $P0 = node['close_namespace'] + if null $P0 goto return_stat + .return tree.'get'('past', $P0, 'PIRGrammar::close_namespace') + return_stat: + $P0 = node['return_stat'] + if null $P0 goto sub_invocation + .return tree.'get'('past', $P0, 'PIRGrammar::return_stat') + sub_invocation: + $P0 = node['sub_invocation'] + if null $P0 goto macro_invocation + .return tree.'get'('past', $P0, 'PIRGrammar::sub_invocation') + macro_invocation: + $P0 = node['assignment_stat'] + if null $P0 goto lexical_decl + .return tree.'get'('past', $P0, 'PIRGrammar::macro_invocation') } -transform past (PunieGrammar::label) :language('PIR') { - .return () + +# past (PIRGrammar::pasm_instr) +# +# Create a PAST::Op node that represents the PASM instruction +# +transform past (PIRGrammar::pasm_instr) :language('PIR') { + .local pmc past + past = new 'PAST::Op' + # FIX: set the correct pirop + past.'init'('node'=>node, 'pasttype'=>'pirop', 'pirop'=>'XX') + .return (past) } -transform past (PunieGrammar::oexpr) :language('PIR') { - .local pmc result - result = new .ResizablePMCArray - $P1 = node.get_hash() - .local pmc iter - iter = new Iterator, $P1 # setup iterator for node - set iter, 0 - iter_loop: - unless iter, iter_end # while (entries) ... - shift $S1, iter # get key for next entry - $P2 = iter[$S1] # get entry at current key - $P3 = tree.get('past', $P2, $S1) - if null $P3 goto iter_loop - push result, $P3 - goto iter_loop - iter_end: - $I0 = elements result - if $I0 != 1 goto err_too_many - $P4 = result[0] - .return ($P4) - err_too_many: - print "An 'oexpr' node can only have one child.\n" - end +transform past (PIRGrammar::simple_expr) :language('PIR') { + .local pmc past + int_constant: + $P0 = node['int_constant'] + if null $P0 goto float_constant + past = new 'PAST::Val' + past.'init'('node'=>node, 'vtype'=>'.Integer', 'name'=>node, 'ctype'=>'i+') + .return (past) + float_constant: + $P0 = node['float_constant'] + if null $P0 goto string_constant + past = new 'PAST::Val' + past.'init'('node'=>node, 'vtype'=>'.Float', 'name'=>node, 'ctype'=>'n+') + .return (past) + string_constant: + $P0 = node['string_constant'] + if null $P0 goto target + .return tree.'get'('past', $P0, 'PIRGrammar::string_constant') + target: + $P0 = node['target'] + .return tree.'get'('past', $P0, 'PIRGrammar::target') } -transform past (PunieGrammar::variable) :language('PIR') { - .local pmc result - result = new 'PAST::Var' - result.'init'('node'=>node, 'viviself'=>'.Undef') - .local string sigil - .local string name - sigil = node['sigil'] - $S1 = node['word'] - name = sigil . $S1 +transform past (PIRGrammar::target) :language('PIR') { - result.'name'(name) - result.'scope'('global') - -# unless sigil == '$' goto not_scalar -# result.'vartype'('scalar') - not_scalar: - - .return (result) } -transform past (PunieGrammar::number) :language('PIR') { - .local pmc result - result = new 'PAST::Val' - result.'init'('node'=>node, 'vtype'=>'.Float', 'name'=>node, 'ctype'=>'n+') - .return (result) -} -transform past (PunieGrammar::integer) :language('PIR') { - .local pmc result - result = new 'PAST::Val' - result.'init'('node'=>node, 'vtype'=>'.Integer', 'name'=>node, 'ctype'=>'i+') - .return (result) +transform past (PIRGrammar::string_constant) :language('PIR') { + stringsingle: + $P0 = node['stringsingle'] + if null $P0 goto stringdouble + .return tree.'get'('past', $P0, 'PIRGrammar::stringsingle') + stringdouble: + $P0 = node['stringsingle'] + .return tree.'get'('past', $P0, 'PIRGrammar::stringsingle') } -transform past (PunieGrammar::stringdouble) :language('PIR') { +transform past (PIRGrammar::stringdouble) :language('PIR') { .local pmc result result = new 'PAST::Val' - - + .local string value # Check if this is a string match $I0 = defined node["PGE::Text::bracketed"] @@ -518,7 +342,7 @@ .return (result) } -transform past (PunieGrammar::stringsingle) :language('PIR') { +transform past (PIRGrammar::stringsingle) :language('PIR') { .local pmc result result = new 'PAST::Val' @@ -535,103 +359,3 @@ result.'init'('node'=>node, 'vtype'=>'.String', 'name'=>value) .return (result) } - -# The following rules are for the results of the operator precedence -# parser. These operate very differently than the standard grammar -# rules, because they give the node type in a "type" hash key inside the -# node, instead of storing the node as the value of a hash key that -# is their type. - -transform past (expr) :language('PIR') { - .local string type - type = node["type"] - unless node goto error_no_node - if type == 'term:' goto transform_term - # else - $P1 = tree.get('op', node, 'expr') - .return($P1) - transform_term: - $P1 = tree.get('term', node, 'expr') - .return($P1) - error_no_node: - print "error: no node\n" - end -} - -transform op (expr) :language('PIR') { - .local pmc result - result = new 'PAST::Op' - .local string type - type = node["type"] - - # XXX Slurped up directly from Perl 6 implementation, refactor later - .local pmc optable, optok - .local string pasttype, pirop - .local int islvalue - optable = get_hll_global [ 'PunieGrammar' ], '$optable' - optok = optable[type] - pasttype = optok['past'] - pirop = optok['pirop'] - islvalue = optok['lvalue'] - - result.'init'('node'=>node, 'name'=>type, 'pasttype'=>pasttype, 'pirop'=>pirop, 'islvalue'=>islvalue) - - $P1 = node.'get_array'() - .local pmc iter - iter = new Iterator, $P1 # setup iterator for node - set iter, 0 # reset iterator, begin at start - iter_loop: - unless iter, iter_end # while (entries) ... - shift $P2, iter # get entry - $P3 = tree.get('past', $P2, 'expr') - if null $P3 goto iter_loop - result.'push'($P3) - goto iter_loop - iter_end: - - .return (result) -} - -transform term (expr) :language('PIR') { - .local pmc result - .local pmc children - children = new .ResizablePMCArray - $P1 = node.get_hash() - $P0 = new Iterator, $P1 # setup iterator for node - set $P0, 0 # reset iterator, begin at start - iter_loop: - unless $P0, iter_end # while (entries) ... - shift $S2, $P0 # get key for next entry - # skip 'type' keys added by the operator precedence parser - if $S2 == 'type' goto iter_loop - $P2 = $P0[$S2] # get entry at current key - $S2 = concat 'PunieGrammar::', $S2 - $P3 = tree.get('past', $P2, $S2) - if null $P3 goto iter_loop - push children, $P3 - goto iter_loop - iter_end: - - $I0 = elements children - unless $I0 == 1 goto err_too_many - result = children[0] - .return (result) - - err_too_many: - print "error: Currently, 'term' nodes should have only one child.\n" - end -} - -=head1 LICENSE - -Copyright (C) 2006-2007, The Perl Foundation. - -This is free software; you may redistribute it and/or modify -it under the same terms as Parrot. - -=head1 AUTHOR - -Allison Randal <[EMAIL PROTECTED]> - -=cut -