Mercurial Hosting > luan
changeset 670:58ebfec6178b
all luan now compiles
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Tue, 12 Apr 2016 01:05:57 -0600 |
parents | e320488819b6 |
children | 82f130eba7b0 |
files | core/src/luan/impl/Block.java core/src/luan/impl/Closure.java core/src/luan/impl/ForStmt.java core/src/luan/impl/GetLocalVar.java core/src/luan/impl/GetUpVar.java core/src/luan/impl/LuanCompiler.java core/src/luan/impl/LuanImpl.java core/src/luan/impl/LuanParser.java core/src/luan/impl/LuanStateImpl.java core/src/luan/impl/Pointer.java core/src/luan/impl/SetLocalVar.java core/src/luan/impl/SetUpVar.java core/src/luan/impl/ThemeParser.java core/src/luan/impl/UpValue.java core/src/luan/impl/VarArgs.java |
diffstat | 15 files changed, 325 insertions(+), 563 deletions(-) [+] |
line wrap: on
line diff
diff -r e320488819b6 -r 58ebfec6178b core/src/luan/impl/Block.java --- a/core/src/luan/impl/Block.java Mon Apr 11 16:00:44 2016 -0600 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,29 +0,0 @@ -package luan.impl; - -import luan.LuanException; - - -final class Block implements Stmt { - final Stmt[] stmts; - private final int stackStart; - private final int stackEnd; - - Block(Stmt[] stmts,int stackStart,int stackEnd) { - if( stmts.length==0 ) - throw new RuntimeException("empty block"); - this.stmts = stmts; - this.stackStart = stackStart; - this.stackEnd = stackEnd; - } - - @Override public void eval(LuanStateImpl luan) throws LuanException { - try { - for( Stmt stmt : stmts ) { - stmt.eval(luan); - } - } finally { - luan.stackClear(stackStart,stackEnd); - } - } - -}
diff -r e320488819b6 -r 58ebfec6178b core/src/luan/impl/Closure.java --- a/core/src/luan/impl/Closure.java Mon Apr 11 16:00:44 2016 -0600 +++ b/core/src/luan/impl/Closure.java Tue Apr 12 01:05:57 2016 -0600 @@ -9,19 +9,10 @@ public abstract class Closure extends LuanFunction implements DeepCloneable, Cloneable { - private final int stackSize; - private final int numArgs; - private final boolean isVarArg; - private UpValue[] upValues; + public Pointer[] upValues; - 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); - } + public Closure(int nUpValues) throws LuanException { + this.upValues = new Pointer[nUpValues]; } @Override public Closure shallowClone() { @@ -33,39 +24,19 @@ } @Override public void deepenClone(DeepCloneable clone,DeepCloner cloner) { - ((Closure)clone).upValues = (UpValue[])cloner.deepClone(upValues); - } - - UpValue[] upValues() { - return upValues; + ((Closure)clone).upValues = (Pointer[])cloner.deepClone(upValues); } - @Override public Object call(LuanState ls,Object[] args) throws LuanException { + @Override public final Object call(LuanState ls,Object[] args) throws LuanException { LuanStateImpl luan = (LuanStateImpl)ls; - Object[] varArgs = null; - if( isVarArg ) { - if( args.length > numArgs ) { - varArgs = new Object[ args.length - numArgs ]; - for( int i=0; i<varArgs.length; i++ ) { - varArgs[i] = args[numArgs+i]; - } - } else { - varArgs = LuanFunction.NOTHING; - } - } - 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]; - } + Closure old = luan.closure; + luan.closure = this; try { - return run(luan); - } catch(StackOverflowError e) { - throw new LuanException( "stack overflow", e ); + return doCall(luan,args); } finally { - luan.popFrame(); - } + luan.closure = old; + } } - public abstract Object run(LuanStateImpl luan) throws LuanException; + public abstract Object doCall(LuanState luan,Object[] args) throws LuanException; }
diff -r e320488819b6 -r 58ebfec6178b core/src/luan/impl/ForStmt.java --- a/core/src/luan/impl/ForStmt.java Mon Apr 11 16:00:44 2016 -0600 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,50 +0,0 @@ -package luan.impl; - -import luan.Luan; -import luan.LuanException; -import luan.LuanFunction; - - -final class ForStmt extends CodeImpl implements Stmt { - private final int iVars; - private final int nVars; - private final Expr iterExpr; - private final Stmt block; - - ForStmt(int iVars,int nVars,Expr iterExpr,Stmt block) { - this.iVars = iVars; - this.nVars = nVars; - this.iterExpr = iterExpr; - this.block = block; - } - - @Override public void eval(LuanStateImpl luan) throws LuanException { - Object fnObj = iterExpr.eval(luan); - try { - LuanFunction iter = Luan.checkFunction(fnObj); - while(true) { - Object vals = iter.call(luan); - if( vals==null ) - break; - if( vals instanceof Object[] ) { - Object[] a = (Object[])vals; - if( a.length==0 || a[0]==null ) - break; - for( int i=0; i<nVars; i++ ) { - luan.stackSet( iVars+i, i < a.length ? a[i] : null ); - } - } else { - luan.stackSet( iVars, vals ); - for( int i=1; i<nVars; i++ ) { - luan.stackSet( iVars+i, null ); - } - } - block.eval(luan); - } - } catch(BreakException e) { - } finally { - luan.stackClear(iVars,iVars+nVars); - } - } - -}
diff -r e320488819b6 -r 58ebfec6178b core/src/luan/impl/GetLocalVar.java --- a/core/src/luan/impl/GetLocalVar.java Mon Apr 11 16:00:44 2016 -0600 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,15 +0,0 @@ -package luan.impl; - - -final class GetLocalVar extends CodeImpl implements Expr { - private final int index; - - GetLocalVar(int index) { - if( index < 0 ) throw new RuntimeException(); - this.index = index; - } - - @Override public Object eval(LuanStateImpl luan) { - return luan.stackGet(index); - } -}
diff -r e320488819b6 -r 58ebfec6178b core/src/luan/impl/GetUpVar.java --- a/core/src/luan/impl/GetUpVar.java Mon Apr 11 16:00:44 2016 -0600 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,15 +0,0 @@ -package luan.impl; - - -final class GetUpVar extends CodeImpl implements Expr { - private final int index; - - GetUpVar(int index) { - if( index < 0 ) throw new RuntimeException(); - this.index = index; - } - - @Override public Object eval(LuanStateImpl luan) { - return luan.closure().upValues()[index].get(); - } -}
diff -r e320488819b6 -r 58ebfec6178b core/src/luan/impl/LuanCompiler.java --- a/core/src/luan/impl/LuanCompiler.java Mon Apr 11 16:00:44 2016 -0600 +++ b/core/src/luan/impl/LuanCompiler.java Tue Apr 12 01:05:57 2016 -0600 @@ -14,13 +14,15 @@ private LuanCompiler() {} // never public static LuanFunction compile(LuanState luan,String sourceName,String sourceText,LuanTable env,boolean allowExpr) throws LuanException { - LuanParser parser = new LuanParser(sourceName,sourceText,env); - parser.addVar( "java", JavaLuan.javaFn ); - parser.addVar( "require", PackageLuan.requireFn ); + LuanParser parser = new LuanParser(sourceName,sourceText); + parser.addVar( env!=null ? "_ENV" : null ); + parser.addVar( "java" ); + parser.addVar( "require" ); Class fnClass = parse(parser,allowExpr); final LuanStateImpl luanImpl = (LuanStateImpl)luan; + Closure closure; try { - return (LuanFunction)fnClass.getConstructor(LuanStateImpl.class).newInstance(luanImpl); + closure = (Closure)fnClass.getConstructor(LuanState.class).newInstance(luanImpl); } catch(NoSuchMethodException e) { throw new RuntimeException(e); } catch(InstantiationException e) { @@ -30,6 +32,10 @@ } catch(InvocationTargetException e) { throw new RuntimeException(e); } + closure.upValues[0].o = env!=null ? env : new LuanTable(); + closure.upValues[1].o = JavaLuan.javaFn; + closure.upValues[2].o = PackageLuan.requireFn; + return closure; } private static Class parse(LuanParser parser,boolean allowExpr) throws LuanException {
diff -r e320488819b6 -r 58ebfec6178b core/src/luan/impl/LuanImpl.java --- a/core/src/luan/impl/LuanImpl.java Mon Apr 11 16:00:44 2016 -0600 +++ b/core/src/luan/impl/LuanImpl.java Tue Apr 12 01:05:57 2016 -0600 @@ -14,7 +14,7 @@ public final class LuanImpl { private LuanImpl() {} // never - +/* private static List list = new ArrayList(); static int addObj(Object obj) { @@ -26,7 +26,7 @@ public static Object getObj(int i) { return list.get(i); } - +*/ public static int len(LuanState luan,Object o) throws LuanException { if( o instanceof String ) { @@ -170,7 +170,7 @@ public static void nop(Object o) {} - +/* public static void set(LuanStateImpl luan,Settable[] vars,Object obj) throws LuanException { if( obj instanceof Object[] ) { Object[] vals = (Object[])obj; @@ -185,7 +185,7 @@ } } } - +*/ public static void put(LuanState luan,Object t,Object key,Object value) throws LuanException { if( t instanceof LuanTable ) { LuanTable tbl = (LuanTable)t; @@ -207,6 +207,17 @@ return i<a.length ? a[i] : null; } + public static Object[] varArgs(Object o,int i) { + if( !(o instanceof Object[]) ) + return i==0 ? new Object[]{o} : LuanFunction.NOTHING; + Object[] a = (Object[])o; + if( i >= a.length ) + return LuanFunction.NOTHING; + Object[] rtn = new Object[a.length - i]; + System.arraycopy(a,i,rtn,0,rtn.length); + return rtn; + } + public static Object[] concatArgs(Object o1,Object o2) { if( o1 instanceof Object[] ) { Object[] a1 = (Object[])o1;
diff -r e320488819b6 -r 58ebfec6178b core/src/luan/impl/LuanParser.java --- a/core/src/luan/impl/LuanParser.java Mon Apr 11 16:00:44 2016 -0600 +++ b/core/src/luan/impl/LuanParser.java Tue Apr 12 01:05:57 2016 -0600 @@ -5,7 +5,6 @@ import java.util.Arrays; import java.util.List; import java.util.ArrayList; -import java.util.Scanner; import luan.Luan; import luan.LuanState; import luan.LuanTable; @@ -14,61 +13,134 @@ final class LuanParser { - private static final class Frame { + private interface Sym { + public ExpString exp(); + } + + private int symCounter = 0; + + private class LocalSym implements Sym { + final String name; + final String javaName; + String pointer = null; + + LocalSym(String name) { + this.name = name; + this.javaName = name + "_" + (++symCounter); + } + + String declaration() { + if( pointer==null ) + return "Object " + javaName + " = null;\n"; + else + return "final Pointer " + javaName + " = " + pointer + ";\n"; + } + + String ref() { + if( pointer==null ) + return javaName; + else + return javaName + ".o"; + } + + @Override public ExpString exp() { + ExpString exp = new ExpString(true,false); + exp.list.add( new Object() { + @Override public String toString() { + return ref(); + } + } ); + return exp; + } + } + + private class UpSym implements Sym { + final String name; + final int i; + final String value; + + UpSym(String name,int i,String value) { + this.name = name; + this.i = i; + this.value = value; + } + + String init() { + return "upValues[" + i + "] = " + value + ";\n"; + } + + String ref() { + return "upValues[" + i + "].o"; + } + + @Override public ExpString exp() { + ExpString exp = new ExpString(true,false); + exp.list.add( new Object() { + @Override public String toString() { + return ref(); + } + } ); + return exp; + } + } + + private final class Frame { final Frame parent; - final List<String> symbols = new ArrayList<String>(); - int stackSize = 0; + final List<LocalSym> symbols = new ArrayList<LocalSym>(); int loops = 0; boolean isVarArg = false; - final List<String> upValueSymbols = new ArrayList<String>(); - final List<UpValue.Getter> upValueGetters = new ArrayList<UpValue.Getter>(); + final List<UpSym> upValueSymbols = new ArrayList<UpSym>(); - Frame(LuanTable java) { + Frame() { this.parent = null; - upValueSymbols.add(JAVA); - upValueGetters.add(new UpValue.ValueGetter(java)); } Frame(Frame parent) { this.parent = parent; - if( upValueIndex(JAVA) != 0 ) - throw new RuntimeException(); } - int stackIndex(String name) { - int i = symbols.size(); - while( --i >= 0 ) { - if( symbols.get(i).equals(name) ) - return i; - } - return -1; + LocalSym addLocalSym(String name) { + LocalSym sym = new LocalSym(name); + symbols.add(sym); + return sym; + } + + UpSym addUpSym(String name,String value) { + UpSym sym = new UpSym( name, upValueSymbols.size(), value ); + upValueSymbols.add(sym); + return sym; } - int upValueIndex(String name) { - int i = upValueSymbols.size(); + LocalSym getLocalSym(String name) { + int i = symbols.size(); while( --i >= 0 ) { - if( upValueSymbols.get(i).equals(name) ) - return i; + LocalSym sym = symbols.get(i); + if( sym.name.equals(name) ) + return sym; } - if( parent==null ) - return -1; - i = parent.stackIndex(name); - if( i != -1 ) { - upValueGetters.add(new UpValue.StackGetter(i)); - } else { - i = parent.upValueIndex(name); - if( i == -1 ) - return -1; - upValueGetters.add(new UpValue.NestedGetter(i)); - } - upValueSymbols.add(name); - return upValueSymbols.size() - 1; + return null; } - void addUpValueGetter(String name,UpValue.Getter upValueGetter) { - upValueSymbols.add(name); - upValueGetters.add(upValueGetter); + UpSym getUpSym(String name) { + for( UpSym upSym : upValueSymbols ) { + if( upSym.name.equals(name) ) + return upSym; + } + for( Frame f=parent; f!=null; f=f.parent ) { + LocalSym sym = f.getLocalSym(name); + if( sym != null ) { + sym.pointer = "new Pointer()"; + return addUpSym(name,sym.javaName); + } + } + return null; } + + Sym getSym(String name) { + Sym sym = getLocalSym(name); + return sym != null ? sym : getUpSym(name); + } + } private static class In { @@ -91,61 +163,56 @@ } } - private static final String JAVA = "-JAVA-"; // inaccessible from Luan - private static final String _ENV = "_ENV"; - private static final UpValue.Getter[] NO_UP_VALUE_GETTERS = new UpValue.Getter[0]; - // final LuanSource source; private Frame frame; private final Parser parser; + private final StmtString top = new StmtString(); - LuanParser(String sourceName,String sourceText,LuanTable env) { + LuanParser(String sourceName,String sourceText) { // this.source = source; - this.frame = new Frame( env!=null ? env : new LuanTable() ); + this.frame = new Frame(); this.parser = new Parser(sourceName,sourceText); - if( env != null ) - addVar(_ENV,env); } - void addVar(String name,Object value) { - frame.addUpValueGetter(name,new UpValue.ValueGetter(value)); - } - - private List<String> symbols() { - return frame.symbols; + void addVar(String name) { + UpSym upSym = frame.addUpSym( "-ADDED-" ,"new Pointer()"); + if( name != null ) { + LocalSym sym = frame.addLocalSym( name ); + sym.pointer = "upValues[" + upSym.i + "]"; + top.list.add( sym.declaration() ); + } } private int symbolsSize() { return frame.symbols.size(); } - private void addSymbol(String name) { - frame.symbols.add(name); - if( frame.stackSize < symbolsSize() ) - frame.stackSize = symbolsSize(); + private void addSymbol(String name,StmtString stmt) { + final LocalSym sym = frame.addLocalSym(name); + stmt.list.add( new Object() { + @Override public String toString() { + return sym.declaration(); + } + } ); } - private void addSymbols(List<String> names) { - frame.symbols.addAll(names); - if( frame.stackSize < symbolsSize() ) - frame.stackSize = symbolsSize(); + private void addSymbols(List<String> names,StmtString stmt) { + for( String name : names ) { + addSymbol(name,stmt); + } } - private int stackIndex(String name) { - return frame.stackIndex(name); + private Sym getSym(String name) { + return frame.getSym(name); } private void popSymbols(int n) { - List<String> symbols = frame.symbols; + List<LocalSym> symbols = frame.symbols; while( n-- > 0 ) { symbols.remove(symbols.size()-1); } } - private int upValueIndex(String name) { - return frame.upValueIndex(name); - } - private void incLoops() { frame.loops++; } @@ -177,13 +244,13 @@ private Class newFnClass(int start,StmtString stmt) { if( !stmt.hasReturn ) stmt.list.add( "return LuanFunction.NOTHING;\n" ); - return toFnClass( stmt, frame.stackSize, symbolsSize(), frame.isVarArg, frame.upValueGetters.toArray(NO_UP_VALUE_GETTERS) ); + return toFnClass( stmt, frame.upValueSymbols ); } private ExpString newFnExpStr(int start,StmtString stmt) { if( !stmt.hasReturn ) stmt.list.add( "return LuanFunction.NOTHING;\n" ); - return toFnExpStr( stmt, frame.stackSize, symbolsSize(), frame.isVarArg, frame.upValueGetters.toArray(NO_UP_VALUE_GETTERS) ); + return toFnExpStr( stmt, frame.upValueSymbols ); } Class Expression() throws ParseException { @@ -191,12 +258,11 @@ int start = parser.begin(); ExpString expr = ExprZ(In.NOTHING); if( expr != null && parser.endOfInput() ) { - StmtString stmt = new StmtString(); - stmt.list.add( "return " ); - stmt.list.addAll( expr.list ); - stmt.list.add( ";\n" ); - stmt.hasReturn = true; - return parser.success(newFnClass(start,stmt)); + top.list.add( "return " ); + top.list.addAll( expr.list ); + top.list.add( ";\n" ); + top.hasReturn = true; + return parser.success(newFnClass(start,top)); } return parser.failure(null); } @@ -205,9 +271,12 @@ Spaces(In.NOTHING); int start = parser.begin(); frame.isVarArg = true; - StmtString stmt = RequiredBlock(); + top.list.add( "final Object[] varArgs = LuanImpl.varArgs(args,0);\n" ); + StmtString block = RequiredBlock(); + top.list.addAll( block.list ); + top.hasReturn = block.hasReturn; if( parser.endOfInput() ) - return parser.success(newFnClass(start,stmt)); + return parser.success(newFnClass(start,top)); throw parser.exception(); } @@ -223,17 +292,6 @@ Spaces(In.NOTHING); int stackEnd = symbolsSize(); popSymbols( stackEnd - stackStart ); - if( stmts.list.isEmpty() ) - return stmts; - String code = stmts.toString(); - if( stackStart < stackEnd ) { - stmts.list.add( 0, "try {\n" ); - stmts.list.add( "" - +"} finally {\n" - +" luan.stackClear("+stackStart+","+stackEnd+");\n" - +"}\n" - ); - } stmts.hasReturn = isReturn; return stmts; } @@ -260,14 +318,13 @@ } private boolean Stmt(StmtString stmts) throws ParseException { - if( LocalStmt(stmts) ) - return false; StmtString stmt; if( (stmt=ReturnStmt()) != null ) { stmts.list.addAll(stmt.list); return true; } if( (stmt=FunctionStmt()) != null + || (stmt=LocalStmt()) != null || (stmt=LocalFunctionStmt()) != null || (stmt=BreakStmt()) != null || (stmt=ForStmt()) != null @@ -387,15 +444,19 @@ parser.begin(); if( !(Keyword("local",In.NOTHING) && Keyword("function",In.NOTHING)) ) return parser.failure(null); + StmtString stmt = new StmtString(); String name = RequiredName(In.NOTHING); - addSymbol( name ); + addSymbol( name, stmt ); ExpString fnDef = RequiredFunction(In.NOTHING); + stmt.list.addAll( nameVar(name).set( fnDef ).list ); +/* Settable s = new SetLocalVar(symbolsSize()-1); StmtString stmt = new StmtString(); stmt.list.add( settableToString(s) ); stmt.list.add( ".set(luan," ); stmt.list.addAll( fnDef.list ); stmt.list.add( ");\n" ); +*/ return parser.success( stmt ); } @@ -423,41 +484,30 @@ ExpString expr = RequiredExpr(In.NOTHING).expr(); RequiredKeyword("do",In.NOTHING); - SetLocalVar[] vars = new SetLocalVar[names.size()]; - for( int i=0; i<vars.length; i++ ) { - vars[i] = new SetLocalVar(stackStart+i); - } - String varsStr = varsToString(vars); - - ExpString firstVar = new ExpString(new GetLocalVar(stackStart)); - addSymbols(names); - StmtString loop = RequiredLoopBlock(); - RequiredKeyword("end",In.NOTHING); String fnVar = "fn"+ ++forCounter; + ExpString fnExp = new ExpString(false,false); + fnExp.list.add( fnVar + ".call(luan)" ); StmtString stmt = new StmtString(); stmt.list.add( "" - +"try {\n" +"LuanFunction "+fnVar+" = Luan.checkFunction(" ); stmt.list.addAll( expr.list ); - stmt.list.add( "" - + ");\n" - +"while(true) {\n" - +"for( int i="+stackStart+"; i<"+symbolsSize()+"; i++ ) {\n" - +"luan.stackSet(i,null);\n" - +"}\n" - +"LuanImpl.set(luan," + varsStr + ", "+fnVar+".call(luan) );\n" - +"if( " - ); + stmt.list.add( ");\n" ); + stmt.list.add( "while(true) {\n" ); + List<Var> vars = new ArrayList<Var>(); + for( String name : names ) { + addSymbol(name, stmt); + vars.add(nameVar(name)); + } + ExpString firstVar = vars.get(0).exp(); + stmt.list.addAll( makeSetStmt(vars,fnExp).list ); + stmt.list.add( "if( " ); stmt.list.addAll( firstVar.list ); stmt.list.add( "==null ) break;\n" ); + StmtString loop = RequiredLoopBlock(); + RequiredKeyword("end",In.NOTHING); stmt.list.addAll( loop.list ); - stmt.list.add( "" - +"}" - +"} finally {\n" - +"luan.stackClear("+stackStart+","+symbolsSize()+");\n" - +"}\n" - ); + stmt.list.add( "}\n" ); popSymbols( symbolsSize() - stackStart ); return parser.success(stmt); } @@ -471,33 +521,30 @@ return parser.success(stmt); } - private boolean LocalStmt(StmtString stmts) throws ParseException { + private StmtString LocalStmt() throws ParseException { parser.begin(); if( !Keyword("local",In.NOTHING) ) - return parser.failure(); + return parser.failure(null); List<String> names = NameList(In.NOTHING); if( names==null ) { if( Keyword("function",In.NOTHING) ) - return parser.failure(); // handled later + return parser.failure(null); // handled later throw parser.exception("Invalid local statement"); } + StmtString stmt = new StmtString(); + addSymbols(names,stmt); if( parser.match( '=' ) ) { Spaces(In.NOTHING); ExpString values = ExpStringList(In.NOTHING); if( values==null ) throw parser.exception("Expressions expected"); - SetLocalVar[] vars = new SetLocalVar[names.size()]; - int stackStart = symbolsSize(); - for( int i=0; i<vars.length; i++ ) { - vars[i] = new SetLocalVar(stackStart+i); + List<Var> vars = new ArrayList<Var>(); + for( String name : names ) { + vars.add(nameVar(name)); } - String varsStr = varsToString(vars); - stmts.list.add( "LuanImpl.set(luan," + varsStr + "," ); - stmts.list.addAll( values.list ); - stmts.list.add( ");\n" ); + stmt.list.addAll( makeSetStmt(vars,values).list ); } - addSymbols(names); - return parser.success(); + return parser.success(stmt); } private List<String> RequiredNameList(In in) throws ParseException { @@ -625,14 +672,18 @@ if( values==null ) // throw parser.exception("Expressions expected"); return parser.failure(null); + return parser.success( makeSetStmt(vars,values) ); + } + + private StmtString makeSetStmt(List<Var> vars,ExpString values) throws ParseException { int n = vars.size(); if( n == 1 ) - return parser.success( vars.get(0).set(values) ); + return vars.get(0).set(values); StmtString stmt = new StmtString(); stmt.list.add( "t = " ); stmt.list.addAll( values.list ); stmt.list.add( ";\n" ); - ExpString t = new ExpString(true,false); + ExpString t = new ExpString(values.isExpr,false); t.list.add( "t" ); stmt.list.addAll( vars.get(0).set(t).list ); for( int i=1; i<n; i++ ) { @@ -640,9 +691,9 @@ t.list.add( "LuanImpl.pick(t,"+i+")" ); stmt.list.addAll( vars.get(i).set(t).list ); } - return parser.success( stmt ); + return stmt; } - +/* private static String varsToString(Settable[] vars) { StringBuilder sb = new StringBuilder(); sb.append( "new Settable[]{" ); @@ -652,7 +703,7 @@ sb.append( "}" ); return sb.toString(); } - +*/ private StmtString ExpressionsStmt() throws ParseException { parser.begin(); ExpString exp = ExprZ(In.NOTHING); @@ -969,15 +1020,15 @@ private ExpString SingleExpr(In in) throws ParseException { parser.begin(); - ExpString es = FunctionExpr(in); - if( es != null ) - return parser.success(es); - es = VarExp(in); - if( es != null ) - return parser.success(es); - Expressions exp = VarArgs(in); + ExpString exp = FunctionExpr(in); + if( exp != null ) + return parser.success(exp); + exp = VarExp(in); if( exp != null ) - return parser.success(new ExpString(exp)); + return parser.success(exp); + exp = VarArgs(in); + if( exp != null ) + return parser.success(exp); return parser.failure(null); } @@ -993,35 +1044,49 @@ In inParens = in.parens(); Spaces(inParens); frame = new Frame(frame); + StmtString stmt = new StmtString(); List<String> names = NameList(in); if( names != null ) { - addSymbols(names); + addSymbols(names,stmt); + List<Var> vars = new ArrayList<Var>(); + for( String name : names ) { + vars.add(nameVar(name)); + } + ExpString args = new ExpString(false,false); + args.list.add( "args" ); + stmt.list.addAll( makeSetStmt(vars,args).list ); if( parser.match(',') ) { Spaces(inParens); if( !parser.match("...") ) throw parser.exception(); Spaces(inParens); frame.isVarArg = true; + stmt.list.add( "final Object[] varArgs = LuanImpl.varArgs(args," + vars.size() + ");\n" ); } } else if( parser.match("...") ) { Spaces(inParens); frame.isVarArg = true; + stmt.list.add( "final Object[] varArgs = LuanImpl.varArgs(args,0);\n" ); } RequiredMatch(')'); Spaces(in); StmtString block = RequiredBlock(); + stmt.list.addAll( block.list ); + stmt.hasReturn = block.hasReturn; RequiredKeyword("end",in); - ExpString fnDef = newFnExpStr(start,block); + ExpString fnDef = newFnExpStr(start,stmt); frame = frame.parent; return parser.success(fnDef); } - private VarArgs VarArgs(In in) throws ParseException { + private ExpString VarArgs(In in) throws ParseException { parser.begin(); if( !frame.isVarArg || !parser.match("...") ) return parser.failure(null); Spaces(in); - return parser.success( new VarArgs() ); + ExpString exp = new ExpString(false,false); + exp.list.add("varArgs"); + return parser.success(exp); } private ExpString TableExpr(In in) throws ParseException { @@ -1142,13 +1207,10 @@ public StmtString set(ExpString val) throws ParseException; } - private Expr env() { - int index = stackIndex(_ENV); - if( index != -1 ) - return new GetLocalVar(index); - index = upValueIndex(_ENV); - if( index != -1 ) - return new GetUpVar(index); + private ExpString env() { + Sym sym = getSym("_ENV"); + if( sym != null ) + return sym.exp(); return null; } @@ -1156,15 +1218,12 @@ return new Var() { public ExpString exp() throws ParseException { - int index = stackIndex(name); - if( index != -1 ) - return new ExpString(new GetLocalVar(index)); - index = upValueIndex(name); - if( index != -1 ) - return new ExpString(new GetUpVar(index)); - Expr envExpr = env(); + Sym sym = getSym(name); + if( sym != null ) + return sym.exp(); + ExpString envExpr = env(); if( envExpr != null ) - return indexExpStr( new ExpString(envExpr), constExpStr(name) ); + return indexExpStr( envExpr, constExpStr(name) ); parser.failure(null); throw parser.exception("name '"+name+"' not defined"); } @@ -1172,7 +1231,7 @@ public boolean isSettable() { return true; } - +/* private Settable settable() throws ParseException { int index = stackIndex(name); if( index != -1 ) @@ -1186,13 +1245,21 @@ parser.failure(null); throw parser.exception("name '"+name+"' not defined"); } - +*/ public StmtString set(ExpString val) throws ParseException { - StmtString stmt = new StmtString(); - stmt.list.add( settableToString(settable()) + ".set(luan," ); - stmt.list.addAll( val.expr().list ); - stmt.list.add( ");\n" ); - return stmt; + Sym sym = getSym(name); + if( sym != null ) { + StmtString stmt = new StmtString(); + stmt.list.addAll( sym.exp().list ); + stmt.list.add( " = " ); + stmt.list.addAll( val.expr().list ); + stmt.list.add( ";\n" ); + return stmt; + } + ExpString envExpr = env(); + if( envExpr != null ) + return indexVar( envExpr, constExpStr(name) ).set(val); + throw new RuntimeException(); } }; } @@ -1699,7 +1766,7 @@ final List list = new ArrayList(); final boolean isExpr; final boolean isStmt; - +/* ExpString(Expressions exp) { if( exp==null ) throw new NullPointerException(); int i = LuanImpl.addObj(exp); @@ -1707,7 +1774,7 @@ isExpr = exp instanceof Expr; isStmt = exp instanceof StmtExp; } - +*/ ExpString(boolean isExpr,boolean isStmt) { this.isExpr = isExpr; this.isStmt = isStmt; @@ -1770,45 +1837,49 @@ return sb.toString(); } - private static Class toFnClass(StmtString stmt,int stackSize,int numArgs,boolean isVarArg,UpValue.Getter[] upValueGetters) { + private Class toFnClass(StmtString stmt,List<UpSym> upValueSymbols) { String code = concat(stmt.list); //System.out.println("code:\n"+code); - int i = LuanImpl.addObj(upValueGetters); String className = "EXP" + ++classCounter; String classCode = "" +"package luan.impl;\n" +"import luan.Luan;\n" +"import luan.LuanFunction;\n" + +"import luan.LuanState;\n" +"import luan.LuanException;\n" +"import luan.modules.PackageLuan;\n" +"\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" + +" public "+className+"(LuanState luan) throws LuanException {\n" + +" super("+upValueSymbols.size()+");\n" + + init(upValueSymbols) +" }\n" +"\n" - +" @Override public Object run(LuanStateImpl luan) throws LuanException {\n" + +" @Override public Object doCall(LuanState luan,Object[] args) throws LuanException {\n" +" Object t;\n" +" " + code +" }\n" +"}\n" ; try { -//System.out.println(classCode); - return LuanJavaCompiler.compile("luan.impl."+className,"code",classCode); +System.out.println(parser.sourceName); +System.out.println(classCode); + return LuanJavaCompiler.compile("luan.impl."+className,parser.sourceName,classCode); } catch(ClassNotFoundException e) { throw new RuntimeException(e); } } - private ExpString toFnExpStr(StmtString stmt,int stackSize,int numArgs,boolean isVarArg,UpValue.Getter[] upValueGetters) { - int i = LuanImpl.addObj(upValueGetters); + private ExpString toFnExpStr(StmtString stmt,List<UpSym> upValueSymbols) { ExpString exp = new ExpString(true,false); exp.list.add( "" +"\n" - +"new Closure(luan,"+stackSize+","+numArgs+","+isVarArg+",(UpValue.Getter[])LuanImpl.getObj("+i+")) {\n" - +" @Override public Object run(LuanStateImpl luan) throws LuanException {\n" + +"new Closure("+upValueSymbols.size()+") {\n" + +"{\n" + + init(upValueSymbols) + +"}\n" + +" @Override public Object doCall(LuanState luan,Object[] args) throws LuanException {\n" +" Object t;\n" +" " ); @@ -1820,11 +1891,19 @@ return exp; } + private static String init(List<UpSym> upValueSymbols) { + StringBuilder sb = new StringBuilder(); + for( UpSym upSym : upValueSymbols ) { + sb.append( upSym.init() ); + } + return sb.toString(); + } +/* private static String settableToString(Settable settable) { if( settable==null ) throw new NullPointerException(); int i = LuanImpl.addObj(settable); return"((Settable)LuanImpl.getObj(" + i + "))"; } - +*/ }
diff -r e320488819b6 -r 58ebfec6178b core/src/luan/impl/LuanStateImpl.java --- a/core/src/luan/impl/LuanStateImpl.java Mon Apr 11 16:00:44 2016 -0600 +++ b/core/src/luan/impl/LuanStateImpl.java Tue Apr 12 01:05:57 2016 -0600 @@ -13,46 +13,7 @@ public final class LuanStateImpl extends LuanState { - - private static class Frame { - final Frame previousFrame; - final Closure closure; - final Object[] stack; - final Object[] varArgs; - UpValue[] downValues = null; - - Frame( Frame previousFrame, Closure closure, int stackSize, Object[] varArgs) { - this.previousFrame = previousFrame; - this.closure = closure; - this.stack = new Object[stackSize]; - this.varArgs = varArgs; - } - - void stackClear(int start,int end) { - if( downValues != null ) { - for( int i=start; i<end; i++ ) { - UpValue downValue = downValues[i]; - if( downValue != null ) { - downValue.close(); - downValues[i] = null; - } - } - } - for( int i=start; i<end; i++ ) { - stack[i] = null; - } - } - - UpValue getUpValue(int index) { - if( downValues==null ) - downValues = new UpValue[stack.length]; - if( downValues[index] == null ) - downValues[index] = new UpValue(stack,index); - return downValues[index]; - } - } - - private Frame frame = null; + Closure closure; LuanStateImpl() {} @@ -61,54 +22,17 @@ } @Override public LuanState shallowClone() { -// if( frame != null ) -// throw new IllegalStateException("frame isn't null"); return new LuanStateImpl(this); } - // returns stack - Object[] newFrame(Closure closure, int stackSize, Object[] varArgs) { - frame = new Frame(frame,closure,stackSize,varArgs); - return frame.stack; - } - - void popFrame() { - frame = frame.previousFrame; - } - - Object stackGet(int index) { - return frame.stack[index]; - } - - public void stackSet(int index,Object value) { - frame.stack[index] = value; - } - - public void stackClear(int start,int end) { - frame.stackClear(start,end); - } - - Object[] varArgs() { - return frame.varArgs; - } - - Closure closure() { - return frame.closure; - } - - UpValue getUpValue(int index) { - return frame.getUpValue(index); - } - @Override public boolean hasJava() { - if( frame==null ) + if( closure==null ) return false; - return ((LuanTable)frame.closure.upValues()[0].get()).hasJava; + return ((LuanTable)closure.upValues[0].o).hasJava; } @Override public void setJava() { - ((LuanTable)frame.closure.upValues()[0].get()).hasJava = true; + ((LuanTable)closure.upValues[0].o).hasJava = true; } - }
diff -r e320488819b6 -r 58ebfec6178b core/src/luan/impl/Pointer.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/core/src/luan/impl/Pointer.java Tue Apr 12 01:05:57 2016 -0600 @@ -0,0 +1,17 @@ +package luan.impl; + +import luan.DeepCloneable; +import luan.DeepCloner; + + +public final class Pointer implements DeepCloneable { + public Object o; + + @Override public Pointer shallowClone() { + return new Pointer(); + } + + @Override public void deepenClone(DeepCloneable clone,DeepCloner cloner) { + ((Pointer)clone).o = cloner.get(o); + } +}
diff -r e320488819b6 -r 58ebfec6178b core/src/luan/impl/SetLocalVar.java --- a/core/src/luan/impl/SetLocalVar.java Mon Apr 11 16:00:44 2016 -0600 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,15 +0,0 @@ -package luan.impl; - - -final class SetLocalVar implements Settable { - private final int index; - - SetLocalVar(int index) { - if( index < 0 ) throw new RuntimeException(); - this.index = index; - } - - @Override public void set(LuanStateImpl luan,Object value) { - luan.stackSet( index, value ); - } -}
diff -r e320488819b6 -r 58ebfec6178b core/src/luan/impl/SetUpVar.java --- a/core/src/luan/impl/SetUpVar.java Mon Apr 11 16:00:44 2016 -0600 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,14 +0,0 @@ -package luan.impl; - - -final class SetUpVar implements Settable { - private final int index; - - SetUpVar(int index) { - this.index = index; - } - - @Override public void set(LuanStateImpl luan,Object value) { - luan.closure().upValues()[index].set(value); - } -}
diff -r e320488819b6 -r 58ebfec6178b core/src/luan/impl/ThemeParser.java --- a/core/src/luan/impl/ThemeParser.java Mon Apr 11 16:00:44 2016 -0600 +++ b/core/src/luan/impl/ThemeParser.java Tue Apr 12 01:05:57 2016 -0600 @@ -27,7 +27,7 @@ */ return null; } - +/* private static final class Frame { final Frame parent; final List<String> symbols = new ArrayList<String>(); @@ -110,7 +110,7 @@ } private Class newFnDef(Stmt stmt) { -// return new FnDef( /*stmt*/null, frame.stackSize, symbolsSize(), frame.isVarArg, frame.upValueGetters.toArray(NO_UP_VALUE_GETTERS) ); +// return new FnDef( stmt, frame.stackSize, symbolsSize(), frame.isVarArg, frame.upValueGetters.toArray(NO_UP_VALUE_GETTERS) ); return null; } @@ -191,7 +191,7 @@ Stmt block = parseBody("define:"+name,spaces,indent); Class fnDef = newFnDef(block); frame = frame.parent; - Stmt rtn = new SetStmt(fnName,/*fnDef*/null); + Stmt rtn = new SetStmt(fnName,fnDef); return parser.success(rtn); } @@ -273,7 +273,7 @@ /* if( tagName.startsWith("define:") ) EndOfLine(); -*/ +* / if( EndOfLine() ) InlineSpaces(); return parser.match("{/") && parser.match(tagName) && parser.match('}') ? parser.success() : parser.failure(); @@ -339,7 +339,7 @@ Expr fn = new IndexExpr( env, new ConstExpr(name) ); List<Expressions> args = new ArrayList<Expressions>(); args.add( env ); - args.add( /*fnDef*/null ); + args.add( fnDef ); FnCall fnCall = new FnCall( fn, ExpList.build(args) ); Stmt rtn = new ExpressionsStmt(fnCall); return parser.success(rtn); @@ -410,5 +410,5 @@ return parser.inCharRange('a', 'z') || parser.inCharRange('A', 'Z') || parser.inCharRange('0', '9') || parser.anyOf("-_."); } - +*/ }
diff -r e320488819b6 -r 58ebfec6178b core/src/luan/impl/UpValue.java --- a/core/src/luan/impl/UpValue.java Mon Apr 11 16:00:44 2016 -0600 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,99 +0,0 @@ -package luan.impl; - -import luan.DeepCloner; -import luan.DeepCloneable; -import luan.LuanException; - - -public final class UpValue implements DeepCloneable { - private Object[] stack; - private int index; - private boolean isClosed = false; - private Object value; - - UpValue(Object[] stack,int index) { - this.stack = stack; - this.index = index; - } - - UpValue(Object value) { - this.value = value; - this.isClosed = true; - } - - private UpValue() {} - - @Override public UpValue shallowClone() { - return new UpValue(); - } - - @Override public void deepenClone(DeepCloneable dc,DeepCloner cloner) { - UpValue clone = (UpValue)dc; - clone.isClosed = isClosed; - if( isClosed ) { - clone.value = cloner.get(value); - } else { - clone.stack = cloner.deepClone(stack); - clone.index = index; - } - } - - Object get() { - return isClosed ? value : stack[index]; - } - - void set(Object value) { - if( isClosed ) { - this.value = value; - } else { - stack[index] = value; - } - } - - void close() { - value = stack[index]; - isClosed = true; - stack = null; - } - - public static interface Getter { - public UpValue get(LuanStateImpl luan) throws LuanException; - } - - static final class StackGetter implements Getter { - private final int index; - - StackGetter(int index) { - this.index = index; - } - - public UpValue get(LuanStateImpl luan) { - return luan.getUpValue(index); - } - } - - static final class NestedGetter implements Getter { - private final int index; - - NestedGetter(int index) { - this.index = index; - } - - public UpValue get(LuanStateImpl luan) { - return luan.closure().upValues()[index]; - } - } - - static final class ValueGetter implements Getter { - private final UpValue upValue; - - ValueGetter(Object value) { - this.upValue = new UpValue(value); - } - - public UpValue get(LuanStateImpl luan) { - return upValue; - } - } - -}
diff -r e320488819b6 -r 58ebfec6178b core/src/luan/impl/VarArgs.java --- a/core/src/luan/impl/VarArgs.java Mon Apr 11 16:00:44 2016 -0600 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,9 +0,0 @@ -package luan.impl; - - -final class VarArgs extends CodeImpl implements Expressions { - - @Override public Object[] eval(LuanStateImpl luan) { - return luan.varArgs(); - } -}