# New Ticket Created by Klaas-Jan Stol # Please include the string: [perl #41762] # in the subject line of all future correspondence about this issue. # <URL: http://rt.perl.org/rt3/Ticket/Display.html?id=41762 >
hi, attached a patch implementing basic function calling for pynie. * function calling without parameters * added 2 more tests for unary - and * added test for function call regards, kjs
Index: languages/pynie/src/parser/Grammar.pg =================================================================== --- languages/pynie/src/parser/Grammar.pg (revision 17410) +++ languages/pynie/src/parser/Grammar.pg (working copy) @@ -367,7 +367,7 @@ <'r'> | <'u'> | <'ur'> | <'R'> | <'U'> | <'UR'> | <'Ur'> | <'uR'> } -rule expression_list { <expression> [ , <expression> ]* <','>? } +rule expression_list { <expression> [ , <expression> ]* (<','>)? } rule list_display { <'['> <listmaker>? <']'> } Index: languages/pynie/src/PAST/Grammar.tg =================================================================== --- languages/pynie/src/PAST/Grammar.tg (revision 17410) +++ languages/pynie/src/PAST/Grammar.tg (working copy) @@ -211,11 +211,77 @@ transform past (Pynie::Grammar::expression) :language('PIR') { $P0 = node['or_test'] + if null $P0 goto lambda $P0 = $P0[0] # this is a hack, 'rule expression' has 1 or more <or_test>s, so it stores them in an array. Handle $P0[1] later. #printerr "pynie::grammar::expression\n" .return tree.'get'('past', $P0, 'Pynie::Grammar::or_test') + lambda: + $P0 = node['lambda_form'] + .return tree.'get'('past', $P0, 'Pynie::Grammar::lambda_form') + } +transform past (Pynie::Grammar::lambda_form) :language('PIR') { + .local pmc past + past = new 'PAST::Block' + past.'init'('node'=>node) + $P0 = node['parameter_list'] + $P0 = $P0[0] + if null $P0 goto skip_parameter_list + .local pmc parampast + parampast = tree.'get'('past', $P0, 'Pynie::Grammar::parameter_list') + #past.'push'(parampast) + + skip_parameter_list: + .local pmc exprnode, exprpast + exprnode = node['expression'] + exprpast = tree.'get'('past', exprnode, 'Pynie::Grammar::expression') + past.'push'(exprpast) + .return (past) +} + +transform past (Pynie::Grammar::parameter_list) :language('PIR') { + .local pmc past + past = new 'PAST::VarList' + past.'init'('node'=>node) + + .local pmc iter + $P0 = node['defparameter'] + iter = new .Iterator, $P0 + iter_loop: + unless iter goto iter_end + .local pmc cnode, cpast + cnode = shift iter + cpast = tree.'get'('past', cnode, 'Pynie::Grammar::defparameter') + past.'push'(cpast) + goto iter_loop + + iter_end: + .return (past) +} + +transform past (Pynie::Grammar::defparameter) :language('PIR') { + $P0 = node['parameter'] + .return tree.'get'('past', $P0, 'Pynie::Grammar::parameter') +} + +transform past (Pynie::Grammar::parameter) :language('PIR') { + $P0 = node['identifier'] + if null $P0 goto sublist + $P1 = tree.'get'('past', $P0, 'Pynie::Grammar::identifier') + $S0 = $P1['name'] + .local pmc past + past = new 'PAST::Var' + past.'init'('node'=>node, 'name'=>$S0, 'scope'=>'parameter') + past.'islvalue'(1) + #.return ($P1) + .return (past) + + sublist: + printerr "Not implemented!\n" + exit 1 +} + transform past (Pynie::Grammar::or_test) :language('PIR') { .local pmc past, iter, clist, cnode clist = node['and_test'] @@ -365,10 +431,38 @@ } transform past_primary (Pynie::Grammar::primary) :language('PIR') { - .local pmc atomnode, atompast + .local pmc past + past = new 'PAST::Op' + past.'init'('node'=>node, 'pasttype'=>'call') + + .local pmc atomnode, atompast atomnode = node['atom'] atompast = tree.'get'('past', atomnode, 'Pynie::Grammar::atom') + + # get the postop nodes; if there aren't any, return atompast + $P0 = node['postop'] + unless null $P0 goto do_postop .return (atompast) + + do_postop: + past.'push'(atompast) + if null $P0 goto iter_end + .local pmc iter + iter = new .Iterator, $P0 + + iter_loop: + unless iter goto iter_end + .local pmc cnode, cpast + cnode = shift iter + $S0 = cnode.'find_key'() + cnode = cnode[$S0] + $S0 = concat 'Pynie::Grammar::', $S0 + cpast = tree.'get'('past', cnode, $S0) + atompast.'push'(cpast) + goto iter_loop + + iter_end: + .return (past) } transform past (Pynie::Grammar::atom) :language('PIR') { @@ -379,6 +473,37 @@ .return tree.'get'('past', cnode, $S0) } +transform past (Pynie::Grammar::call) :language('PIR') { + .local pmc past + past = new 'PAST::Op' + past.'init'('node'=>node, 'pasttype'=>'call') + + $P0 = node['argument_list'] + if null $P0 goto no_args + .local pmc argpast + argpast = tree.'get'('past', $P0, 'Pynie::Grammar::argument_list') + past.'push'(argpast) + + no_args: + .return (past) +} + + +#transform past (Pynie::Grammar::parenth_form) :language('PIR') { +# $P0 = node['expression_list'] +# if null $P0 goto no_list +# .return tree.'get'('past', $P0, 'Pynie::Grammar::expression_list') +# +# # from: http://docs.python.org/ref/parenthesized.html +# # An empty pair of parentheses yields an empty tuple object. +# no_list: +# .local pmc past +# past = new 'PAST::Val' +# past.'init'('node'=>node) +# .return (past) +# +#} + transform past (Pynie::Grammar::literal) :language('PIR') { .local pmc cnode $S0 = node.'find_key'() @@ -413,7 +538,7 @@ .local pmc past past = new 'PAST::Val' # FIX - #past.'init'('node'=>node, 'vtype'=>'.Integer', 'name'=>node, 'ctype'=>'i+') + past.'init'('node'=>node, 'vtype'=>'.Complex', 'name'=>node, 'ctype'=>'i+') .return (past) } @@ -502,11 +627,12 @@ transform past (Pynie::Grammar::expression_list) :language('PIR') { .local pmc past past = new 'PAST::Op' - past.'init'('node'=>node, 'name'=>'listmaker') + past.'init'('node'=>node, 'name'=>'listmaker') + .local pmc expriter $P0 = node['expression'] expriter = new .Iterator, $P0 - iter_loop: + iter_loop: unless expriter goto iter_end .local pmc enode, epast enode = shift expriter @@ -628,43 +754,47 @@ } transform past (Pynie::Grammar::funcdef) :language('PIR') { - .local pmc past - past = new 'PAST::Block' - + past = new 'PAST::Op' + past.'init'('node'=>node, 'pasttype'=>'bind') + + .local pmc funcpast + funcpast = new 'PAST::Block' + .local pmc decnode, fnamenode, plistnode, suitenode -# decnode = node['decorators'] + decnode = node['decorators'] fnamenode = node['funcname'] -# plistnode = node['parameter_list'] -# suitenode = node['suite'] -# -# .local pmc past -# past = new 'PAST::Block' -# -# if null decnode goto skip_decorators -# # handle decorators -# #printerr "Function decorators not implemented!\n" -# exit 1 -# -# skip_decorators: + plistnode = node['parameter_list'] + suitenode = node['suite'] + + if null decnode goto skip_decorators + # handle decorators + printerr "Function decorators not implemented!\n" + exit 1 + + skip_decorators: .local pmc fnamepast fnamepast = tree.'get'('past', fnamenode, 'Pynie::Grammar::funcname') + +####Parameter don't work right now # # if null plistnode goto skip_parameter_list -# #.local plistpast -# #plistpast = tree.'get'('past', plistnode, 'Pynie::Grammar::parameter_list') -# #printerr "Parameters not implemented!\n" -# exit 1 -# -# skip_parameter_list: -# .local pmc stmtpast -# stmtpast = tree.'get'('past', suitenode, 'Pynie::Grammar::suite') -# -# # FIX -# past.'init'('node'=>node, 'name'=>fnamepast) -# .local pmc past -# - past.'init'('node'=>node, 'name'=>fnamepast) +# .local plistpast +# plistpast = tree.'get'('past', plistnode, 'Pynie::Grammar::parameter_list') +# funcpast.'push'(plistpast) +#### + + skip_parameter_list: + .local pmc stmtpast + stmtpast = tree.'get'('past', suitenode, 'Pynie::Grammar::suite') + + # a function is just an anonymous block of code binded to some identifier + # so no name. + funcpast.'init'('node'=>node) + funcpast.'push'(stmtpast) + + past.'push'(fnamepast) + past.'push'(funcpast) .return (past) } Index: languages/pynie/t/00-parrot/02-op-math.t =================================================================== --- languages/pynie/t/00-parrot/02-op-math.t (revision 17410) +++ languages/pynie/t/00-parrot/02-op-math.t (working copy) @@ -1,6 +1,6 @@ #!./parrot -print '1..8' +print '1..10' # basic math operators @@ -14,3 +14,9 @@ print 'ok', 3<<1 print 'ok', 14>>1 print 'ok', 0 // 1 + 8 + +# unary + and - +print 'ok', +9 +print 'ok', -10 + 20 + + Index: languages/pynie/t/00-parrot/08-func.t =================================================================== --- languages/pynie/t/00-parrot/08-func.t (revision 0) +++ languages/pynie/t/00-parrot/08-func.t (revision 0) @@ -0,0 +1,11 @@ +#!./parrot + +print '1..1' + +def x(): + print "The wow starts now!\n" + +x() + +print 'ok 1' +