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

Reply via email to