Mercurial Hosting > luan
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) {