# 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'
+