diff core/src/luan/impl/LuanParser.java @ 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
line wrap: on
line diff
--- 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;