Author: pmichaud
Date: Thu Jan 25 19:01:46 2007
New Revision: 16800

Modified:
   trunk/compilers/past-pm/POST/Grammar.tg

Log:
[past-pm]:  Redesign of assign/bind operations to support perl6 binding


Modified: trunk/compilers/past-pm/POST/Grammar.tg
==============================================================================
--- trunk/compilers/past-pm/POST/Grammar.tg     (original)
+++ trunk/compilers/past-pm/POST/Grammar.tg     Thu Jan 25 19:01:46 2007
@@ -369,28 +369,31 @@
 }
 
 
-transform assign (PAST::Op) :language('PIR') {
-    .local pmc post, lpast, lpost, rpast, rpost, pasttype
-    post = new 'POST::Ops'
-    post.'init'('node'=>node)
-    lpast = node[0]
+transform bind (PAST::Op) :language('PIR') {
+    .local pmc lpast, rpast, lpost, rpost, post
     rpast = node[1]
     rpost = tree.'get'('post', rpast)
-    post.'push'(rpost)
-    pasttype = node.'pasttype'()
-    if pasttype == 'bind' goto bind_variable
-    rpost = post.'push_pirop'('clone', rpost, rpost, 'result'=>rpost)
-  bind_variable:
+    lpast = node[0]
     lpast.'bindvalue'(rpost)
-    lpost = tree.'get'('post', lpast)
-    post.'push'(lpost)
-    post.'result'(lpost)
+    lpost = tree.'get'('bind', lpast)
+    post = lpost.'new'('POST::Ops', rpost, lpost, 'node'=>node)
     .return (post)
 }
 
 
-transform bind (PAST::Op) :language('PIR') {
-    .return tree.'get'('assign', node)
+transform assign (PAST::Op) :language('PIR') {
+    .local pmc lpast, rpast, lpost, rpost, post, alabel
+    rpast = node[1]
+    rpost = tree.'get'('post', rpast)
+    lpast = node[0]
+    lpost = tree.'get'('post', lpast)
+    post = lpost.'new'('POST::Ops', rpost, lpost, 'node'=>node, 
'result'=>lpost)
+    alabel = post.'new'('POST::Label', 'name'=>'assign_')
+    post.'push_pirop'('eq_addr', lpost, rpost, alabel)
+    post.'push_pirop'('morph', lpost, '.Undef')
+    post.'push_pirop'('assign', lpost, rpost)
+    post.'push'(alabel)
+    .return (post)
 }
 
 
@@ -474,57 +477,8 @@
 }
 
 
-transform post (PAST::Var) :language('PIR') {
-    .local pmc post, vivibindop, bindvalue
-    .local string scope
-    scope = node.'scope'()
-    bindvalue = node.'bindvalue'()
-    if scope == 'keyed' goto keyed
-
-    .local string name
-    name = node.'name'()
-    name = node.'escape'(name)
-    if scope == 'lexical' goto lexical
-    if scope == 'parameter' goto parameter
-
-  package:
-    if bindvalue goto package_bind
-    post = new 'POST::Ops'
-    post.'init'('node'=>node)
-    post.'push_pirop'('get_global', post, name)
-    vivibindop = post.'new'('POST::Op', 'pirop'=>'set_global')
-    vivibindop.'arglist'(name, post)
-    goto check_vivify
-
-  package_bind:
-    post = new 'POST::Op'
-    post.'init'('node'=>node, 'pirop'=>'set_global', 'result'=>bindvalue)
-    post.'arglist'(name, bindvalue)
-    .return (post)
-
-  lexical:
-    post = new 'POST::Ops'
-    post.'init'('node'=>node)
-    $I0 = node.'ismy'()
-    if $I0 == 0 goto lexical_outer
-    $P0 = post.'push_new'('POST::Op', 'pirop'=>'.lex')
-    if bindvalue goto lexical_my_bind
-    $P0.'arglist'(name, $P0)
-    goto check_vivify
-  lexical_outer:
-    if bindvalue goto lexical_bind
-    post.'push_pirop'('find_lex', post, name)
-    vivibindop = post.'new'('POST::Op', 'pirop'=>'store_lex')
-    vivibindop.'arglist'(name, post)
-    goto check_vivify
-
-  lexical_bind:
-    $P0 = post.'push_new'('POST::Op', 'node'=>node, 'pirop'=>'store_lex', 
'result'=>bindvalue)
-  lexical_my_bind:
-    $P0.'arglist'(name, bindvalue)
-    .return (post)
-
-  keyed:
+transform keypost (PAST::Var) :language('PIR') {
+    .local pmc post
     post = new 'POST::Ops'
     post.'init'('node'=>node)
     .local pmc basepast, keypast
@@ -542,28 +496,99 @@
     $S0 = keypost.'result'()
     key .= $S0
     key .= ']'
-    if bindvalue goto keyed_bind
+    post.'result'(key)
+    .return (post)
+}
+
+
+transform bind (PAST::Var) :language('PIR') {
+    .local pmc bindvalue
+    .local string scope
+    bindvalue = node.'bindvalue'()
+    scope = node.'scope'()
+    if scope == 'keyed' goto keyed
+
+    .local string name
+    name = node.'name'()
+    name = node.'escape'(name)
+    .local pmc post
+    post = new 'POST::Op'
+    post.'init'('node'=>node, 'result'=>bindvalue, 'pirop'=>'set_global')
+    post.'arglist'(name, bindvalue)
+    if scope == 'lexical' goto lexical
+    .return (post)
+
+  lexical:
+    .local int isdecl
+    isdecl = node.'ismy'()
+    if isdecl goto lexical_decl
+    post.'pirop'('store_lex')
+    .return (post)
 
-  keyed_rvalue:
-    .local pmc labelpost
-    .local string ireg
-    ireg = post.'unique'('$I')
-    labelpost = post.'new'('POST::Label', 'name'=>'keyed_')
-    post.'result'(basepost)
-    post.'push_pirop'('defined', ireg, basepost)
-    post.'push_pirop'('unless', ireg, labelpost)
-    post.'push_pirop'('set', post, key)
-    post.'push'(labelpost)
-    vivibindop = post.'new'('POST::Op', 'pirop'=>'set')
-    vivibindop.'arglist'(key, post)
-    goto check_vivify
-
-  keyed_bind:
-    post.'push_pirop'('set', key, bindvalue)
-    post.'push_pirop'('set', post, key)
+  lexical_decl:
+    post.'pirop'('.lex')
+    .return (post)
+
+  keyed:
+    .local pmc post, keypost
+    keypost = tree.'get'('keypost', node)
+    post = keypost.'new'('POST::Op', keypost, 'node'=>node, 'pirop'=>'set', 
'result'=>bindvalue)
+    post.'arglist'(keypost, bindvalue)
+    .return (post)
+}
+
+
+transform vivipost (PAST::Var) :language('PIR') {
+    .local pmc vivipost, vivilabel
+    .local string viviself
+    viviself = node.'viviself'()
+    if viviself goto have_viviself
+    viviself = '.Undef'
+  have_viviself:
+    vivipost = new 'POST::Op'
+    vivipost.'init'('node'=>node, 'pirop'=>'new', 'result'=>vivipost)
+    vivipost.'arglist'(vivipost, viviself)
+    .return (vivipost)
+}
+
+
+transform post (PAST::Var) :language('PIR') {
+    .local pmc vivipost, vivilabel, post
+    vivipost = tree.'get'('vivipost', node)
+    post = vivipost.'new'('POST::Ops', 'node'=>node, 'result'=>vivipost)
+    vivilabel = post.'new'('POST::Label', 'name'=>'vivify_')
+
+    .local string scope, name, fetchop, storeop
+    scope = node.'scope'()
+    if scope == 'keyed' goto scope_keyed
+    name = node.'name'()
+    name = node.'escape'(name)
+    if scope == 'lexical' goto scope_lexical
+    if scope == 'parameter' goto scope_parameter
+  scope_package:
+    fetchop = 'get_global'
+    storeop = 'set_global'
+    goto have_scope
+
+  scope_keyed:
+    .local pmc keypost, basepost
+    keypost = tree.'get'('keypost', node)
+    post.'push'(keypost)
+    name = keypost.'result'()
+    fetchop = 'set'
+    storeop = 'set'
+    goto have_scope
+
+  scope_lexical:
+    fetchop = 'find_lex'
+    storeop = 'store_lex'
+    $I0 = node.'ismy'()
+    if $I0 == 0 goto have_scope
+    post.'push'(vivipost)
+    post.'push_pirop'('.lex', name, vivipost)
     .return (post)
 
-  parameter:
+  scope_parameter:
     post = new 'POST::Op'
     post.'pirop'('.lex')
     .local string pname
@@ -575,24 +600,16 @@
     subpost.'push_param'('pmc', pname)
     .return (post)
 
-  check_vivify:
-    .local pmc viviself
-    viviself = node.'viviself'()
-    unless viviself goto end
-  do_vivify:
-    .local pmc vivlabel
-    .local string ireg
-    vivlabel = post.'new'('POST::Label', 'name'=>'vivify_')
-    ireg = post.'unique'('$I')
-    post.'push_pirop'('defined', ireg, post)
-    post.'push_pirop'('if', ireg, vivlabel)
-    post.'push_pirop'('new', post, viviself)
-    $I0 = node.'islvalue'()
-    unless $I0 goto do_vivify_1
-    post.'push'(vivibindop)
-  do_vivify_1:
-    post.'push'(vivlabel)
-  end:
+  have_scope:
+    post.'push_pirop'(fetchop, vivipost, name)
+    post.'push_pirop'('unless_null', post, vivilabel)
+    post.'push'(vivipost)
+    .local int islvalue
+    islvalue = node.'islvalue'()
+    unless islvalue goto done_lvalue
+    post.'push_pirop'(storeop, name, post)
+  done_lvalue:
+    post.'push'(vivilabel)
     .return (post)
 }
 

Reply via email to