changeset 20:d85510d92eee

add BreakStmt git-svn-id: https://luan-java.googlecode.com/svn/trunk@21 21e917c8-12df-6dd8-5cb6-c86387c605b9
author fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
date Sun, 02 Dec 2012 10:51:18 +0000
parents a7c13c6017f7
children c93d8c781853
files src/luan/interp/BreakException.java src/luan/interp/BreakStmt.java src/luan/interp/GenericForStmt.java src/luan/interp/LuaParser.java src/luan/interp/NumericForStmt.java src/luan/interp/RepeatStmt.java src/luan/interp/WhileStmt.java
diffstat 7 files changed, 56 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
diff -r a7c13c6017f7 -r d85510d92eee src/luan/interp/BreakException.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/luan/interp/BreakException.java	Sun Dec 02 10:51:18 2012 +0000
@@ -0,0 +1,4 @@
+package luan.interp;
+
+
+final class BreakException extends RuntimeException {}
diff -r a7c13c6017f7 -r d85510d92eee src/luan/interp/BreakStmt.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/luan/interp/BreakStmt.java	Sun Dec 02 10:51:18 2012 +0000
@@ -0,0 +1,11 @@
+package luan.interp;
+
+import luan.LuaState;
+
+
+final class BreakStmt implements Stmt {
+
+	@Override public void eval(LuaState lua) {
+		throw new BreakException();
+	}
+}
diff -r a7c13c6017f7 -r d85510d92eee src/luan/interp/GenericForStmt.java
--- a/src/luan/interp/GenericForStmt.java	Sun Dec 02 10:08:24 2012 +0000
+++ b/src/luan/interp/GenericForStmt.java	Sun Dec 02 10:51:18 2012 +0000
@@ -32,6 +32,7 @@
 				}
 				block.eval(lua);
 			}
+		} catch(BreakException e) {
 		} finally {
 			for( int i=iVars; i<iVars+nVars; i++ ) {
 				stack[i] = null;
diff -r a7c13c6017f7 -r d85510d92eee src/luan/interp/LuaParser.java
--- a/src/luan/interp/LuaParser.java	Sun Dec 02 10:08:24 2012 +0000
+++ b/src/luan/interp/LuaParser.java	Sun Dec 02 10:51:18 2012 +0000
@@ -26,6 +26,7 @@
 	int parens = 0;
 	List<String> symbols = new ArrayList<String>();
 	int stackSize = 0;
+	int loops = 0;
 
 	boolean nEquals(int n) {
 		nEquals = n;
@@ -58,6 +59,17 @@
 		return true;
 	}
 
+	boolean incLoops() {
+		loops++;
+		return true;
+	}
+
+	boolean decLoops() {
+		loops--;
+		return true;
+	}
+
+
 	public Rule Target() {
 		return Sequence(
 			Spaces(),
@@ -122,6 +134,7 @@
 			LocalStmt(stmts),
 			Sequence(
 				FirstOf(
+					BreakStmt(),
 					GenericForStmt(),
 					NumericForStmt(),
 					DoStmt(),
@@ -136,10 +149,18 @@
 		);
 	}
 
+	Rule BreakStmt() {
+		return Sequence(
+			Keyword("break"),
+			loops > 0,
+			push( new BreakStmt() )
+		);
+	}
+
 	Rule GenericForStmt() {
 		Var<Integer> stackStart = new Var<Integer>(symbols.size());
 		return Sequence(
-			Keyword("for"), NameList(), Keyword("in"), Expr(), Keyword("do"), Block(), Keyword("end"),
+			Keyword("for"), NameList(), Keyword("in"), Expr(), Keyword("do"), LoopBlock(), Keyword("end"),
 			push( new GenericForStmt( stackStart.get(), symbols.size() - stackStart.get(), expr(pop(1)), (Stmt)pop() ) ),
 			popSymbols( symbols.size() - stackStart.get() )
 		);
@@ -155,7 +176,7 @@
 				Expr()
 			),
 			symbols.add( (String)pop(3) ),  // add "for" var to symbols
-			Keyword("do"), Block(), Keyword("end"),
+			Keyword("do"), LoopBlock(), Keyword("end"),
 			push( new NumericForStmt( symbols.size()-1, expr(pop(3)), expr(pop(2)), expr(pop(1)), (Stmt)pop() ) ),
 			popSymbols(1)
 		);
@@ -200,18 +221,22 @@
 
 	Rule WhileStmt() {
 		return Sequence(
-			Keyword("while"), Expr(), Keyword("do"), Block(), Keyword("end"),
+			Keyword("while"), Expr(), Keyword("do"), LoopBlock(), Keyword("end"),
 			push( new WhileStmt( expr(pop(1)), (Stmt)pop() ) )
 		);
 	}
 
 	Rule RepeatStmt() {
 		return Sequence(
-			Keyword("repeat"), Block(), Keyword("until"), Expr(),
+			Keyword("repeat"), LoopBlock(), Keyword("until"), Expr(),
 			push( new RepeatStmt( (Stmt)pop(1), expr(pop()) ) )
 		);
 	}
 
+	Rule LoopBlock() {
+		return Sequence( incLoops(), Block(), decLoops() );
+	}
+
 	Rule IfStmt() {
 		Var<Integer> n = new Var<Integer>(1);
 		return Sequence(
diff -r a7c13c6017f7 -r d85510d92eee src/luan/interp/NumericForStmt.java
--- a/src/luan/interp/NumericForStmt.java	Sun Dec 02 10:08:24 2012 +0000
+++ b/src/luan/interp/NumericForStmt.java	Sun Dec 02 10:51:18 2012 +0000
@@ -32,6 +32,7 @@
 				block.eval(lua);
 				v += step;
 			}
+		} catch(BreakException e) {
 		} finally {
 			stack[iVar] = null;
 		}
diff -r a7c13c6017f7 -r d85510d92eee src/luan/interp/RepeatStmt.java
--- a/src/luan/interp/RepeatStmt.java	Sun Dec 02 10:08:24 2012 +0000
+++ b/src/luan/interp/RepeatStmt.java	Sun Dec 02 10:51:18 2012 +0000
@@ -15,8 +15,10 @@
 	}
 
 	@Override public void eval(LuaState lua) throws LuaException {
-		do {
-			doStmt.eval(lua);
-		} while( !Lua.toBoolean( cnd.eval(lua) ) );
+		try {
+			do {
+				doStmt.eval(lua);
+			} while( !Lua.toBoolean( cnd.eval(lua) ) );
+		} catch(BreakException e) {}
 	}
 }
diff -r a7c13c6017f7 -r d85510d92eee src/luan/interp/WhileStmt.java
--- a/src/luan/interp/WhileStmt.java	Sun Dec 02 10:08:24 2012 +0000
+++ b/src/luan/interp/WhileStmt.java	Sun Dec 02 10:51:18 2012 +0000
@@ -15,8 +15,10 @@
 	}
 
 	@Override public void eval(LuaState lua) throws LuaException {
-		while( Lua.toBoolean( cnd.eval(lua) ) ) {
-			doStmt.eval(lua);
-		}
+		try {
+			while( Lua.toBoolean( cnd.eval(lua) ) ) {
+				doStmt.eval(lua);
+			}
+		} catch(BreakException e) {}
 	}
 }