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
--- 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;
 }
--- 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;
-}
--- 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) {
--- 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;
 	}
--- 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);