Mercurial Hosting > luan
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;