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
--- 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);
--- /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;
+		}
+	}
+
+}