Mercurial Hosting > luan
changeset 667:08966099aa6d
implement Closure directly
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Fri, 08 Apr 2016 07:00:17 -0600 |
parents | 2f449ccf54d2 |
children | 7780cafca27f |
files | core/src/luan/impl/Closure.java core/src/luan/impl/FnDef.java core/src/luan/impl/LuanCompiler.java core/src/luan/impl/LuanParser.java core/src/luan/impl/ThemeParser.java |
diffstat | 5 files changed, 62 insertions(+), 73 deletions(-) [+] |
line wrap: on
line diff
diff -r 2f449ccf54d2 -r 08966099aa6d core/src/luan/impl/Closure.java --- a/core/src/luan/impl/Closure.java Thu Apr 07 23:36:56 2016 -0600 +++ b/core/src/luan/impl/Closure.java Fri Apr 08 07:00:17 2016 -0600 @@ -8,25 +8,28 @@ import luan.DeepCloneable; -final class Closure extends LuanFunction implements DeepCloneable { - final FnDef fnDef; +public abstract class Closure extends LuanFunction implements DeepCloneable, Cloneable { + private final int stackSize; + private final int numArgs; + private final boolean isVarArg; private UpValue[] upValues; - Closure(LuanStateImpl luan,FnDef fnDef) throws LuanException { - this.fnDef = fnDef; - UpValue.Getter[] upValueGetters = fnDef.upValueGetters; + public Closure(LuanStateImpl luan,int stackSize,int numArgs,boolean isVarArg,UpValue.Getter[] upValueGetters) throws LuanException { + this.stackSize = stackSize; + this.numArgs = numArgs; + this.isVarArg = isVarArg; this.upValues = new UpValue[upValueGetters.length]; for( int i=0; i<upValues.length; i++ ) { upValues[i] = upValueGetters[i].get(luan); } } - private Closure(Closure c) { - this.fnDef = c.fnDef; - } - @Override public Closure shallowClone() { - return new Closure(this); + try { + return (Closure)clone(); + } catch(CloneNotSupportedException e) { + throw new RuntimeException(e); + } } @Override public void deepenClone(DeepCloneable clone,DeepCloner cloner) { @@ -40,24 +43,24 @@ @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 ) { - varArgs = new Object[ args.length - fnDef.numArgs ]; + if( isVarArg ) { + if( args.length > numArgs ) { + varArgs = new Object[ args.length - numArgs ]; for( int i=0; i<varArgs.length; i++ ) { - varArgs[i] = args[fnDef.numArgs+i]; + varArgs[i] = args[numArgs+i]; } } else { varArgs = LuanFunction.NOTHING; } } - Object[] stack = luan.newFrame(this,fnDef.stackSize,varArgs); - final int n = Math.min(args.length,fnDef.numArgs); + Object[] stack = luan.newFrame(this,stackSize,varArgs); + final int n = Math.min(args.length,numArgs); for( int i=0; i<n; i++ ) { stack[i] = args[i]; } Object returnValues; try { - return fnDef.run(luan); + return run(luan); } catch(StackOverflowError e) { throw new LuanException( "stack overflow", e ); } finally { @@ -65,4 +68,5 @@ } } + public abstract Object run(LuanStateImpl luan) throws LuanException; }
diff -r 2f449ccf54d2 -r 08966099aa6d core/src/luan/impl/FnDef.java --- a/core/src/luan/impl/FnDef.java Thu Apr 07 23:36:56 2016 -0600 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,24 +0,0 @@ -package luan.impl; - -import luan.LuanException; - - -public abstract class FnDef extends CodeImpl implements Expr { - final int stackSize; - final int numArgs; - final boolean isVarArg; - final UpValue.Getter[] upValueGetters; - - public FnDef(int stackSize,int numArgs,boolean isVarArg,UpValue.Getter[] upValueGetters) { - this.stackSize = stackSize; - this.numArgs = numArgs; - this.isVarArg = isVarArg; - this.upValueGetters = upValueGetters; - } - - @Override public Object eval(LuanStateImpl luan) throws LuanException { - return new Closure(luan,this); - } - - public abstract Object run(LuanStateImpl luan) throws LuanException; -}
diff -r 2f449ccf54d2 -r 08966099aa6d core/src/luan/impl/LuanCompiler.java --- a/core/src/luan/impl/LuanCompiler.java Thu Apr 07 23:36:56 2016 -0600 +++ b/core/src/luan/impl/LuanCompiler.java Fri Apr 08 07:00:17 2016 -0600 @@ -1,12 +1,13 @@ package luan.impl; +import java.util.Map; +import java.lang.reflect.InvocationTargetException; import luan.LuanFunction; import luan.LuanState; import luan.LuanException; import luan.LuanTable; import luan.modules.JavaLuan; import luan.modules.PackageLuan; -import java.util.Map; public final class LuanCompiler { @@ -16,17 +17,27 @@ LuanParser parser = new LuanParser(sourceName,sourceText,env); parser.addVar( "java", JavaLuan.javaFn ); parser.addVar( "require", PackageLuan.requireFn ); - FnDef fnDef = parse(parser,allowExpr); + Class fnClass = parse(parser,allowExpr); final LuanStateImpl luanImpl = (LuanStateImpl)luan; - return new Closure(luanImpl,fnDef); + try { + return (LuanFunction)fnClass.getConstructor(LuanStateImpl.class).newInstance(luanImpl); + } catch(NoSuchMethodException e) { + throw new RuntimeException(e); + } catch(InstantiationException e) { + throw new RuntimeException(e); + } catch(IllegalAccessException e) { + throw new RuntimeException(e); + } catch(InvocationTargetException e) { + throw new RuntimeException(e); + } } - private static FnDef parse(LuanParser parser,boolean allowExpr) throws LuanException { + private static Class parse(LuanParser parser,boolean allowExpr) throws LuanException { try { if( allowExpr ) { - FnDef fnDef = parser.Expression(); - if( fnDef != null ) - return fnDef; + Class fnClass = parser.Expression(); + if( fnClass != null ) + return fnClass; } return parser.RequiredModule(); } catch(ParseException e) {
diff -r 2f449ccf54d2 -r 08966099aa6d core/src/luan/impl/LuanParser.java --- a/core/src/luan/impl/LuanParser.java Thu Apr 07 23:36:56 2016 -0600 +++ b/core/src/luan/impl/LuanParser.java Fri Apr 08 07:00:17 2016 -0600 @@ -174,10 +174,10 @@ return new ExpressionsExpr(exprs); } - private FnDef newFnDef(int start,StmtString stmt) { + private Class newFnClass(int start,StmtString stmt) { if( !stmt.hasReturn ) stmt.list.add( "return LuanFunction.NOTHING;\n" ); - return toFnDef( stmt, frame.stackSize, symbolsSize(), frame.isVarArg, frame.upValueGetters.toArray(NO_UP_VALUE_GETTERS) ); + return toFnClass( stmt, frame.stackSize, symbolsSize(), frame.isVarArg, frame.upValueGetters.toArray(NO_UP_VALUE_GETTERS) ); } private ExpString newFnExpStr(int start,StmtString stmt) { @@ -186,7 +186,7 @@ return toFnExpStr( stmt, frame.stackSize, symbolsSize(), frame.isVarArg, frame.upValueGetters.toArray(NO_UP_VALUE_GETTERS) ); } - FnDef Expression() throws ParseException { + Class Expression() throws ParseException { Spaces(In.NOTHING); int start = parser.begin(); ExpString expr = ExprZ(In.NOTHING); @@ -196,18 +196,18 @@ stmt.list.addAll( expr.list ); stmt.list.add( ";\n" ); stmt.hasReturn = true; - return parser.success(newFnDef(start,stmt)); + return parser.success(newFnClass(start,stmt)); } return parser.failure(null); } - FnDef RequiredModule() throws ParseException { + Class RequiredModule() throws ParseException { Spaces(In.NOTHING); int start = parser.begin(); frame.isVarArg = true; StmtString stmt = RequiredBlock(); if( parser.endOfInput() ) - return parser.success(newFnDef(start,stmt)); + return parser.success(newFnClass(start,stmt)); throw parser.exception(); } @@ -1757,7 +1757,7 @@ boolean hasReturn = false; } - private static FnDef toFnDef(StmtString stmt,int stackSize,int numArgs,boolean isVarArg,UpValue.Getter[] upValueGetters) { + private static Class toFnClass(StmtString stmt,int stackSize,int numArgs,boolean isVarArg,UpValue.Getter[] upValueGetters) { StringBuilder sb = new StringBuilder(); for( Object o : stmt.list ) { if( o instanceof List ) throw new RuntimeException(); @@ -1777,9 +1777,9 @@ +"import luan.LuanException;\n" +"import luan.modules.PackageLuan;\n" +"\n" - +"public class " + className +" extends FnDef {\n" - +" public "+className+"() {\n" - +" super("+stackSize+","+numArgs+","+isVarArg+",(UpValue.Getter[])LuanImpl.getObj("+i+"));\n" + +"public class " + className +" extends Closure {\n" + +" public "+className+"(LuanStateImpl luan) throws LuanException {\n" + +" super(luan,"+stackSize+","+numArgs+","+isVarArg+",(UpValue.Getter[])LuanImpl.getObj("+i+"));\n" +" }\n" +"\n" +" @Override public Object run(LuanStateImpl luan) throws LuanException {\n" @@ -1790,14 +1790,9 @@ ; try { //System.out.println(classCode); - Class cls = LuanJavaCompiler.compile("luan.impl."+className,"code",classCode); - return (FnDef)cls.newInstance(); + return LuanJavaCompiler.compile("luan.impl."+className,"code",classCode); } catch(ClassNotFoundException e) { throw new RuntimeException(e); - } catch(InstantiationException e) { - throw new RuntimeException(e); - } catch(IllegalAccessException e) { - throw new RuntimeException(e); } } @@ -1806,7 +1801,7 @@ ExpString exp = new ExpString(true,false); exp.list.add( "" +"\n" - +"new FnDef("+stackSize+","+numArgs+","+isVarArg+",(UpValue.Getter[])LuanImpl.getObj("+i+")) {\n" + +"new Closure(luan,"+stackSize+","+numArgs+","+isVarArg+",(UpValue.Getter[])LuanImpl.getObj("+i+")) {\n" +" @Override public Object run(LuanStateImpl luan) throws LuanException {\n" +" Object t;\n" +" " @@ -1814,7 +1809,7 @@ exp.list.addAll( stmt.list ); exp.list.add( "" +" }\n" - +"}.eval(luan)\n" + +"}\n" ); return exp; }
diff -r 2f449ccf54d2 -r 08966099aa6d core/src/luan/impl/ThemeParser.java --- a/core/src/luan/impl/ThemeParser.java Thu Apr 07 23:36:56 2016 -0600 +++ b/core/src/luan/impl/ThemeParser.java Fri Apr 08 07:00:17 2016 -0600 @@ -15,6 +15,7 @@ public final class ThemeParser { public static LuanFunction compile(LuanState luan,String sourceName,String sourceText) throws LuanException { +/* try { FnDef fnDef = new ThemeParser(sourceName,sourceText).parse(); final LuanStateImpl luanImpl = (LuanStateImpl)luan; @@ -23,6 +24,8 @@ //e.printStackTrace(); throw new LuanException( e.getFancyMessage() ); } +*/ + return null; } private static final class Frame { @@ -106,7 +109,7 @@ frame.stackSize = symbolsSize(); } - private FnDef newFnDef(Stmt stmt) { + private Class newFnDef(Stmt stmt) { // return new FnDef( /*stmt*/null, frame.stackSize, symbolsSize(), frame.isVarArg, frame.upValueGetters.toArray(NO_UP_VALUE_GETTERS) ); return null; } @@ -135,7 +138,7 @@ return new GetLocalVar(stackIndex(ENV)); } - private FnDef parse() throws ParseException { + private Class parse() throws ParseException { List<Stmt> stmts = new ArrayList<Stmt>(); int stackStart = symbolsSize(); { @@ -161,7 +164,7 @@ } stmts.add( new ReturnStmt(new GetLocalVar(stackIndex(MOD))) ); Stmt block = new Block( stmts.toArray(new Stmt[0]), stackStart, symbolsSize() ); - FnDef fnDef = newFnDef(block); + Class fnDef = newFnDef(block); return fnDef; } @@ -186,9 +189,9 @@ frame = new Frame(frame); addSymbol(ENV); Stmt block = parseBody("define:"+name,spaces,indent); - FnDef fnDef = newFnDef(block); + Class fnDef = newFnDef(block); frame = frame.parent; - Stmt rtn = new SetStmt(fnName,fnDef); + Stmt rtn = new SetStmt(fnName,/*fnDef*/null); return parser.success(rtn); } @@ -329,14 +332,14 @@ frame = new Frame(frame); addSymbol(ENV); Stmt block = parseBody("block:"+name,spaces,false); - FnDef fnDef = newFnDef(block); + Class fnDef = newFnDef(block); frame = frame.parent; // String rtn = "<% env." + tag.name + "(" + (tag.attrs.isEmpty() ? "nil" : table(tag.attrs)) + ",env,function(env) %>" + block + "<% end) %>"; Expr env = env(); Expr fn = new IndexExpr( env, new ConstExpr(name) ); List<Expressions> args = new ArrayList<Expressions>(); args.add( env ); - args.add( fnDef ); + args.add( /*fnDef*/null ); FnCall fnCall = new FnCall( fn, ExpList.build(args) ); Stmt rtn = new ExpressionsStmt(fnCall); return parser.success(rtn);