diff src/luan/interp/LuaParser.java @ 40:e3624b7cd603

implement stack trace git-svn-id: https://luan-java.googlecode.com/svn/trunk@41 21e917c8-12df-6dd8-5cb6-c86387c605b9
author fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
date Fri, 21 Dec 2012 10:45:54 +0000
parents e51906de0f11
children 786699c78837
line wrap: on
line diff
--- a/src/luan/interp/LuaParser.java	Thu Dec 20 02:54:06 2012 +0000
+++ b/src/luan/interp/LuaParser.java	Fri Dec 21 10:45:54 2012 +0000
@@ -19,10 +19,17 @@
 import luan.Lua;
 import luan.LuaNumber;
 import luan.LuaState;
+import luan.LuaSource;
 
 
 class LuaParser extends BaseParser<Object> {
 
+	LuaSource source;
+
+	LuaSource.Element se(int start) {
+		return new LuaSource.Element(source,start,currentIndex());
+	}
+
 	static final String _ENV = "_ENV";
 
 	static final class Frame {
@@ -144,20 +151,22 @@
 		return true;
 	}
 
-	Chunk newChunk() {
-		return new Chunk( (Stmt)pop(), frame.stackSize, symbolsSize(), frame.isVarArg, frame.upValueGetters.toArray(NO_UP_VALUE_GETTERS) );
+	Chunk newChunk(int start) {
+		return new Chunk( se(start), (Stmt)pop(), frame.stackSize, symbolsSize(), frame.isVarArg, frame.upValueGetters.toArray(NO_UP_VALUE_GETTERS) );
 	}
 
 	Rule Target() {
+		Var<Integer> start = new Var<Integer>();
 		return Sequence(
 			Spaces(),
 			FirstOf(
 				Sequence( ExpList(), EOI ),
 				Sequence(
+					start.set(currentIndex()),
 					action( frame.isVarArg = true ),
 					Block(),
 					EOI,
-					push( newChunk() )
+					push( newChunk(start.get()) )
 				)
 			)
 		);
@@ -227,9 +236,11 @@
 	}
 
 	Rule ReturnStmt() {
+		Var<Integer> start = new Var<Integer>();
 		return Sequence(
+			start.set(currentIndex()),
 			Keyword("return"), Expressions(),
-			push( new ReturnStmt( (Expressions)pop() ) )
+			push( new ReturnStmt( se(start.get()), (Expressions)pop() ) )
 		);
 	}
 
@@ -241,15 +252,17 @@
 	}
 
 	Rule FnName() {
+		Var<Integer> start = new Var<Integer>();
 		return Sequence(
+			start.set(currentIndex()),
 			push(null),  // marker
 			Name(),
 			ZeroOrMore(
 				'.', Spaces(),
-				makeVarExp(),
+				makeVarExp(start.get()),
 				NameExpr()
 			),
-			makeSettableVar()
+			makeSettableVar(start.get())
 		);
 	}
 
@@ -272,19 +285,23 @@
 	}
 
 	Rule GenericForStmt() {
+		Var<Integer> start = new Var<Integer>();
 		Var<Integer> stackStart = new Var<Integer>(symbolsSize());
 		Var<List<String>> names = new Var<List<String>>(new ArrayList<String>());
 		return Sequence(
+			start.set(currentIndex()),
 			Keyword("for"), NameList(names), Keyword("in"), Expr(), Keyword("do"),
 			addSymbols(names.get()),
 			LoopBlock(), Keyword("end"),
-			push( new GenericForStmt( stackStart.get(), symbolsSize() - stackStart.get(), expr(pop(1)), (Stmt)pop() ) ),
+			push( new GenericForStmt( se(start.get()), stackStart.get(), symbolsSize() - stackStart.get(), expr(pop(1)), (Stmt)pop() ) ),
 			popSymbols( symbolsSize() - stackStart.get() )
 		);
 	}
 
 	Rule NumericForStmt() {
+		Var<Integer> start = new Var<Integer>();
 		return Sequence(
+			start.set(currentIndex()),
 			Keyword("for"), Name(), '=', Spaces(), Expr(), Keyword("to"), Expr(),
 			push( new ConstExpr(new LuaNumber(1)) ),  // default step
 			Optional(
@@ -294,7 +311,7 @@
 			),
 			addSymbol( (String)pop(3) ),  // add "for" var to symbols
 			Keyword("do"), LoopBlock(), Keyword("end"),
-			push( new NumericForStmt( symbolsSize()-1, expr(pop(3)), expr(pop(2)), expr(pop(1)), (Stmt)pop() ) ),
+			push( new NumericForStmt( se(start.get()), symbolsSize()-1, expr(pop(3)), expr(pop(2)), expr(pop(1)), (Stmt)pop() ) ),
 			popSymbols(1)
 		);
 	}
@@ -421,10 +438,15 @@
 	}
 
 	Rule SettableVar() {
-		return Sequence( Var(), makeSettableVar() );
+		Var<Integer> start = new Var<Integer>();
+		return Sequence(
+			start.set(currentIndex()),
+			Var(),
+			makeSettableVar(start.get())
+		);
 	}
 
-	boolean makeSettableVar() {
+	boolean makeSettableVar(int start) {
 		Object obj2 = pop();
 		if( obj2==null )
 			return false;
@@ -432,7 +454,7 @@
 		if( obj1!=null ) {
 			Expr key = expr(obj2);
 			Expr table = expr(obj1);
-			return push( new SetTableEntry(table,key) );
+			return push( new SetTableEntry(se(start),table,key) );
 		}
 		String name = (String)obj2;
 		int index = stackIndex(name);
@@ -441,7 +463,7 @@
 		index = upValueIndex(name);
 		if( index != -1 )
 			return push( new SetUpVar(index) );
-		return push( new SetTableEntry( env(), new ConstExpr(name) ) );
+		return push( new SetTableEntry( se(start), env(), new ConstExpr(name) ) );
 	}
 
 	Rule Expr() {
@@ -452,80 +474,98 @@
 	}
 
 	Rule OrExpr() {
+		Var<Integer> start = new Var<Integer>();
 		return Sequence(
+			start.set(currentIndex()),
 			AndExpr(),
-			ZeroOrMore( "or", Spaces(), AndExpr(), push( new OrExpr(expr(pop(1)),expr(pop())) ) )
+			ZeroOrMore( "or", Spaces(), AndExpr(), push( new OrExpr(se(start.get()),expr(pop(1)),expr(pop())) ) )
 		);
 	}
 
 	Rule AndExpr() {
+		Var<Integer> start = new Var<Integer>();
 		return Sequence(
+			start.set(currentIndex()),
 			RelExpr(),
-			ZeroOrMore( "and", Spaces(), RelExpr(), push( new AndExpr(expr(pop(1)),expr(pop())) ) )
+			ZeroOrMore( "and", Spaces(), RelExpr(), push( new AndExpr(se(start.get()),expr(pop(1)),expr(pop())) ) )
 		);
 	}
 
 	Rule RelExpr() {
+		Var<Integer> start = new Var<Integer>();
 		return Sequence(
+			start.set(currentIndex()),
 			ConcatExpr(),
 			ZeroOrMore(
 				FirstOf(
-					Sequence( "==", Spaces(), ConcatExpr(), push( new EqExpr(expr(pop(1)),expr(pop())) ) ),
-					Sequence( "~=", Spaces(), ConcatExpr(), push( new NotExpr(new EqExpr(expr(pop(1)),expr(pop()))) ) ),
-					Sequence( "<=", Spaces(), ConcatExpr(), push( new LeExpr(expr(pop(1)),expr(pop())) ) ),
-					Sequence( ">=", Spaces(), ConcatExpr(), push( new LeExpr(expr(pop()),expr(pop())) ) ),
-					Sequence( "<", Spaces(), ConcatExpr(), push( new LtExpr(expr(pop(1)),expr(pop())) ) ),
-					Sequence( ">", Spaces(), ConcatExpr(), push( new LtExpr(expr(pop()),expr(pop())) ) )
+					Sequence( "==", Spaces(), ConcatExpr(), push( new EqExpr(se(start.get()),expr(pop(1)),expr(pop())) ) ),
+					Sequence( "~=", Spaces(), ConcatExpr(), push( new NotExpr(se(start.get()),new EqExpr(se(start.get()),expr(pop(1)),expr(pop()))) ) ),
+					Sequence( "<=", Spaces(), ConcatExpr(), push( new LeExpr(se(start.get()),expr(pop(1)),expr(pop())) ) ),
+					Sequence( ">=", Spaces(), ConcatExpr(), push( new LeExpr(se(start.get()),expr(pop()),expr(pop())) ) ),
+					Sequence( "<", Spaces(), ConcatExpr(), push( new LtExpr(se(start.get()),expr(pop(1)),expr(pop())) ) ),
+					Sequence( ">", Spaces(), ConcatExpr(), push( new LtExpr(se(start.get()),expr(pop()),expr(pop())) ) )
 				)
 			)
 		);
 	}
 
 	Rule ConcatExpr() {
+		Var<Integer> start = new Var<Integer>();
 		return Sequence(
+			start.set(currentIndex()),
 			SumExpr(),
-			Optional( "..", Spaces(), ConcatExpr(), push( new ConcatExpr(expr(pop(1)),expr(pop())) ) )
+			Optional( "..", Spaces(), ConcatExpr(), push( new ConcatExpr(se(start.get()),expr(pop(1)),expr(pop())) ) )
 		);
 	}
 
 	Rule SumExpr() {
+		Var<Integer> start = new Var<Integer>();
 		return Sequence(
+			start.set(currentIndex()),
 			TermExpr(),
 			ZeroOrMore(
 				FirstOf(
-					Sequence( '+', Spaces(), TermExpr(), push( new AddExpr(expr(pop(1)),expr(pop())) ) ),
-					Sequence( '-', TestNot('-'), Spaces(), TermExpr(), push( new SubExpr(expr(pop(1)),expr(pop())) ) )
+					Sequence( '+', Spaces(), TermExpr(), push( new AddExpr(se(start.get()),expr(pop(1)),expr(pop())) ) ),
+					Sequence( '-', TestNot('-'), Spaces(), TermExpr(), push( new SubExpr(se(start.get()),expr(pop(1)),expr(pop())) ) )
 				)
 			)
 		);
 	}
 
 	Rule TermExpr() {
+		Var<Integer> start = new Var<Integer>();
 		return Sequence(
+			start.set(currentIndex()),
 			UnaryExpr(),
 			ZeroOrMore(
 				FirstOf(
-					Sequence( '*', Spaces(), UnaryExpr(), push( new MulExpr(expr(pop(1)),expr(pop())) ) ),
-					Sequence( '/', Spaces(), UnaryExpr(), push( new DivExpr(expr(pop(1)),expr(pop())) ) ),
-					Sequence( '%', Spaces(), UnaryExpr(), push( new ModExpr(expr(pop(1)),expr(pop())) ) )
+					Sequence( '*', Spaces(), UnaryExpr(), push( new MulExpr(se(start.get()),expr(pop(1)),expr(pop())) ) ),
+					Sequence( '/', Spaces(), UnaryExpr(), push( new DivExpr(se(start.get()),expr(pop(1)),expr(pop())) ) ),
+					Sequence( '%', Spaces(), UnaryExpr(), push( new ModExpr(se(start.get()),expr(pop(1)),expr(pop())) ) )
 				)
 			)
 		);
 	}
 
 	Rule UnaryExpr() {
-		return FirstOf(
-			Sequence( '#', Spaces(), PowExpr(), push( new LenExpr(expr(pop())) ) ),
-			Sequence( '-', TestNot('-'), Spaces(), PowExpr(), push( new UnmExpr(expr(pop())) ) ),
-			Sequence( "not", Spaces(), PowExpr(), push( new NotExpr(expr(pop())) ) ),
-			PowExpr()
+		Var<Integer> start = new Var<Integer>();
+		return Sequence(
+			start.set(currentIndex()),
+			FirstOf(
+				Sequence( '#', Spaces(), PowExpr(), push( new LenExpr(se(start.get()),expr(pop())) ) ),
+				Sequence( '-', TestNot('-'), Spaces(), PowExpr(), push( new UnmExpr(se(start.get()),expr(pop())) ) ),
+				Sequence( "not", Spaces(), PowExpr(), push( new NotExpr(se(start.get()),expr(pop())) ) ),
+				PowExpr()
+			)
 		);
 	}
 
 	Rule PowExpr() {
+		Var<Integer> start = new Var<Integer>();
 		return Sequence(
+			start.set(currentIndex()),
 			SingleExpr(),
-			Optional( '^', Spaces(), PowExpr(), push( new PowExpr(expr(pop(1)),expr(pop())) ) )
+			Optional( '^', Spaces(), PowExpr(), push( new PowExpr(se(start.get()),expr(pop(1)),expr(pop())) ) )
 		);
 	}
 
@@ -543,8 +583,10 @@
 	}
 
 	Rule Function() {
+		Var<Integer> start = new Var<Integer>();
 		Var<List<String>> names = new Var<List<String>>(new ArrayList<String>());
 		return Sequence(
+			start.set(currentIndex()),
 			'(', incParens(), Spaces(),
 			action( frame = new Frame(frame) ),
 			Optional(
@@ -557,7 +599,7 @@
 				)
 			),
 			')', decParens(), Spaces(), Block(), Keyword("end"),
-			push( newChunk() ),
+			push( newChunk(start.get()) ),
 			action( frame = frame.parent )
 		);
 	}
@@ -570,17 +612,21 @@
 	}
 
 	Rule VarArgs() {
+		Var<Integer> start = new Var<Integer>();
 		return Sequence(
+			start.set(currentIndex()),
 			"...", Spaces(),
 			frame.isVarArg,
-			push( VarArgs.INSTANCE )
+			push( new VarArgs(se(start.get())) )
 		);
 	}
 
 	Rule TableExpr() {
+		Var<Integer> start = new Var<Integer>();
 		Var<List<TableExpr.Field>> fields = new Var<List<TableExpr.Field>>(new ArrayList<TableExpr.Field>());
 		Var<ExpList.Builder> builder = new Var<ExpList.Builder>(new ExpList.Builder());
 		return Sequence(
+			start.set(currentIndex()),
 			'{', incParens(), Spaces(),
 			Optional(
 				Field(fields,builder),
@@ -592,7 +638,7 @@
 			),
 			'}', decParens(),
 			Spaces(),
-			push( new TableExpr( fields.get().toArray(new TableExpr.Field[0]), builder.get().build() ) )
+			push( new TableExpr( se(start.get()), fields.get().toArray(new TableExpr.Field[0]), builder.get().build() ) )
 		);
 	}
 
@@ -621,14 +667,18 @@
 	}
 
 	Rule VarExp() {
+		Var<Integer> start = new Var<Integer>();
 		return Sequence(
+			start.set(currentIndex()),
 			Var(),
-			makeVarExp()
+			makeVarExp(start.get())
 		);
 	}
 
 	Rule Var() {
+		Var<Integer> start = new Var<Integer>();
 		return Sequence(
+			start.set(currentIndex()),
 			FirstOf(
 				Sequence(
 					'(', incParens(), Spaces(), Expr(), ')', decParens(), Spaces(),
@@ -641,12 +691,12 @@
 				)
 			),
 			ZeroOrMore(
-				makeVarExp(),
+				makeVarExp(start.get()),
 				FirstOf(
 					SubExpr(),
 					Sequence( '.', Spaces(), NameExpr() ),
 					Sequence(
-						Args(),
+						Args(start),
 						push(null)  // marker
 					)
 				)
@@ -657,32 +707,32 @@
 	Expr env() {
 		int index = stackIndex(_ENV);
 		if( index != -1 )
-			return new GetLocalVar(index);
+			return new GetLocalVar(null,index);
 		index = upValueIndex(_ENV);
 		if( index != -1 )
-			return new GetUpVar(index);
+			return new GetUpVar(null,index);
 		throw new RuntimeException("_ENV not found");
 	}
 
-	boolean makeVarExp() {
+	boolean makeVarExp(int start) {
 		Object obj2 = pop();
 		if( obj2==null )
 			return true;
 		Object obj1 = pop();
 		if( obj1 != null )
-			return push( new IndexExpr( expr(obj1), expr(obj2) ) );
+			return push( new IndexExpr( se(start), expr(obj1), expr(obj2) ) );
 		String name = (String)obj2;
 		int index = stackIndex(name);
 		if( index != -1 )
-			return push( new GetLocalVar(index) );
+			return push( new GetLocalVar(se(start),index) );
 		index = upValueIndex(name);
 		if( index != -1 )
-			return push( new GetUpVar(index) );
-		return push( new IndexExpr( env(), new ConstExpr(name) ) );
+			return push( new GetUpVar(se(start),index) );
+		return push( new IndexExpr( se(start), env(), new ConstExpr(name) ) );
 	}
 
 	// function should be on top of the stack
-	Rule Args() {
+	Rule Args(Var<Integer> start) {
 		return Sequence(
 			FirstOf(
 				Sequence(
@@ -697,7 +747,7 @@
 					push( new ExpList.SingleExpList(new ConstExpr(pop())) )
 				)
 			),
-			push( new FnCall( expr(pop(1)), (Expressions)pop() ) )
+			push( new FnCall( se(start.get()), expr(pop(1)), (Expressions)pop() ) )
 		);
 	}