Mercurial Hosting > luan
diff core/src/luan/impl/LuanParser.java @ 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 |
line wrap: on
line diff
--- 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 + "))"; } - +*/ }