comparison core/src/luan/impl/LuanParser.java @ 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
comparison
equal deleted inserted replaced
665:41f8fdbc3a0a 666:2f449ccf54d2
174 return new ExpressionsExpr(exprs); 174 return new ExpressionsExpr(exprs);
175 } 175 }
176 176
177 private FnDef newFnDef(int start,StmtString stmt) { 177 private FnDef newFnDef(int start,StmtString stmt) {
178 if( !stmt.hasReturn ) 178 if( !stmt.hasReturn )
179 stmt = new StmtString( stmt.code + "return LuanFunction.NOTHING;\n" ); 179 stmt.list.add( "return LuanFunction.NOTHING;\n" );
180 return toFnDef( stmt, frame.stackSize, symbolsSize(), frame.isVarArg, frame.upValueGetters.toArray(NO_UP_VALUE_GETTERS) ); 180 return toFnDef( stmt, frame.stackSize, symbolsSize(), frame.isVarArg, frame.upValueGetters.toArray(NO_UP_VALUE_GETTERS) );
181 } 181 }
182 182
183 private ExpString newFnExpStr(int start,StmtString stmt) { 183 private ExpString newFnExpStr(int start,StmtString stmt) {
184 if( !stmt.hasReturn ) 184 if( !stmt.hasReturn )
185 stmt = new StmtString( stmt.code + "return LuanFunction.NOTHING;\n" ); 185 stmt.list.add( "return LuanFunction.NOTHING;\n" );
186 return toFnExpStr( stmt, frame.stackSize, symbolsSize(), frame.isVarArg, frame.upValueGetters.toArray(NO_UP_VALUE_GETTERS) ); 186 return toFnExpStr( stmt, frame.stackSize, symbolsSize(), frame.isVarArg, frame.upValueGetters.toArray(NO_UP_VALUE_GETTERS) );
187 } 187 }
188 188
189 FnDef Expression() throws ParseException { 189 FnDef Expression() throws ParseException {
190 Spaces(In.NOTHING); 190 Spaces(In.NOTHING);
191 int start = parser.begin(); 191 int start = parser.begin();
192 ExpString expr = ExprZ(In.NOTHING); 192 ExpString expr = ExprZ(In.NOTHING);
193 if( expr != null && parser.endOfInput() ) { 193 if( expr != null && parser.endOfInput() ) {
194 String code = "return " + expr.code + ";\n"; 194 StmtString stmt = new StmtString();
195 StmtString stmt = new StmtString(code); 195 stmt.list.add( "return " );
196 stmt.list.addAll( expr.list );
197 stmt.list.add( ";\n" );
196 stmt.hasReturn = true; 198 stmt.hasReturn = true;
197 return parser.success(newFnDef(start,stmt)); 199 return parser.success(newFnDef(start,stmt));
198 } 200 }
199 return parser.failure(null); 201 return parser.failure(null);
200 } 202 }
208 return parser.success(newFnDef(start,stmt)); 210 return parser.success(newFnDef(start,stmt));
209 throw parser.exception(); 211 throw parser.exception();
210 } 212 }
211 213
212 private StmtString RequiredBlock() throws ParseException { 214 private StmtString RequiredBlock() throws ParseException {
213 StringBuilder stmts = new StringBuilder(); 215 StmtString stmts = new StmtString();
214 int stackStart = symbolsSize(); 216 int stackStart = symbolsSize();
215 boolean isReturn = Stmt(stmts); 217 boolean isReturn = Stmt(stmts);
216 while( !isReturn && StmtSep(stmts) ) { 218 while( !isReturn && StmtSep(stmts) ) {
217 Spaces(In.NOTHING); 219 Spaces(In.NOTHING);
218 isReturn = Stmt(stmts); 220 isReturn = Stmt(stmts);
219 } 221 }
220 StmtSep(null); 222 StmtSep(null);
221 Spaces(In.NOTHING); 223 Spaces(In.NOTHING);
222 int stackEnd = symbolsSize(); 224 int stackEnd = symbolsSize();
223 popSymbols( stackEnd - stackStart ); 225 popSymbols( stackEnd - stackStart );
224 if( stmts.length() == 0 ) 226 if( stmts.list.isEmpty() )
225 return EMPTY_STMT; 227 return stmts;
226 String code = stmts.toString(); 228 String code = stmts.toString();
227 if( stackStart < stackEnd ) 229 if( stackStart < stackEnd ) {
228 code = "" 230 stmts.list.add( 0, "try {\n" );
229 +"try {\n" 231 stmts.list.add( ""
230 + code
231 +"} finally {\n" 232 +"} finally {\n"
232 +" luan.stackClear("+stackStart+","+stackEnd+");\n" 233 +" luan.stackClear("+stackStart+","+stackEnd+");\n"
233 +"}\n" 234 +"}\n"
234 ; 235 );
235 StmtString stmt = new StmtString(code); 236 }
236 stmt.hasReturn = isReturn; 237 stmts.hasReturn = isReturn;
237 return stmt; 238 return stmts;
238 } 239 }
239 240
240 private boolean StmtSep(StringBuilder stmts) throws ParseException { 241 private boolean StmtSep(StmtString stmts) throws ParseException {
241 parser.begin(); 242 parser.begin();
242 if( parser.match( ';' ) ) 243 if( parser.match( ';' ) )
243 return parser.success(); 244 return parser.success();
244 if( EndOfLine() ) 245 if( EndOfLine() )
245 return parser.success(); 246 return parser.success();
246 if( stmts != null ) { 247 if( stmts != null ) {
247 // parser.rollback(); 248 // parser.rollback();
248 StmtString stmt = TemplateStmt(); 249 StmtString stmt = TemplateStmt();
249 if( stmt != null ) { 250 if( stmt != null ) {
250 stmts.append(stmt.code); 251 stmts.list.addAll(stmt.list);
251 return parser.success(); 252 return parser.success();
252 } 253 }
253 } 254 }
254 return parser.failure(); 255 return parser.failure();
255 } 256 }
256 257
257 private boolean EndOfLine() { 258 private boolean EndOfLine() {
258 return parser.match( "\r\n" ) || parser.match( '\r' ) || parser.match( '\n' ); 259 return parser.match( "\r\n" ) || parser.match( '\r' ) || parser.match( '\n' );
259 } 260 }
260 261
261 private boolean Stmt(StringBuilder stmts) throws ParseException { 262 private boolean Stmt(StmtString stmts) throws ParseException {
262 if( LocalStmt(stmts) ) 263 if( LocalStmt(stmts) )
263 return false; 264 return false;
264 StmtString stmt; 265 StmtString stmt;
265 if( (stmt=ReturnStmt()) != null ) { 266 if( (stmt=ReturnStmt()) != null ) {
266 stmts.append(stmt.code); 267 stmts.list.addAll(stmt.list);
267 return true; 268 return true;
268 } 269 }
269 if( (stmt=FunctionStmt()) != null 270 if( (stmt=FunctionStmt()) != null
270 || (stmt=LocalFunctionStmt()) != null 271 || (stmt=LocalFunctionStmt()) != null
271 || (stmt=BreakStmt()) != null 272 || (stmt=BreakStmt()) != null
275 || (stmt=RepeatStmt()) != null 276 || (stmt=RepeatStmt()) != null
276 || (stmt=IfStmt()) != null 277 || (stmt=IfStmt()) != null
277 || (stmt=SetStmt()) != null 278 || (stmt=SetStmt()) != null
278 || (stmt=ExpressionsStmt()) != null 279 || (stmt=ExpressionsStmt()) != null
279 ) { 280 ) {
280 stmts.append(stmt.code); 281 stmts.list.addAll(stmt.list);
281 } 282 }
282 return false; 283 return false;
283 } 284 }
284 285
285 private ExpString indexExpStr(ExpString exp1,ExpString exp2) { 286 private ExpString indexExpStr(ExpString exp1,ExpString exp2) {
286 String code = "luan.index(" + exp1.expr().code + "," + exp2.expr().code + ")"; 287 ExpString exp = new ExpString(true,false);
287 return new ExpString(code,true,false); 288 exp.list.add( "luan.index(" );
289 exp.list.addAll( exp1.expr().list );
290 exp.list.add( "," );
291 exp.list.addAll( exp2.expr().list );
292 exp.list.add( ")" );
293 return exp;
288 } 294 }
289 295
290 private ExpString callExpStr(ExpString fn,ExpString args) { 296 private ExpString callExpStr(ExpString fn,ExpString args) {
291 String code = "Luan.checkFunction(" + fn.expr().code + ").call(luan,Luan.array(" + args.code + "))"; 297 ExpString exp = new ExpString(false,true);
292 return new ExpString(code,false,true); 298 exp.list.add( "Luan.checkFunction(" );
299 exp.list.addAll( fn.expr().list );
300 exp.list.add( ").call(luan,Luan.array(" );
301 exp.list.addAll( args.list );
302 exp.list.add( "))" );
303 return exp;
293 } 304 }
294 305
295 private StmtString TemplateStmt() throws ParseException { 306 private StmtString TemplateStmt() throws ParseException {
296 ExpString exprs = TemplateExpressions(In.NOTHING); 307 ExpString exprs = TemplateExpressions(In.NOTHING);
297 if( exprs == null ) 308 if( exprs == null )
298 return null; 309 return null;
299 String code = "PackageLuan.require(luan,\"luan:Io\")"; 310 ExpString requireCall = new ExpString(true,false);
300 ExpString requireCall = new ExpString(code,true,false); 311 requireCall.list.add( "PackageLuan.require(luan,\"luan:Io\")" );
301 ExpString stdoutExp = indexExpStr( requireCall.expr(), constExpStr("stdout") ); 312 ExpString stdoutExp = indexExpStr( requireCall.expr(), constExpStr("stdout") );
302 ExpString writeExp = indexExpStr( stdoutExp, constExpStr("write") ); 313 ExpString writeExp = indexExpStr( stdoutExp, constExpStr("write") );
303 ExpString writeCall = callExpStr( writeExp, exprs ); 314 ExpString writeCall = callExpStr( writeExp, exprs );
304 return new StmtString( writeCall.code + ";\n" ); 315 StmtString stmt = new StmtString();
316 stmt.list.addAll( writeCall.list );
317 stmt.list.add( ";\n" );
318 return stmt;
305 } 319 }
306 320
307 private ExpString TemplateExpressions(In in) throws ParseException { 321 private ExpString TemplateExpressions(In in) throws ParseException {
308 if( in.template ) 322 if( in.template )
309 return null; 323 return null;
338 private StmtString ReturnStmt() throws ParseException { 352 private StmtString ReturnStmt() throws ParseException {
339 parser.begin(); 353 parser.begin();
340 if( !Keyword("return",In.NOTHING) ) 354 if( !Keyword("return",In.NOTHING) )
341 return parser.failure(null); 355 return parser.failure(null);
342 ExpString exprs = ExpStringList(In.NOTHING); 356 ExpString exprs = ExpStringList(In.NOTHING);
343 String code = "return " + (exprs!=null ? exprs.code : "LuanFunction.NOTHING") + ";\n"; 357 StmtString stmt = new StmtString();
344 return parser.success( new StmtString(code) ); 358 stmt.list.add( "return " );
359 if( exprs != null )
360 stmt.list.addAll( exprs.list );
361 else
362 stmt.list.add( "LuanFunction.NOTHING" );
363 stmt.list.add( ";\n" );
364 return parser.success( stmt );
345 } 365 }
346 366
347 private StmtString FunctionStmt() throws ParseException { 367 private StmtString FunctionStmt() throws ParseException {
348 parser.begin(); 368 parser.begin();
349 if( !Keyword("function",In.NOTHING) ) 369 if( !Keyword("function",In.NOTHING) )
369 return parser.failure(null); 389 return parser.failure(null);
370 String name = RequiredName(In.NOTHING); 390 String name = RequiredName(In.NOTHING);
371 addSymbol( name ); 391 addSymbol( name );
372 ExpString fnDef = RequiredFunction(In.NOTHING); 392 ExpString fnDef = RequiredFunction(In.NOTHING);
373 Settable s = new SetLocalVar(symbolsSize()-1); 393 Settable s = new SetLocalVar(symbolsSize()-1);
374 String code = new SettableString(s).code + ".set(luan," + fnDef.code + ");\n"; 394 StmtString stmt = new StmtString();
375 return parser.success( new StmtString(code) ); 395 stmt.list.add( settableToString(s) );
396 stmt.list.add( ".set(luan," );
397 stmt.list.addAll( fnDef.list );
398 stmt.list.add( ");\n" );
399 return parser.success( stmt );
376 } 400 }
377 401
378 private StmtString BreakStmt() throws ParseException { 402 private StmtString BreakStmt() throws ParseException {
379 parser.begin(); 403 parser.begin();
380 if( !Keyword("break",In.NOTHING) ) 404 if( !Keyword("break",In.NOTHING) )
381 return parser.failure(null); 405 return parser.failure(null);
382 if( frame.loops <= 0 ) 406 if( frame.loops <= 0 )
383 throw parser.exception("'break' outside of loop"); 407 throw parser.exception("'break' outside of loop");
384 return parser.success( new StmtString("break;\n") ); 408 StmtString stmt = new StmtString();
409 stmt.list.add( "break;\n" );
410 return parser.success( stmt );
385 } 411 }
386 412
387 int forCounter = 0; 413 int forCounter = 0;
388 414
389 private StmtString ForStmt() throws ParseException { 415 private StmtString ForStmt() throws ParseException {
406 ExpString firstVar = new ExpString(new GetLocalVar(stackStart)); 432 ExpString firstVar = new ExpString(new GetLocalVar(stackStart));
407 addSymbols(names); 433 addSymbols(names);
408 StmtString loop = RequiredLoopBlock(); 434 StmtString loop = RequiredLoopBlock();
409 RequiredKeyword("end",In.NOTHING); 435 RequiredKeyword("end",In.NOTHING);
410 String fnVar = "fn"+ ++forCounter; 436 String fnVar = "fn"+ ++forCounter;
411 String code = "" 437 StmtString stmt = new StmtString();
438 stmt.list.add( ""
412 +"try {\n" 439 +"try {\n"
413 +"LuanFunction "+fnVar+" = Luan.checkFunction(" + expr.code + ");\n" 440 +"LuanFunction "+fnVar+" = Luan.checkFunction("
441 );
442 stmt.list.addAll( expr.list );
443 stmt.list.add( ""
444 + ");\n"
414 +"while(true) {\n" 445 +"while(true) {\n"
415 +"for( int i="+stackStart+"; i<"+symbolsSize()+"; i++ ) {\n" 446 +"for( int i="+stackStart+"; i<"+symbolsSize()+"; i++ ) {\n"
416 +"luan.stackSet(i,null);\n" 447 +"luan.stackSet(i,null);\n"
417 +"}\n" 448 +"}\n"
418 +"LuanImpl.set(luan," + varsStr + ", "+fnVar+".call(luan) );\n" 449 +"LuanImpl.set(luan," + varsStr + ", "+fnVar+".call(luan) );\n"
419 +"if( " + firstVar.code + "==null ) break;\n" 450 +"if( "
420 + loop.code 451 );
452 stmt.list.addAll( firstVar.list );
453 stmt.list.add( "==null ) break;\n" );
454 stmt.list.addAll( loop.list );
455 stmt.list.add( ""
421 +"}" 456 +"}"
422 +"} finally {\n" 457 +"} finally {\n"
423 +"luan.stackClear("+stackStart+","+symbolsSize()+");\n" 458 +"luan.stackClear("+stackStart+","+symbolsSize()+");\n"
424 +"}\n" 459 +"}\n"
425 ; 460 );
426 StmtString stmt = new StmtString(code);
427 popSymbols( symbolsSize() - stackStart ); 461 popSymbols( symbolsSize() - stackStart );
428 return parser.success(stmt); 462 return parser.success(stmt);
429 } 463 }
430 464
431 private StmtString DoStmt() throws ParseException { 465 private StmtString DoStmt() throws ParseException {
435 StmtString stmt = RequiredBlock(); 469 StmtString stmt = RequiredBlock();
436 RequiredKeyword("end",In.NOTHING); 470 RequiredKeyword("end",In.NOTHING);
437 return parser.success(stmt); 471 return parser.success(stmt);
438 } 472 }
439 473
440 private boolean LocalStmt(StringBuilder stmts) throws ParseException { 474 private boolean LocalStmt(StmtString stmts) throws ParseException {
441 parser.begin(); 475 parser.begin();
442 if( !Keyword("local",In.NOTHING) ) 476 if( !Keyword("local",In.NOTHING) )
443 return parser.failure(); 477 return parser.failure();
444 List<String> names = NameList(In.NOTHING); 478 List<String> names = NameList(In.NOTHING);
445 if( names==null ) { 479 if( names==null ) {
456 int stackStart = symbolsSize(); 490 int stackStart = symbolsSize();
457 for( int i=0; i<vars.length; i++ ) { 491 for( int i=0; i<vars.length; i++ ) {
458 vars[i] = new SetLocalVar(stackStart+i); 492 vars[i] = new SetLocalVar(stackStart+i);
459 } 493 }
460 String varsStr = varsToString(vars); 494 String varsStr = varsToString(vars);
461 String code = "LuanImpl.set(luan," + varsStr + "," + values.code + ");\n"; 495 stmts.list.add( "LuanImpl.set(luan," + varsStr + "," );
462 stmts.append(code); 496 stmts.list.addAll( values.list );
497 stmts.list.add( ");\n" );
463 } 498 }
464 addSymbols(names); 499 addSymbols(names);
465 return parser.success(); 500 return parser.success();
466 } 501 }
467 502
502 return parser.failure(null); 537 return parser.failure(null);
503 ExpString cnd = RequiredExpr(In.NOTHING).expr(); 538 ExpString cnd = RequiredExpr(In.NOTHING).expr();
504 RequiredKeyword("do",In.NOTHING); 539 RequiredKeyword("do",In.NOTHING);
505 StmtString loop = RequiredLoopBlock(); 540 StmtString loop = RequiredLoopBlock();
506 RequiredKeyword("end",In.NOTHING); 541 RequiredKeyword("end",In.NOTHING);
507 String code = "" 542 StmtString stmt = new StmtString();
508 +"while( Luan.checkBoolean(" + cnd.code + ") ) {\n" 543 stmt.list.add( "while( Luan.checkBoolean(" );
509 + loop.code 544 stmt.list.addAll( cnd.list );
510 +"}\n" 545 stmt.list.add( ") ) {\n" );
511 ; 546 stmt.list.addAll( loop.list );
512 return parser.success( new StmtString(code) ); 547 stmt.list.add( "}\n" );
548 return parser.success( stmt );
513 } 549 }
514 550
515 private StmtString RepeatStmt() throws ParseException { 551 private StmtString RepeatStmt() throws ParseException {
516 parser.begin(); 552 parser.begin();
517 if( !Keyword("repeat",In.NOTHING) ) 553 if( !Keyword("repeat",In.NOTHING) )
518 return parser.failure(null); 554 return parser.failure(null);
519 StmtString loop =RequiredLoopBlock(); 555 StmtString loop =RequiredLoopBlock();
520 RequiredKeyword("until",In.NOTHING); 556 RequiredKeyword("until",In.NOTHING);
521 ExpString cnd = RequiredExpr(In.NOTHING).expr(); 557 ExpString cnd = RequiredExpr(In.NOTHING).expr();
522 String code = "" 558 StmtString stmt = new StmtString();
523 +"do {\n" 559 stmt.list.add( "do {\n" );
524 + loop.code 560 stmt.list.addAll( loop.list );
525 +"} while( !Luan.checkBoolean(" + cnd.code + ") );\n" 561 stmt.list.add( "} while( !Luan.checkBoolean(" );
526 ; 562 stmt.list.addAll( cnd.list );
527 return parser.success( new StmtString(code) ); 563 stmt.list.add( ") );\n" );
564 return parser.success( stmt );
528 } 565 }
529 566
530 private StmtString RequiredLoopBlock() throws ParseException { 567 private StmtString RequiredLoopBlock() throws ParseException {
531 incLoops(); 568 incLoops();
532 StmtString stmt = RequiredBlock(); 569 StmtString stmt = RequiredBlock();
536 573
537 private StmtString IfStmt() throws ParseException { 574 private StmtString IfStmt() throws ParseException {
538 parser.begin(); 575 parser.begin();
539 if( !Keyword("if",In.NOTHING) ) 576 if( !Keyword("if",In.NOTHING) )
540 return parser.failure(null); 577 return parser.failure(null);
541 StringBuilder sb = new StringBuilder(); 578 StmtString stmt = new StmtString();
542 ExpString cnd; 579 ExpString cnd;
543 StmtString block; 580 StmtString block;
544 cnd = RequiredExpr(In.NOTHING).expr(); 581 cnd = RequiredExpr(In.NOTHING).expr();
545 RequiredKeyword("then",In.NOTHING); 582 RequiredKeyword("then",In.NOTHING);
546 block = RequiredBlock(); 583 block = RequiredBlock();
547 sb.append( "if( Luan.checkBoolean(" ).append( cnd.code ).append( ") ) {\n" ).append( block.code ); 584 stmt.list.add( "if( Luan.checkBoolean(" );
585 stmt.list.addAll( cnd.list );
586 stmt.list.add( ") ) {\n" );
587 stmt.list.addAll( block.list );
548 while( Keyword("elseif",In.NOTHING) ) { 588 while( Keyword("elseif",In.NOTHING) ) {
549 cnd = RequiredExpr(In.NOTHING).expr(); 589 cnd = RequiredExpr(In.NOTHING).expr();
550 RequiredKeyword("then",In.NOTHING); 590 RequiredKeyword("then",In.NOTHING);
551 block = RequiredBlock(); 591 block = RequiredBlock();
552 sb.append( "} else if( Luan.checkBoolean(" ).append( cnd.code ).append( ") ) {\n" ).append( block.code ); 592 stmt.list.add( "} else if( Luan.checkBoolean(" );
593 stmt.list.addAll( cnd.list );
594 stmt.list.add( ") ) {\n" );
595 stmt.list.addAll( block.list );
553 } 596 }
554 if( Keyword("else",In.NOTHING) ) { 597 if( Keyword("else",In.NOTHING) ) {
555 block = RequiredBlock(); 598 block = RequiredBlock();
556 sb.append( "} else {\n" ).append( block.code ); 599 stmt.list.add( "} else {\n" );
600 stmt.list.addAll( block.list );
557 } 601 }
558 RequiredKeyword("end",In.NOTHING); 602 RequiredKeyword("end",In.NOTHING);
559 sb.append( "}\n" ); 603 stmt.list.add( "}\n" );
560 return parser.success( new StmtString(sb.toString()) ); 604 return parser.success( stmt );
561 } 605 }
562 606
563 private StmtString SetStmt() throws ParseException { 607 private StmtString SetStmt() throws ParseException {
564 parser.begin(); 608 parser.begin();
565 List<Var> vars = new ArrayList<Var>(); 609 List<Var> vars = new ArrayList<Var>();
582 // throw parser.exception("Expressions expected"); 626 // throw parser.exception("Expressions expected");
583 return parser.failure(null); 627 return parser.failure(null);
584 int n = vars.size(); 628 int n = vars.size();
585 if( n == 1 ) 629 if( n == 1 )
586 return parser.success( vars.get(0).set(values) ); 630 return parser.success( vars.get(0).set(values) );
587 StringBuilder sb = new StringBuilder(); 631 StmtString stmt = new StmtString();
588 sb.append( "t = " + values.code + ";\n" ); 632 stmt.list.add( "t = " );
589 ExpString t = new ExpString("t",true,false); 633 stmt.list.addAll( values.list );
590 sb.append( vars.get(0).set(new ExpString("t",true,false)).code ); 634 stmt.list.add( ";\n" );
635 ExpString t = new ExpString(true,false);
636 t.list.add( "t" );
637 stmt.list.addAll( vars.get(0).set(t).list );
591 for( int i=1; i<n; i++ ) { 638 for( int i=1; i<n; i++ ) {
592 sb.append( vars.get(i).set(new ExpString("LuanImpl.pick(t,"+i+")",true,false)).code ); 639 t.list.clear();
593 } 640 t.list.add( "LuanImpl.pick(t,"+i+")" );
594 return parser.success( new StmtString(sb.toString()) ); 641 stmt.list.addAll( vars.get(i).set(t).list );
642 }
643 return parser.success( stmt );
595 } 644 }
596 645
597 private static String varsToString(Settable[] vars) { 646 private static String varsToString(Settable[] vars) {
598 StringBuilder sb = new StringBuilder(); 647 StringBuilder sb = new StringBuilder();
599 sb.append( "new Settable[]{" ); 648 sb.append( "new Settable[]{" );
600 for( Settable v : vars ) { 649 for( Settable v : vars ) {
601 sb.append( new SettableString(v).code ).append( ',' ); 650 sb.append( settableToString(v) ).append( ',' );
602 } 651 }
603 sb.append( "}" ); 652 sb.append( "}" );
604 return sb.toString(); 653 return sb.toString();
605 } 654 }
606 655
607 private StmtString ExpressionsStmt() throws ParseException { 656 private StmtString ExpressionsStmt() throws ParseException {
608 parser.begin(); 657 parser.begin();
609 ExpString exp = ExprZ(In.NOTHING); 658 ExpString exp = ExprZ(In.NOTHING);
610 if( exp != null && exp.isStmt ) { 659 if( exp != null && exp.isStmt ) {
611 String code = exp.code; 660 StmtString stmt = new StmtString();
612 if( exp.isExpr ) 661 if( exp.isExpr ) {
613 code = "LuanImpl.nop(" + code + ")"; 662 stmt.list.add( "LuanImpl.nop(" );
614 code += ";\n"; 663 stmt.list.addAll( exp.list );
615 return parser.success( new StmtString(code) ); 664 stmt.list.add( ")" );
665 } else {
666 stmt.list.addAll( exp.list );
667 }
668 stmt.list.add( ";\n" );
669 return parser.success( stmt );
616 } 670 }
617 return parser.failure(null); 671 return parser.failure(null);
618 } 672 }
619 673
620 private Var SettableVar() throws ParseException { 674 private Var SettableVar() throws ParseException {
640 if( exp==null ) 694 if( exp==null )
641 return parser.failure(null); 695 return parser.failure(null);
642 while( Keyword("or",in) ) { 696 while( Keyword("or",in) ) {
643 exp = exp.expr(); 697 exp = exp.expr();
644 ExpString exp2 = required(RelExpr(in)).expr(); 698 ExpString exp2 = required(RelExpr(in)).expr();
645 String code = "(LuanImpl.cnd(t = " + exp.code + ") ? t : (" + exp2.code + "))"; 699 ExpString newExp = new ExpString(true,true);
646 exp = new ExpString(code,true,true); 700 newExp.list.add( "(LuanImpl.cnd(t = " );
701 newExp.list.addAll( exp.list );
702 newExp.list.add( ") ? t : (" );
703 newExp.list.addAll( exp2.list );
704 newExp.list.add( "))" );
705 exp = newExp;
647 } 706 }
648 return parser.success(exp); 707 return parser.success(exp);
649 } 708 }
650 709
651 private ExpString AndExpr(In in) throws ParseException { 710 private ExpString AndExpr(In in) throws ParseException {
654 if( exp==null ) 713 if( exp==null )
655 return parser.failure(null); 714 return parser.failure(null);
656 while( Keyword("and",in) ) { 715 while( Keyword("and",in) ) {
657 exp = exp.expr(); 716 exp = exp.expr();
658 ExpString exp2 = required(RelExpr(in)).expr(); 717 ExpString exp2 = required(RelExpr(in)).expr();
659 String code = "(LuanImpl.cnd(t = " + exp.code + ") ? (" + exp2.code + ") : t)"; 718 ExpString newExp = new ExpString(true,true);
660 exp = new ExpString(code,true,true); 719 newExp.list.add( "(LuanImpl.cnd(t = " );
720 newExp.list.addAll( exp.list );
721 newExp.list.add( ") ? (" );
722 newExp.list.addAll( exp2.list );
723 newExp.list.add( ") : t)" );
724 exp = newExp;
661 } 725 }
662 return parser.success(exp); 726 return parser.success(exp);
663 } 727 }
664 728
665 private ExpString RelExpr(In in) throws ParseException { 729 private ExpString RelExpr(In in) throws ParseException {
670 while(true) { 734 while(true) {
671 if( parser.match("==") ) { 735 if( parser.match("==") ) {
672 Spaces(in); 736 Spaces(in);
673 exp = exp.expr(); 737 exp = exp.expr();
674 ExpString exp2 = required(ConcatExpr(in)).expr(); 738 ExpString exp2 = required(ConcatExpr(in)).expr();
675 String code = "LuanImpl.eq(luan," + exp.code + "," + exp2.code + ")"; 739 ExpString newExp = new ExpString(true,false);
676 exp = new ExpString(code,true,false); 740 newExp.list.add( "LuanImpl.eq(luan," );
741 newExp.list.addAll( exp.list );
742 newExp.list.add( "," );
743 newExp.list.addAll( exp2.list );
744 newExp.list.add( ")" );
745 exp = newExp;
677 } else if( parser.match("~=") ) { 746 } else if( parser.match("~=") ) {
678 Spaces(in); 747 Spaces(in);
679 exp = exp.expr(); 748 exp = exp.expr();
680 ExpString exp2 = required(ConcatExpr(in)).expr(); 749 ExpString exp2 = required(ConcatExpr(in)).expr();
681 String code = "!LuanImpl.eq(luan," + exp.code + "," + exp2.code + ")"; 750 ExpString newExp = new ExpString(true,false);
682 exp = new ExpString(code,true,false); 751 newExp.list.add( "!LuanImpl.eq(luan," );
752 newExp.list.addAll( exp.list );
753 newExp.list.add( "," );
754 newExp.list.addAll( exp2.list );
755 newExp.list.add( ")" );
756 exp = newExp;
683 } else if( parser.match("<=") ) { 757 } else if( parser.match("<=") ) {
684 Spaces(in); 758 Spaces(in);
685 exp = exp.expr(); 759 exp = exp.expr();
686 ExpString exp2 = required(ConcatExpr(in)).expr(); 760 ExpString exp2 = required(ConcatExpr(in)).expr();
687 String code = "LuanImpl.le(luan," + exp.code + "," + exp2.code + ")"; 761 ExpString newExp = new ExpString(true,false);
688 exp = new ExpString(code,true,false); 762 newExp.list.add( "LuanImpl.le(luan," );
763 newExp.list.addAll( exp.list );
764 newExp.list.add( "," );
765 newExp.list.addAll( exp2.list );
766 newExp.list.add( ")" );
767 exp = newExp;
689 } else if( parser.match(">=") ) { 768 } else if( parser.match(">=") ) {
690 Spaces(in); 769 Spaces(in);
691 exp = exp.expr(); 770 exp = exp.expr();
692 ExpString exp2 = required(ConcatExpr(in)).expr(); 771 ExpString exp2 = required(ConcatExpr(in)).expr();
693 String code = "LuanImpl.le(luan," + exp2.code + "," + exp.code + ")"; 772 ExpString newExp = new ExpString(true,false);
694 exp = new ExpString(code,true,false); 773 newExp.list.add( "LuanImpl.le(luan," );
774 newExp.list.addAll( exp2.list );
775 newExp.list.add( "," );
776 newExp.list.addAll( exp.list );
777 newExp.list.add( ")" );
778 exp = newExp;
695 } else if( parser.match("<") ) { 779 } else if( parser.match("<") ) {
696 Spaces(in); 780 Spaces(in);
697 exp = exp.expr(); 781 exp = exp.expr();
698 ExpString exp2 = required(ConcatExpr(in)).expr(); 782 ExpString exp2 = required(ConcatExpr(in)).expr();
699 String code = "LuanImpl.lt(luan," + exp.code + "," + exp2.code + ")"; 783 ExpString newExp = new ExpString(true,false);
700 exp = new ExpString(code,true,false); 784 newExp.list.add( "LuanImpl.lt(luan," );
701 } else if( parser.match(">") ) { 785 newExp.list.addAll( exp.list );
786 newExp.list.add( "," );
787 newExp.list.addAll( exp2.list );
788 newExp.list.add( ")" );
789 exp = newExp;
790 } else if( parser.match(">") ) {
702 Spaces(in); 791 Spaces(in);
703 exp = exp.expr(); 792 exp = exp.expr();
704 ExpString exp2 = required(ConcatExpr(in)).expr(); 793 ExpString exp2 = required(ConcatExpr(in)).expr();
705 String code = "LuanImpl.lt(luan," + exp2.code + "," + exp.code + ")"; 794 ExpString newExp = new ExpString(true,false);
706 exp = new ExpString(code,true,false); 795 newExp.list.add( "LuanImpl.lt(luan," );
796 newExp.list.addAll( exp2.list );
797 newExp.list.add( "," );
798 newExp.list.addAll( exp.list );
799 newExp.list.add( ")" );
800 exp = newExp;
707 } else 801 } else
708 break; 802 break;
709 } 803 }
710 return parser.success(exp); 804 return parser.success(exp);
711 } 805 }
717 return parser.failure(null); 811 return parser.failure(null);
718 if( parser.match("..") ) { 812 if( parser.match("..") ) {
719 Spaces(in); 813 Spaces(in);
720 exp = exp.expr(); 814 exp = exp.expr();
721 ExpString exp2 = required(ConcatExpr(in)).expr(); 815 ExpString exp2 = required(ConcatExpr(in)).expr();
722 String code = "LuanImpl.concat(luan," + exp.code + "," + exp2.code + ")"; 816 ExpString newExp = new ExpString(true,false);
723 exp = new ExpString(code,true,false); 817 newExp.list.add( "LuanImpl.concat(luan," );
818 newExp.list.addAll( exp.list );
819 newExp.list.add( "," );
820 newExp.list.addAll( exp2.list );
821 newExp.list.add( ")" );
822 exp = newExp;
724 } 823 }
725 return parser.success(exp); 824 return parser.success(exp);
726 } 825 }
727 826
728 private ExpString SumExpr(In in) throws ParseException { 827 private ExpString SumExpr(In in) throws ParseException {
733 while(true) { 832 while(true) {
734 if( parser.match('+') ) { 833 if( parser.match('+') ) {
735 Spaces(in); 834 Spaces(in);
736 exp = exp.expr(); 835 exp = exp.expr();
737 ExpString exp2 = required(TermExpr(in)).expr(); 836 ExpString exp2 = required(TermExpr(in)).expr();
738 String code = "LuanImpl.add(luan," + exp.code + "," + exp2.code + ")"; 837 ExpString newExp = new ExpString(true,false);
739 exp = new ExpString(code,true,false); 838 newExp.list.add( "LuanImpl.add(luan," );
839 newExp.list.addAll( exp.list );
840 newExp.list.add( "," );
841 newExp.list.addAll( exp2.list );
842 newExp.list.add( ")" );
843 exp = newExp;
740 } else if( Minus() ) { 844 } else if( Minus() ) {
741 Spaces(in); 845 Spaces(in);
742 exp = exp.expr(); 846 exp = exp.expr();
743 ExpString exp2 = required(TermExpr(in)).expr(); 847 ExpString exp2 = required(TermExpr(in)).expr();
744 String code = "LuanImpl.sub(luan," + exp.code + "," + exp2.code + ")"; 848 ExpString newExp = new ExpString(true,false);
745 exp = new ExpString(code,true,false); 849 newExp.list.add( "LuanImpl.sub(luan," );
850 newExp.list.addAll( exp.list );
851 newExp.list.add( "," );
852 newExp.list.addAll( exp2.list );
853 newExp.list.add( ")" );
854 exp = newExp;
746 } else 855 } else
747 break; 856 break;
748 } 857 }
749 return parser.success(exp); 858 return parser.success(exp);
750 } 859 }
762 while(true) { 871 while(true) {
763 if( parser.match('*') ) { 872 if( parser.match('*') ) {
764 Spaces(in); 873 Spaces(in);
765 exp = exp.expr(); 874 exp = exp.expr();
766 ExpString exp2 = required(UnaryExpr(in)).expr(); 875 ExpString exp2 = required(UnaryExpr(in)).expr();
767 String code = "LuanImpl.mul(luan," + exp.code + "," + exp2.code + ")"; 876 ExpString newExp = new ExpString(true,false);
768 exp = new ExpString(code,true,false); 877 newExp.list.add( "LuanImpl.mul(luan," );
878 newExp.list.addAll( exp.list );
879 newExp.list.add( "," );
880 newExp.list.addAll( exp2.list );
881 newExp.list.add( ")" );
882 exp = newExp;
769 } else if( parser.match('/') ) { 883 } else if( parser.match('/') ) {
770 Spaces(in); 884 Spaces(in);
771 exp = exp.expr(); 885 exp = exp.expr();
772 ExpString exp2 = required(UnaryExpr(in)).expr(); 886 ExpString exp2 = required(UnaryExpr(in)).expr();
773 String code = "LuanImpl.div(luan," + exp.code + "," + exp2.code + ")"; 887 ExpString newExp = new ExpString(true,false);
774 exp = new ExpString(code,true,false); 888 newExp.list.add( "LuanImpl.div(luan," );
889 newExp.list.addAll( exp.list );
890 newExp.list.add( "," );
891 newExp.list.addAll( exp2.list );
892 newExp.list.add( ")" );
893 exp = newExp;
775 } else if( Mod() ) { 894 } else if( Mod() ) {
776 Spaces(in); 895 Spaces(in);
777 exp = exp.expr(); 896 exp = exp.expr();
778 ExpString exp2 = required(UnaryExpr(in)).expr(); 897 ExpString exp2 = required(UnaryExpr(in)).expr();
779 String code = "LuanImpl.mod(luan," + exp.code + "," + exp2.code + ")"; 898 ExpString newExp = new ExpString(true,false);
780 exp = new ExpString(code,true,false); 899 newExp.list.add( "LuanImpl.mod(luan," );
900 newExp.list.addAll( exp.list );
901 newExp.list.add( "," );
902 newExp.list.addAll( exp2.list );
903 newExp.list.add( ")" );
904 exp = newExp;
781 } else 905 } else
782 break; 906 break;
783 } 907 }
784 return parser.success(exp); 908 return parser.success(exp);
785 } 909 }
792 private ExpString UnaryExpr(In in) throws ParseException { 916 private ExpString UnaryExpr(In in) throws ParseException {
793 parser.begin(); 917 parser.begin();
794 if( parser.match('#') ) { 918 if( parser.match('#') ) {
795 Spaces(in); 919 Spaces(in);
796 ExpString exp = required(UnaryExpr(in)).expr(); 920 ExpString exp = required(UnaryExpr(in)).expr();
797 String code = "LuanImpl.len(luan," + exp.code + ")"; 921 ExpString newExp = new ExpString(true,false);
798 exp = new ExpString(code,true,false); 922 newExp.list.add( "LuanImpl.len(luan," );
799 return parser.success(exp); 923 newExp.list.addAll( exp.list );
924 newExp.list.add( ")" );
925 return parser.success(newExp);
800 } 926 }
801 if( Minus() ) { 927 if( Minus() ) {
802 Spaces(in); 928 Spaces(in);
803 ExpString exp = required(UnaryExpr(in)).expr(); 929 ExpString exp = required(UnaryExpr(in)).expr();
804 String code = "LuanImpl.unm(luan," + exp.code + ")"; 930 ExpString newExp = new ExpString(true,false);
805 exp = new ExpString(code,true,false); 931 newExp.list.add( "LuanImpl.unm(luan," );
806 return parser.success(exp); 932 newExp.list.addAll( exp.list );
933 newExp.list.add( ")" );
934 return parser.success(newExp);
807 } 935 }
808 if( Keyword("not",in) ) { 936 if( Keyword("not",in) ) {
809 Spaces(in); 937 Spaces(in);
810 ExpString exp = required(UnaryExpr(in)).expr(); 938 ExpString exp = required(UnaryExpr(in)).expr();
811 String code = "!Luan.checkBoolean(" + exp.code + ")"; 939 ExpString newExp = new ExpString(true,false);
812 exp = new ExpString(code,true,false); 940 newExp.list.add( "!Luan.checkBoolean(" );
813 return parser.success(exp); 941 newExp.list.addAll( exp.list );
942 newExp.list.add( ")" );
943 return parser.success(newExp);
814 } 944 }
815 ExpString exp = PowExpr(in); 945 ExpString exp = PowExpr(in);
816 if( exp==null ) 946 if( exp==null )
817 return parser.failure(null); 947 return parser.failure(null);
818 return parser.success(exp); 948 return parser.success(exp);
824 if( exp1==null ) 954 if( exp1==null )
825 return parser.failure(null); 955 return parser.failure(null);
826 if( parser.match('^') ) { 956 if( parser.match('^') ) {
827 Spaces(in); 957 Spaces(in);
828 ExpString exp2 = required(PowExpr(in)); 958 ExpString exp2 = required(PowExpr(in));
829 String code = "LuanImpl.pow(luan," + exp1.code + "," + exp2.code + ")"; 959 ExpString newExp = new ExpString(true,false);
830 exp1 = new ExpString(code,true,false); 960 newExp.list.add( "LuanImpl.pow(luan," );
961 newExp.list.addAll( exp1.expr().list );
962 newExp.list.add( "," );
963 newExp.list.addAll( exp2.expr().list );
964 newExp.list.add( ")" );
965 exp1 = newExp;
831 } 966 }
832 return parser.success(exp1); 967 return parser.success(exp1);
833 } 968 }
834 969
835 private ExpString SingleExpr(In in) throws ParseException { 970 private ExpString SingleExpr(In in) throws ParseException {
904 if( exp != null ) 1039 if( exp != null )
905 builder.add(exp); 1040 builder.add(exp);
906 if( !parser.match('}') ) 1041 if( !parser.match('}') )
907 throw parser.exception("Expected table element or '}'"); 1042 throw parser.exception("Expected table element or '}'");
908 Spaces(in); 1043 Spaces(in);
909 String code = "LuanImpl.table(" + expString(builder).code + ")"; 1044 exp = new ExpString(true,false);
910 return parser.success( new ExpString(code,true,false) ); 1045 exp.list.add( "LuanImpl.table(" );
1046 exp.list.addAll( expString(builder).list );
1047 exp.list.add( ")" );
1048 return parser.success( exp );
911 } 1049 }
912 1050
913 private boolean FieldSep() throws ParseException { 1051 private boolean FieldSep() throws ParseException {
914 return parser.anyOf(",;") || EndOfLine(); 1052 return parser.anyOf(",;") || EndOfLine();
915 } 1053 }
920 if( exp==null ) 1058 if( exp==null )
921 exp = NameExpr(In.NOTHING); 1059 exp = NameExpr(In.NOTHING);
922 if( exp!=null && parser.match('=') ) { 1060 if( exp!=null && parser.match('=') ) {
923 Spaces(In.NOTHING); 1061 Spaces(In.NOTHING);
924 ExpString val = RequiredExpr(In.NOTHING).expr(); 1062 ExpString val = RequiredExpr(In.NOTHING).expr();
925 String code = "new TableField(" + exp.code + "," + val.code + ")"; 1063 ExpString newExp = new ExpString(true,false);
926 builder.add( new ExpString(code,true,false) ); 1064 newExp.list.add( "new TableField(" );
1065 newExp.list.addAll( exp.list );
1066 newExp.list.add( "," );
1067 newExp.list.addAll( val.list );
1068 newExp.list.add( ")" );
1069 builder.add( newExp );
927 return parser.success(); 1070 return parser.success();
928 } 1071 }
929 parser.rollback(); 1072 parser.rollback();
930 ExpString exprs = ExprZ(In.NOTHING); 1073 ExpString exprs = ExprZ(In.NOTHING);
931 if( exprs != null ) { 1074 if( exprs != null ) {
1043 parser.failure(null); 1186 parser.failure(null);
1044 throw parser.exception("name '"+name+"' not defined"); 1187 throw parser.exception("name '"+name+"' not defined");
1045 } 1188 }
1046 1189
1047 public StmtString set(ExpString val) throws ParseException { 1190 public StmtString set(ExpString val) throws ParseException {
1048 String code = new SettableString(settable()).code + ".set(luan," + val.expr().code + ");\n"; 1191 StmtString stmt = new StmtString();
1049 return new StmtString(code); 1192 stmt.list.add( settableToString(settable()) + ".set(luan," );
1193 stmt.list.addAll( val.expr().list );
1194 stmt.list.add( ");\n" );
1195 return stmt;
1050 } 1196 }
1051 }; 1197 };
1052 } 1198 }
1053 1199
1054 private Var exprVar(final ExpString expr) { 1200 private Var exprVar(final ExpString expr) {
1082 public Settable settable() { 1228 public Settable settable() {
1083 return new SetTableEntry(expr(LuanParser.exp(table)),expr(LuanParser.exp(key))); 1229 return new SetTableEntry(expr(LuanParser.exp(table)),expr(LuanParser.exp(key)));
1084 } 1230 }
1085 */ 1231 */
1086 public StmtString set(ExpString val) { 1232 public StmtString set(ExpString val) {
1087 String code = "LuanImpl.put(luan," + table.expr().code + "," + key.expr().code + "," + val.expr().code + ");\n"; 1233 StmtString stmt = new StmtString();
1088 return new StmtString(code); 1234 stmt.list.add( "LuanImpl.put(luan," );
1235 stmt.list.addAll( table.expr().list );
1236 stmt.list.add( "," );
1237 stmt.list.addAll( key.expr().list );
1238 stmt.list.add( "," );
1239 stmt.list.addAll( val.expr().list );
1240 stmt.list.add( ");\n" );
1241 return stmt;
1089 } 1242 }
1090 }; 1243 };
1091 } 1244 }
1092 1245
1093 private ExpString Args(In in,ExpString fn,List<ExpString> builder) throws ParseException { 1246 private ExpString Args(In in,ExpString fn,List<ExpString> builder) throws ParseException {
1251 "while" 1404 "while"
1252 )); 1405 ));
1253 1406
1254 private ExpString Literal(In in) throws ParseException { 1407 private ExpString Literal(In in) throws ParseException {
1255 parser.begin(); 1408 parser.begin();
1256 if( NilLiteral(in) ) 1409 if( NilLiteral(in) ) {
1257 return parser.success(new ExpString("null",true,false)); 1410 ExpString exp = new ExpString(true,false);
1411 exp.list.add( "null" );
1412 return parser.success(exp);
1413 }
1258 Boolean b = BooleanLiteral(in); 1414 Boolean b = BooleanLiteral(in);
1259 if( b != null ) 1415 if( b != null ) {
1260 return parser.success(new ExpString(b.toString(),true,false)); 1416 ExpString exp = new ExpString(true,false);
1417 exp.list.add( b.toString() );
1418 return parser.success(exp);
1419 }
1261 Number n = NumberLiteral(in); 1420 Number n = NumberLiteral(in);
1262 if( n != null ) { 1421 if( n != null ) {
1263 String s = n.toString(); 1422 String s = n.toString();
1264 if( n instanceof Long ) 1423 if( n instanceof Long )
1265 s += "L"; 1424 s += "L";
1266 return parser.success(new ExpString(s,true,false)); 1425 ExpString exp = new ExpString(true,false);
1426 exp.list.add( s );
1427 return parser.success(exp);
1267 } 1428 }
1268 String s = StringLiteral(in); 1429 String s = StringLiteral(in);
1269 if( s != null ) 1430 if( s != null )
1270 return parser.success(constExpStr(s)); 1431 return parser.success(constExpStr(s));
1271 return parser.failure(null); 1432 return parser.failure(null);
1278 .replace("\n","\\n") 1439 .replace("\n","\\n")
1279 .replace("\r","\\r") 1440 .replace("\r","\\r")
1280 .replace("\t","\\t") 1441 .replace("\t","\\t")
1281 .replace("\b","\\b") 1442 .replace("\b","\\b")
1282 ; 1443 ;
1283 return new ExpString( "\""+s+"\"", true,false); 1444 ExpString exp = new ExpString(true,false);
1445 exp.list.add( "\""+s+"\"" );
1446 return exp;
1284 } 1447 }
1285 1448
1286 private boolean NilLiteral(In in) throws ParseException { 1449 private boolean NilLiteral(In in) throws ParseException {
1287 return Keyword("nil",in); 1450 return Keyword("nil",in);
1288 } 1451 }
1531 1694
1532 1695
1533 private static int classCounter = 0; 1696 private static int classCounter = 0;
1534 1697
1535 private class ExpString { 1698 private class ExpString {
1536 final String code; 1699 final List list = new ArrayList();
1537 final boolean isExpr; 1700 final boolean isExpr;
1538 final boolean isStmt; 1701 final boolean isStmt;
1539 1702
1540 ExpString(Expressions exp) { 1703 ExpString(Expressions exp) {
1541 if( exp==null ) throw new NullPointerException(); 1704 if( exp==null ) throw new NullPointerException();
1542 int i = LuanImpl.addObj(exp); 1705 int i = LuanImpl.addObj(exp);
1543 code = "((Expressions)LuanImpl.getObj(" + i + ")).eval(luan)"; 1706 list.add( "((Expressions)LuanImpl.getObj(" + i + ")).eval(luan)" );
1544 isExpr = exp instanceof Expr; 1707 isExpr = exp instanceof Expr;
1545 isStmt = exp instanceof StmtExp; 1708 isStmt = exp instanceof StmtExp;
1546 } 1709 }
1547 1710
1548 ExpString(String code,boolean isExpr,boolean isStmt) { 1711 ExpString(boolean isExpr,boolean isStmt) {
1549 this.code = code;
1550 this.isExpr = isExpr; 1712 this.isExpr = isExpr;
1551 this.isStmt = isStmt; 1713 this.isStmt = isStmt;
1552 } 1714 }
1553 1715
1554 ExpString expr() { 1716 ExpString expr() {
1555 return isExpr ? this : new ExpString( "Luan.first(" + code + ")", true, isStmt ); 1717 if( isExpr )
1718 return this;
1719 ExpString exp = new ExpString(true,isStmt);
1720 exp.list.addAll( list );
1721 return exp;
1556 } 1722 }
1557 } 1723 }
1558 1724
1559 private ExpString expString(List<ExpString> list) { 1725 private ExpString expString(List<ExpString> list) {
1726 ExpString exp = new ExpString(false,false);
1560 switch(list.size()) { 1727 switch(list.size()) {
1561 case 0: 1728 case 0:
1562 return new ExpString("LuanFunction.NOTHING",false,false); 1729 exp.list.add("LuanFunction.NOTHING");
1730 return exp;
1563 case 1: 1731 case 1:
1564 return list.get(0); 1732 return list.get(0);
1565 default: 1733 default:
1566 int lastI = list.size() - 1; 1734 int lastI = list.size() - 1;
1567 StringBuilder sb = new StringBuilder(); 1735 exp.list.add( "new Object[]{" );
1568 sb.append( "new Object[]{" );
1569 for( int i=0; i<lastI; i++ ) { 1736 for( int i=0; i<lastI; i++ ) {
1570 sb.append( list.get(i).expr().code ).append( ',' ); 1737 exp.list.addAll( list.get(i).expr().list );
1738 exp.list.add( "," );
1571 } 1739 }
1572 ExpString last = list.get(lastI); 1740 ExpString last = list.get(lastI);
1573 if( last.isExpr ) { 1741 if( last.isExpr ) {
1574 sb.append( last.code ).append( '}' ); 1742 exp.list.addAll( last.list );
1575 return new ExpString(sb.toString(),false,false); 1743 exp.list.add( "}" );
1576 } else { 1744 } else {
1577 sb.append( '}' ); 1745 exp.list.add( "}" );
1578 String s = "LuanImpl.concatArgs(" + sb + "," + last.code + ")"; 1746 exp.list.add( 0, "LuanImpl.concatArgs(" );
1579 return new ExpString(s,false,false); 1747 exp.list.add( "," );
1580 } 1748 exp.list.addAll( last.list );
1749 exp.list.add( ")" );
1750 }
1751 return exp;
1581 } 1752 }
1582 } 1753 }
1583 1754
1584 private static class StmtString { 1755 private static class StmtString {
1585 final String code; 1756 final List list = new ArrayList();
1586 boolean hasReturn = false; 1757 boolean hasReturn = false;
1587 1758 }
1588 StmtString(String code) {
1589 this.code = code;
1590 if( code.contains("LuanParser") ) throw new RuntimeException("\n"+code);
1591 }
1592 }
1593
1594 private static StmtString EMPTY_STMT = new StmtString("");
1595 1759
1596 private static FnDef toFnDef(StmtString stmt,int stackSize,int numArgs,boolean isVarArg,UpValue.Getter[] upValueGetters) { 1760 private static FnDef toFnDef(StmtString stmt,int stackSize,int numArgs,boolean isVarArg,UpValue.Getter[] upValueGetters) {
1761 StringBuilder sb = new StringBuilder();
1762 for( Object o : stmt.list ) {
1763 if( o instanceof List ) throw new RuntimeException();
1764 if( o instanceof ExpString ) throw new RuntimeException();
1765 if( o instanceof StmtString ) throw new RuntimeException();
1766 sb.append( o.toString() );
1767 }
1768 String code = sb.toString();
1769 //System.out.println("code:\n"+code);
1770
1597 int i = LuanImpl.addObj(upValueGetters); 1771 int i = LuanImpl.addObj(upValueGetters);
1598 String className = "EXP" + ++classCounter; 1772 String className = "EXP" + ++classCounter;
1599 String classCode = "" 1773 String classCode = ""
1600 +"package luan.impl;\n" 1774 +"package luan.impl;\n"
1601 +"import luan.Luan;\n" 1775 +"import luan.Luan;\n"
1608 +" super("+stackSize+","+numArgs+","+isVarArg+",(UpValue.Getter[])LuanImpl.getObj("+i+"));\n" 1782 +" super("+stackSize+","+numArgs+","+isVarArg+",(UpValue.Getter[])LuanImpl.getObj("+i+"));\n"
1609 +" }\n" 1783 +" }\n"
1610 +"\n" 1784 +"\n"
1611 +" @Override public Object run(LuanStateImpl luan) throws LuanException {\n" 1785 +" @Override public Object run(LuanStateImpl luan) throws LuanException {\n"
1612 +" Object t;\n" 1786 +" Object t;\n"
1613 +" " + stmt.code 1787 +" " + code
1614 +" }\n" 1788 +" }\n"
1615 +"}\n" 1789 +"}\n"
1616 ; 1790 ;
1617 try { 1791 try {
1618 //System.out.println(classCode); 1792 //System.out.println(classCode);
1627 } 1801 }
1628 } 1802 }
1629 1803
1630 private ExpString toFnExpStr(StmtString stmt,int stackSize,int numArgs,boolean isVarArg,UpValue.Getter[] upValueGetters) { 1804 private ExpString toFnExpStr(StmtString stmt,int stackSize,int numArgs,boolean isVarArg,UpValue.Getter[] upValueGetters) {
1631 int i = LuanImpl.addObj(upValueGetters); 1805 int i = LuanImpl.addObj(upValueGetters);
1632 String classCode = "" 1806 ExpString exp = new ExpString(true,false);
1807 exp.list.add( ""
1633 +"\n" 1808 +"\n"
1634 +"new FnDef("+stackSize+","+numArgs+","+isVarArg+",(UpValue.Getter[])LuanImpl.getObj("+i+")) {\n" 1809 +"new FnDef("+stackSize+","+numArgs+","+isVarArg+",(UpValue.Getter[])LuanImpl.getObj("+i+")) {\n"
1635 +" @Override public Object run(LuanStateImpl luan) throws LuanException {\n" 1810 +" @Override public Object run(LuanStateImpl luan) throws LuanException {\n"
1636 +" Object t;\n" 1811 +" Object t;\n"
1637 +" " + stmt.code 1812 +" "
1813 );
1814 exp.list.addAll( stmt.list );
1815 exp.list.add( ""
1638 +" }\n" 1816 +" }\n"
1639 +"}.eval(luan)\n" 1817 +"}.eval(luan)\n"
1640 ; 1818 );
1641 return new ExpString(classCode,true,false); 1819 return exp;
1642 } 1820 }
1643 1821
1644 1822
1645 private static class SettableString { 1823 private static String settableToString(Settable settable) {
1646 final String code; 1824 if( settable==null ) throw new NullPointerException();
1647 1825 int i = LuanImpl.addObj(settable);
1648 SettableString(Settable settable) { 1826 return"((Settable)LuanImpl.getObj(" + i + "))";
1649 if( settable==null ) throw new NullPointerException();
1650 int i = LuanImpl.addObj(settable);
1651 code = "((Settable)LuanImpl.getObj(" + i + "))";
1652 }
1653
1654 SettableString(String code) {
1655 this.code = code;
1656 }
1657
1658 } 1827 }
1659 1828
1660 } 1829 }