Author: fperrad
Date: Fri Jun 8 00:22:30 2007
New Revision: 18870
Modified:
trunk/languages/lua/src/PASTGrammar.tg
trunk/languages/lua/src/POSTGrammar.tg
trunk/languages/lua/src/lua51.pg
trunk/languages/lua/src/lua51.pir
trunk/languages/lua/t/test_lex.t
Log:
[Lua]
- PAST/POST : vararg, break, ...
Modified: trunk/languages/lua/src/PASTGrammar.tg
==============================================================================
--- trunk/languages/lua/src/PASTGrammar.tg (original)
+++ trunk/languages/lua/src/PASTGrammar.tg Fri Jun 8 00:22:30 2007
@@ -61,6 +61,15 @@
}
+transform past (Lua::Grammar::do_block) :language('PIR') {
+ .local pmc symbtab
+ symbtab = get_hll_global ['Lua::PAST'], '$symbtab'
+ symbtab.'push_scope'()
+ $P0 = node['block']
+ .return tree.'get'('past', $P0, 'Lua::Grammar::block')
+}
+
+
transform past (Lua::Grammar::if_stat) :language('PIR') {
.local pmc past, cpast, expr, blk
$P0 = node['expression']
@@ -273,7 +282,7 @@
transform past (Lua::Grammar::break_statement) :language('PIR') {
.local pmc past
past = new 'PAST::Op'
- past.'init'('node'=>node, 'pasttype'=>'break')
+ past.'init'(node, 'node'=>node, 'pasttype'=>'break')
.return (past)
}
@@ -427,7 +436,6 @@
L1:
$P0 = node['parameter_list']
if null $P0 goto L2
- $P0 = shift $P0
$P1 = $P0['name_list']
if null $P1 goto L3
$P1 = $P1['name']
@@ -447,9 +455,14 @@
if null $P1 goto L2
$P1 = shift $P1
var = new 'PAST::Var'
- var.'init'('node'=>$P1, 'name'=>'...', 'scope'=>'parameter', 'isslurpy'=>1)
+ var.'init'('node'=>$P1, 'name'=>'vararg', 'scope'=>'parameter',
'isslurpy'=>1)
push parlist, var
+ goto L5
L2:
+ var = new 'PAST::Var'
+ var.'init'('node'=>$P0, 'name'=>'extra', 'scope'=>'parameter',
'isslurpy'=>1)
+ push parlist, var
+ L5:
$P0 = node['block']
past = tree.'get'('past', $P0, 'Lua::Grammar::block')
.return past.'new'('PAST::Block', parlist :flat, past, 'node'=>node)
@@ -649,7 +662,10 @@
transform past (Lua::Grammar::vararg) :language('PIR') {
- internal_error("not implemented (vararg)")
+ .local pmc past
+ new past, 'PAST::Op'
+ past.'init'('node'=>node, 'pasttype'=>'vararg')
+ .return (past)
}
Modified: trunk/languages/lua/src/POSTGrammar.tg
==============================================================================
--- trunk/languages/lua/src/POSTGrammar.tg (original)
+++ trunk/languages/lua/src/POSTGrammar.tg Fri Jun 8 00:22:30 2007
@@ -20,12 +20,18 @@
if name != '' goto with_name
name = node.unique('anon_')
with_name:
+ .local pmc endlabels
+ endlabels = get_hll_global ['Lua::POST'], '@endlabels'
+ $P0 = new .ResizablePMCArray
+ set_hll_global ['Lua::POST'], '@endlabels', $P0
.local pmc outerpost
outerpost = get_hll_global ['Lua::POST'], '$?SUB'
.local pmc post
post = new 'POST::Sub'
post.'init'('node'=>node, 'name'=>name, 'outer'=>outerpost,
'pragma'=>':anon :lex', 'blocktype'=>'declaration', 'result'=>'')
set_hll_global ['Lua::POST'], '$?SUB', post
+ post.'push_pirop'('inline', ' .local pmc subr')
+ post.'push_pirop'('inline', ' subr = interpinfo
.INTERPINFO_CURRENT_SUB')
.local pmc iter
iter = node.'iterator'()
iter_loop:
@@ -36,6 +42,7 @@
goto iter_loop
iter_end:
set_hll_global ['Lua::POST'], '$?SUB', outerpost
+ set_hll_global ['Lua::POST'], '@endlabels', endlabels
unless null outerpost goto no_chunk
.local pmc start
start = post.'new'('POST::Sub', 'name'=>'__start', 'pragma'=>':main',
'result'=>'')
@@ -58,7 +65,10 @@
onload = post.'new'('POST::Sub', 'name'=>'__onload', 'pragma'=>':anon
:init', 'result'=>'')
onload.'push_pirop'('inline', ' .const .Sub main = "_main"')
onload.'push_pirop'('inline', '# print "onload\n"')
- .return post.'new'('Lua::POST::Chunk', post, onload, start,
'prologue'=>'.HLL "Lua", "lua_group"')
+ .return post.'new'('Lua::POST::Chunk', post, onload, start,
'prologue'=><<'PIRCODE')
+.include 'interpinfo.pasm'
+.HLL "Lua", "lua_group"
+PIRCODE
no_chunk:
.local pmc ops
ops = post.'new'('POST::Ops', 'node'=>node)
@@ -68,8 +78,7 @@
ops.'push_pirop'('inline', ' .const .Sub %0 = %1', $S0, $S1)
$P0 = ops.'push_pirop'('newclosure')
$P0.'arglist'($P0, $S0)
- $P1 = ops.'push_pirop'('get_global')
- $P1.'arglist'($P1, '"_G"')
+ $P1= ops.'push_pirop'('callmethod', 'getfenv', 'subr')
#ops.'push_pirop'('callmethod', 'setfenv', $P0, $P1, 'result'=>'')
ops.'push_pirop'('callmethod', 'setfenv', $P0, $P1)
ops.'result'($P0)
@@ -237,6 +246,15 @@
}
+transform vararg (PAST::Op) :language('PIR') {
+ .local pmc post
+ post = new 'POST::Op'
+ post.'init'('node'=>node, 'pirop'=>'call')
+ post.'arglist'('mkarg', 'vararg')
+ .return (post)
+}
+
+
transform if (PAST::Op) :language('PIR') {
.local pmc ops, expr, then, else
ops = new 'POST::Ops'
@@ -270,6 +288,8 @@
transform while (PAST::Op) :language('PIR') {
+ .local pmc endlabels
+ endlabels = get_hll_global ['Lua::POST'], '@endlabels'
.local pmc ops, expr, blk
ops = new 'POST::Ops'
ops.'init'('node'=>node)
@@ -278,6 +298,7 @@
looplabel = ops.'new'('POST::Label', 'result'=>$S0)
$S0 = concat $S0, '_end'
endlabel = ops.'new'('POST::Label', 'result'=>$S0)
+ unshift endlabels, endlabel
ops.'push'(looplabel)
$P0 = node[0]
expr = tree.'get'('post', $P0)
@@ -288,11 +309,14 @@
ops.'push'(blk)
ops.'push_pirop'('goto', looplabel)
ops.'push'(endlabel)
+ $P0 = shift endlabels
.return (ops)
}
transform repeat (PAST::Op) :language('PIR') {
+ .local pmc endlabels
+ endlabels = get_hll_global ['Lua::POST'], '@endlabels'
.local pmc ops, expr, blk
ops = new 'POST::Ops'
ops.'init'('node'=>node)
@@ -301,6 +325,7 @@
looplabel = ops.'new'('POST::Label', 'result'=>$S0)
$S0 = concat $S0, '_end'
endlabel = ops.'new'('POST::Label', 'result'=>$S0)
+ unshift endlabels, endlabel
ops.'push'(looplabel)
$P0 = node[0]
blk = tree.'get'('post', $P0)
@@ -311,12 +336,15 @@
ops.'push_pirop'('if', expr, endlabel)
ops.'push_pirop'('goto', looplabel)
ops.'push'(endlabel)
+ $P0 = shift endlabels
.return (ops)
}
transform fornum (PAST::Op) :language('PIR') {
internal_error("not implemented (fornum)")
+ .local pmc endlabels
+ endlabels = get_hll_global ['Lua::POST'], '@endlabels'
.local pmc ops, var, limit, step, blk
ops = new 'POST::Ops'
ops.'init'('node'=>node)
@@ -365,6 +393,8 @@
transform forlist (PAST::Op) :language('PIR') {
internal_error("not implemented (forlist)")
+ .local pmc endlabels
+ endlabels = get_hll_global ['Lua::POST'], '@endlabels'
.local pmc ops, var, limit, step, blk
ops = new 'POST::Ops'
ops.'init'('node'=>node)
@@ -406,7 +436,20 @@
transform break (PAST::Op) :language('PIR') {
- internal_error("not implemented (break)")
+ .local pmc endlabels
+ endlabels = get_hll_global ['Lua::POST'], '@endlabels'
+ $I0 = endlabels
+ unless $I0 > 0 goto L1
+ .local pmc post
+ post = new 'POST::Op'
+ post.'init'('node'=>node, 'pirop'=>'goto')
+ $P0 = endlabels[0]
+ post.'arglist'($P0)
+ .return (post)
+ L1:
+ $P0 = get_hll_global ['Lua::Grammar'], 'syntax_error'
+ $P1 = node[0]
+ $P1.$P0("no loop to break")
}
@@ -543,83 +586,76 @@
}
-transform vivipost (PAST::Var) :language('PIR') {
- .local pmc vivipost
- .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
+ .local pmc ops
.local pmc keypost, basepost
- vivipost = tree.'get'('vivipost', node)
- post = vivipost.'new'('POST::Ops', 'node'=>node, 'result'=>vivipost)
- vivilabel = post.'new'('POST::Label', 'name'=>'vivify_')
+ ops = new 'POST::Ops'
+ ops.'init'('node'=>node)
.local string scope, name, key, fetchop, storeop
scope = node.'scope'()
if scope == 'keyed' goto scope_keyed
- name = node.'name'()
- name = node.'escape'(name)
+ $S0 = node.'name'()
+ name = node.'escape'($S0)
if scope == 'lexical' goto scope_lexical
if scope == 'parameter' goto scope_parameter
scope_package:
- basepost = post.'push_pirop'('get_global')
- basepost.'arglist'(basepost, '"_G"')
- keypost = post.'push_pirop'('new')
+ basepost = ops.'push_pirop'('callmethod', 'getfenv', 'subr')
+ keypost = ops.'push_pirop'('new')
keypost.'arglist'(keypost, '.LuaString')
- post.'push_pirop'('set', keypost, name)
+ ops.'push_pirop'('set', keypost, name)
goto have_scope
scope_keyed:
$P0 = node[0]
basepost = tree.'get'('post', $P0)
- post.'push'(basepost)
+ ops.'push'(basepost)
$P0 = node[1]
keypost = tree.'get'('post', $P0)
- post.'push'(keypost)
+ ops.'push'(keypost)
goto have_scope
scope_lexical:
+ .local pmc vivipost
+ vivipost = ops.'new'('POST::Op', 'pirop'=>'new')
+ vivipost.'arglist'(vivipost, '.LuaNil')
$I0 = node.'ismy'()
if $I0 == 0 goto L1
- post.'push'(vivipost)
- post.'push_pirop'('.lex', name, vivipost)
- .return (post)
+ ops.'push'(vivipost)
+ ops.'push_pirop'('.lex', name, vivipost)
+ ops.'result'(vivipost)
+ .return (ops)
L1:
$I0 = node.'islvalue'()
unless $I0 goto L2
- post.'push_pirop'('store_lex', name, post)
- .return (post)
+ ops.'push_pirop'('store_lex', name, ops)
+ ops.'result'(ops)
+ .return (ops)
L2:
- post.'push_pirop'('find_lex', vivipost, name)
- post.'result'(post)
- .return (post)
+ ops.'push_pirop'('find_lex', vivipost, name)
+ ops.'result'(vivipost)
+ .return (ops)
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 ['Lua::POST'], '$?SUB'
$I0 = node.'isslurpy'()
unless $I0 goto no_slurpy
- subpost.'push_param'('pmc', pname, ':slurpy')
- .return (post)
+ $S0 = node.'name'()
+ subpost.'push_param'('pmc', $S0, ':slurpy')
+ .return (ops)
no_slurpy:
+ .local string pname
+ pname = ops.'unique'('param_')
subpost.'push_param'('pmc', pname, ':optional')
- .return (post)
+ ops.'push_pirop'('.lex', name, pname)
+ .local pmc vivilabel
+ vivilabel = ops.'new'('POST::Label', 'name'=>'vivify_')
+ ops.'push_pirop'('unless_null', pname, vivilabel)
+ ops.'push_pirop'('new', pname, '.LuaNil')
+ ops.'push'(vivilabel)
+ ops.'result'(pname)
+ .return (ops)
have_scope:
key = basepost.'result'()
@@ -627,14 +663,14 @@
$S0 = keypost.'result'()
key .= $S0
key .= ']'
- post.'result'(key)
+ ops.'result'(key)
$I0 = node.'islvalue'()
if $I0 goto done_lvalue
- $P0 = post.'push_pirop'('set')
+ $P0 = ops.'push_pirop'('set')
$P0.'arglist'($P0, key)
- post.'result'($P0)
+ ops.'result'($P0)
done_lvalue:
- .return (post)
+ .return (ops)
}
Modified: trunk/languages/lua/src/lua51.pg
==============================================================================
--- trunk/languages/lua/src/lua51.pg (original)
+++ trunk/languages/lua/src/lua51.pg Fri Jun 8 00:22:30 2007
@@ -139,11 +139,11 @@
rule parameter_list {
| <name_list> [ <','> <vararg> ]?
- | <vararg>
+ | <vararg>?
}
rule function_body {
- <'('> <parameter_list>? <?closeparen> <block> <?end>
+ <'('> <parameter_list> <?closeparen> <block> <?end>
}
rule expression_list {
Modified: trunk/languages/lua/src/lua51.pir
==============================================================================
--- trunk/languages/lua/src/lua51.pir (original)
+++ trunk/languages/lua/src/lua51.pir Fri Jun 8 00:22:30 2007
@@ -105,11 +105,12 @@
.param pmc mob
.param string message
.local int lineno
+ $S0 = 'lua: '
# .local pmc infile
# infile = get_hll_global ['TGE::Compiler'], '$!infile'
# $S0 = infile
# $S0 .= ':'
- $S0 = '_._:'
+ $S0 .= '_._:'
$P0 = get_hll_global ['PGE::Util'], 'line_number'
lineno = mob.$P0()
inc lineno
Modified: trunk/languages/lua/t/test_lex.t
==============================================================================
--- trunk/languages/lua/t/test_lex.t (original)
+++ trunk/languages/lua/t/test_lex.t Fri Jun 8 00:22:30 2007
@@ -120,13 +120,13 @@
language_output_like( 'Lua_lex', <<'CODE', <<'OUT', 'unfinished string' );
print "unfinished string
CODE
-/^\w+\.\w+:1: unfinished string near '"?unfinished string'/
+/^[^:]+: [^:]+:1: unfinished string near '"?unfinished string'/
OUT
language_output_like( 'Lua_lex', <<'CODE', <<'OUT', 'string with escape
sequence too large' );
print "escape\333sequence"
CODE
-/^\w+\.\w+:1: escape sequence too large near '"?escape/
+/^[^:]+: [^:]+:1: escape sequence too large near '"?escape/
OUT
language_output_is( 'Lua_lex', <<'CODE', <<'OUT', 'long string' );
@@ -145,21 +145,21 @@
language_output_like( 'Lua_lex', <<'CODE', <<'OUT', 'invalid long string
delimiter' );
print [===+ string ]===]
CODE
-/^\w+\.\w+:1: invalid long string delimiter near '\[==='/
+/^[^:]+: [^:]+:1: invalid long string delimiter near '\[==='/
OUT
language_output_like( 'Lua_lex', <<'CODE', <<'OUT', 'unfinished string' );
print [[unfinished long string
CODE
-/^\w+\.\w+:1: unfinished long string/
+/^[^:]+: [^:]+:1: unfinished long string/
OUT
language_output_like( 'Lua_lex', <<'CODE', <<'OUT', 'nested long string' );
print [[ long string [[ nested ]] ]]
CODE
-/^\w+\.\w+:1: nesting of \[\[\.\.\.\]\] is deprecated near '\[\[ long string
\[\['/
+/^[^:]+: [^:]+:1: nesting of \[\[\.\.\.\]\] is deprecated near '\[\[ long
string \[\['/
OUT
language_output_is( 'Lua_lex', <<'CODE', <<'OUT', 'number' );
@@ -185,19 +185,19 @@
language_output_like( 'Lua_lex', <<'CODE', <<'OUT', 'malformed number' );
0x1Bh
CODE
-/^\w+\.\w+:1: malformed number near '0x1Bh'/
+/^[^:]+: [^:]+:1: malformed number near '0x1Bh'/
OUT
language_output_like( 'Lua_lex', <<'CODE', <<'OUT', 'malformed number' );
1.2.34
CODE
-/^\w+\.\w+:1: malformed number near '1.2.34'/
+/^[^:]+: [^:]+:1: malformed number near '1.2.34'/
OUT
language_output_like( 'Lua_lex', <<'CODE', <<'OUT', 'malformed number' );
.2A
CODE
-/^\w+\.\w+:1: malformed number near '.2A'/
+/^[^:]+: [^:]+:1: malformed number near '.2A'/
OUT
language_output_is( 'Lua_lex', <<'CODE', <<'OUT', 'comment' );
@@ -238,20 +238,20 @@
--[[unfinished long comment
CODE
-/^\w+\.\w+:1: unfinished long comment/
+/^[^:]+: [^:]+:1: unfinished long comment/
OUT
language_output_like( 'Lua_lex', <<'CODE', <<'OUT', 'nested long comment' );
--[[ long comment [[ nested ]] ]]
CODE
-/^\w+\.\w+:1: nesting of \[\[\.\.\.\]\] is deprecated near '\[\[ long comment
\[\['/
+/^[^:]+: [^:]+:1: nesting of \[\[\.\.\.\]\] is deprecated near '\[\[ long
comment \[\['/
OUT
language_output_like( 'Lua_lex', <<'CODE', <<'OUT', 'syntax error' );
!!
CODE
-/^\w+\.\w+:1: syntax error/
+/^[^:]+: [^:]+:1: syntax error/
OUT