# New Ticket Created by  Klaas-Jan Stol 
# Please include the string:  [perl #41678]
# in the subject line of all future correspondence about this issue. 
# <URL: http://rt.perl.org/rt3/Ticket/Display.html?id=41678 >


hi,

attached a new patch for lang/pynie.

This patch includes the changes of my previous patch (is not applied 
yet). (the in/not test renames)

This patch also includes:

* fix for while_stmt (test 06 is now passing)
* start of function def and parameters
* start of class def
* add transform for compound_stmt

regards,
kjs
Index: languages/pynie/src/parser/Grammar.pg
===================================================================
--- languages/pynie/src/parser/Grammar.pg	(revision 17307)
+++ languages/pynie/src/parser/Grammar.pg	(working copy)
@@ -150,12 +150,13 @@
 
 
 rule classdef {
-    <'class'> <classname> <inheritance>? <':'> <suite>
+    <'class'> <identifier> <inheritance>? <':'> <suite>
 }
 
-rule classname {
-    <identifier>
-}
+# prevent another subrule
+#rule classname {
+#    <identifier>
+#}
 
 rule inheritance {
     <'('> <expression_list>? <')'>
@@ -482,15 +483,15 @@
 
 rule not_test {
     | <'not'> <not_test>
-    | <not_in_test>
+    | <in_test>
 }
 
-rule not_in_test {
-    <is_not_test> [ <'not'>? <'in'> <is_not_test> ]*
+rule in_test {
+    <is_test> [ (<'not'>)? <'in'> <is_test> ]*
 }
 
-rule is_not_test {
-    <comparison> [ <'is'> <'not'>? <comparison> ]*
+rule is_test {
+    <comparison> [ <'is'> (<'not'>)? <comparison> ]*
 }
 
 token 'comparison' is optable { ... }
Index: languages/pynie/src/PAST/Grammar.tg
===================================================================
--- languages/pynie/src/PAST/Grammar.tg	(revision 17307)
+++ languages/pynie/src/PAST/Grammar.tg	(working copy)
@@ -28,6 +28,12 @@
     .return tree.'get'('past', $P0, $S0)
 }
 
+transform past (Pynie::Grammar::compound_stmt) :language('PIR') {
+    $S0 = node.'find_key'()
+    $P0 = node[$S0]
+    $S0 = concat 'Pynie::Grammar::', $S0
+    .return tree.'get'('past', $P0, $S0)
+}
 
 transform past (Pynie::Grammar::stmt_list) :language('PIR') {
     .local pmc past
@@ -203,10 +209,15 @@
 
 
 transform past (Pynie::Grammar::expression) :language('PIR') {
+    $S0 = node.'find_key'()
     $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']
+    .return tree.'get'('past', $P0, 'Pynie::Grammar::lambda_form')
 }
 
 transform past (Pynie::Grammar::or_test) :language('PIR') {
@@ -226,30 +237,94 @@
 }
 
 transform past (Pynie::Grammar::and_test) :language('PIR') {
-    $P0 = node['not_test']
-    $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::and_test\n"
-    .return tree.'get'('past', $P0, 'Pynie::Grammar::not_test')
+  .local pmc past, iter, clist, cnode
+    clist = node['not_test']
+    clist = clone clist
+    cnode = pop clist
+    past = tree.'get'('past', cnode, 'Pynie::Grammar::not_test')
+    unless clist goto end
+  clist_loop:
+    cnode = pop clist
+    $P0 = tree.'get'('past', cnode, 'Pynie::Grammar::not_test')
+    past = past.'new'('PAST::Op', $P0, past, 'node'=>node, 'pasttype'=>'if')
+    if clist goto clist_loop
+  end:
+    .return (past)
 }
 
 transform past (Pynie::Grammar::not_test) :language('PIR') {
-    $P0 = node['not_in_test']
-    #printerr "pynie::grammar::not_test\n"
-    .return tree.'get'('past', $P0, 'Pynie::Grammar::not_in_test')
+    .local string key, fullkey
+    .local pmc cnode, past, notpast
+
+    cnode = node['not_test']
+    if null cnode goto do_in_test
+    notpast = tree.'get'('past', cnode, 'Pynie::Grammar::not_test')
+
+    past = new 'PAST::Op'
+    past.'init'('node'=>cnode, 'pasttype'=>'pirop', 'pirop'=>'not')
+    past.'push'(notpast)
+
+    .return (past)
+
+  do_in_test:
+    cnode = node['in_test']
+    past = tree.'get'('past', cnode, 'Pynie::Grammar::in_test')
+    .return (past)
 }
 
-transform past (Pynie::Grammar::not_in_test) :language('PIR') {
-    $P0 = node['is_not_test']
-    $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::not_in_test\n"
-    .return tree.'get'('past', $P0, 'Pynie::Grammar::is_not_test')
+transform past (Pynie::Grammar::in_test) :language('PIR') {
+    .local pmc past, iter, clist, cnode
+    clist = node['is_test']
+    clist = clone clist
+    cnode = pop clist
+    past = tree.'get'('past', cnode, 'Pynie::Grammar::is_test')
+    unless clist goto end
+  clist_loop:
+    cnode = pop clist
+    $P0 = tree.'get'('past', cnode, 'Pynie::Grammar::is_test')
+    #
+    # FIX THIS; also check for "not"
+    #
+    past = past.'new'('PAST::Op', $P0, past, 'node'=>node, 'pasttype'=>'pirop', 'pirop'=>'IN (FIX)')
+    if clist goto clist_loop
+  end:
+    .return (past)
 }
 
-transform past (Pynie::Grammar::is_not_test) :language('PIR') {
-    $P0 = node['comparison']
-    $P0 = $P0[0]
-    $P0 = $P0['expr']
-    #printerr "pynie::grammar::is_not_test\n"
+transform past (Pynie::Grammar::is_test) :language('PIR') {
+    .local pmc past, iter, clist, cnode
+    .local int hasnot
+
+    hasnot = 1
+    # HACK:
+    # TODO: figure out how presence of "not" can be checked.
+    # then set flag for each iteration.
+
+    clist = node['comparison']
+    clist = clone clist
+
+    cnode = pop clist
+    past = tree.'get'('past', cnode, 'Pynie::Grammar::comparison')
+    unless clist goto end
+
+  clist_loop:
+    cnode = pop clist
+    $P0 = tree.'get'('past', cnode, 'Pynie::Grammar::comparison')
+  if hasnot == 0 goto do_issame
+    $S0 = "isntsame"
+    goto done
+  do_issame:
+    $S0 = "issame"
+  done:
+    past = past.'new'('PAST::Op', $P0, past, 'node'=>node, 'pasttype'=>'pirop', 'pirop'=>$S0)
+    if clist goto clist_loop
+  end:
+    .return (past)
+}
+
+
+transform past (Pynie::Grammar::comparison) :language('PIR') {
+    $P0 = node['expr']
     .return tree.'get'('past', $P0, 'Pynie::Grammar::expr')
 }
 
@@ -440,7 +515,7 @@
     dec suitec
     elsenode = suitelist[suitec]
     elsepast = tree.'get'('past', elsenode, 'Pynie::Grammar::suite')
-    elsepast.'suitetype'('immediate')
+    #elsepast.'suitetype'('immediate')
 
   expr_suite_pair:
     ##   each remaining suite is paired with an "if" (or "elsif")
@@ -462,23 +537,30 @@
 
 
 transform past (Pynie::Grammar::while_stmt) :language('PIR') {
-   # .local pmc past
-   # past = new 'PAST::Op'
-   # past.'init'('node'=>node, 'pasttype'=>'inline', 'inline'=>'# while stmt not implemented')
-   # .return (past)
-
-    .local pmc exprnode, stmtnode
+    .local pmc exprnode, stmtnode, suitenode
     exprnode = node['expression']
-    stmtnode = node['suite']
-    stmtnode = stmtnode[0]
+    suitenode = node['suite']
+    stmtnode = suitenode[0]
 
-    .local pmc past, exprpast, stmtpast
-    past = new 'PAST::Op'
-    past.'init'('node'=>node, 'pasttype'=>'while')
+    .local pmc past, whilepast, exprpast, stmtpast
+    past = new 'PAST::Stmts'
+    past.'init'('node'=>node)
+
+    whilepast = new 'PAST::Op'
+    whilepast.'init'('node'=>node, 'pasttype'=>'while')
     exprpast = tree.'get'('past', exprnode, 'Pynie::Grammar::expression')
-    past.'push'(exprpast)
+    whilepast.'push'(exprpast)
     stmtpast = tree.'get'('past', stmtnode, 'Pynie::Grammar::suite')
+    whilepast.'push'(stmtpast)
+    past.'push'(whilepast)
+
+    stmtnode = suitenode[1]
+    if null stmtnode goto no_else
+    unless stmtnode goto no_else # check for .Undef # why does that happen?
+    stmtpast = tree.'get'('past', stmtnode, 'Pynie::Grammar::suite')
     past.'push'(stmtpast)
+
+  no_else:
     .return (past)
 }
 
@@ -526,93 +608,167 @@
 }
 
 transform past (Pynie::Grammar::funcdef) :language('PIR') {
+    .local pmc past, decnode, fnamenode, plistnode, suitenode
+    decnode   = node['decorators']
+    fnamenode = node['funcname']
+    plistnode = node['parameter_list']
+    suitenode = node['suite']
 
     .local pmc past
     past = new 'PAST::Block'
 
-    .local pmc decnode, fnamenode, plistnode, suitenode
-#   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:
+    if null decnode goto skip_decorators
+    # handle decorators
+    printerr "Function decorators not implemented!\n"
+  skip_decorators:
     .local pmc fnamepast
     fnamepast = tree.'get'('past', fnamenode, 'Pynie::Grammar::funcname')
-#
-#   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)
+
+    printerr "function name: "
+    S0 = fnamepast['name']
+    printerr S0
+    printerr "\n"
+
+    # handle parameters
+    if null plistnode goto function_body
+    .local pmc plistpast
+    plistpast = tree.'get'('past', plistnode, 'Pynie::Grammar::parameter_list')
+    #past.'push'(plistpast)
+
+  function_body:
+    .local pmc stmtpast
+    stmtpast = tree.'get'('past', suitenode, 'Pynie::Grammar::suite')
+
+    #past.'init'('node'=>node, 'name'=>fnamepast)
     .return (past)
 }
 
+
+
 transform past (Pynie::Grammar::funcname) :language('PIR') {
     $P0 = node['identifier']
     .return tree.'get'('past', $P0, 'Pynie::Grammar::identifier')
 }
 
+transform past (Pynie::Grammar::parameter_list) :language('PIR') {
+    .local pmc past, iter
+    past = new 'PAST::VarList'
 
+    $P0 = node['defparameter']
+    past.'init'('node'=>$P0)
+
+    $S0 = $P0.'find_key'()
+    #printerr $S0
+    $P0 = $P0[$S0]
+    $P2 = tree.'get'('past', $P0, 'Pynie::Grammar::defparameter')
+    past.'push'($P2)
+
+    # handle others later
+
+    .return (past)
+}
+
+
+transform past (Pynie::Grammar::defparameter) :language('PIR') {
+    .local pmc past
+    past = new 'PAST::VarList'
+    $P0 = node[0]
+    past.'init'('node'=>$P0)
+    #$S0 = node.'find_key'()
+    #printerr $S0
+
+    .local pmc iter, parampast
+    iter = new .Iterator, node
+  iter_loop:
+    unless iter goto iter_end
+
+    # get next object
+    $P1 = shift iter
+
+    # what kind of parameter?
+    $S0 = $P1.'find_key'()
+    #printerr $S0
+    #printerr "\n"
+
+    # get that node
+    $P1 = $P1[$S0]
+    $S0 = concat 'Pynie::Grammar::', $S0
+    parampast = tree.'get'('past', $P1, $S0)
+    past.'push'(parampast)
+    goto iter_loop
+  iter_end:
+
+
+
+    .return (past)
+}
+
+transform past (Pynie::Grammar::parameter) :language('PIR') {
+    .local pmc past
+
+
+    $P0 = node['identifier']
+    if null $P0 goto sublist
+    $P1 = tree.'get'('past', $P0, 'Pynie::Grammar::identifier')
+    $S0 = $P1['name']
+
+    #printerr "parameter: "
+    #printerr $S0
+    #printerr "\n"
+
+    past = new 'PAST::Var'
+    past.'init'('node'=>$P0, 'scope'=>'parameter', 'name'=>$S0)
+    .return (past)
+
+  sublist:
+    # TODO
+
+}
+
 ## FIX: fix this, not sure about how to handle instructions such
 ## as subclass etc.
 ##
 transform past (Pynie::Grammar::classdef) :language('PIR') {
 
     .local pmc past
-    past = new 'PAST::Op'
-    past.'init'('node'=>node, 'pasttype'=>'inline', 'inline'=>'# classdef stmt not implemented')
+    past = new 'PAST::Stmts'
+    past.'init'('node'=>node)
+
+    #past.'init'('node'=>node, 'pasttype'=>'inline', 'inline'=>'# classdef stmt not implemented')
+    #.return (past)
+
+    .local pmc instr
+    instr = new 'PAST::Op'
+
+    $P0 = node['inheritance']
+    if null $P0 goto skip_inheritance
+    instr.'init'('node'=>node, 'pasttype'=>'pirop', 'pirop'=>'subclass')
+    # inheritancenot implemented right now
+    printerr "inheritance not implemented\n"
+    goto handle_class_body
+
+  skip_inheritance:
+    instr.'init'('node'=>node, 'pasttype'=>'pirop', 'pirop'=>'newclass')
+    $P0 = node['identifier']
+    $P1 = tree.'get'('past', $P0, 'Pynie::Grammar::identifier')
+    $S0 = $P1['name']
+    $P2 = new 'PAST::Val'
+    $P2.'init'('node'=>$P1, 'ctype'=>'s', 'vtype'=>'.String', 'name'=>$S0)
+    instr.'push'($P2)
+
+ handle_class_body:
+    # add newclass or subclass instruction to Stmts node
+    past.'push'(instr)
+
+    # add a .namespace[ <class_id> ] instruction to add methods?
+    #$P1 = new 'PAST::Block'
+
+    $P0 = node['suite']
+    $P1 = tree.'get'('past', $P0, 'Pynie::Grammar::suite')
+    past.'push'($P1)
+
+  done:
     .return (past)
-
-#   .local pmc past
-#   past = new 'PAST::Stmts'
-#   past.'init'('node'=>node)
-#
-#   .local pmc instr
-#   instr = new 'PAST::Op'
-#
-#   $P0 = node['inheritance']
-#   if null $P0 goto skip_inheritance
-#   instr.'init'('node'=>node, 'pasttype'=>'pirop', 'pirop'=>'subclass')
-#   # inheritancenot implemented right now
-#   goto handle_class_body
-#
-# skip_inheritance:
-#   instr.'init'('node'=>node, 'pasttype'=>'pirop', 'pirop'=>'newclass')
-#   $P0 = node['classname']
-#   $P1 = tree.'get'('past', $P0, 'Pynie::Grammar::classname')
-#   instr.'push'($P1)
-#
-# handle_class_body:
-#   # add newclass or subclass instruction to Stmts node
-#   past.'push'(instr)
-#
-#   # add a .namespace[ <class_id> ] instruction to add methods?
-#   $P0 = node['suite']
-#   $P1 = tree.'get'('past', $P0, 'Pynie::Grammar::suite')
-#   past.'push'($P1)
-#
-#
-# done:
-#   .return (past)
 }
 
 ## FIX: Return class name as a string, not using "get_global" as in identifier.

Reply via email to