changeset 663:b438a47196bc

finish compiling function blocks
author Franklin Schmidt <fschmidt@gmail.com>
date Thu, 07 Apr 2016 00:01:10 -0600
parents ee00a619eec1
children 71f8f5075df8
files core/src/luan/impl/Closure.java core/src/luan/impl/FnDef.java core/src/luan/impl/LuanImpl.java core/src/luan/impl/LuanParser.java core/src/luan/impl/LuanStateImpl.java core/src/luan/impl/ReturnStmt.java core/src/luan/impl/ThemeParser.java
diffstat 7 files changed, 77 insertions(+), 48 deletions(-) [+]
line wrap: on
line diff
--- a/core/src/luan/impl/Closure.java	Wed Apr 06 21:47:45 2016 -0600
+++ b/core/src/luan/impl/Closure.java	Thu Apr 07 00:01:10 2016 -0600
@@ -37,16 +37,8 @@
 		return upValues;
 	}
 
-	@Override public Object call(LuanState luan,Object[] args) throws LuanException {
-		try {
-			return call(this,(LuanStateImpl)luan,args);
-		} catch(StackOverflowError e) {
-			throw new LuanException( "stack overflow", e );
-		}
-	}
-
-	private static Object call(Closure closure,LuanStateImpl luan,Object[] args) throws LuanException {
-		FnDef fnDef = closure.fnDef;
+	@Override public Object call(LuanState ls,Object[] args) throws LuanException {
+		LuanStateImpl luan = (LuanStateImpl)ls;
 		Object[] varArgs = null;
 		if( fnDef.isVarArg ) {
 			if( args.length > fnDef.numArgs ) {
@@ -58,20 +50,19 @@
 				varArgs = LuanFunction.NOTHING;
 			}
 		}
-		Object[] stack = luan.newFrame(closure,fnDef.stackSize,varArgs);
+		Object[] stack = luan.newFrame(this,fnDef.stackSize,varArgs);
 		final int n = Math.min(args.length,fnDef.numArgs);
 		for( int i=0; i<n; i++ ) {
 			stack[i] = args[i];
 		}
 		Object returnValues;
 		try {
-			fnDef.block.eval(luan);
-		} catch(ReturnException e) {
+			return fnDef.block.eval(luan);
+		} catch(StackOverflowError e) {
+			throw new LuanException( "stack overflow", e );
 		} finally {
-			returnValues = luan.returnValues;
 			luan.popFrame();
 		}
-		return returnValues;
 	}
 
 }
--- a/core/src/luan/impl/FnDef.java	Wed Apr 06 21:47:45 2016 -0600
+++ b/core/src/luan/impl/FnDef.java	Thu Apr 07 00:01:10 2016 -0600
@@ -4,21 +4,21 @@
 
 
 final class FnDef extends CodeImpl implements Expr {
-	final Stmt block;
+	final Expressions block;
 	final int stackSize;
 	final int numArgs;
 	final boolean isVarArg;
 	final UpValue.Getter[] upValueGetters;
 
-	FnDef(Stmt block,int stackSize,int numArgs,boolean isVarArg,UpValue.Getter[] upValueGetters) {
+	FnDef(Expressions block,int stackSize,int numArgs,boolean isVarArg,UpValue.Getter[] upValueGetters) {
 		this.block = block;
 		this.stackSize = stackSize;
 		this.numArgs = numArgs;
 		this.isVarArg = isVarArg;
 		this.upValueGetters = upValueGetters;
-		fixReturns(block);
+//		fixReturns(block);
 	}
-
+/*
 	private static void fixReturns(Stmt stmt) {
 		if( stmt instanceof ReturnStmt ) {
 			ReturnStmt rs = (ReturnStmt)stmt;
@@ -32,7 +32,7 @@
 			fixReturns( is.elseStmt );
 		}
 	}
-
+*/
 	@Override public Object eval(LuanStateImpl luan) throws LuanException {
 		return new Closure(luan,this);
 	}
--- a/core/src/luan/impl/LuanImpl.java	Wed Apr 06 21:47:45 2016 -0600
+++ b/core/src/luan/impl/LuanImpl.java	Thu Apr 07 00:01:10 2016 -0600
@@ -27,7 +27,7 @@
 		return listExpressions.get(i);
 	}
 
-
+/*
 	private static List<Stmt> listStmt = new ArrayList<Stmt>();
 
 	static int addStmt(Stmt stmt) {
@@ -39,7 +39,7 @@
 	public static Stmt getStmt(int i) {
 		return listStmt.get(i);
 	}
-
+*/
 
 	private static List<Settable> listSettable = new ArrayList<Settable>();
 
--- a/core/src/luan/impl/LuanParser.java	Wed Apr 06 21:47:45 2016 -0600
+++ b/core/src/luan/impl/LuanParser.java	Thu Apr 07 00:01:10 2016 -0600
@@ -174,8 +174,10 @@
 		return new ExpressionsExpr(exprs);
 	}
 
-	private FnDef newFnDef(int start,Stmt stmt) {
-		return new FnDef( stmt, frame.stackSize, symbolsSize(), frame.isVarArg, frame.upValueGetters.toArray(NO_UP_VALUE_GETTERS) );
+	private FnDef newFnDef(int start,StmtString stmt) {
+		if( !stmt.hasReturn )
+			stmt = new StmtString( stmt.code + "return LuanFunction.NOTHING;\n" );
+		return new FnDef( toExpressions(stmt), frame.stackSize, symbolsSize(), frame.isVarArg, frame.upValueGetters.toArray(NO_UP_VALUE_GETTERS) );
 	}
 
 	FnDef Expression() throws ParseException {
@@ -183,8 +185,8 @@
 		int start = parser.begin();
 		ExpString expr = ExprZ(In.NOTHING);
 		if( expr != null && parser.endOfInput() ) {
-			String code = "luan.returnValues = " + expr.code + ";\n";
-			Stmt stmt = stmt( new StmtString(code) );
+			String code = "return " + expr.code + ";\n";
+			StmtString stmt = new StmtString(code);
 			return parser.success(newFnDef(start,stmt));
 		}
 		return parser.failure(null);
@@ -194,7 +196,7 @@
 		Spaces(In.NOTHING);
 		int start = parser.begin();
 		frame.isVarArg = true;
-		Stmt stmt = stmt(RequiredBlock());
+		StmtString stmt = RequiredBlock();
 		if( parser.endOfInput() )
 			return parser.success(newFnDef(start,stmt));
 		throw parser.exception();
@@ -203,11 +205,13 @@
 	private StmtString RequiredBlock() throws ParseException {
 		StringBuilder stmts = new StringBuilder();
 		int stackStart = symbolsSize();
-		Stmt(stmts);
-		while( StmtSep(stmts) ) {
+		boolean isReturn = Stmt(stmts);
+		while( !isReturn && StmtSep(stmts) ) {
 			Spaces(In.NOTHING);
-			Stmt(stmts);
+			isReturn = Stmt(stmts);
 		}
+		StmtSep(null);
+		Spaces(In.NOTHING);
 		int stackEnd = symbolsSize();
 		popSymbols( stackEnd - stackStart );
 		if( stmts.length() == 0 )
@@ -221,7 +225,9 @@
 				+"	luan.stackClear("+stackStart+","+stackEnd+");\n"
 				+"}\n"
 			;
-		return new StmtString(code);
+		StmtString stmt = new StmtString(code);
+		stmt.hasReturn = isReturn;
+		return stmt;
 	}
 
 	private boolean StmtSep(StringBuilder stmts) throws ParseException {
@@ -230,11 +236,13 @@
 			return parser.success();
 		if( EndOfLine() )
 			return parser.success();
-		parser.rollback();
-		StmtString stmt = TemplateStmt();
-		if( stmt != null ) {
-			stmts.append(stmt.code);
-			return parser.success();
+		if( stmts != null ) {
+//			parser.rollback();
+			StmtString stmt = TemplateStmt();
+			if( stmt != null ) {
+				stmts.append(stmt.code);
+				return parser.success();
+			}
 		}
 		return parser.failure();
 	}
@@ -243,12 +251,15 @@
 		return parser.match( "\r\n" ) || parser.match( '\r' ) || parser.match( '\n' );
 	}
 
-	private void Stmt(StringBuilder stmts) throws ParseException {
+	private boolean Stmt(StringBuilder stmts) throws ParseException {
 		if( LocalStmt(stmts) )
-			return;
+			return false;
 		StmtString stmt;
-		if( (stmt=ReturnStmt()) != null
-			|| (stmt=FunctionStmt()) != null
+		if( (stmt=ReturnStmt()) != null ) {
+			stmts.append(stmt.code);
+			return true;
+		}
+		if( (stmt=FunctionStmt()) != null
 			|| (stmt=LocalFunctionStmt()) != null
 			|| (stmt=BreakStmt()) != null
 			|| (stmt=ForStmt()) != null
@@ -261,6 +272,7 @@
 		) {
 			stmts.append(stmt.code);
 		}
+		return false;
 	}
 
 	private ExpString indexExpStr(ExpString exp1,ExpString exp2) {
@@ -333,8 +345,7 @@
 		if( !Keyword("return",In.NOTHING) )
 			return parser.failure(null);
 		ExpString exprs = ExpStringList(In.NOTHING);
-		String code = "luan.returnValues = " + (exprs!=null ? exprs.code : "LuanFunction.NOTHING") + ";\n"
-			+"return;\n";
+		String code = "return " + (exprs!=null ? exprs.code : "LuanFunction.NOTHING") + ";\n";
 		return parser.success( new StmtString(code) );
 	}
 
@@ -868,7 +879,7 @@
 		}
 		RequiredMatch(')');
 		Spaces(in);
-		Stmt block = stmt(RequiredBlock());
+		StmtString block = RequiredBlock();
 		RequiredKeyword("end",in);
 		FnDef fnDef = newFnDef(start,block);
 		frame = frame.parent;
@@ -1565,6 +1576,7 @@
 
 	private static class StmtString {
 		final String code;
+		boolean hasReturn = false;
 /*
 		StmtString(Stmt stmt) {
 			if( stmt==null )  throw new NullPointerException();
@@ -1614,6 +1626,35 @@
 	}
 
 
+	static Expressions toExpressions(StmtString stmt) {
+		String className = "EXP" + ++classCounter;
+		String classCode = ""
+			+"package luan.impl;\n"
+			+"import luan.Luan;\n"
+			+"import luan.LuanFunction;\n"
+			+"import luan.LuanException;\n"
+			+"import luan.modules.PackageLuan;\n"
+			+"\n"
+			+"public class " + className +" implements Expressions {\n"
+			+"	@Override public Object eval(LuanStateImpl luan) throws LuanException {\n"
+			+"		Object t;\n"
+			+"		" + stmt.code
+			+"	}\n"
+			+"}\n"
+		;
+		try {
+			Class cls = LuanJavaCompiler.compile("luan.impl."+className,"code",classCode);
+			return (Expressions)cls.newInstance();
+		} catch(ClassNotFoundException e) {
+			throw new RuntimeException(e);
+		} catch(InstantiationException e) {
+			throw new RuntimeException(e);
+		} catch(IllegalAccessException e) {
+			throw new RuntimeException(e);
+		}
+	}
+
+
 	private static class SettableString {
 		final String code;
 
--- a/core/src/luan/impl/LuanStateImpl.java	Wed Apr 06 21:47:45 2016 -0600
+++ b/core/src/luan/impl/LuanStateImpl.java	Thu Apr 07 00:01:10 2016 -0600
@@ -53,7 +53,6 @@
 	}
 
 	private Frame frame = null;
-	public Object returnValues;
 
 	LuanStateImpl() {}
 
@@ -69,13 +68,11 @@
 
 	// returns stack
 	Object[] newFrame(Closure closure, int stackSize, Object[] varArgs) {
-		returnValues = LuanFunction.NOTHING;
 		frame = new Frame(frame,closure,stackSize,varArgs);
 		return frame.stack;
 	}
 
 	void popFrame() {
-		returnValues = LuanFunction.NOTHING;
 		frame = frame.previousFrame;
 	}
 
--- a/core/src/luan/impl/ReturnStmt.java	Wed Apr 06 21:47:45 2016 -0600
+++ b/core/src/luan/impl/ReturnStmt.java	Thu Apr 07 00:01:10 2016 -0600
@@ -14,7 +14,7 @@
 	}
 
 	@Override public void eval(LuanStateImpl luan) throws LuanException {
-		luan.returnValues = expressions.eval(luan);
+//		luan.returnValues = expressions.eval(luan);
 		if( throwReturnException )
 			throw new ReturnException();
 	}
--- a/core/src/luan/impl/ThemeParser.java	Wed Apr 06 21:47:45 2016 -0600
+++ b/core/src/luan/impl/ThemeParser.java	Thu Apr 07 00:01:10 2016 -0600
@@ -107,7 +107,7 @@
 	}
 
 	private FnDef newFnDef(Stmt stmt) {
-		return new FnDef( stmt, frame.stackSize, symbolsSize(), frame.isVarArg, frame.upValueGetters.toArray(NO_UP_VALUE_GETTERS) );
+		return new FnDef( /*stmt*/null, frame.stackSize, symbolsSize(), frame.isVarArg, frame.upValueGetters.toArray(NO_UP_VALUE_GETTERS) );
 	}
 
 	private int stackIndex(String name) {