Author: fperrad
Date: Wed May 23 00:22:06 2007
New Revision: 18631
Added:
trunk/languages/lua/lua.pir
- copied, changed from r18617, /trunk/languages/lua/luac.pir
trunk/languages/lua/src/PASTGrammar.tg
- copied, changed from r18617, /trunk/languages/lua/src/ASTGrammar.tg
trunk/languages/lua/src/POSTGrammar.tg (contents, props changed)
Removed:
trunk/languages/lua/luac.pir
trunk/languages/lua/src/ASTGrammar.tg
Modified:
trunk/languages/lua/config/makefiles/root.in
trunk/languages/lua/doc/status.pod
trunk/languages/lua/src/ (props changed)
trunk/languages/lua/src/lua51.pg
trunk/languages/lua/src/lua51.pir
trunk/languages/lua/t/Parrot/Test/Lua.pm
trunk/languages/lua/test_lex.pir
Log:
[Lua]
- introduce a POSTGrammar.tg
- rename ASTGrammar.tg to PASTGrammar.tg
- rename luac.pir to lua.pir
- update doc (link)
Modified: trunk/languages/lua/config/makefiles/root.in
==============================================================================
--- trunk/languages/lua/config/makefiles/root.in (original)
+++ trunk/languages/lua/config/makefiles/root.in Wed May 23 00:22:06 2007
@@ -58,12 +58,12 @@
GEN_PIR = \
src/lua51_testlex_gen.pir \
src/dumplex_gen.pir \
- src/lua51_grammar_gen.pir \
- src/ASTGrammar.pir
+ src/lua51_gen.pir \
+ src/PASTGrammar_gen.pir \
+ src/POSTGrammar_gen.pir
GEN_PBC = \
- src/lua51.pbc \
- luac.pbc
+ lua.pbc
all: \
pmc/lua_group$(LOAD_EXT) \
@@ -79,18 +79,17 @@
src/dumplex_gen.pir: src/dumplex.tg
$(TGE) --output=src/dumplex_gen.pir src/dumplex.tg
-src/lua51_grammar_gen.pir: src/lua51.pg
- $(PGE) --output=src/lua51_grammar_gen.pir src/lua51.pg
+src/lua51_gen.pir: src/lua51.pg
+ $(PGE) --output=src/lua51_gen.pir src/lua51.pg
-src/ASTGrammar.pir: src/ASTGrammar.tg
- $(TGE) --output=src/ASTGrammar.pir src/ASTGrammar.tg
+src/PASTGrammar_gen.pir: src/PASTGrammar.tg
+ $(TGE) --output=src/PASTGrammar_gen.pir src/PASTGrammar.tg
-src/lua51.pbc: src/lua51.pir src/lua51_grammar_gen.pir src/ASTGrammar.pir
- $(PARROT) -o src/lua51.pbc --output-pbc src/lua51.pir
-
-luac.pbc: luac.pir
- $(PARROT) -o luac.pbc --output-pbc luac.pir
+src/POSTGrammar_gen.pir: src/POSTGrammar.tg
+ $(TGE) --output=src/POSTGrammar_gen.pir src/POSTGrammar.tg
+lua.pbc: lua.pir src/lua51.pir src/lua51_gen.pir src/PASTGrammar_gen.pir
src/POSTGrammar_gen.pir
+ $(PARROT) -o lua.pbc --output-pbc lua.pir
pmc/lua_group$(LOAD_EXT) : $(PMC_FILES)
@cd $(PMCDIR) && $(PMCBUILD) generate $(PMCS)
@@ -184,7 +183,7 @@
BUILD_CLEANERS = \
$(GEN_PIR) \
- "src/*.pbc" \
+ "*.pbc" \
"$(PMCDIR)/*.dump" \
"$(PMCDIR)/*.c" \
"$(PMCDIR)/*.h" \
Modified: trunk/languages/lua/doc/status.pod
==============================================================================
--- trunk/languages/lua/doc/status.pod (original)
+++ trunk/languages/lua/doc/status.pod Wed May 23 00:22:06 2007
@@ -19,7 +19,8 @@
=head1 PIR Compiler/Interpreter
-Work started, but B<not functional>, see F<languages/lua/src/lua51.pir>.
+Work started, but B<not functional>, see F<languages/lua/src/lua51.pir> &
+F<languages/lua/lua.pir>.
The lexicography part could be checked with F<languages/lua/test_lex.pir>.
Copied: trunk/languages/lua/lua.pir (from r18617, /trunk/languages/lua/luac.pir)
==============================================================================
--- /trunk/languages/lua/luac.pir (original)
+++ trunk/languages/lua/lua.pir Wed May 23 00:22:06 2007
@@ -3,33 +3,38 @@
=head1 NAME
-luac -- A compiler for Lua 5.1
+lua -- An interpreter for Lua 5.1
=head1 SYNOPSIS
- $ parrot luac.pbc script.lua
- $ parrot luac.pbc --target=parse script.lua
- PAST
- POST
- PIR
+ $ parrot lua.pbc script.lua
+ $ parrot lua.pbc --target=parse script.lua
+ PAST
+ POST
+ PIR
=head1 DESCRIPTION
-C<luac> is a compiler for Lua version 5.1, running on Parrot.
+C<lua> is a interpreter for Lua version 5.1, running on Parrot.
=cut
.sub 'main' :main
.param pmc args
- load_bytecode 'languages/lua/src/lua51.pbc'
load_bytecode 'PGE/Dumper.pbc'
$P0 = compreg 'Lua'
$P0.'command_line'(args)
.end
-=head1 AUTHOR
+.include 'languages/lua/src/lua51.pir'
-Klaas-Jan Stol <[EMAIL PROTECTED]>
+=head1 SEE ALSO
+
+F<languages/lua/doc/status.pod>
+
+=head1 AUTHORS
+
+Francois Perrad
=cut
Copied: trunk/languages/lua/src/PASTGrammar.tg (from r18617,
/trunk/languages/lua/src/ASTGrammar.tg)
==============================================================================
--- /trunk/languages/lua/src/ASTGrammar.tg (original)
+++ trunk/languages/lua/src/PASTGrammar.tg Wed May 23 00:22:06 2007
@@ -3,8 +3,8 @@
=head1 NAME
-ASTGrammar.tg - A grammar for transforming the output of a PGE parse into
-an abstract syntax tree.
+PASTGrammar.tg - A grammar for transforming the output of a PGE parse into
+an abstract syntax tree (PAST).
=head1 DESCRIPTION
Added: trunk/languages/lua/src/POSTGrammar.tg
==============================================================================
--- (empty file)
+++ trunk/languages/lua/src/POSTGrammar.tg Wed May 23 00:22:06 2007
@@ -0,0 +1,663 @@
+# Copyright (C) 2007, The Perl Foundation.
+# $Id$
+
+=head1 NAME
+
+POSTGrammar.tg - A grammar for transforming the abstract syntax tree (PAST)
+into an opcode syntax tree (POST).
+
+=head1 DESCRIPTION
+
+
+=cut
+
+grammar Lua::POST::Grammar is TGE::Grammar;
+
+transform root (PAST::Block) :language('PIR') {
+ .local pmc post
+ post = tree.'get'('post', node)
+ $I0 = isa post, 'POST::Sub'
+ if $I0 goto end
+ $S0 = post.'unique'('__anon_')
+ post = post.'new'('POST::Sub', post, 'name'=>$S0)
+ end:
+ .return (post)
+}
+
+
+transform post (PAST::Block) :language('PIR') {
+ .local string name, pragma, blocktype
+ name = node.'name'()
+ if name != '' goto with_name
+ name = node.unique('_block')
+ with_name:
+ pragma = node.'pragma'()
+ blocktype = node.'blocktype'()
+ .local pmc outerpost
+ outerpost = get_hll_global ['POST'], '$?SUB'
+ .local pmc post
+ post = new 'POST::Sub'
+ post.'init'('node'=>node, 'name'=>name, 'outer'=>outerpost,
'pragma'=>pragma, 'blocktype'=>blocktype)
+ set_hll_global ['POST'], '$?SUB', post
+ .local string compiler
+ compiler = node.'compiler'()
+ if compiler goto hll_block
+ past_block:
+ .local pmc iter
+ iter = node.'iterator'()
+ unless iter goto iter_end
+ iter_loop:
+ .local pmc cpast, cpost
+ cpast = shift iter
+ cpost = tree.'get'('post', cpast)
+ post.'push'(cpost)
+ if iter goto iter_loop
+ post.'result'(cpost)
+ iter_end:
+ goto end
+
+ hll_block:
+ post.'compiler'(compiler)
+ iter = node.'iterator'()
+ hll_loop:
+ unless iter goto end
+ $P0 = shift iter
+ post.'push'($P0)
+ goto hll_loop
+
+ end:
+ set_hll_global ['POST'], '$?SUB', outerpost
+ if blocktype != 'immediate' goto blocktype_end
+ post = post.'new'('POST::Op', post, 'node'=>node, 'pirop'=>'call',
'arglist'=>post)
+ blocktype_end:
+ .return (post)
+}
+
+
+transform post (PAST::Stmts) :language('PIR') {
+ .local pmc ops
+ ops = new 'POST::Ops'
+ ops.'init'('node'=>node)
+ .local pmc iter
+ iter = node.'iterator'()
+ unless iter goto end
+ iter_loop:
+ .local pmc cpast, cpost
+ cpast = shift iter
+ cpost = tree.'get'('post', cpast)
+ ops.'push'(cpost)
+ if iter goto iter_loop
+ iter_end:
+ ops.'result'(cpost)
+ end:
+ .return (ops)
+}
+
+
+transform post (PAST::Op) :language('PIR') {
+ .local string pasttype
+ pasttype = node.'pasttype'()
+ if pasttype goto post_pasttype
+
+ post_pirop:
+ .local string pirop
+ pirop = node.'pirop'()
+ if pirop goto have_pirop
+ node.'pirop'('call')
+ have_pirop:
+ .return tree.'get'('pirop', node)
+
+ post_pasttype:
+ .return tree.'get'(pasttype, node)
+}
+
+
+transform pirop (PAST::Op) :language('PIR') {
+ .local string pirop
+ .local pmc post
+ pirop = node.'pirop'()
+ post = new 'POST::Op'
+ post.'init'('node'=>node, 'pirop'=>pirop)
+
+ .local pmc pirtable
+ .local string signature
+ pirtable = get_hll_global ['POST'], '%pirtable'
+ signature = pirtable[pirop]
+ if signature > '' goto have_signature
+ signature = '%uppppppppppppp' # FIXME:
+ have_signature:
+ .local pmc arglist, iter
+ .local int aindex
+ aindex = 2
+ arglist = new .ResizablePMCArray
+ iter = node.'iterator'()
+ iter_loop:
+ unless iter goto iter_end
+ .local pmc cpast, cpost
+ cpast = shift iter
+ $S0 = substr signature, aindex, 1
+ cpast.'atype'($S0)
+ cpost = tree.'get'('post', cpast)
+ post.'push'(cpost)
+ push arglist, cpost
+ inc aindex
+ goto iter_loop
+ iter_end:
+ .local int argresult
+ argresult = 1
+
+ if pirop == 'call' goto pirop_call
+ if pirop == 'callmethod' goto pirop_call
+ if pirop == 'inline' goto pirop_inline
+ goto pirop_result
+
+ pirop_call:
+ .local string name
+ argresult = 0
+ name = node.'name'()
+ unless name goto pirop_result
+ name = node.'escape'(name)
+ unshift arglist, name
+ goto pirop_result
+
+ pirop_inline:
+ .local string inline
+ argresult = 0
+ inline = node.'inline'()
+ unless inline goto pirop_result
+ unshift arglist, inline
+ signature = inline
+ goto pirop_result
+
+ pirop_result:
+ $I0 = index signature, '%v'
+ if $I0 >= 0 goto pirop_void
+ $I0 = index signature, '%r'
+ if $I0 >= 0 goto pirop_reg
+ .local string returns
+ returns = '.LuaNil'
+ $S0 = node.'returns'()
+ unless $S0 goto pirop_returns
+ returns = $S0
+ pirop_returns:
+ $P0 = post.'push_new'('POST::Op', 'pirop'=>'new')
+ $P0.'arglist'($P0, returns)
+ post.'result'($P0)
+ goto pirop_reg
+ pirop_void:
+ $P0 = post[0]
+ post.'result'($P0)
+ argresult = 0
+ pirop_reg:
+ unless argresult goto have_result
+ unshift arglist, post
+ have_result:
+ post.'arglist'(arglist :flat)
+ .return (post)
+}
+
+
+transform call (PAST::Op) :language('PIR') {
+ node.'pirop'('call')
+ $P0 = tree.'get'('pirop', node)
+ .return ($P0)
+}
+
+
+transform callmethod (PAST::Op) :language('PIR') {
+ node.'pirop'('callmethod')
+ $P0 = tree.'get'('pirop', node)
+ .return ($P0)
+}
+
+
+transform inline (PAST::Op) :language('PIR') {
+ node.'pirop'('inline')
+ .return tree.'get'('pirop', node)
+}
+
+
+transform if (PAST::Op) :language('PIR') {
+ .local pmc ops
+ ops = new 'POST::Ops'
+ ops.'init'('node'=>node)
+
+ .local pmc exprpast, thenpast, elsepast
+ .local pmc exprpost, thenpost, elsepost
+ exprpast = node[0]
+ thenpast = node[1]
+ elsepast = node[2]
+
+ .local pmc thenlabel, endlabel
+ .local string pasttype, n
+ pasttype = node.'pasttype'()
+ n = node.'unique'('_')
+ $S0 = concat pasttype, n
+ thenlabel = ops.'new'('POST::Label', 'result'=>$S0)
+ $S0 = concat $S0, '_end'
+ endlabel = ops.'new'('POST::Label', 'result'=>$S0)
+
+ exprpost = tree.'get'('post', exprpast)
+ ops.'push'(exprpost)
+ ops.'push_pirop'(pasttype, exprpost, thenlabel)
+ elsepost = exprpost
+ $I0 = defined elsepast
+ if $I0 == 0 goto else_done
+ elsepost = tree.'get'('post', elsepast)
+ ops.'push'(elsepost)
+ else_done:
+ ops.'push_pirop'('set', ops, elsepost)
+ ops.'push_pirop'('goto', endlabel)
+ ops.'push'(thenlabel)
+ thenpost = exprpost
+ $I0 = defined thenpast
+ if $I0 == 0 goto then_done
+ thenpost = tree.'get'('post', thenpast)
+ ops.'push'(thenpost)
+ then_done:
+ ops.'push_pirop'('set', ops, thenpost)
+ ops.'push'(endlabel)
+ .return (ops)
+}
+
+
+transform unless (PAST::Op) :language('PIR') {
+ .return tree.'get'('if', node)
+}
+
+
+transform while (PAST::Op) :language('PIR') {
+ .local pmc ops
+ ops = new 'POST::Ops'
+ ops.'init'('node'=>node)
+
+ .local pmc exprpast, blockpast
+ .local pmc exprpost, blockpost
+ exprpast = node[0]
+ blockpast = node[1]
+
+ .local pmc looplabel, endlabel
+ .local string pasttype, n
+ pasttype = node.'pasttype'()
+ n = node.'unique'('_')
+ $S0 = concat pasttype, n
+ looplabel = ops.'new'('POST::Label', 'result'=>$S0)
+ $S0 = concat $S0, '_end'
+ endlabel = ops.'new'('POST::Label', 'result'=>$S0)
+
+ ## determine if we need an 'if' or an 'unless' on
+ ## the conditional (while => if, until => unless)
+ .local string iftype
+ iftype = 'if'
+ if $S0 == 'until' goto done_iftype
+ iftype = 'unless'
+ done_iftype:
+
+ ops.'push'(looplabel)
+ exprpost = tree.'get'('post', exprpast)
+ ops.'push'(exprpost)
+ ops.'push_pirop'(iftype, exprpost, endlabel)
+ blockpost = tree.'get'('post', blockpast)
+ ops.'push'(blockpost)
+ ops.'push_pirop'('goto', looplabel)
+ ops.'push'(endlabel)
+ ops.'result'(exprpost)
+ .return (ops)
+}
+
+
+transform until (PAST::Op) :language('PIR') {
+ .return tree.'get'('while', node)
+}
+
+
+transform try (PAST::Op) :language('PIR') {
+ .local pmc trypast, trypost, post, traplabel, endlabel
+ trypast = node[0]
+ trypost = tree.'get'('post', trypast)
+ post = trypost.'new'('POST::Ops', 'node'=>node, 'result'=>trypost)
+ $S0 = node.'unique'('trap_')
+ traplabel = post.'new'('POST::Label', 'result'=>$S0)
+ $S0 = concat $S0, '_end'
+ endlabel = post.'new'('POST::Label', 'result'=>$S0)
+ post.'push_pirop'('push_eh', traplabel)
+ post.'push'(trypost)
+ post.'push_pirop'('clear_eh')
+ post.'push_pirop'('goto', endlabel)
+ post.'push'(traplabel)
+ .local pmc catchnode, catchpast
+ catchnode = node[1]
+ unless catchnode goto have_catch
+ catchpast = tree.'get'('post', catchnode)
+ post.'push'(catchpast)
+ have_catch:
+ post.'push'(endlabel)
+ .return (post)
+}
+
+
+transform xor (PAST::Op) :language('PIR') {
+ .local pmc ops
+ ops = new 'POST::Ops'
+ ops.'init'('node'=>node)
+
+ .local pmc endlabel, falselabel
+ falselabel = ops.'new'('POST::Label', 'name'=>'xor_false')
+ endlabel = ops.'new'('POST::Label', 'name'=>'xor_end')
+
+ .local pmc iter, apast, apost, i, t, u
+ i = ops.unique('$I')
+ t = ops.unique('$I')
+ u = ops.unique('$I')
+ iter = node.'iterator'()
+ apast = shift iter
+ apost = tree.'get'('post', apast)
+ ops.'push'(apost)
+ ops.'push_pirop'('set', ops, apost)
+ ops.'push_pirop'('istrue', t, apost)
+ middle_child:
+ .local pmc bpast, bpost
+ bpast = shift iter
+ bpost = tree.'get'('post', bpast)
+ ops.'push'(bpost)
+ ops.'push_pirop'('istrue', u, bpost)
+ ops.'push_pirop'('and', i, t, u)
+ ops.'push_pirop'('if', i, falselabel)
+ unless iter goto last_child
+ .local pmc s
+ s = ops.'new'('POST::Label', 'name'=>'xor_skip')
+ ops.'push_pirop'('if', t, s)
+ ops.'push_pirop'('set', ops, bpost)
+ ops.'push_pirop'('set', t, u)
+ ops.'push'(s)
+ goto middle_child
+ last_child:
+ ops.'push_pirop'('if', t, endlabel)
+ ops.'push_pirop'('set', ops, bpost)
+ ops.'push_pirop'('goto', endlabel)
+ ops.'push'(falselabel)
+ ops.'push_pirop'('new', ops, '.LuaNil')
+ ops.'push'(endlabel)
+ .return (ops)
+}
+
+
+transform bind (PAST::Op) :language('PIR') {
+ .local pmc lpast, rpast, lpost, rpost, post
+ rpast = node[1]
+ rpost = tree.'get'('post', rpast)
+ lpast = node[0]
+ lpast.'bindvalue'(rpost)
+ lpost = tree.'get'('bind', lpast)
+ post = lpost.'new'('POST::Ops', rpost, lpost, 'node'=>node)
+ .return (post)
+}
+
+
+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, '.LuaNil')
+ post.'push_pirop'('assign', lpost, rpost)
+ post.'push'(alabel)
+ .return (post)
+}
+
+
+transform chain (PAST::Op) :language('PIR') {
+ .local pmc clist, cpast
+ clist = new .ResizablePMCArray
+ cpast = node
+ chain_loop:
+ $I0 = isa cpast, 'PAST::Op'
+ if $I0 == 0 goto chain_end
+ .local string pasttype
+ pasttype = cpast.'pasttype'()
+ if pasttype != 'chain' goto chain_end
+ push clist, cpast
+ cpast = cpast[0]
+ goto chain_loop
+ chain_end:
+
+ .local pmc ops, endlabel, apast, apost
+ ops = new 'POST::Ops'
+ ops.'init'('node'=>node)
+ cpast = pop clist
+ endlabel = ops.'new'('POST::Label', 'name'=>'chain_end_')
+ apast = cpast[0]
+ apost = tree.'get'('post', apast)
+ ops.'push'(apost)
+
+ clist_loop:
+ .local pmc bpast, bpost
+ bpast = cpast[1]
+ bpost = tree.'get'('post', bpast)
+ .local string name
+ name = cpast.'name'()
+ name = cpast.'escape'(name)
+ ops.'push'(bpost)
+ $P0 = ops.'push_pirop'('call', name, apost, bpost)
+ $P0.'result'(ops)
+ unless clist goto clist_end
+ ops.'push_pirop'('unless', ops, endlabel)
+ cpast = pop clist
+ apost = bpost
+ goto clist_loop
+ clist_end:
+ ops.'push'(endlabel)
+ .return (ops)
+}
+
+
+transform post (PAST::Val) :language('PIR') {
+ .local string vtype, ctype, name
+ vtype = node.'vtype'()
+ ctype = node.'ctype'()
+ name = node.'name'()
+
+ $I0 = index ctype, '~'
+ if $I0 < 0 goto skip_escape
+ name = node.'escape'(name)
+ skip_escape:
+
+ .local pmc post
+ post = new 'POST::Ops'
+ post.'init'('node'=>node)
+
+ .local string atype
+ atype = node.'atype'()
+ if ctype == '' goto return_pmc
+ if atype == '*' goto return_native
+ $I0 = index ctype, atype
+ if $I0 >= 0 goto return_native
+
+ return_pmc:
+ $P0 = post.'push_new'('POST::Op', 'pirop'=>'new')
+ $P0.'arglist'($P0, vtype)
+ $P1 = post.'push_pirop'('assign', $P0, name, 'result'=>$P0)
+ post.'result'($P1)
+ .return (post)
+
+ return_native:
+ post.'result'(name)
+ .return (post)
+}
+
+
+transform keypost (PAST::Var) :language('PIR') {
+ .local pmc post
+ post = new 'POST::Ops'
+ post.'init'('node'=>node)
+ .local pmc basepast, keypast
+ .local pmc basepost, keypost
+ basepast = node[0]
+ keypast = node[1]
+ keypast.'atype'('*')
+ keypost = tree.'get'('post', keypast)
+ post.'push'(keypost)
+ basepost = tree.'get'('post', basepast)
+ post.'push'(basepost)
+ .local string key
+ key = basepost.'result'()
+ key = concat key, '['
+ $S0 = keypost.'result'()
+ key .= $S0
+ key .= ']'
+ 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)
+
+ 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 = '.LuaNil'
+ 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)
+
+ scope_parameter:
+ post = new 'POST::Op'
+ post.'pirop'('.lex')
+ .local string pname
+ pname = post.'unique'('param_')
+ post.'arglist'(name, pname)
+ post.'result'(pname)
+ .local pmc subpost
+ subpost = get_hll_global ['POST'], '$?SUB'
+ subpost.'push_param'('pmc', pname)
+ .return (post)
+
+ 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)
+}
+
+
+transform bind (PAST::VarList) :language('PIR') {
+ .local pmc post, bindvalue, binditer
+ post = new 'POST::Ops'
+ post.'init'('node'=>node)
+
+ bindvalue = node.'bindvalue'()
+ binditer = post.'push_new'('POST::Op', 'pirop'=>'new')
+ binditer.'arglist'(binditer, '.Iterator', bindvalue)
+
+ .local pmc iter
+ iter = node.'iterator'()
+ iter_loop:
+ unless iter goto iter_end
+ .local pmc cpast, cpost
+ cpast = shift iter
+ post.'push_pirop'('shift', post, binditer)
+ cpast.'bindvalue'(post)
+ cpost = tree.'get'('bind', cpast)
+ post.'push'(cpost)
+ goto iter_loop
+ iter_end:
+ .return (post)
+}
+
+=head1 HISTORY
+
+Mostly taken from F<compilers/past-pm/POST/Grammar.tg>.
+
+=head1 AUTHORS
+
+Francois Perrad
+
+=cut
+
Modified: trunk/languages/lua/src/lua51.pg
==============================================================================
--- trunk/languages/lua/src/lua51.pg (original)
+++ trunk/languages/lua/src/lua51.pg Wed May 23 00:22:06 2007
@@ -191,60 +191,6 @@
}
-=head2 EXPRESSIONS
-
-Operator precedence is implemented using an optable.
-
-=cut
-
-rule 'expression' is optable { ... }
-
-proto 'term:' is precedence('=')
- is parsed(&simple_expression) { ... }
-
-proto 'infix:^' is looser('term:') is pirop('pow') is
assoc('right')
- is returns('.LuaNumber') { ... }
-
-proto 'prefix:not' is looser('infix:^') is pirop('not')
- is returns('.LuaBoolean') { ... }
-proto 'prefix:#' is equiv('prefix:not') is pirop('len')
- is returns('.LuaNumber') { ... }
-proto 'prefix:-' is equiv('prefix:not') is pirop('neg')
- is returns('.LuaNumber') { ... }
-
-proto 'infix:*' is looser('prefix:not') is pirop('mul')
- is returns('.LuaNumber') { ... }
-proto 'infix:/' is equiv('infix:*') is pirop('div')
- is returns('.LuaNumber') { ... }
-proto 'infix:%' is equiv('infix:*') is pirop('mod')
- is returns('.LuaNumber') { ... }
-
-proto 'infix:+' is looser('infix:*') is pirop('add')
- is returns('.LuaNumber') { ... }
-proto 'infix:-' is equiv('infix:+') is pirop('sub')
- is returns('.LuaNumber') { ... }
-
-proto 'infix:..' is looser('infix:+') is pirop('concat') is
assoc('right')
- is returns('.LusString') { ... }
-
-proto 'infix:<' is looser('infix:..') is pirop('islt')
- is returns('.LuaBoolean') { ... }
-proto 'infix:>' is equiv('infix:<') is pirop('isgt')
- is returns('.LuaBoolean') { ... }
-proto 'infix:<=' is equiv('infix:<') is pirop('isle')
- is returns('.LuaBoolean') { ... }
-proto 'infix:>=' is equiv('infix:<') is pirop('isge')
- is returns('.LuaBoolean') { ... }
-proto 'infix:~=' is equiv('infix:<') is pirop('isne')
- is returns('.LuaBoolean') { ... }
-proto 'infix:==' is equiv('infix:<') is pirop('iseq')
- is returns('.LuaBoolean') { ... }
-
-proto 'infix:and' is looser('infix:<') is past('if') { ... }
-
-proto 'infix:or' is looser('infix:and') is past('unless') { ... }
-
-
=head2 HELPER RULES
Helper rules will match a specific token, otherwise a syntax error is
generated.
@@ -294,10 +240,10 @@
}
-=head3 Strings
+=head2 TOKENS
-A string can be either a single-quoted, double-quoted or a long string.
-Long strings are parsed using a custom parsing method.
+Tokens not defined here (in PGE) are written in PIR in
+F<languages/lua/src/lua51.pir>.
=cut
@@ -330,9 +276,66 @@
]*
}
+
+=head2 EXPRESSIONS
+
+Operator precedence is implemented using an optable.
+
+=cut
+
+rule 'expression' is optable { ... }
+
+proto 'term:' is precedence('=')
+ is parsed(&simple_expression) { ... }
+
+proto 'infix:^' is looser('term:') is pirop('pow') is
assoc('right')
+ is returns('.LuaNumber') { ... }
+
+proto 'prefix:not' is looser('infix:^') is pirop('not')
+ is returns('.LuaBoolean') { ... }
+proto 'prefix:#' is equiv('prefix:not') is pirop('len')
+ is returns('.LuaNumber') { ... }
+proto 'prefix:-' is equiv('prefix:not') is pirop('neg')
+ is returns('.LuaNumber') { ... }
+
+proto 'infix:*' is looser('prefix:not') is pirop('mul')
+ is returns('.LuaNumber') { ... }
+proto 'infix:/' is equiv('infix:*') is pirop('div')
+ is returns('.LuaNumber') { ... }
+proto 'infix:%' is equiv('infix:*') is pirop('mod')
+ is returns('.LuaNumber') { ... }
+
+proto 'infix:+' is looser('infix:*') is pirop('add')
+ is returns('.LuaNumber') { ... }
+proto 'infix:-' is equiv('infix:+') is pirop('sub')
+ is returns('.LuaNumber') { ... }
+
+proto 'infix:..' is looser('infix:+') is pirop('concat') is
assoc('right')
+ is returns('.LusString') { ... }
+
+proto 'infix:<' is looser('infix:..') is pirop('islt')
+ is returns('.LuaBoolean') { ... }
+proto 'infix:>' is equiv('infix:<') is pirop('isgt')
+ is returns('.LuaBoolean') { ... }
+proto 'infix:<=' is equiv('infix:<') is pirop('isle')
+ is returns('.LuaBoolean') { ... }
+proto 'infix:>=' is equiv('infix:<') is pirop('isge')
+ is returns('.LuaBoolean') { ... }
+proto 'infix:~=' is equiv('infix:<') is pirop('isne')
+ is returns('.LuaBoolean') { ... }
+proto 'infix:==' is equiv('infix:<') is pirop('iseq')
+ is returns('.LuaBoolean') { ... }
+
+proto 'infix:and' is looser('infix:<') is past('if') { ... }
+
+proto 'infix:or' is looser('infix:and') is past('unless') { ... }
+
+
=head1 AUTHORS
Klaas-Jan Stol <[EMAIL PROTECTED]>
+Francois Perrad
+
=cut
Modified: trunk/languages/lua/src/lua51.pir
==============================================================================
--- trunk/languages/lua/src/lua51.pir (original)
+++ trunk/languages/lua/src/lua51.pir Wed May 23 00:22:06 2007
@@ -16,17 +16,13 @@
=item * parse F<languages/lua/src/lua51.pg>
-=item * past F<languages/lua/src/ASTGrammar.tg>
+=item * PAST F<languages/lua/src/PASTGrammar.tg>
-=item * post F<languages/lua/src/OSTGrammar.tg>
-
-=item * pir F<languages/lua/src/PIRGrammar.tg>
-
-=item * run
+=item * POST F<languages/lua/src/POSTGrammar.tg>
=back
-Used by F<languages/lua/luac.pir>.
+Used by F<languages/lua/lua.pir>.
=cut
@@ -43,6 +39,7 @@
$P0.'language'('Lua')
$P0.'parsegrammar'('Lua::Grammar')
$P0.'astgrammar'('Lua::PAST::Grammar')
+ $P0.'ostgrammar'('Lua::POST::Grammar')
$S0 = "Lua 5.1 on Parrot Copyright (C) 2005-2007, The Perl Foundation.\n"
$P0.'commandline_banner'($S0)
@@ -701,8 +698,9 @@
.return (past)
.end
-.include 'languages/lua/src/ASTGrammar.pir'
-.include 'languages/lua/src/lua51_grammar_gen.pir'
+.include 'languages/lua/src/lua51_gen.pir'
+.include 'languages/lua/src/PASTGrammar_gen.pir'
+.include 'languages/lua/src/POSTGrammar_gen.pir'
=back
Modified: trunk/languages/lua/t/Parrot/Test/Lua.pm
==============================================================================
--- trunk/languages/lua/t/Parrot/Test/Lua.pm (original)
+++ trunk/languages/lua/t/Parrot/Test/Lua.pm Wed May 23 00:22:06 2007
@@ -79,7 +79,7 @@
"perl -Ilanguages/lua languages/lua/luac.pl
languages/${lang_fn}",
"$self->{parrot} --no-gc languages/${pir_fn} $params",
- # "$self->{parrot} languages/lua/luac.pir
languages/${lang_fn}",
+ # "$self->{parrot} languages/lua/lua.pbc languages/${lang_fn}",
);
}
Modified: trunk/languages/lua/test_lex.pir
==============================================================================
--- trunk/languages/lua/test_lex.pir (original)
+++ trunk/languages/lua/test_lex.pir Wed May 23 00:22:06 2007
@@ -34,7 +34,7 @@
=cut
.sub '__onload' :load :init
- load_bytecode 'languages/lua/src/lua51.pbc'
+ load_bytecode 'languages/lua/lua.pbc'
$P0 = new [ 'HLLCompiler' ]
$P0.'language'('LuaTestLex')