Mercurial Hosting > luan
changeset 666:2f449ccf54d2
use lists to assemble source
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Thu, 07 Apr 2016 23:36:56 -0600 |
parents | 41f8fdbc3a0a |
children | 08966099aa6d |
files | core/src/luan/impl/LuanParser.java |
diffstat | 1 files changed, 334 insertions(+), 165 deletions(-) [+] |
line wrap: on
line diff
--- a/core/src/luan/impl/LuanParser.java Thu Apr 07 17:06:22 2016 -0600 +++ b/core/src/luan/impl/LuanParser.java Thu Apr 07 23:36:56 2016 -0600 @@ -176,13 +176,13 @@ private FnDef newFnDef(int start,StmtString stmt) { if( !stmt.hasReturn ) - stmt = new StmtString( stmt.code + "return LuanFunction.NOTHING;\n" ); + stmt.list.add( "return LuanFunction.NOTHING;\n" ); return toFnDef( stmt, frame.stackSize, symbolsSize(), frame.isVarArg, frame.upValueGetters.toArray(NO_UP_VALUE_GETTERS) ); } private ExpString newFnExpStr(int start,StmtString stmt) { if( !stmt.hasReturn ) - stmt = new StmtString( stmt.code + "return LuanFunction.NOTHING;\n" ); + stmt.list.add( "return LuanFunction.NOTHING;\n" ); return toFnExpStr( stmt, frame.stackSize, symbolsSize(), frame.isVarArg, frame.upValueGetters.toArray(NO_UP_VALUE_GETTERS) ); } @@ -191,8 +191,10 @@ int start = parser.begin(); ExpString expr = ExprZ(In.NOTHING); if( expr != null && parser.endOfInput() ) { - String code = "return " + expr.code + ";\n"; - StmtString stmt = new StmtString(code); + StmtString stmt = new StmtString(); + stmt.list.add( "return " ); + stmt.list.addAll( expr.list ); + stmt.list.add( ";\n" ); stmt.hasReturn = true; return parser.success(newFnDef(start,stmt)); } @@ -210,7 +212,7 @@ } private StmtString RequiredBlock() throws ParseException { - StringBuilder stmts = new StringBuilder(); + StmtString stmts = new StmtString(); int stackStart = symbolsSize(); boolean isReturn = Stmt(stmts); while( !isReturn && StmtSep(stmts) ) { @@ -221,23 +223,22 @@ Spaces(In.NOTHING); int stackEnd = symbolsSize(); popSymbols( stackEnd - stackStart ); - if( stmts.length() == 0 ) - return EMPTY_STMT; + if( stmts.list.isEmpty() ) + return stmts; String code = stmts.toString(); - if( stackStart < stackEnd ) - code = "" - +"try {\n" - + code + if( stackStart < stackEnd ) { + stmts.list.add( 0, "try {\n" ); + stmts.list.add( "" +"} finally {\n" +" luan.stackClear("+stackStart+","+stackEnd+");\n" +"}\n" - ; - StmtString stmt = new StmtString(code); - stmt.hasReturn = isReturn; - return stmt; + ); + } + stmts.hasReturn = isReturn; + return stmts; } - private boolean StmtSep(StringBuilder stmts) throws ParseException { + private boolean StmtSep(StmtString stmts) throws ParseException { parser.begin(); if( parser.match( ';' ) ) return parser.success(); @@ -247,7 +248,7 @@ // parser.rollback(); StmtString stmt = TemplateStmt(); if( stmt != null ) { - stmts.append(stmt.code); + stmts.list.addAll(stmt.list); return parser.success(); } } @@ -258,12 +259,12 @@ return parser.match( "\r\n" ) || parser.match( '\r' ) || parser.match( '\n' ); } - private boolean Stmt(StringBuilder stmts) throws ParseException { + private boolean Stmt(StmtString stmts) throws ParseException { if( LocalStmt(stmts) ) return false; StmtString stmt; if( (stmt=ReturnStmt()) != null ) { - stmts.append(stmt.code); + stmts.list.addAll(stmt.list); return true; } if( (stmt=FunctionStmt()) != null @@ -277,31 +278,44 @@ || (stmt=SetStmt()) != null || (stmt=ExpressionsStmt()) != null ) { - stmts.append(stmt.code); + stmts.list.addAll(stmt.list); } return false; } private ExpString indexExpStr(ExpString exp1,ExpString exp2) { - String code = "luan.index(" + exp1.expr().code + "," + exp2.expr().code + ")"; - return new ExpString(code,true,false); + ExpString exp = new ExpString(true,false); + exp.list.add( "luan.index(" ); + exp.list.addAll( exp1.expr().list ); + exp.list.add( "," ); + exp.list.addAll( exp2.expr().list ); + exp.list.add( ")" ); + return exp; } private ExpString callExpStr(ExpString fn,ExpString args) { - String code = "Luan.checkFunction(" + fn.expr().code + ").call(luan,Luan.array(" + args.code + "))"; - return new ExpString(code,false,true); + ExpString exp = new ExpString(false,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( "))" ); + return exp; } private StmtString TemplateStmt() throws ParseException { ExpString exprs = TemplateExpressions(In.NOTHING); if( exprs == null ) return null; - String code = "PackageLuan.require(luan,\"luan:Io\")"; - ExpString requireCall = new ExpString(code,true,false); + ExpString requireCall = new ExpString(true,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 ); - return new StmtString( writeCall.code + ";\n" ); + StmtString stmt = new StmtString(); + stmt.list.addAll( writeCall.list ); + stmt.list.add( ";\n" ); + return stmt; } private ExpString TemplateExpressions(In in) throws ParseException { @@ -340,8 +354,14 @@ if( !Keyword("return",In.NOTHING) ) return parser.failure(null); ExpString exprs = ExpStringList(In.NOTHING); - String code = "return " + (exprs!=null ? exprs.code : "LuanFunction.NOTHING") + ";\n"; - return parser.success( new StmtString(code) ); + StmtString stmt = new StmtString(); + stmt.list.add( "return " ); + if( exprs != null ) + stmt.list.addAll( exprs.list ); + else + stmt.list.add( "LuanFunction.NOTHING" ); + stmt.list.add( ";\n" ); + return parser.success( stmt ); } private StmtString FunctionStmt() throws ParseException { @@ -371,8 +391,12 @@ addSymbol( name ); ExpString fnDef = RequiredFunction(In.NOTHING); Settable s = new SetLocalVar(symbolsSize()-1); - String code = new SettableString(s).code + ".set(luan," + fnDef.code + ");\n"; - return parser.success( new StmtString(code) ); + 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 ); } private StmtString BreakStmt() throws ParseException { @@ -381,7 +405,9 @@ return parser.failure(null); if( frame.loops <= 0 ) throw parser.exception("'break' outside of loop"); - return parser.success( new StmtString("break;\n") ); + StmtString stmt = new StmtString(); + stmt.list.add( "break;\n" ); + return parser.success( stmt ); } int forCounter = 0; @@ -408,22 +434,30 @@ StmtString loop = RequiredLoopBlock(); RequiredKeyword("end",In.NOTHING); String fnVar = "fn"+ ++forCounter; - String code = "" + StmtString stmt = new StmtString(); + stmt.list.add( "" +"try {\n" - +"LuanFunction "+fnVar+" = Luan.checkFunction(" + expr.code + ");\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( " + firstVar.code + "==null ) break;\n" - + loop.code + +"if( " + ); + stmt.list.addAll( firstVar.list ); + stmt.list.add( "==null ) break;\n" ); + stmt.list.addAll( loop.list ); + stmt.list.add( "" +"}" +"} finally {\n" +"luan.stackClear("+stackStart+","+symbolsSize()+");\n" +"}\n" - ; - StmtString stmt = new StmtString(code); + ); popSymbols( symbolsSize() - stackStart ); return parser.success(stmt); } @@ -437,7 +471,7 @@ return parser.success(stmt); } - private boolean LocalStmt(StringBuilder stmts) throws ParseException { + private boolean LocalStmt(StmtString stmts) throws ParseException { parser.begin(); if( !Keyword("local",In.NOTHING) ) return parser.failure(); @@ -458,8 +492,9 @@ vars[i] = new SetLocalVar(stackStart+i); } String varsStr = varsToString(vars); - String code = "LuanImpl.set(luan," + varsStr + "," + values.code + ");\n"; - stmts.append(code); + stmts.list.add( "LuanImpl.set(luan," + varsStr + "," ); + stmts.list.addAll( values.list ); + stmts.list.add( ");\n" ); } addSymbols(names); return parser.success(); @@ -504,12 +539,13 @@ RequiredKeyword("do",In.NOTHING); StmtString loop = RequiredLoopBlock(); RequiredKeyword("end",In.NOTHING); - String code = "" - +"while( Luan.checkBoolean(" + cnd.code + ") ) {\n" - + loop.code - +"}\n" - ; - return parser.success( new StmtString(code) ); + StmtString stmt = new StmtString(); + stmt.list.add( "while( Luan.checkBoolean(" ); + stmt.list.addAll( cnd.list ); + stmt.list.add( ") ) {\n" ); + stmt.list.addAll( loop.list ); + stmt.list.add( "}\n" ); + return parser.success( stmt ); } private StmtString RepeatStmt() throws ParseException { @@ -519,12 +555,13 @@ StmtString loop =RequiredLoopBlock(); RequiredKeyword("until",In.NOTHING); ExpString cnd = RequiredExpr(In.NOTHING).expr(); - String code = "" - +"do {\n" - + loop.code - +"} while( !Luan.checkBoolean(" + cnd.code + ") );\n" - ; - return parser.success( new StmtString(code) ); + StmtString stmt = new StmtString(); + stmt.list.add( "do {\n" ); + stmt.list.addAll( loop.list ); + stmt.list.add( "} while( !Luan.checkBoolean(" ); + stmt.list.addAll( cnd.list ); + stmt.list.add( ") );\n" ); + return parser.success( stmt ); } private StmtString RequiredLoopBlock() throws ParseException { @@ -538,26 +575,33 @@ parser.begin(); if( !Keyword("if",In.NOTHING) ) return parser.failure(null); - StringBuilder sb = new StringBuilder(); + StmtString stmt = new StmtString(); ExpString cnd; StmtString block; cnd = RequiredExpr(In.NOTHING).expr(); RequiredKeyword("then",In.NOTHING); block = RequiredBlock(); - sb.append( "if( Luan.checkBoolean(" ).append( cnd.code ).append( ") ) {\n" ).append( block.code ); + stmt.list.add( "if( Luan.checkBoolean(" ); + stmt.list.addAll( cnd.list ); + stmt.list.add( ") ) {\n" ); + stmt.list.addAll( block.list ); while( Keyword("elseif",In.NOTHING) ) { cnd = RequiredExpr(In.NOTHING).expr(); RequiredKeyword("then",In.NOTHING); block = RequiredBlock(); - sb.append( "} else if( Luan.checkBoolean(" ).append( cnd.code ).append( ") ) {\n" ).append( block.code ); + stmt.list.add( "} else if( Luan.checkBoolean(" ); + stmt.list.addAll( cnd.list ); + stmt.list.add( ") ) {\n" ); + stmt.list.addAll( block.list ); } if( Keyword("else",In.NOTHING) ) { block = RequiredBlock(); - sb.append( "} else {\n" ).append( block.code ); + stmt.list.add( "} else {\n" ); + stmt.list.addAll( block.list ); } RequiredKeyword("end",In.NOTHING); - sb.append( "}\n" ); - return parser.success( new StmtString(sb.toString()) ); + stmt.list.add( "}\n" ); + return parser.success( stmt ); } private StmtString SetStmt() throws ParseException { @@ -584,21 +628,26 @@ int n = vars.size(); if( n == 1 ) return parser.success( vars.get(0).set(values) ); - StringBuilder sb = new StringBuilder(); - sb.append( "t = " + values.code + ";\n" ); - ExpString t = new ExpString("t",true,false); - sb.append( vars.get(0).set(new ExpString("t",true,false)).code ); + StmtString stmt = new StmtString(); + stmt.list.add( "t = " ); + stmt.list.addAll( values.list ); + stmt.list.add( ";\n" ); + ExpString t = new ExpString(true,false); + t.list.add( "t" ); + stmt.list.addAll( vars.get(0).set(t).list ); for( int i=1; i<n; i++ ) { - sb.append( vars.get(i).set(new ExpString("LuanImpl.pick(t,"+i+")",true,false)).code ); + t.list.clear(); + t.list.add( "LuanImpl.pick(t,"+i+")" ); + stmt.list.addAll( vars.get(i).set(t).list ); } - return parser.success( new StmtString(sb.toString()) ); + return parser.success( stmt ); } private static String varsToString(Settable[] vars) { StringBuilder sb = new StringBuilder(); sb.append( "new Settable[]{" ); for( Settable v : vars ) { - sb.append( new SettableString(v).code ).append( ',' ); + sb.append( settableToString(v) ).append( ',' ); } sb.append( "}" ); return sb.toString(); @@ -608,11 +657,16 @@ parser.begin(); ExpString exp = ExprZ(In.NOTHING); if( exp != null && exp.isStmt ) { - String code = exp.code; - if( exp.isExpr ) - code = "LuanImpl.nop(" + code + ")"; - code += ";\n"; - return parser.success( new StmtString(code) ); + StmtString stmt = new StmtString(); + if( exp.isExpr ) { + stmt.list.add( "LuanImpl.nop(" ); + stmt.list.addAll( exp.list ); + stmt.list.add( ")" ); + } else { + stmt.list.addAll( exp.list ); + } + stmt.list.add( ";\n" ); + return parser.success( stmt ); } return parser.failure(null); } @@ -642,8 +696,13 @@ while( Keyword("or",in) ) { exp = exp.expr(); ExpString exp2 = required(RelExpr(in)).expr(); - String code = "(LuanImpl.cnd(t = " + exp.code + ") ? t : (" + exp2.code + "))"; - exp = new ExpString(code,true,true); + ExpString newExp = new ExpString(true,true); + newExp.list.add( "(LuanImpl.cnd(t = " ); + newExp.list.addAll( exp.list ); + newExp.list.add( ") ? t : (" ); + newExp.list.addAll( exp2.list ); + newExp.list.add( "))" ); + exp = newExp; } return parser.success(exp); } @@ -656,8 +715,13 @@ while( Keyword("and",in) ) { exp = exp.expr(); ExpString exp2 = required(RelExpr(in)).expr(); - String code = "(LuanImpl.cnd(t = " + exp.code + ") ? (" + exp2.code + ") : t)"; - exp = new ExpString(code,true,true); + ExpString newExp = new ExpString(true,true); + newExp.list.add( "(LuanImpl.cnd(t = " ); + newExp.list.addAll( exp.list ); + newExp.list.add( ") ? (" ); + newExp.list.addAll( exp2.list ); + newExp.list.add( ") : t)" ); + exp = newExp; } return parser.success(exp); } @@ -672,38 +736,68 @@ Spaces(in); exp = exp.expr(); ExpString exp2 = required(ConcatExpr(in)).expr(); - String code = "LuanImpl.eq(luan," + exp.code + "," + exp2.code + ")"; - exp = new ExpString(code,true,false); + ExpString newExp = new ExpString(true,false); + newExp.list.add( "LuanImpl.eq(luan," ); + newExp.list.addAll( exp.list ); + newExp.list.add( "," ); + newExp.list.addAll( exp2.list ); + newExp.list.add( ")" ); + exp = newExp; } else if( parser.match("~=") ) { Spaces(in); exp = exp.expr(); ExpString exp2 = required(ConcatExpr(in)).expr(); - String code = "!LuanImpl.eq(luan," + exp.code + "," + exp2.code + ")"; - exp = new ExpString(code,true,false); + ExpString newExp = new ExpString(true,false); + newExp.list.add( "!LuanImpl.eq(luan," ); + newExp.list.addAll( exp.list ); + newExp.list.add( "," ); + newExp.list.addAll( exp2.list ); + newExp.list.add( ")" ); + exp = newExp; } else if( parser.match("<=") ) { Spaces(in); exp = exp.expr(); ExpString exp2 = required(ConcatExpr(in)).expr(); - String code = "LuanImpl.le(luan," + exp.code + "," + exp2.code + ")"; - exp = new ExpString(code,true,false); + ExpString newExp = new ExpString(true,false); + newExp.list.add( "LuanImpl.le(luan," ); + newExp.list.addAll( exp.list ); + newExp.list.add( "," ); + newExp.list.addAll( exp2.list ); + newExp.list.add( ")" ); + exp = newExp; } else if( parser.match(">=") ) { Spaces(in); exp = exp.expr(); ExpString exp2 = required(ConcatExpr(in)).expr(); - String code = "LuanImpl.le(luan," + exp2.code + "," + exp.code + ")"; - exp = new ExpString(code,true,false); + ExpString newExp = new ExpString(true,false); + newExp.list.add( "LuanImpl.le(luan," ); + newExp.list.addAll( exp2.list ); + newExp.list.add( "," ); + newExp.list.addAll( exp.list ); + newExp.list.add( ")" ); + exp = newExp; } else if( parser.match("<") ) { Spaces(in); exp = exp.expr(); ExpString exp2 = required(ConcatExpr(in)).expr(); - String code = "LuanImpl.lt(luan," + exp.code + "," + exp2.code + ")"; - exp = new ExpString(code,true,false); - } else if( parser.match(">") ) { + ExpString newExp = new ExpString(true,false); + newExp.list.add( "LuanImpl.lt(luan," ); + newExp.list.addAll( exp.list ); + newExp.list.add( "," ); + newExp.list.addAll( exp2.list ); + newExp.list.add( ")" ); + exp = newExp; + } else if( parser.match(">") ) { Spaces(in); exp = exp.expr(); ExpString exp2 = required(ConcatExpr(in)).expr(); - String code = "LuanImpl.lt(luan," + exp2.code + "," + exp.code + ")"; - exp = new ExpString(code,true,false); + ExpString newExp = new ExpString(true,false); + newExp.list.add( "LuanImpl.lt(luan," ); + newExp.list.addAll( exp2.list ); + newExp.list.add( "," ); + newExp.list.addAll( exp.list ); + newExp.list.add( ")" ); + exp = newExp; } else break; } @@ -719,8 +813,13 @@ Spaces(in); exp = exp.expr(); ExpString exp2 = required(ConcatExpr(in)).expr(); - String code = "LuanImpl.concat(luan," + exp.code + "," + exp2.code + ")"; - exp = new ExpString(code,true,false); + ExpString newExp = new ExpString(true,false); + newExp.list.add( "LuanImpl.concat(luan," ); + newExp.list.addAll( exp.list ); + newExp.list.add( "," ); + newExp.list.addAll( exp2.list ); + newExp.list.add( ")" ); + exp = newExp; } return parser.success(exp); } @@ -735,14 +834,24 @@ Spaces(in); exp = exp.expr(); ExpString exp2 = required(TermExpr(in)).expr(); - String code = "LuanImpl.add(luan," + exp.code + "," + exp2.code + ")"; - exp = new ExpString(code,true,false); + ExpString newExp = new ExpString(true,false); + newExp.list.add( "LuanImpl.add(luan," ); + newExp.list.addAll( exp.list ); + newExp.list.add( "," ); + newExp.list.addAll( exp2.list ); + newExp.list.add( ")" ); + exp = newExp; } else if( Minus() ) { Spaces(in); exp = exp.expr(); ExpString exp2 = required(TermExpr(in)).expr(); - String code = "LuanImpl.sub(luan," + exp.code + "," + exp2.code + ")"; - exp = new ExpString(code,true,false); + ExpString newExp = new ExpString(true,false); + newExp.list.add( "LuanImpl.sub(luan," ); + newExp.list.addAll( exp.list ); + newExp.list.add( "," ); + newExp.list.addAll( exp2.list ); + newExp.list.add( ")" ); + exp = newExp; } else break; } @@ -764,20 +873,35 @@ Spaces(in); exp = exp.expr(); ExpString exp2 = required(UnaryExpr(in)).expr(); - String code = "LuanImpl.mul(luan," + exp.code + "," + exp2.code + ")"; - exp = new ExpString(code,true,false); + ExpString newExp = new ExpString(true,false); + newExp.list.add( "LuanImpl.mul(luan," ); + newExp.list.addAll( exp.list ); + newExp.list.add( "," ); + newExp.list.addAll( exp2.list ); + newExp.list.add( ")" ); + exp = newExp; } else if( parser.match('/') ) { Spaces(in); exp = exp.expr(); ExpString exp2 = required(UnaryExpr(in)).expr(); - String code = "LuanImpl.div(luan," + exp.code + "," + exp2.code + ")"; - exp = new ExpString(code,true,false); + ExpString newExp = new ExpString(true,false); + newExp.list.add( "LuanImpl.div(luan," ); + newExp.list.addAll( exp.list ); + newExp.list.add( "," ); + newExp.list.addAll( exp2.list ); + newExp.list.add( ")" ); + exp = newExp; } else if( Mod() ) { Spaces(in); exp = exp.expr(); ExpString exp2 = required(UnaryExpr(in)).expr(); - String code = "LuanImpl.mod(luan," + exp.code + "," + exp2.code + ")"; - exp = new ExpString(code,true,false); + ExpString newExp = new ExpString(true,false); + newExp.list.add( "LuanImpl.mod(luan," ); + newExp.list.addAll( exp.list ); + newExp.list.add( "," ); + newExp.list.addAll( exp2.list ); + newExp.list.add( ")" ); + exp = newExp; } else break; } @@ -794,23 +918,29 @@ if( parser.match('#') ) { Spaces(in); ExpString exp = required(UnaryExpr(in)).expr(); - String code = "LuanImpl.len(luan," + exp.code + ")"; - exp = new ExpString(code,true,false); - return parser.success(exp); + ExpString newExp = new ExpString(true,false); + newExp.list.add( "LuanImpl.len(luan," ); + newExp.list.addAll( exp.list ); + newExp.list.add( ")" ); + return parser.success(newExp); } if( Minus() ) { Spaces(in); ExpString exp = required(UnaryExpr(in)).expr(); - String code = "LuanImpl.unm(luan," + exp.code + ")"; - exp = new ExpString(code,true,false); - return parser.success(exp); + ExpString newExp = new ExpString(true,false); + newExp.list.add( "LuanImpl.unm(luan," ); + newExp.list.addAll( exp.list ); + newExp.list.add( ")" ); + return parser.success(newExp); } if( Keyword("not",in) ) { Spaces(in); ExpString exp = required(UnaryExpr(in)).expr(); - String code = "!Luan.checkBoolean(" + exp.code + ")"; - exp = new ExpString(code,true,false); - return parser.success(exp); + ExpString newExp = new ExpString(true,false); + newExp.list.add( "!Luan.checkBoolean(" ); + newExp.list.addAll( exp.list ); + newExp.list.add( ")" ); + return parser.success(newExp); } ExpString exp = PowExpr(in); if( exp==null ) @@ -826,8 +956,13 @@ if( parser.match('^') ) { Spaces(in); ExpString exp2 = required(PowExpr(in)); - String code = "LuanImpl.pow(luan," + exp1.code + "," + exp2.code + ")"; - exp1 = new ExpString(code,true,false); + ExpString newExp = new ExpString(true,false); + newExp.list.add( "LuanImpl.pow(luan," ); + newExp.list.addAll( exp1.expr().list ); + newExp.list.add( "," ); + newExp.list.addAll( exp2.expr().list ); + newExp.list.add( ")" ); + exp1 = newExp; } return parser.success(exp1); } @@ -906,8 +1041,11 @@ if( !parser.match('}') ) throw parser.exception("Expected table element or '}'"); Spaces(in); - String code = "LuanImpl.table(" + expString(builder).code + ")"; - return parser.success( new ExpString(code,true,false) ); + exp = new ExpString(true,false); + exp.list.add( "LuanImpl.table(" ); + exp.list.addAll( expString(builder).list ); + exp.list.add( ")" ); + return parser.success( exp ); } private boolean FieldSep() throws ParseException { @@ -922,8 +1060,13 @@ if( exp!=null && parser.match('=') ) { Spaces(In.NOTHING); ExpString val = RequiredExpr(In.NOTHING).expr(); - String code = "new TableField(" + exp.code + "," + val.code + ")"; - builder.add( new ExpString(code,true,false) ); + ExpString newExp = new ExpString(true,false); + newExp.list.add( "new TableField(" ); + newExp.list.addAll( exp.list ); + newExp.list.add( "," ); + newExp.list.addAll( val.list ); + newExp.list.add( ")" ); + builder.add( newExp ); return parser.success(); } parser.rollback(); @@ -1045,8 +1188,11 @@ } public StmtString set(ExpString val) throws ParseException { - String code = new SettableString(settable()).code + ".set(luan," + val.expr().code + ");\n"; - return new StmtString(code); + StmtString stmt = new StmtString(); + stmt.list.add( settableToString(settable()) + ".set(luan," ); + stmt.list.addAll( val.expr().list ); + stmt.list.add( ");\n" ); + return stmt; } }; } @@ -1084,8 +1230,15 @@ } */ public StmtString set(ExpString val) { - String code = "LuanImpl.put(luan," + table.expr().code + "," + key.expr().code + "," + val.expr().code + ");\n"; - return new StmtString(code); + StmtString stmt = new StmtString(); + stmt.list.add( "LuanImpl.put(luan," ); + stmt.list.addAll( table.expr().list ); + stmt.list.add( "," ); + stmt.list.addAll( key.expr().list ); + stmt.list.add( "," ); + stmt.list.addAll( val.expr().list ); + stmt.list.add( ");\n" ); + return stmt; } }; } @@ -1253,17 +1406,25 @@ private ExpString Literal(In in) throws ParseException { parser.begin(); - if( NilLiteral(in) ) - return parser.success(new ExpString("null",true,false)); + if( NilLiteral(in) ) { + ExpString exp = new ExpString(true,false); + exp.list.add( "null" ); + return parser.success(exp); + } Boolean b = BooleanLiteral(in); - if( b != null ) - return parser.success(new ExpString(b.toString(),true,false)); + if( b != null ) { + ExpString exp = new ExpString(true,false); + exp.list.add( b.toString() ); + return parser.success(exp); + } Number n = NumberLiteral(in); if( n != null ) { String s = n.toString(); if( n instanceof Long ) s += "L"; - return parser.success(new ExpString(s,true,false)); + ExpString exp = new ExpString(true,false); + exp.list.add( s ); + return parser.success(exp); } String s = StringLiteral(in); if( s != null ) @@ -1280,7 +1441,9 @@ .replace("\t","\\t") .replace("\b","\\b") ; - return new ExpString( "\""+s+"\"", true,false); + ExpString exp = new ExpString(true,false); + exp.list.add( "\""+s+"\"" ); + return exp; } private boolean NilLiteral(In in) throws ParseException { @@ -1533,67 +1696,78 @@ private static int classCounter = 0; private class ExpString { - final String code; + 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); - code = "((Expressions)LuanImpl.getObj(" + i + ")).eval(luan)"; + list.add( "((Expressions)LuanImpl.getObj(" + i + ")).eval(luan)" ); isExpr = exp instanceof Expr; isStmt = exp instanceof StmtExp; } - ExpString(String code,boolean isExpr,boolean isStmt) { - this.code = code; + ExpString(boolean isExpr,boolean isStmt) { this.isExpr = isExpr; this.isStmt = isStmt; } ExpString expr() { - return isExpr ? this : new ExpString( "Luan.first(" + code + ")", true, isStmt ); + if( isExpr ) + return this; + ExpString exp = new ExpString(true,isStmt); + exp.list.addAll( list ); + return exp; } } private ExpString expString(List<ExpString> list) { + ExpString exp = new ExpString(false,false); switch(list.size()) { case 0: - return new ExpString("LuanFunction.NOTHING",false,false); + exp.list.add("LuanFunction.NOTHING"); + return exp; case 1: return list.get(0); default: int lastI = list.size() - 1; - StringBuilder sb = new StringBuilder(); - sb.append( "new Object[]{" ); + exp.list.add( "new Object[]{" ); for( int i=0; i<lastI; i++ ) { - sb.append( list.get(i).expr().code ).append( ',' ); + exp.list.addAll( list.get(i).expr().list ); + exp.list.add( "," ); } ExpString last = list.get(lastI); if( last.isExpr ) { - sb.append( last.code ).append( '}' ); - return new ExpString(sb.toString(),false,false); + exp.list.addAll( last.list ); + exp.list.add( "}" ); } else { - sb.append( '}' ); - String s = "LuanImpl.concatArgs(" + sb + "," + last.code + ")"; - return new ExpString(s,false,false); + exp.list.add( "}" ); + exp.list.add( 0, "LuanImpl.concatArgs(" ); + exp.list.add( "," ); + exp.list.addAll( last.list ); + exp.list.add( ")" ); } + return exp; } } private static class StmtString { - final String code; + final List list = new ArrayList(); boolean hasReturn = false; - - StmtString(String code) { - this.code = code; - if( code.contains("LuanParser") ) throw new RuntimeException("\n"+code); - } } - private static StmtString EMPTY_STMT = new StmtString(""); + private static FnDef toFnDef(StmtString stmt,int stackSize,int numArgs,boolean isVarArg,UpValue.Getter[] upValueGetters) { + StringBuilder sb = new StringBuilder(); + for( Object o : stmt.list ) { + if( o instanceof List ) throw new RuntimeException(); + if( o instanceof ExpString ) throw new RuntimeException(); + if( o instanceof StmtString ) throw new RuntimeException(); + sb.append( o.toString() ); + } + String code = sb.toString(); +//System.out.println("code:\n"+code); - private static FnDef toFnDef(StmtString stmt,int stackSize,int numArgs,boolean isVarArg,UpValue.Getter[] upValueGetters) { int i = LuanImpl.addObj(upValueGetters); String className = "EXP" + ++classCounter; String classCode = "" @@ -1610,7 +1784,7 @@ +"\n" +" @Override public Object run(LuanStateImpl luan) throws LuanException {\n" +" Object t;\n" - +" " + stmt.code + +" " + code +" }\n" +"}\n" ; @@ -1629,32 +1803,27 @@ private ExpString toFnExpStr(StmtString stmt,int stackSize,int numArgs,boolean isVarArg,UpValue.Getter[] upValueGetters) { int i = LuanImpl.addObj(upValueGetters); - String classCode = "" + ExpString exp = new ExpString(true,false); + exp.list.add( "" +"\n" +"new FnDef("+stackSize+","+numArgs+","+isVarArg+",(UpValue.Getter[])LuanImpl.getObj("+i+")) {\n" +" @Override public Object run(LuanStateImpl luan) throws LuanException {\n" +" Object t;\n" - +" " + stmt.code + +" " + ); + exp.list.addAll( stmt.list ); + exp.list.add( "" +" }\n" +"}.eval(luan)\n" - ; - return new ExpString(classCode,true,false); + ); + return exp; } - private static class SettableString { - final String code; - - SettableString(Settable settable) { - if( settable==null ) throw new NullPointerException(); - int i = LuanImpl.addObj(settable); - code = "((Settable)LuanImpl.getObj(" + i + "))"; - } - - SettableString(String code) { - this.code = code; - } - + private static String settableToString(Settable settable) { + if( settable==null ) throw new NullPointerException(); + int i = LuanImpl.addObj(settable); + return"((Settable)LuanImpl.getObj(" + i + "))"; } }