Mercurial Hosting > luan
changeset 18:3971113699b8
add NumericForStmt
git-svn-id: https://luan-java.googlecode.com/svn/trunk@19 21e917c8-12df-6dd8-5cb6-c86387c605b9
author | fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9> |
---|---|
date | Sun, 02 Dec 2012 07:00:44 +0000 |
parents | 09d41f7490a8 |
children | a7c13c6017f7 |
files | src/luan/interp/LuaParser.java src/luan/interp/NumericForStmt.java |
diffstat | 2 files changed, 74 insertions(+), 13 deletions(-) [+] |
line wrap: on
line diff
diff -r 09d41f7490a8 -r 3971113699b8 src/luan/interp/LuaParser.java --- a/src/luan/interp/LuaParser.java Fri Nov 30 11:46:34 2012 +0000 +++ b/src/luan/interp/LuaParser.java Sun Dec 02 07:00:44 2012 +0000 @@ -45,6 +45,7 @@ int index(String name) { int i = symbols.size(); while( --i >= 0 ) { +System.out.println("index ["+name+"] ["+symbols.get(i)+"] "+symbols.get(i).equals(name)); if( symbols.get(i).equals(name) ) return i; } @@ -70,21 +71,20 @@ Rule Block() { Var<List<Stmt>> stmts = new Var<List<Stmt>>(new ArrayList<Stmt>()); + Var<Integer> stackCount = new Var<Integer>(0); return Sequence( - push(0), // stackCount - Optional( Stmt(stmts) ), + Optional( Stmt(stmts,stackCount) ), ZeroOrMore( StmtSep(), - Optional( Stmt(stmts) ) + Optional( Stmt(stmts,stackCount) ) ), - push( newBlock(stmts.get()) ) + push( newBlock(stmts.get(),stackCount.get()) ) ); } - Stmt newBlock(List<Stmt> stmts) { + Stmt newBlock(List<Stmt> stmts,int stackN) { if( stackSize < symbols.size() ) stackSize = symbols.size(); - int stackN = (Integer)pop(); for( int i=0; i<stackN; i++ ) { symbols.remove(symbols.size()-1); // pop } @@ -112,11 +112,12 @@ return FirstOf("\r\n", '\r', '\n'); } - Rule Stmt(Var<List<Stmt>> stmts) { + Rule Stmt(Var<List<Stmt>> stmts,Var<Integer> stackCount) { return FirstOf( - LocalStmt(stmts), + LocalStmt(stmts,stackCount), Sequence( FirstOf( + NumericForStmt(), DoStmt(), WhileStmt(), RepeatStmt(), @@ -129,21 +130,37 @@ ); } + Rule NumericForStmt() { + return Sequence( + Keyword("for"), Name(), '=', Spaces(), Expr(), ',', Spaces(), Expr(), + push( new ConstExpr(new LuaNumber(1)) ), // default step + Optional( + ',', Spaces(), + drop(), + Expr() + ), + symbols.add( (String)pop(3) ), // add "for" var to symbols + Keyword("do"), Block(), Keyword("end"), + push( new NumericForStmt( symbols.size()-1, expr(pop(3)), expr(pop(2)), expr(pop(1)), (Stmt)pop() ) ), + action( symbols.remove(symbols.size()-1) ) // pop + ); + } + Rule DoStmt() { return Sequence( Keyword("do"), Block(), Keyword("end") ); } - Rule LocalStmt(Var<List<Stmt>> stmts) { + Rule LocalStmt(Var<List<Stmt>> stmts,Var<Integer> stackCount) { Var<List<String>> names = new Var<List<String>>(new ArrayList<String>()); return Sequence( Keyword("local"), Name(), - newName(names.get()), + newName(names.get(),stackCount), ZeroOrMore( ',', Spaces(), Name(), - newName(names.get()) + newName(names.get(),stackCount) ), Optional( '=', Spaces(), @@ -153,11 +170,11 @@ ); } - boolean newName(List<String> names) { + boolean newName(List<String> names,Var<Integer> stackCount) { String name = (String)pop(); names.add(name); symbols.add(name); - push( ((Integer)pop()) + 1 ); + stackCount.set( stackCount.get() + 1 ); return true; } @@ -820,6 +837,10 @@ return Sequence( ']', ZeroOrMore('='), nEquals==matchLength(), ']' ); } + static boolean action(Object obj) { + return true; + } + // for debugging boolean print(Object o) { System.out.println(o);
diff -r 09d41f7490a8 -r 3971113699b8 src/luan/interp/NumericForStmt.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/luan/interp/NumericForStmt.java Sun Dec 02 07:00:44 2012 +0000 @@ -0,0 +1,40 @@ +package luan.interp; + +import luan.Lua; +import luan.LuaNumber; +import luan.LuaState; +import luan.LuaException; + + +final class NumericForStmt implements Stmt { + private final int iVar; + private final Expr fromExpr; + private final Expr toExpr; + private final Expr stepExpr; + private final Stmt block; + + NumericForStmt(int iVar,Expr fromExpr,Expr toExpr,Expr stepExpr,Stmt block) { + this.iVar = iVar; + this.fromExpr = fromExpr; + this.toExpr = toExpr; + this.stepExpr = stepExpr; + this.block = block; + } + + @Override public void eval(LuaState lua) throws LuaException { + double v = Lua.checkNumber( fromExpr.eval(lua) ).value(); + double limit = Lua.checkNumber( toExpr.eval(lua) ).value(); + double step = Lua.checkNumber( stepExpr.eval(lua) ).value(); + Object[] stack = lua.stack(); + try { + while( step > 0.0 && v <= limit || step < 0.0 && v >= limit ) { + stack[iVar] = new LuaNumber(v); + block.eval(lua); + v += step; + } + } finally { + stack[iVar] = null; + } + } + +}