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

Reply via email to