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)
}