Mercurial Hosting > luan
changeset 674:2994e46f62b7
some optimization
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Tue, 12 Apr 2016 19:31:18 -0600 |
parents | 33629d753cf9 |
children | d95caff8ba8c |
files | core/src/luan/impl/LuanImpl.java core/src/luan/impl/LuanParser.java |
diffstat | 2 files changed, 285 insertions(+), 313 deletions(-) [+] |
line wrap: on
line diff
--- a/core/src/luan/impl/LuanImpl.java Tue Apr 12 17:09:06 2016 -0600 +++ b/core/src/luan/impl/LuanImpl.java Tue Apr 12 19:31:18 2016 -0600 @@ -14,20 +14,6 @@ public final class LuanImpl { private LuanImpl() {} // never -/* - private static List list = new ArrayList(); - - static int addObj(Object obj) { - int i = list.size(); - list.add(obj); - return i; - } - - public static Object getObj(int i) { - return list.get(i); - } -*/ - public static int len(LuanState luan,Object o) throws LuanException { if( o instanceof String ) { String s = (String)o; @@ -191,10 +177,7 @@ 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; + public static Object[] varArgs(Object[] a,int i) { if( i >= a.length ) return LuanFunction.NOTHING; Object[] rtn = new Object[a.length - i]; @@ -233,10 +216,10 @@ } } - public static LuanTable table(Object o) { + public static LuanTable table(Object[] a) { LuanTable table = new LuanTable(); int i = 0; - for( Object fld : Luan.array(o) ) { + for( Object fld : a ) { if( fld instanceof TableField ) { TableField tblFld = (TableField)fld; Object key = tblFld.key; @@ -252,4 +235,8 @@ return table; } + public static Object first(Object[] a) { + return a.length==0 ? null : a[0]; + } + }
--- a/core/src/luan/impl/LuanParser.java Tue Apr 12 17:09:06 2016 -0600 +++ b/core/src/luan/impl/LuanParser.java Tue Apr 12 19:31:18 2016 -0600 @@ -14,7 +14,7 @@ final class LuanParser { private interface Sym { - public ExpString exp(); + public Expr exp(); } private int symCounter = 0; @@ -29,8 +29,8 @@ this.javaName = name + "_" + (++symCounter); } - StmtString declaration(ExpString value) { - StmtString stmt = new StmtString(); + Stmts declaration(Expr value) { + Stmts stmt = new Stmts(); if( value==null ) { stmt.list.add( new Object() { @Override public String toString() { @@ -41,6 +41,7 @@ } } ); } else { + if( value.valType != Val.SINGLE ) throw new RuntimeException(); stmt.list.add( new Object() { @Override public String toString() { if( !isPointer ) @@ -62,8 +63,8 @@ return stmt; } - @Override public ExpString exp() { - ExpString exp = new ExpString(true,false); + @Override public Expr exp() { + Expr exp = new Expr(Val.SINGLE,false); exp.list.add( new Object() { @Override public String toString() { if( !isPointer ) @@ -91,8 +92,8 @@ return "upValues[" + i + "] = " + value + ";\n"; } - @Override public ExpString exp() { - ExpString exp = new ExpString(true,false); + @Override public Expr exp() { + Expr exp = new Expr(Val.SINGLE,false); exp.list.add( new Object() { @Override public String toString() { return "upValues[" + i + "].o"; @@ -184,7 +185,7 @@ // final LuanSource source; private Frame frame; private final Parser parser; - private final StmtString top = new StmtString(); + private final Stmts top = new Stmts(); LuanParser(String sourceName,String sourceText) { // this.source = source; @@ -205,7 +206,7 @@ return frame.symbols.size(); } - private StmtString addSymbol(String name,ExpString value) { + private Stmts addSymbol(String name,Expr value) { final LocalSym sym = frame.addLocalSym(name); return sym.declaration(value); } @@ -240,22 +241,14 @@ throw parser.exception(msg); return t; } -/* - private static Expr expr(Expressions exprs) { - if( exprs==null ) - return null; - if( exprs instanceof Expr ) - return (Expr)exprs; - return new ExpressionsExpr(exprs); - } -*/ - private Class newFnClass(int start,StmtString stmt) { + + private Class newFnClass(int start,Stmts stmt) { if( !stmt.hasReturn ) stmt.list.add( "return LuanFunction.NOTHING;\n" ); return toFnClass( stmt, frame.upValueSymbols ); } - private ExpString newFnExpStr(int start,StmtString stmt) { + private Expr newFnExpStr(int start,Stmts stmt) { if( !stmt.hasReturn ) stmt.list.add( "return LuanFunction.NOTHING;\n" ); return toFnExpStr( stmt, frame.upValueSymbols ); @@ -264,7 +257,7 @@ Class Expression() throws ParseException { Spaces(In.NOTHING); int start = parser.begin(); - ExpString expr = ExprZ(In.NOTHING); + Expr expr = ExprZ(In.NOTHING); if( expr != null && parser.endOfInput() ) { top.list.add( "return " ); top.list.addAll( expr.list ); @@ -280,7 +273,7 @@ int start = parser.begin(); frame.isVarArg = true; top.list.add( "final Object[] varArgs = LuanImpl.varArgs(args,0);\n" ); - StmtString block = RequiredBlock(); + Stmts block = RequiredBlock(); top.list.addAll( block.list ); top.hasReturn = block.hasReturn; if( parser.endOfInput() ) @@ -288,8 +281,8 @@ throw parser.exception(); } - private StmtString RequiredBlock() throws ParseException { - StmtString stmts = new StmtString(); + private Stmts RequiredBlock() throws ParseException { + Stmts stmts = new Stmts(); int stackStart = symbolsSize(); boolean isReturn = Stmt(stmts); while( !isReturn && StmtSep(stmts) ) { @@ -304,7 +297,7 @@ return stmts; } - private boolean StmtSep(StmtString stmts) throws ParseException { + private boolean StmtSep(Stmts stmts) throws ParseException { parser.begin(); if( parser.match( ';' ) ) return parser.success(); @@ -312,7 +305,7 @@ return parser.success(); if( stmts != null ) { // parser.rollback(); - StmtString stmt = TemplateStmt(); + Stmts stmt = TemplateStmt(); if( stmt != null ) { stmts.list.addAll(stmt.list); return parser.success(); @@ -325,8 +318,8 @@ return parser.match( "\r\n" ) || parser.match( '\r' ) || parser.match( '\n' ); } - private boolean Stmt(StmtString stmts) throws ParseException { - StmtString stmt; + private boolean Stmt(Stmts stmts) throws ParseException { + Stmts stmt; if( (stmt=ReturnStmt()) != null ) { stmts.list.addAll(stmt.list); return true; @@ -348,42 +341,42 @@ return false; } - private ExpString indexExpStr(ExpString exp1,ExpString exp2) { - ExpString exp = new ExpString(true,false); + private Expr indexExpStr(Expr exp1,Expr exp2) { + Expr exp = new Expr(Val.SINGLE,false); exp.list.add( "luan.index(" ); - exp.list.addAll( exp1.expr().list ); + exp.list.addAll( exp1.single().list ); exp.list.add( "," ); - exp.list.addAll( exp2.expr().list ); + exp.list.addAll( exp2.single().list ); exp.list.add( ")" ); return exp; } - private ExpString callExpStr(ExpString fn,ExpString args) { - ExpString exp = new ExpString(false,true); + private Expr callExpStr(Expr fn,Expr args) { + Expr exp = new Expr(null,true); exp.list.add( "Luan.checkFunction(" ); - exp.list.addAll( fn.expr().list ); - exp.list.add( ").call(luan,Luan.array(" ); - exp.list.addAll( args.list ); - exp.list.add( "))" ); + exp.list.addAll( fn.single().list ); + exp.list.add( ").call(luan," ); + exp.list.addAll( args.array().list ); + exp.list.add( ")" ); return exp; } - private StmtString TemplateStmt() throws ParseException { - ExpString exprs = TemplateExpressions(In.NOTHING); + private Stmts TemplateStmt() throws ParseException { + Expr exprs = TemplateExpressions(In.NOTHING); if( exprs == null ) return null; - ExpString requireCall = new ExpString(true,false); + Expr requireCall = new Expr(Val.SINGLE,false); requireCall.list.add( "PackageLuan.require(luan,\"luan:Io\")" ); - ExpString stdoutExp = indexExpStr( requireCall.expr(), constExpStr("stdout") ); - ExpString writeExp = indexExpStr( stdoutExp, constExpStr("write") ); - ExpString writeCall = callExpStr( writeExp, exprs ); - StmtString stmt = new StmtString(); + Expr stdoutExp = indexExpStr( requireCall.single(), constExpStr("stdout") ); + Expr writeExp = indexExpStr( stdoutExp, constExpStr("write") ); + Expr writeCall = callExpStr( writeExp, exprs ); + Stmts stmt = new Stmts(); stmt.list.addAll( writeCall.list ); stmt.list.add( ";\n" ); return stmt; } - private ExpString TemplateExpressions(In in) throws ParseException { + private Expr TemplateExpressions(In in) throws ParseException { if( in.template ) return null; int start = parser.begin(); @@ -391,7 +384,7 @@ return parser.failure(null); EndOfLine(); In inTemplate = in.template(); - List<ExpString> builder = new ArrayList<ExpString>(); + List<Expr> builder = new ArrayList<Expr>(); while(true) { if( parser.match( "<%=" ) ) { Spaces(inTemplate); @@ -414,12 +407,12 @@ } } - private StmtString ReturnStmt() throws ParseException { + private Stmts ReturnStmt() throws ParseException { parser.begin(); if( !Keyword("return",In.NOTHING) ) return parser.failure(null); - ExpString exprs = ExpStringList(In.NOTHING); - StmtString stmt = new StmtString(); + Expr exprs = ExpStringList(In.NOTHING); + Stmts stmt = new Stmts(); stmt.list.add( "return " ); if( exprs != null ) stmt.list.addAll( exprs.list ); @@ -429,7 +422,7 @@ return parser.success( stmt ); } - private StmtString FunctionStmt() throws ParseException { + private Stmts FunctionStmt() throws ParseException { parser.begin(); if( !Keyword("function",In.NOTHING) ) return parser.failure(null); @@ -438,28 +431,28 @@ Var var = nameVar(RequiredName(In.NOTHING)); while( parser.match( '.' ) ) { Spaces(In.NOTHING); - ExpString exp = NameExpr(In.NOTHING); + Expr exp = NameExpr(In.NOTHING); if( exp==null ) return parser.failure(null); var = indexVar( var.exp(), exp ); } - ExpString fnDef = RequiredFunction(In.NOTHING); + Expr fnDef = RequiredFunction(In.NOTHING); return parser.success( var.set(fnDef) ); } - private StmtString LocalFunctionStmt() throws ParseException { + private Stmts LocalFunctionStmt() throws ParseException { parser.begin(); if( !(Keyword("local",In.NOTHING) && Keyword("function",In.NOTHING)) ) return parser.failure(null); - StmtString stmt = new StmtString(); + Stmts stmt = new Stmts(); String name = RequiredName(In.NOTHING); stmt.list.addAll( addSymbol(name,null).list ); - ExpString fnDef = RequiredFunction(In.NOTHING); + Expr fnDef = RequiredFunction(In.NOTHING); stmt.list.addAll( nameVar(name).set(fnDef).list ); /* Settable s = new SetLocalVar(symbolsSize()-1); - StmtString stmt = new StmtString(); + Stmts stmt = new Stmts(); stmt.list.add( settableToString(s) ); stmt.list.add( ".set(luan," ); stmt.list.addAll( fnDef.list ); @@ -468,20 +461,20 @@ return parser.success( stmt ); } - private StmtString BreakStmt() throws ParseException { + private Stmts BreakStmt() throws ParseException { parser.begin(); if( !Keyword("break",In.NOTHING) ) return parser.failure(null); if( frame.loops <= 0 ) throw parser.exception("'break' outside of loop"); - StmtString stmt = new StmtString(); + Stmts stmt = new Stmts(); stmt.list.add( "break;\n" ); return parser.success( stmt ); } int forCounter = 0; - private StmtString ForStmt() throws ParseException { + private Stmts ForStmt() throws ParseException { parser.begin(); int stackStart = symbolsSize(); if( !Keyword("for",In.NOTHING) ) @@ -489,13 +482,13 @@ List<String> names = RequiredNameList(In.NOTHING); if( !Keyword("in",In.NOTHING) ) return parser.failure(null); - ExpString expr = RequiredExpr(In.NOTHING).expr(); + Expr expr = RequiredExpr(In.NOTHING).single(); RequiredKeyword("do",In.NOTHING); String fnVar = "fn"+ ++forCounter; - ExpString fnExp = new ExpString(false,false); + Expr fnExp = new Expr(null,false); fnExp.list.add( fnVar + ".call(luan)" ); - StmtString stmt = new StmtString(); + Stmts stmt = new Stmts(); stmt.list.add( "" +"LuanFunction "+fnVar+" = Luan.checkFunction(" ); @@ -506,7 +499,7 @@ stmt.list.add( "if( " ); stmt.list.addAll( nameVar(names.get(0)).exp().list ); stmt.list.add( "==null ) break;\n" ); - StmtString loop = RequiredLoopBlock(); + Stmts loop = RequiredLoopBlock(); RequiredKeyword("end",In.NOTHING); stmt.list.addAll( loop.list ); stmt.list.add( "}\n" ); @@ -514,16 +507,16 @@ return parser.success(stmt); } - private StmtString DoStmt() throws ParseException { + private Stmts DoStmt() throws ParseException { parser.begin(); if( !Keyword("do",In.NOTHING) ) return parser.failure(null); - StmtString stmt = RequiredBlock(); + Stmts stmt = RequiredBlock(); RequiredKeyword("end",In.NOTHING); return parser.success(stmt); } - private StmtString LocalStmt() throws ParseException { + private Stmts LocalStmt() throws ParseException { parser.begin(); if( !Keyword("local",In.NOTHING) ) return parser.failure(null); @@ -533,15 +526,15 @@ return parser.failure(null); // handled later throw parser.exception("Invalid local statement"); } - StmtString stmt = new StmtString(); + Stmts stmt = new Stmts(); if( parser.match( '=' ) ) { Spaces(In.NOTHING); - ExpString values = ExpStringList(In.NOTHING); + Expr values = ExpStringList(In.NOTHING); if( values==null ) throw parser.exception("Expressions expected"); stmt.list.addAll( makeLocalSetStmt(names,values).list ); } else { - ExpString value = new ExpString(true,false); + Expr value = new Expr(Val.SINGLE,false); value.list.add( "null" ); for( String name : names ) { stmt.list.addAll( addSymbol(name,value).list ); @@ -581,15 +574,15 @@ return parser.success(name); } - private StmtString WhileStmt() throws ParseException { + private Stmts WhileStmt() throws ParseException { parser.begin(); if( !Keyword("while",In.NOTHING) ) return parser.failure(null); - ExpString cnd = RequiredExpr(In.NOTHING).expr(); + Expr cnd = RequiredExpr(In.NOTHING).single(); RequiredKeyword("do",In.NOTHING); - StmtString loop = RequiredLoopBlock(); + Stmts loop = RequiredLoopBlock(); RequiredKeyword("end",In.NOTHING); - StmtString stmt = new StmtString(); + Stmts stmt = new Stmts(); stmt.list.add( "while( Luan.checkBoolean(" ); stmt.list.addAll( cnd.list ); stmt.list.add( ") ) {\n" ); @@ -598,14 +591,14 @@ return parser.success( stmt ); } - private StmtString RepeatStmt() throws ParseException { + private Stmts RepeatStmt() throws ParseException { parser.begin(); if( !Keyword("repeat",In.NOTHING) ) return parser.failure(null); - StmtString loop =RequiredLoopBlock(); + Stmts loop =RequiredLoopBlock(); RequiredKeyword("until",In.NOTHING); - ExpString cnd = RequiredExpr(In.NOTHING).expr(); - StmtString stmt = new StmtString(); + Expr cnd = RequiredExpr(In.NOTHING).single(); + Stmts stmt = new Stmts(); stmt.list.add( "do {\n" ); stmt.list.addAll( loop.list ); stmt.list.add( "} while( !Luan.checkBoolean(" ); @@ -614,21 +607,21 @@ return parser.success( stmt ); } - private StmtString RequiredLoopBlock() throws ParseException { + private Stmts RequiredLoopBlock() throws ParseException { incLoops(); - StmtString stmt = RequiredBlock(); + Stmts stmt = RequiredBlock(); decLoops(); return stmt; } - private StmtString IfStmt() throws ParseException { + private Stmts IfStmt() throws ParseException { parser.begin(); if( !Keyword("if",In.NOTHING) ) return parser.failure(null); - StmtString stmt = new StmtString(); - ExpString cnd; - StmtString block; - cnd = RequiredExpr(In.NOTHING).expr(); + Stmts stmt = new Stmts(); + Expr cnd; + Stmts block; + cnd = RequiredExpr(In.NOTHING).single(); RequiredKeyword("then",In.NOTHING); block = RequiredBlock(); stmt.list.add( "if( Luan.checkBoolean(" ); @@ -636,7 +629,7 @@ stmt.list.add( ") ) {\n" ); stmt.list.addAll( block.list ); while( Keyword("elseif",In.NOTHING) ) { - cnd = RequiredExpr(In.NOTHING).expr(); + cnd = RequiredExpr(In.NOTHING).single(); RequiredKeyword("then",In.NOTHING); block = RequiredBlock(); stmt.list.add( "} else if( Luan.checkBoolean(" ); @@ -654,7 +647,7 @@ return parser.success( stmt ); } - private StmtString SetStmt() throws ParseException { + private Stmts SetStmt() throws ParseException { parser.begin(); List<Var> vars = new ArrayList<Var>(); Var v = SettableVar(); @@ -671,57 +664,61 @@ if( !parser.match( '=' ) ) return parser.failure(null); Spaces(In.NOTHING); - ExpString values = ExpStringList(In.NOTHING); + Expr values = ExpStringList(In.NOTHING); 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 { + private Stmts makeSetStmt(List<Var> vars,Expr values) throws ParseException { int n = vars.size(); if( n == 1 ) return vars.get(0).set(values); - StmtString stmt = new StmtString(); - stmt.list.add( "t = " ); + Stmts stmt = new Stmts(); + String varName = values.valType==Val.ARRAY ? "a" : "t"; + stmt.list.add( varName + " = " ); stmt.list.addAll( values.list ); stmt.list.add( ";\n" ); - ExpString t = new ExpString(values.isExpr,false); - t.list.add( "t" ); + Expr t = new Expr(values.valType,false); + t.list.add( varName ); + t = t.single(); stmt.list.addAll( vars.get(0).set(t).list ); for( int i=1; i<n; i++ ) { t.list.clear(); - t.list.add( "LuanImpl.pick(t,"+i+")" ); + t.list.add( "LuanImpl.pick(" + varName + ","+i+")" ); stmt.list.addAll( vars.get(i).set(t).list ); } return stmt; } - private StmtString makeLocalSetStmt(List<String> names,ExpString values) throws ParseException { + private Stmts makeLocalSetStmt(List<String> names,Expr values) throws ParseException { int n = names.size(); if( n == 1 ) - return addSymbol(names.get(0),values.expr()); - StmtString stmt = new StmtString(); - stmt.list.add( "t = " ); + return addSymbol(names.get(0),values.single()); + Stmts stmt = new Stmts(); + String varName = values.valType==Val.ARRAY ? "a" : "t"; + stmt.list.add( varName + " = " ); stmt.list.addAll( values.list ); stmt.list.add( ";\n" ); - ExpString t = new ExpString(values.isExpr,false); - t.list.add( "t" ); - stmt.list.addAll( addSymbol(names.get(0),t.expr()).list ); + Expr t = new Expr(values.valType,false); + t.list.add( varName ); + t = t.single(); + stmt.list.addAll( addSymbol(names.get(0),t).list ); for( int i=1; i<n; i++ ) { t.list.clear(); - t.list.add( "LuanImpl.pick(t,"+i+")" ); + t.list.add( "LuanImpl.pick(" + varName + ","+i+")" ); stmt.list.addAll( addSymbol(names.get(i),t).list ); } return stmt; } - private StmtString ExpressionsStmt() throws ParseException { + private Stmts ExpressionsStmt() throws ParseException { parser.begin(); - ExpString exp = ExprZ(In.NOTHING); + Expr exp = ExprZ(In.NOTHING); if( exp != null && exp.isStmt ) { - StmtString stmt = new StmtString(); - if( exp.isExpr ) { + Stmts stmt = new Stmts(); + if( exp.valType==Val.SINGLE ) { stmt.list.add( "LuanImpl.nop(" ); stmt.list.addAll( exp.list ); stmt.list.add( ")" ); @@ -742,24 +739,24 @@ return parser.success( var ); } - private ExpString RequiredExpr(In in) throws ParseException { + private Expr RequiredExpr(In in) throws ParseException { parser.begin(); return parser.success(required(ExprZ(in),"Bad expression")); } - private ExpString ExprZ(In in) throws ParseException { + private Expr ExprZ(In in) throws ParseException { return OrExpr(in); } - private ExpString OrExpr(In in) throws ParseException { + private Expr OrExpr(In in) throws ParseException { parser.begin(); - ExpString exp = AndExpr(in); + Expr exp = AndExpr(in); if( exp==null ) return parser.failure(null); while( Keyword("or",in) ) { - exp = exp.expr(); - ExpString exp2 = required(RelExpr(in)).expr(); - ExpString newExp = new ExpString(true,true); + exp = exp.single(); + Expr exp2 = required(RelExpr(in)).single(); + Expr newExp = new Expr(Val.SINGLE,true); newExp.list.add( "(LuanImpl.cnd(t = " ); newExp.list.addAll( exp.list ); newExp.list.add( ") ? t : (" ); @@ -770,15 +767,15 @@ return parser.success(exp); } - private ExpString AndExpr(In in) throws ParseException { + private Expr AndExpr(In in) throws ParseException { parser.begin(); - ExpString exp = RelExpr(in); + Expr exp = RelExpr(in); if( exp==null ) return parser.failure(null); while( Keyword("and",in) ) { - exp = exp.expr(); - ExpString exp2 = required(RelExpr(in)).expr(); - ExpString newExp = new ExpString(true,true); + exp = exp.single(); + Expr exp2 = required(RelExpr(in)).single(); + Expr newExp = new Expr(Val.SINGLE,true); newExp.list.add( "(LuanImpl.cnd(t = " ); newExp.list.addAll( exp.list ); newExp.list.add( ") ? (" ); @@ -789,17 +786,17 @@ return parser.success(exp); } - private ExpString RelExpr(In in) throws ParseException { + private Expr RelExpr(In in) throws ParseException { parser.begin(); - ExpString exp = ConcatExpr(in); + Expr exp = ConcatExpr(in); if( exp==null ) return parser.failure(null); while(true) { if( parser.match("==") ) { Spaces(in); - exp = exp.expr(); - ExpString exp2 = required(ConcatExpr(in)).expr(); - ExpString newExp = new ExpString(true,false); + exp = exp.single(); + Expr exp2 = required(ConcatExpr(in)).single(); + Expr newExp = new Expr(Val.SINGLE,false); newExp.list.add( "LuanImpl.eq(luan," ); newExp.list.addAll( exp.list ); newExp.list.add( "," ); @@ -808,9 +805,9 @@ exp = newExp; } else if( parser.match("~=") ) { Spaces(in); - exp = exp.expr(); - ExpString exp2 = required(ConcatExpr(in)).expr(); - ExpString newExp = new ExpString(true,false); + exp = exp.single(); + Expr exp2 = required(ConcatExpr(in)).single(); + Expr newExp = new Expr(Val.SINGLE,false); newExp.list.add( "!LuanImpl.eq(luan," ); newExp.list.addAll( exp.list ); newExp.list.add( "," ); @@ -819,9 +816,9 @@ exp = newExp; } else if( parser.match("<=") ) { Spaces(in); - exp = exp.expr(); - ExpString exp2 = required(ConcatExpr(in)).expr(); - ExpString newExp = new ExpString(true,false); + exp = exp.single(); + Expr exp2 = required(ConcatExpr(in)).single(); + Expr newExp = new Expr(Val.SINGLE,false); newExp.list.add( "LuanImpl.le(luan," ); newExp.list.addAll( exp.list ); newExp.list.add( "," ); @@ -830,9 +827,9 @@ exp = newExp; } else if( parser.match(">=") ) { Spaces(in); - exp = exp.expr(); - ExpString exp2 = required(ConcatExpr(in)).expr(); - ExpString newExp = new ExpString(true,false); + exp = exp.single(); + Expr exp2 = required(ConcatExpr(in)).single(); + Expr newExp = new Expr(Val.SINGLE,false); newExp.list.add( "LuanImpl.le(luan," ); newExp.list.addAll( exp2.list ); newExp.list.add( "," ); @@ -841,9 +838,9 @@ exp = newExp; } else if( parser.match("<") ) { Spaces(in); - exp = exp.expr(); - ExpString exp2 = required(ConcatExpr(in)).expr(); - ExpString newExp = new ExpString(true,false); + exp = exp.single(); + Expr exp2 = required(ConcatExpr(in)).single(); + Expr newExp = new Expr(Val.SINGLE,false); newExp.list.add( "LuanImpl.lt(luan," ); newExp.list.addAll( exp.list ); newExp.list.add( "," ); @@ -852,9 +849,9 @@ exp = newExp; } else if( parser.match(">") ) { Spaces(in); - exp = exp.expr(); - ExpString exp2 = required(ConcatExpr(in)).expr(); - ExpString newExp = new ExpString(true,false); + exp = exp.single(); + Expr exp2 = required(ConcatExpr(in)).single(); + Expr newExp = new Expr(Val.SINGLE,false); newExp.list.add( "LuanImpl.lt(luan," ); newExp.list.addAll( exp2.list ); newExp.list.add( "," ); @@ -867,16 +864,16 @@ return parser.success(exp); } - private ExpString ConcatExpr(In in) throws ParseException { + private Expr ConcatExpr(In in) throws ParseException { parser.begin(); - ExpString exp = SumExpr(in); + Expr exp = SumExpr(in); if( exp==null ) return parser.failure(null); if( parser.match("..") ) { Spaces(in); - exp = exp.expr(); - ExpString exp2 = required(ConcatExpr(in)).expr(); - ExpString newExp = new ExpString(true,false); + exp = exp.single(); + Expr exp2 = required(ConcatExpr(in)).single(); + Expr newExp = new Expr(Val.SINGLE,false); newExp.list.add( "LuanImpl.concat(luan," ); newExp.list.addAll( exp.list ); newExp.list.add( "," ); @@ -887,17 +884,17 @@ return parser.success(exp); } - private ExpString SumExpr(In in) throws ParseException { + private Expr SumExpr(In in) throws ParseException { parser.begin(); - ExpString exp = TermExpr(in); + Expr exp = TermExpr(in); if( exp==null ) return parser.failure(null); while(true) { if( parser.match('+') ) { Spaces(in); - exp = exp.expr(); - ExpString exp2 = required(TermExpr(in)).expr(); - ExpString newExp = new ExpString(true,false); + exp = exp.single(); + Expr exp2 = required(TermExpr(in)).single(); + Expr newExp = new Expr(Val.SINGLE,false); newExp.list.add( "LuanImpl.add(luan," ); newExp.list.addAll( exp.list ); newExp.list.add( "," ); @@ -906,9 +903,9 @@ exp = newExp; } else if( Minus() ) { Spaces(in); - exp = exp.expr(); - ExpString exp2 = required(TermExpr(in)).expr(); - ExpString newExp = new ExpString(true,false); + exp = exp.single(); + Expr exp2 = required(TermExpr(in)).single(); + Expr newExp = new Expr(Val.SINGLE,false); newExp.list.add( "LuanImpl.sub(luan," ); newExp.list.addAll( exp.list ); newExp.list.add( "," ); @@ -926,17 +923,17 @@ return parser.match('-') && !parser.match('-') ? parser.success() : parser.failure(); } - private ExpString TermExpr(In in) throws ParseException { + private Expr TermExpr(In in) throws ParseException { parser.begin(); - ExpString exp = UnaryExpr(in); + Expr exp = UnaryExpr(in); if( exp==null ) return parser.failure(null); while(true) { if( parser.match('*') ) { Spaces(in); - exp = exp.expr(); - ExpString exp2 = required(UnaryExpr(in)).expr(); - ExpString newExp = new ExpString(true,false); + exp = exp.single(); + Expr exp2 = required(UnaryExpr(in)).single(); + Expr newExp = new Expr(Val.SINGLE,false); newExp.list.add( "LuanImpl.mul(luan," ); newExp.list.addAll( exp.list ); newExp.list.add( "," ); @@ -945,9 +942,9 @@ exp = newExp; } else if( parser.match('/') ) { Spaces(in); - exp = exp.expr(); - ExpString exp2 = required(UnaryExpr(in)).expr(); - ExpString newExp = new ExpString(true,false); + exp = exp.single(); + Expr exp2 = required(UnaryExpr(in)).single(); + Expr newExp = new Expr(Val.SINGLE,false); newExp.list.add( "LuanImpl.div(luan," ); newExp.list.addAll( exp.list ); newExp.list.add( "," ); @@ -956,9 +953,9 @@ exp = newExp; } else if( Mod() ) { Spaces(in); - exp = exp.expr(); - ExpString exp2 = required(UnaryExpr(in)).expr(); - ExpString newExp = new ExpString(true,false); + exp = exp.single(); + Expr exp2 = required(UnaryExpr(in)).single(); + Expr newExp = new Expr(Val.SINGLE,false); newExp.list.add( "LuanImpl.mod(luan," ); newExp.list.addAll( exp.list ); newExp.list.add( "," ); @@ -976,12 +973,12 @@ return parser.match('%') && !parser.match('>') ? parser.success() : parser.failure(); } - private ExpString UnaryExpr(In in) throws ParseException { + private Expr UnaryExpr(In in) throws ParseException { parser.begin(); if( parser.match('#') ) { Spaces(in); - ExpString exp = required(UnaryExpr(in)).expr(); - ExpString newExp = new ExpString(true,false); + Expr exp = required(UnaryExpr(in)).single(); + Expr newExp = new Expr(Val.SINGLE,false); newExp.list.add( "LuanImpl.len(luan," ); newExp.list.addAll( exp.list ); newExp.list.add( ")" ); @@ -989,8 +986,8 @@ } if( Minus() ) { Spaces(in); - ExpString exp = required(UnaryExpr(in)).expr(); - ExpString newExp = new ExpString(true,false); + Expr exp = required(UnaryExpr(in)).single(); + Expr newExp = new Expr(Val.SINGLE,false); newExp.list.add( "LuanImpl.unm(luan," ); newExp.list.addAll( exp.list ); newExp.list.add( ")" ); @@ -998,41 +995,41 @@ } if( Keyword("not",in) ) { Spaces(in); - ExpString exp = required(UnaryExpr(in)).expr(); - ExpString newExp = new ExpString(true,false); + Expr exp = required(UnaryExpr(in)).single(); + Expr newExp = new Expr(Val.SINGLE,false); newExp.list.add( "!Luan.checkBoolean(" ); newExp.list.addAll( exp.list ); newExp.list.add( ")" ); return parser.success(newExp); } - ExpString exp = PowExpr(in); + Expr exp = PowExpr(in); if( exp==null ) return parser.failure(null); return parser.success(exp); } - private ExpString PowExpr(In in) throws ParseException { + private Expr PowExpr(In in) throws ParseException { parser.begin(); - ExpString exp1 = SingleExpr(in); + Expr exp1 = SingleExpr(in); if( exp1==null ) return parser.failure(null); if( parser.match('^') ) { Spaces(in); - ExpString exp2 = required(PowExpr(in)); - ExpString newExp = new ExpString(true,false); + Expr exp2 = required(PowExpr(in)); + Expr newExp = new Expr(Val.SINGLE,false); newExp.list.add( "LuanImpl.pow(luan," ); - newExp.list.addAll( exp1.expr().list ); + newExp.list.addAll( exp1.single().list ); newExp.list.add( "," ); - newExp.list.addAll( exp2.expr().list ); + newExp.list.addAll( exp2.single().list ); newExp.list.add( ")" ); exp1 = newExp; } return parser.success(exp1); } - private ExpString SingleExpr(In in) throws ParseException { + private Expr SingleExpr(In in) throws ParseException { parser.begin(); - ExpString exp = FunctionExpr(in); + Expr exp = FunctionExpr(in); if( exp != null ) return parser.success(exp); exp = VarExp(in); @@ -1044,22 +1041,22 @@ return parser.failure(null); } - private ExpString FunctionExpr(In in) throws ParseException { + private Expr FunctionExpr(In in) throws ParseException { if( !Keyword("function",in) ) return null; return RequiredFunction(in); } - private ExpString RequiredFunction(In in) throws ParseException { + private Expr RequiredFunction(In in) throws ParseException { int start = parser.begin(); RequiredMatch('('); In inParens = in.parens(); Spaces(inParens); frame = new Frame(frame); - StmtString stmt = new StmtString(); + Stmts stmt = new Stmts(); List<String> names = NameList(in); if( names != null ) { - ExpString args = new ExpString(false,false); + Expr args = new Expr(Val.ARRAY,false); args.list.add( "args" ); stmt.list.addAll( makeLocalSetStmt(names,args).list ); if( parser.match(',') ) { @@ -1077,45 +1074,45 @@ } RequiredMatch(')'); Spaces(in); - StmtString block = RequiredBlock(); + Stmts block = RequiredBlock(); stmt.list.addAll( block.list ); stmt.hasReturn = block.hasReturn; RequiredKeyword("end",in); - ExpString fnDef = newFnExpStr(start,stmt); + Expr fnDef = newFnExpStr(start,stmt); frame = frame.parent; return parser.success(fnDef); } - private ExpString VarArgs(In in) throws ParseException { + private Expr VarArgs(In in) throws ParseException { parser.begin(); if( !frame.isVarArg || !parser.match("...") ) return parser.failure(null); Spaces(in); - ExpString exp = new ExpString(false,false); + Expr exp = new Expr(Val.ARRAY,false); exp.list.add("varArgs"); return parser.success(exp); } - private ExpString TableExpr(In in) throws ParseException { + private Expr TableExpr(In in) throws ParseException { parser.begin(); if( !parser.match('{') ) return parser.failure(null); Spaces(In.NOTHING); - List<ExpString> builder = new ArrayList<ExpString>(); + List<Expr> builder = new ArrayList<Expr>(); Field(builder); while( FieldSep() ) { Spaces(In.NOTHING); Field(builder); } - ExpString exp = TemplateExpressions(In.NOTHING); + Expr exp = TemplateExpressions(In.NOTHING); if( exp != null ) builder.add(exp); if( !parser.match('}') ) throw parser.exception("Expected table element or '}'"); Spaces(in); - exp = new ExpString(true,false); + exp = new Expr(Val.SINGLE,false); exp.list.add( "LuanImpl.table(" ); - exp.list.addAll( expString(builder).list ); + exp.list.addAll( expString(builder).array().list ); exp.list.add( ")" ); return parser.success( exp ); } @@ -1124,15 +1121,15 @@ return parser.anyOf(",;") || EndOfLine(); } - private boolean Field(List<ExpString> builder) throws ParseException { + private boolean Field(List<Expr> builder) throws ParseException { parser.begin(); - ExpString exp = SubExpr(In.NOTHING); + Expr exp = SubExpr(In.NOTHING); if( exp==null ) exp = NameExpr(In.NOTHING); if( exp!=null && parser.match('=') ) { Spaces(In.NOTHING); - ExpString val = RequiredExpr(In.NOTHING).expr(); - ExpString newExp = new ExpString(true,false); + Expr val = RequiredExpr(In.NOTHING).single(); + Expr newExp = new Expr(Val.SINGLE,false); newExp.list.add( "new TableField(" ); newExp.list.addAll( exp.list ); newExp.list.add( "," ); @@ -1142,7 +1139,7 @@ return parser.success(); } parser.rollback(); - ExpString exprs = ExprZ(In.NOTHING); + Expr exprs = ExprZ(In.NOTHING); if( exprs != null ) { builder.add(exprs); return parser.success(); @@ -1150,7 +1147,7 @@ return parser.failure(); } - private ExpString VarExp(In in) throws ParseException { + private Expr VarExp(In in) throws ParseException { Var var = VarZ(in); return var==null ? null : var.exp(); } @@ -1171,7 +1168,7 @@ if( parser.match('(') ) { In inParens = in.parens(); Spaces(inParens); - ExpString exp = RequiredExpr(inParens).expr(); + Expr exp = RequiredExpr(inParens).single(); RequiredMatch(')'); Spaces(in); return exprVar(exp); @@ -1179,7 +1176,7 @@ String name = Name(in); if( name != null ) return nameVar(name); - ExpString exp; + Expr exp; exp = TableExpr(in); if( exp != null ) return exprVar(exp); @@ -1189,9 +1186,9 @@ return null; } - private Var Var2(In in,ExpString exp1) throws ParseException { + private Var Var2(In in,Expr exp1) throws ParseException { parser.begin(); - ExpString exp2 = SubExpr(in); + Expr exp2 = SubExpr(in); if( exp2 != null ) return parser.success(indexVar(exp1,exp2)); if( parser.match('.') ) { @@ -1201,20 +1198,20 @@ return parser.success(indexVar(exp1,exp2)); return parser.failure(null); } - ExpString fnCall = Args( in, exp1, new ArrayList<ExpString>() ); + Expr fnCall = Args( in, exp1, new ArrayList<Expr>() ); if( fnCall != null ) return parser.success(exprVar(fnCall)); return parser.failure(null); } private interface Var { - public ExpString exp() throws ParseException; + public Expr exp() throws ParseException; // public Settable settable() throws ParseException; public boolean isSettable(); - public StmtString set(ExpString val) throws ParseException; + public Stmts set(Expr val) throws ParseException; } - private ExpString env() { + private Expr env() { Sym sym = getSym("_ENV"); if( sym != null ) return sym.exp(); @@ -1224,11 +1221,11 @@ private Var nameVar(final String name) { return new Var() { - public ExpString exp() throws ParseException { + public Expr exp() throws ParseException { Sym sym = getSym(name); if( sym != null ) return sym.exp(); - ExpString envExpr = env(); + Expr envExpr = env(); if( envExpr != null ) return indexExpStr( envExpr, constExpStr(name) ); parser.failure(null); @@ -1238,32 +1235,18 @@ public boolean isSettable() { return true; } -/* - private Settable settable() throws ParseException { - int index = stackIndex(name); - if( index != -1 ) - return new SetLocalVar(index); - index = upValueIndex(name); - if( index != -1 ) - return new SetUpVar(index); - Expr envExpr = env(); - if( envExpr != null ) - return new SetTableEntry( envExpr, new ConstExpr(name) ); - parser.failure(null); - throw parser.exception("name '"+name+"' not defined"); - } -*/ - public StmtString set(ExpString val) throws ParseException { + + public Stmts set(Expr val) throws ParseException { Sym sym = getSym(name); if( sym != null ) { - StmtString stmt = new StmtString(); + Stmts stmt = new Stmts(); stmt.list.addAll( sym.exp().list ); stmt.list.add( " = " ); - stmt.list.addAll( val.expr().list ); + stmt.list.addAll( val.single().list ); stmt.list.add( ";\n" ); return stmt; } - ExpString envExpr = env(); + Expr envExpr = env(); if( envExpr != null ) return indexVar( envExpr, constExpStr(name) ).set(val); throw new RuntimeException(); @@ -1271,10 +1254,10 @@ }; } - private Var exprVar(final ExpString expr) { + private Var exprVar(final Expr expr) { return new Var() { - public ExpString exp() { + public Expr exp() { return expr; } @@ -1282,49 +1265,45 @@ return false; } - public StmtString set(ExpString val) { + public Stmts set(Expr val) { throw new RuntimeException(); } }; } - private Var indexVar(final ExpString table,final ExpString key) { + private Var indexVar(final Expr table,final Expr key) { return new Var() { - public ExpString exp() { + public Expr exp() { return indexExpStr( table, key ); } public boolean isSettable() { return true; } -/* - public Settable settable() { - return new SetTableEntry(expr(LuanParser.exp(table)),expr(LuanParser.exp(key))); - } -*/ - public StmtString set(ExpString val) { - StmtString stmt = new StmtString(); + + public Stmts set(Expr val) { + Stmts stmt = new Stmts(); stmt.list.add( "LuanImpl.put(luan," ); - stmt.list.addAll( table.expr().list ); + stmt.list.addAll( table.single().list ); stmt.list.add( "," ); - stmt.list.addAll( key.expr().list ); + stmt.list.addAll( key.single().list ); stmt.list.add( "," ); - stmt.list.addAll( val.expr().list ); + stmt.list.addAll( val.single().list ); stmt.list.add( ");\n" ); return stmt; } }; } - private ExpString Args(In in,ExpString fn,List<ExpString> builder) throws ParseException { + private Expr Args(In in,Expr fn,List<Expr> builder) throws ParseException { parser.begin(); return args(in,builder) ? parser.success( callExpStr( fn, expString(builder) ) ) - : parser.failure((ExpString)null); + : parser.failure((Expr)null); } - private boolean args(In in,List<ExpString> builder) throws ParseException { + private boolean args(In in,List<Expr> builder) throws ParseException { parser.begin(); if( parser.match('(') ) { In inParens = in.parens(); @@ -1335,7 +1314,7 @@ Spaces(in); return parser.success(); } - ExpString exp = TableExpr(in); + Expr exp = TableExpr(in); if( exp != null ) { builder.add(exp); return parser.success(); @@ -1355,14 +1334,14 @@ return parser.failure(); } - private ExpString ExpStringList(In in) throws ParseException { - List<ExpString> builder = new ArrayList<ExpString>(); + private Expr ExpStringList(In in) throws ParseException { + List<Expr> builder = new ArrayList<Expr>(); return ExpList(in,builder) ? expString(builder) : null; } - private boolean ExpList(In in,List<ExpString> builder) throws ParseException { + private boolean ExpList(In in,List<Expr> builder) throws ParseException { parser.begin(); - ExpString exp = TemplateExpressions(in); + Expr exp = TemplateExpressions(in); if( exp != null ) { builder.add(exp); return parser.success(); @@ -1383,18 +1362,18 @@ return parser.success(); } - private ExpString SubExpr(In in) throws ParseException { + private Expr SubExpr(In in) throws ParseException { parser.begin(); if( !parser.match('[') || parser.test("[") || parser.test("=") ) return parser.failure(null); Spaces(In.NOTHING); - ExpString exp = RequiredExpr(In.NOTHING).expr(); + Expr exp = RequiredExpr(In.NOTHING).single(); RequiredMatch(']'); Spaces(in); return parser.success(exp); } - private ExpString NameExpr(In in) throws ParseException { + private Expr NameExpr(In in) throws ParseException { parser.begin(); String name = Name(in); if( name==null ) @@ -1478,16 +1457,16 @@ "while" )); - private ExpString Literal(In in) throws ParseException { + private Expr Literal(In in) throws ParseException { parser.begin(); if( NilLiteral(in) ) { - ExpString exp = new ExpString(true,false); + Expr exp = new Expr(Val.SINGLE,false); exp.list.add( "null" ); return parser.success(exp); } Boolean b = BooleanLiteral(in); if( b != null ) { - ExpString exp = new ExpString(true,false); + Expr exp = new Expr(Val.SINGLE,false); exp.list.add( b.toString() ); return parser.success(exp); } @@ -1496,7 +1475,7 @@ String s = n.toString(); if( n instanceof Long ) s += "L"; - ExpString exp = new ExpString(true,false); + Expr exp = new Expr(Val.SINGLE,false); exp.list.add( s ); return parser.success(exp); } @@ -1506,7 +1485,7 @@ return parser.failure(null); } - private ExpString constExpStr(String s) { + private Expr constExpStr(String s) { s = s .replace("\\","\\\\") .replace("\"","\\\"") @@ -1515,7 +1494,7 @@ .replace("\t","\\t") .replace("\b","\\b") ; - ExpString exp = new ExpString(true,false); + Expr exp = new Expr(Val.SINGLE,false); exp.list.add( "\""+s+"\"" ); return exp; } @@ -1769,37 +1748,48 @@ private static int classCounter = 0; - private class ExpString { + private enum Val { SINGLE, ARRAY } + + private class Expr { final List list = new ArrayList(); - final boolean isExpr; + final Val valType; final boolean isStmt; -/* - ExpString(Expressions exp) { - if( exp==null ) throw new NullPointerException(); - int i = LuanImpl.addObj(exp); - list.add( "((Expressions)LuanImpl.getObj(" + i + ")).eval(luan)" ); - isExpr = exp instanceof Expr; - isStmt = exp instanceof StmtExp; - } -*/ - ExpString(boolean isExpr,boolean isStmt) { - this.isExpr = isExpr; + + Expr(Val valType,boolean isStmt) { + this.valType = valType; this.isStmt = isStmt; } - ExpString expr() { - if( isExpr ) + Expr single() { + if( valType==Val.SINGLE ) return this; - ExpString exp = new ExpString(true,isStmt); - exp.list.add( "Luan.first(" ); + Expr exp = new Expr(Val.SINGLE,isStmt); + exp.list.add( valType==Val.ARRAY ? "LuanImpl.first(" : "Luan.first(" ); exp.list.addAll( list ); exp.list.add( ")" ); return exp; } + + Expr array() { + if( valType==Val.ARRAY ) + return this; + Expr exp = new Expr(Val.ARRAY,isStmt); + if( valType==Val.SINGLE ) { + exp.list.add( "new Object[]{" ); + exp.list.addAll( list ); + exp.list.add( "}" ); + } else { + exp.list.add( "Luan.array(" ); + exp.list.addAll( list ); + exp.list.add( ")" ); + } + return exp; + } + } - private ExpString expString(List<ExpString> list) { - ExpString exp = new ExpString(false,false); + private Expr expString(List<Expr> list) { + Expr exp = new Expr(Val.ARRAY,false); switch(list.size()) { case 0: exp.list.add("LuanFunction.NOTHING"); @@ -1810,11 +1800,11 @@ int lastI = list.size() - 1; exp.list.add( "new Object[]{" ); for( int i=0; i<lastI; i++ ) { - exp.list.addAll( list.get(i).expr().list ); + exp.list.addAll( list.get(i).single().list ); exp.list.add( "," ); } - ExpString last = list.get(lastI); - if( last.isExpr ) { + Expr last = list.get(lastI); + if( last.valType==Val.SINGLE ) { exp.list.addAll( last.list ); exp.list.add( "}" ); } else { @@ -1828,7 +1818,7 @@ } } - private static class StmtString { + private static class Stmts { final List list = new ArrayList(); boolean hasReturn = false; } @@ -1837,14 +1827,14 @@ StringBuilder sb = new StringBuilder(); for( Object o : list ) { if( o instanceof List ) throw new RuntimeException(); - if( o instanceof ExpString ) throw new RuntimeException(); - if( o instanceof StmtString ) throw new RuntimeException(); + if( o instanceof Expr ) throw new RuntimeException(); + if( o instanceof Stmts ) throw new RuntimeException(); sb.append( o.toString() ); } return sb.toString(); } - private Class toFnClass(StmtString stmt,List<UpSym> upValueSymbols) { + private Class toFnClass(Stmts stmt,List<UpSym> upValueSymbols) { String code = concat(stmt.list); //System.out.println("code:\n"+code); @@ -1866,6 +1856,7 @@ +"\n" +" @Override public Object doCall(LuanState luan,Object[] args) throws LuanException {\n" +" Object t;\n" + +" Object[] a;\n" +" " + code +" }\n" +"}\n" @@ -1879,8 +1870,8 @@ } } - private ExpString toFnExpStr(StmtString stmt,List<UpSym> upValueSymbols) { - ExpString exp = new ExpString(true,false); + private Expr toFnExpStr(Stmts stmt,List<UpSym> upValueSymbols) { + Expr exp = new Expr(Val.SINGLE,false); exp.list.add( "" +"\n" +"new Closure("+upValueSymbols.size()+",java) {\n" @@ -1889,6 +1880,7 @@ +"}\n" +" @Override public Object doCall(LuanState luan,Object[] args) throws LuanException {\n" +" Object t;\n" + +" Object[] a;\n" +" " ); exp.list.addAll( stmt.list ); @@ -1907,11 +1899,4 @@ 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 + "))"; - } -*/ }