Mercurial Hosting > luan
comparison core/src/luan/impl/LuanParser.java @ 654:ea7dbd2dfa65
compile TemplateStmt
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Tue, 05 Apr 2016 14:16:14 -0600 |
parents | 538b0ae08faa |
children | e2be71451d04 |
comparison
equal
deleted
inserted
replaced
653:538b0ae08faa | 654:ea7dbd2dfa65 |
---|---|
215 if( stackStart < stackEnd ) | 215 if( stackStart < stackEnd ) |
216 code = "" | 216 code = "" |
217 +"try {\n" | 217 +"try {\n" |
218 + code | 218 + code |
219 +"} finally {\n" | 219 +"} finally {\n" |
220 +" $luan.stackClear("+stackStart+","+stackEnd+");\n" | 220 +" luan.stackClear("+stackStart+","+stackEnd+");\n" |
221 +"}\n" | 221 +"}\n" |
222 ; | 222 ; |
223 return new StmtString(code); | 223 return new StmtString(code); |
224 } | 224 } |
225 | 225 |
228 if( parser.match( ';' ) ) | 228 if( parser.match( ';' ) ) |
229 return parser.success(); | 229 return parser.success(); |
230 if( EndOfLine() ) | 230 if( EndOfLine() ) |
231 return parser.success(); | 231 return parser.success(); |
232 parser.rollback(); | 232 parser.rollback(); |
233 StmtString stmt = stmtStr(TemplateStmt()); | 233 StmtString stmt = TemplateStmt(); |
234 if( stmt != null ) { | 234 if( stmt != null ) { |
235 stmts.append(stmt.code); | 235 stmts.append(stmt.code); |
236 return parser.success(); | 236 return parser.success(); |
237 } | 237 } |
238 return parser.failure(); | 238 return parser.failure(); |
260 ) { | 260 ) { |
261 stmts.append(stmt.code); | 261 stmts.append(stmt.code); |
262 } | 262 } |
263 } | 263 } |
264 | 264 |
265 private Stmt TemplateStmt() throws ParseException { | 265 private ExpString indexExpStr(ExpString exp1,ExpString exp2) { |
266 parser.currentIndex(); | 266 String code = "luan.index(" + exp1.expr().code + "," + exp2.expr().code + ")"; |
267 Expressions exprs = TemplateExpressions(In.NOTHING); | 267 return new ExpString(code,true,false); |
268 } | |
269 | |
270 private ExpString constExpStr(Object obj) { | |
271 return new ExpString(new ConstExpr(obj)); | |
272 } | |
273 | |
274 private ExpString callExpStr(ExpString fn,ExpString args) { | |
275 String code = "Luan.checkFunction(" + fn.expr().code + ").call(luan,Luan.array(" + args.code + "))"; | |
276 return new ExpString(code,false,true); | |
277 } | |
278 | |
279 private StmtString TemplateStmt() throws ParseException { | |
280 ExpString exprs = TemplateExpressions(In.NOTHING); | |
268 if( exprs == null ) | 281 if( exprs == null ) |
269 return null; | 282 return null; |
270 FnCall requireCall = new FnCall( new ConstExpr(PackageLuan.requireFn), new ConstExpr("luan:Io") ); | 283 ExpString requireCall = callExpStr( constExpStr(PackageLuan.requireFn), constExpStr("luan:Io") ); |
271 Expr stdoutExp = new IndexExpr( expr(requireCall), new ConstExpr("stdout") ); | 284 ExpString stdoutExp = indexExpStr( requireCall.expr(), constExpStr("stdout") ); |
272 Expr writeExp = new IndexExpr( stdoutExp, new ConstExpr("write") ); | 285 ExpString writeExp = indexExpStr( stdoutExp, constExpStr("write") ); |
273 FnCall writeCall = new FnCall( writeExp, exprs ); | 286 ExpString writeCall = callExpStr( writeExp, exprs ); |
274 return new ExpressionsStmt(writeCall); | 287 String code = writeCall.code + ";\n"; |
275 } | 288 return new StmtString(code); |
276 | 289 } |
277 private Expressions TemplateExpressions(In in) throws ParseException { | 290 |
291 private ExpString TemplateExpressions(In in) throws ParseException { | |
278 if( in.template ) | 292 if( in.template ) |
279 return null; | 293 return null; |
280 int start = parser.begin(); | 294 int start = parser.begin(); |
281 if( !parser.match( "%>" ) ) | 295 if( !parser.match( "%>" ) ) |
282 return parser.failure(null); | 296 return parser.failure(null); |
283 EndOfLine(); | 297 EndOfLine(); |
284 In inTemplate = in.template(); | 298 In inTemplate = in.template(); |
285 List<Expressions> builder = new ArrayList<Expressions>(); | 299 List<ExpString> builder = new ArrayList<ExpString>(); |
286 while(true) { | 300 while(true) { |
287 if( parser.match( "<%=" ) ) { | 301 if( parser.match( "<%=" ) ) { |
288 Spaces(inTemplate); | 302 Spaces(inTemplate); |
289 builder.add( exp(RequiredExpr(inTemplate)) ); | 303 builder.add( RequiredExpr(inTemplate) ); |
290 RequiredMatch( "%>" ); | 304 RequiredMatch( "%>" ); |
291 } else if( parser.match( "<%" ) ) { | 305 } else if( parser.match( "<%" ) ) { |
292 Spaces(inTemplate); | 306 Spaces(inTemplate); |
293 return parser.success(ExpList.build(builder)); | 307 return parser.success(expString(builder)); |
294 } else { | 308 } else { |
295 int i = parser.currentIndex(); | 309 int i = parser.currentIndex(); |
296 do { | 310 do { |
297 if( parser.match( "%>" ) ) | 311 if( parser.match( "%>" ) ) |
298 throw parser.exception("'%>' unexpected"); | 312 throw parser.exception("'%>' unexpected"); |
299 if( !parser.anyChar() ) | 313 if( !parser.anyChar() ) |
300 throw parser.exception("Unclosed template expression"); | 314 throw parser.exception("Unclosed template expression"); |
301 } while( !parser.test( "<%" ) ); | 315 } while( !parser.test( "<%" ) ); |
302 String match = parser.textFrom(i); | 316 String match = parser.textFrom(i); |
303 builder.add( new ConstExpr(match) ); | 317 builder.add( constExpStr(match) ); |
304 } | 318 } |
305 } | 319 } |
306 } | 320 } |
307 | 321 |
308 private Stmt ReturnStmt() throws ParseException { | 322 private Stmt ReturnStmt() throws ParseException { |
375 | 389 |
376 ExpString firstVar = new ExpString(new GetLocalVar(stackStart)); | 390 ExpString firstVar = new ExpString(new GetLocalVar(stackStart)); |
377 addSymbols(names); | 391 addSymbols(names); |
378 StmtString loop = RequiredLoopBlock(); | 392 StmtString loop = RequiredLoopBlock(); |
379 RequiredKeyword("end",In.NOTHING); | 393 RequiredKeyword("end",In.NOTHING); |
380 String fnVar = "$fn"+ ++forCounter; | 394 String fnVar = "fn"+ ++forCounter; |
381 String code = "" | 395 String code = "" |
382 +"try {\n" | 396 +"try {\n" |
383 +"LuanFunction "+fnVar+" = $Luan.checkFunction(" + expr.code + ");\n" | 397 +"LuanFunction "+fnVar+" = Luan.checkFunction(" + expr.code + ");\n" |
384 +"while(true) {\n" | 398 +"while(true) {\n" |
385 +"for( int i="+stackStart+"; i<"+symbolsSize()+"; i++ ) {\n" | 399 +"for( int i="+stackStart+"; i<"+symbolsSize()+"; i++ ) {\n" |
386 +"$luan.stackSet(i,null);\n" | 400 +"luan.stackSet(i,null);\n" |
387 +"}\n" | 401 +"}\n" |
388 +"$Luan.set($luan," + varsStr + ", "+fnVar+".call($luan) );\n" | 402 +"LuanImpl.set(luan," + varsStr + ", "+fnVar+".call(luan) );\n" |
389 +"if( " + firstVar.code + "==null ) break;\n" | 403 +"if( " + firstVar.code + "==null ) break;\n" |
390 + loop.code | 404 + loop.code |
391 +"}" | 405 +"}" |
392 +"} finally {\n" | 406 +"} finally {\n" |
393 +"$luan.stackClear("+stackStart+","+symbolsSize()+");\n" | 407 +"luan.stackClear("+stackStart+","+symbolsSize()+");\n" |
394 +"}\n" | 408 +"}\n" |
395 ; | 409 ; |
396 StmtString stmt = new StmtString(code); | 410 StmtString stmt = new StmtString(code); |
397 popSymbols( symbolsSize() - stackStart ); | 411 popSymbols( symbolsSize() - stackStart ); |
398 return parser.success(stmt); | 412 return parser.success(stmt); |
426 int stackStart = symbolsSize(); | 440 int stackStart = symbolsSize(); |
427 for( int i=0; i<vars.length; i++ ) { | 441 for( int i=0; i<vars.length; i++ ) { |
428 vars[i] = new SetLocalVar(stackStart+i); | 442 vars[i] = new SetLocalVar(stackStart+i); |
429 } | 443 } |
430 String varsStr = varsToString(vars); | 444 String varsStr = varsToString(vars); |
431 String code = "$Luan.set($luan," + varsStr + "," + values.code + ");\n"; | 445 String code = "LuanImpl.set(luan," + varsStr + "," + values.code + ");\n"; |
432 stmts.append(code); | 446 stmts.append(code); |
433 } | 447 } |
434 addSymbols(names); | 448 addSymbols(names); |
435 return parser.success(); | 449 return parser.success(); |
436 } | 450 } |
473 ExpString cnd = RequiredExpr(In.NOTHING).expr(); | 487 ExpString cnd = RequiredExpr(In.NOTHING).expr(); |
474 RequiredKeyword("do",In.NOTHING); | 488 RequiredKeyword("do",In.NOTHING); |
475 StmtString loop = RequiredLoopBlock(); | 489 StmtString loop = RequiredLoopBlock(); |
476 RequiredKeyword("end",In.NOTHING); | 490 RequiredKeyword("end",In.NOTHING); |
477 String code = "" | 491 String code = "" |
478 +"while( $Luan.checkBoolean(" + cnd.code + ") ) {\n" | 492 +"while( Luan.checkBoolean(" + cnd.code + ") ) {\n" |
479 + loop.code | 493 + loop.code |
480 +"}\n" | 494 +"}\n" |
481 ; | 495 ; |
482 return parser.success( new StmtString(code) ); | 496 return parser.success( new StmtString(code) ); |
483 } | 497 } |
490 RequiredKeyword("until",In.NOTHING); | 504 RequiredKeyword("until",In.NOTHING); |
491 ExpString cnd = RequiredExpr(In.NOTHING).expr(); | 505 ExpString cnd = RequiredExpr(In.NOTHING).expr(); |
492 String code = "" | 506 String code = "" |
493 +"do {\n" | 507 +"do {\n" |
494 + loop.code | 508 + loop.code |
495 +"} while( !$Luan.checkBoolean(" + cnd.code + ") );\n" | 509 +"} while( !Luan.checkBoolean(" + cnd.code + ") );\n" |
496 ; | 510 ; |
497 return parser.success( new StmtString(code) ); | 511 return parser.success( new StmtString(code) ); |
498 } | 512 } |
499 | 513 |
500 private StmtString RequiredLoopBlock() throws ParseException { | 514 private StmtString RequiredLoopBlock() throws ParseException { |
512 ExpString cnd; | 526 ExpString cnd; |
513 StmtString block; | 527 StmtString block; |
514 cnd = RequiredExpr(In.NOTHING).expr(); | 528 cnd = RequiredExpr(In.NOTHING).expr(); |
515 RequiredKeyword("then",In.NOTHING); | 529 RequiredKeyword("then",In.NOTHING); |
516 block = RequiredBlock(); | 530 block = RequiredBlock(); |
517 sb.append( "if( $Luan.checkBoolean(" ).append( cnd.code ).append( ") ) {\n" ).append( block.code ); | 531 sb.append( "if( Luan.checkBoolean(" ).append( cnd.code ).append( ") ) {\n" ).append( block.code ); |
518 while( Keyword("elseif",In.NOTHING) ) { | 532 while( Keyword("elseif",In.NOTHING) ) { |
519 cnd = RequiredExpr(In.NOTHING).expr(); | 533 cnd = RequiredExpr(In.NOTHING).expr(); |
520 RequiredKeyword("then",In.NOTHING); | 534 RequiredKeyword("then",In.NOTHING); |
521 block = RequiredBlock(); | 535 block = RequiredBlock(); |
522 sb.append( "} else if( $Luan.checkBoolean(" ).append( cnd.code ).append( ") ) {\n" ).append( block.code ); | 536 sb.append( "} else if( Luan.checkBoolean(" ).append( cnd.code ).append( ") ) {\n" ).append( block.code ); |
523 } | 537 } |
524 if( Keyword("else",In.NOTHING) ) { | 538 if( Keyword("else",In.NOTHING) ) { |
525 block = RequiredBlock(); | 539 block = RequiredBlock(); |
526 sb.append( "} else {\n" ).append( block.code ); | 540 sb.append( "} else {\n" ).append( block.code ); |
527 } | 541 } |
550 ExpString values = ExpStringList(In.NOTHING); | 564 ExpString values = ExpStringList(In.NOTHING); |
551 if( values==null ) | 565 if( values==null ) |
552 // throw parser.exception("Expressions expected"); | 566 // throw parser.exception("Expressions expected"); |
553 return parser.failure(null); | 567 return parser.failure(null); |
554 String varsStr = varsToString(vars.toArray(new Settable[0])); | 568 String varsStr = varsToString(vars.toArray(new Settable[0])); |
555 String code = "$Luan.set($luan," + varsStr + "," + values.code + "); "; | 569 String code = "LuanImpl.set(luan," + varsStr + "," + values.code + "); "; |
556 return parser.success( new StmtString(code) ); | 570 return parser.success( new StmtString(code) ); |
557 } | 571 } |
558 | 572 |
559 private static String varsToString(Settable[] vars) { | 573 private static String varsToString(Settable[] vars) { |
560 StringBuilder sb = new StringBuilder(); | 574 StringBuilder sb = new StringBuilder(); |
570 parser.begin(); | 584 parser.begin(); |
571 ExpString exp = ExprZ(In.NOTHING); | 585 ExpString exp = ExprZ(In.NOTHING); |
572 if( exp != null && exp.isStmt ) { | 586 if( exp != null && exp.isStmt ) { |
573 String code = exp.code; | 587 String code = exp.code; |
574 if( exp.isExpr ) | 588 if( exp.isExpr ) |
575 code = "$Luan.nop(" + code + ")"; | 589 code = "LuanImpl.nop(" + code + ")"; |
576 code += ";\n"; | 590 code += ";\n"; |
577 return parser.success( new StmtString(code) ); | 591 return parser.success( new StmtString(code) ); |
578 } | 592 } |
579 return parser.failure(null); | 593 return parser.failure(null); |
580 } | 594 } |
602 if( exp==null ) | 616 if( exp==null ) |
603 return parser.failure(null); | 617 return parser.failure(null); |
604 while( Keyword("or",in) ) { | 618 while( Keyword("or",in) ) { |
605 exp = exp.expr(); | 619 exp = exp.expr(); |
606 ExpString exp2 = required(RelExpr(in)).expr(); | 620 ExpString exp2 = required(RelExpr(in)).expr(); |
607 String code = "($Luan.cnd($cnd = " + exp.code + ") ? $cnd : (" + exp2.code + "))"; | 621 String code = "(LuanImpl.cnd(cnd = " + exp.code + ") ? cnd : (" + exp2.code + "))"; |
608 exp = new ExpString(code,true,true); | 622 exp = new ExpString(code,true,true); |
609 } | 623 } |
610 return parser.success(exp); | 624 return parser.success(exp); |
611 } | 625 } |
612 | 626 |
616 if( exp==null ) | 630 if( exp==null ) |
617 return parser.failure(null); | 631 return parser.failure(null); |
618 while( Keyword("and",in) ) { | 632 while( Keyword("and",in) ) { |
619 exp = exp.expr(); | 633 exp = exp.expr(); |
620 ExpString exp2 = required(RelExpr(in)).expr(); | 634 ExpString exp2 = required(RelExpr(in)).expr(); |
621 String code = "($Luan.cnd($cnd = " + exp.code + ") ? (" + exp2.code + ") : $cnd)"; | 635 String code = "(LuanImpl.cnd(cnd = " + exp.code + ") ? (" + exp2.code + ") : cnd)"; |
622 exp = new ExpString(code,true,true); | 636 exp = new ExpString(code,true,true); |
623 } | 637 } |
624 return parser.success(exp); | 638 return parser.success(exp); |
625 } | 639 } |
626 | 640 |
632 while(true) { | 646 while(true) { |
633 if( parser.match("==") ) { | 647 if( parser.match("==") ) { |
634 Spaces(in); | 648 Spaces(in); |
635 exp = exp.expr(); | 649 exp = exp.expr(); |
636 ExpString exp2 = required(ConcatExpr(in)).expr(); | 650 ExpString exp2 = required(ConcatExpr(in)).expr(); |
637 String code = "$Luan.eq($luan," + exp.code + "," + exp2.code + ")"; | 651 String code = "LuanImpl.eq(luan," + exp.code + "," + exp2.code + ")"; |
638 exp = new ExpString(code,true,false); | 652 exp = new ExpString(code,true,false); |
639 } else if( parser.match("~=") ) { | 653 } else if( parser.match("~=") ) { |
640 Spaces(in); | 654 Spaces(in); |
641 exp = exp.expr(); | 655 exp = exp.expr(); |
642 ExpString exp2 = required(ConcatExpr(in)).expr(); | 656 ExpString exp2 = required(ConcatExpr(in)).expr(); |
643 String code = "!$Luan.eq($luan," + exp.code + "," + exp2.code + ")"; | 657 String code = "!LuanImpl.eq(luan," + exp.code + "," + exp2.code + ")"; |
644 exp = new ExpString(code,true,false); | 658 exp = new ExpString(code,true,false); |
645 } else if( parser.match("<=") ) { | 659 } else if( parser.match("<=") ) { |
646 Spaces(in); | 660 Spaces(in); |
647 exp = exp.expr(); | 661 exp = exp.expr(); |
648 ExpString exp2 = required(ConcatExpr(in)).expr(); | 662 ExpString exp2 = required(ConcatExpr(in)).expr(); |
649 String code = "$Luan.le($luan," + exp.code + "," + exp2.code + ")"; | 663 String code = "LuanImpl.le(luan," + exp.code + "," + exp2.code + ")"; |
650 exp = new ExpString(code,true,false); | 664 exp = new ExpString(code,true,false); |
651 } else if( parser.match(">=") ) { | 665 } else if( parser.match(">=") ) { |
652 Spaces(in); | 666 Spaces(in); |
653 exp = exp.expr(); | 667 exp = exp.expr(); |
654 ExpString exp2 = required(ConcatExpr(in)).expr(); | 668 ExpString exp2 = required(ConcatExpr(in)).expr(); |
655 String code = "$Luan.le($luan," + exp2.code + "," + exp.code + ")"; | 669 String code = "LuanImpl.le(luan," + exp2.code + "," + exp.code + ")"; |
656 exp = new ExpString(code,true,false); | 670 exp = new ExpString(code,true,false); |
657 } else if( parser.match("<") ) { | 671 } else if( parser.match("<") ) { |
658 Spaces(in); | 672 Spaces(in); |
659 exp = exp.expr(); | 673 exp = exp.expr(); |
660 ExpString exp2 = required(ConcatExpr(in)).expr(); | 674 ExpString exp2 = required(ConcatExpr(in)).expr(); |
661 String code = "$Luan.lt($luan," + exp.code + "," + exp2.code + ")"; | 675 String code = "LuanImpl.lt(luan," + exp.code + "," + exp2.code + ")"; |
662 exp = new ExpString(code,true,false); | 676 exp = new ExpString(code,true,false); |
663 } else if( parser.match(">") ) { | 677 } else if( parser.match(">") ) { |
664 Spaces(in); | 678 Spaces(in); |
665 exp = exp.expr(); | 679 exp = exp.expr(); |
666 ExpString exp2 = required(ConcatExpr(in)).expr(); | 680 ExpString exp2 = required(ConcatExpr(in)).expr(); |
667 String code = "$Luan.lt($luan," + exp2.code + "," + exp.code + ")"; | 681 String code = "LuanImpl.lt(luan," + exp2.code + "," + exp.code + ")"; |
668 exp = new ExpString(code,true,false); | 682 exp = new ExpString(code,true,false); |
669 } else | 683 } else |
670 break; | 684 break; |
671 } | 685 } |
672 return parser.success(exp); | 686 return parser.success(exp); |
679 return parser.failure(null); | 693 return parser.failure(null); |
680 if( parser.match("..") ) { | 694 if( parser.match("..") ) { |
681 Spaces(in); | 695 Spaces(in); |
682 exp = exp.expr(); | 696 exp = exp.expr(); |
683 ExpString exp2 = required(ConcatExpr(in)).expr(); | 697 ExpString exp2 = required(ConcatExpr(in)).expr(); |
684 String code = "$Luan.concat($luan," + exp.code + "," + exp2.code + ")"; | 698 String code = "LuanImpl.concat(luan," + exp.code + "," + exp2.code + ")"; |
685 exp = new ExpString(code,true,false); | 699 exp = new ExpString(code,true,false); |
686 } | 700 } |
687 return parser.success(exp); | 701 return parser.success(exp); |
688 } | 702 } |
689 | 703 |
695 while(true) { | 709 while(true) { |
696 if( parser.match('+') ) { | 710 if( parser.match('+') ) { |
697 Spaces(in); | 711 Spaces(in); |
698 exp = exp.expr(); | 712 exp = exp.expr(); |
699 ExpString exp2 = required(TermExpr(in)).expr(); | 713 ExpString exp2 = required(TermExpr(in)).expr(); |
700 String code = "$Luan.add($luan," + exp.code + "," + exp2.code + ")"; | 714 String code = "LuanImpl.add(luan," + exp.code + "," + exp2.code + ")"; |
701 exp = new ExpString(code,true,false); | 715 exp = new ExpString(code,true,false); |
702 } else if( Minus() ) { | 716 } else if( Minus() ) { |
703 Spaces(in); | 717 Spaces(in); |
704 exp = exp.expr(); | 718 exp = exp.expr(); |
705 ExpString exp2 = required(TermExpr(in)).expr(); | 719 ExpString exp2 = required(TermExpr(in)).expr(); |
706 String code = "$Luan.sub($luan," + exp.code + "," + exp2.code + ")"; | 720 String code = "LuanImpl.sub(luan," + exp.code + "," + exp2.code + ")"; |
707 exp = new ExpString(code,true,false); | 721 exp = new ExpString(code,true,false); |
708 } else | 722 } else |
709 break; | 723 break; |
710 } | 724 } |
711 return parser.success(exp); | 725 return parser.success(exp); |
724 while(true) { | 738 while(true) { |
725 if( parser.match('*') ) { | 739 if( parser.match('*') ) { |
726 Spaces(in); | 740 Spaces(in); |
727 exp = exp.expr(); | 741 exp = exp.expr(); |
728 ExpString exp2 = required(UnaryExpr(in)).expr(); | 742 ExpString exp2 = required(UnaryExpr(in)).expr(); |
729 String code = "$Luan.mul($luan," + exp.code + "," + exp2.code + ")"; | 743 String code = "LuanImpl.mul(luan," + exp.code + "," + exp2.code + ")"; |
730 exp = new ExpString(code,true,false); | 744 exp = new ExpString(code,true,false); |
731 } else if( parser.match('/') ) { | 745 } else if( parser.match('/') ) { |
732 Spaces(in); | 746 Spaces(in); |
733 exp = exp.expr(); | 747 exp = exp.expr(); |
734 ExpString exp2 = required(UnaryExpr(in)).expr(); | 748 ExpString exp2 = required(UnaryExpr(in)).expr(); |
735 String code = "$Luan.div($luan," + exp.code + "," + exp2.code + ")"; | 749 String code = "LuanImpl.div(luan," + exp.code + "," + exp2.code + ")"; |
736 exp = new ExpString(code,true,false); | 750 exp = new ExpString(code,true,false); |
737 } else if( Mod() ) { | 751 } else if( Mod() ) { |
738 Spaces(in); | 752 Spaces(in); |
739 exp = exp.expr(); | 753 exp = exp.expr(); |
740 ExpString exp2 = required(UnaryExpr(in)).expr(); | 754 ExpString exp2 = required(UnaryExpr(in)).expr(); |
741 String code = "$Luan.mod($luan," + exp.code + "," + exp2.code + ")"; | 755 String code = "LuanImpl.mod(luan," + exp.code + "," + exp2.code + ")"; |
742 exp = new ExpString(code,true,false); | 756 exp = new ExpString(code,true,false); |
743 } else | 757 } else |
744 break; | 758 break; |
745 } | 759 } |
746 return parser.success(exp); | 760 return parser.success(exp); |
754 private ExpString UnaryExpr(In in) throws ParseException { | 768 private ExpString UnaryExpr(In in) throws ParseException { |
755 parser.begin(); | 769 parser.begin(); |
756 if( parser.match('#') ) { | 770 if( parser.match('#') ) { |
757 Spaces(in); | 771 Spaces(in); |
758 ExpString exp = required(UnaryExpr(in)).expr(); | 772 ExpString exp = required(UnaryExpr(in)).expr(); |
759 String code = "$Luan.len($luan," + exp.code + ")"; | 773 String code = "LuanImpl.len(luan," + exp.code + ")"; |
760 exp = new ExpString(code,true,false); | 774 exp = new ExpString(code,true,false); |
761 return parser.success(exp); | 775 return parser.success(exp); |
762 } | 776 } |
763 if( Minus() ) { | 777 if( Minus() ) { |
764 Spaces(in); | 778 Spaces(in); |
765 ExpString exp = required(UnaryExpr(in)).expr(); | 779 ExpString exp = required(UnaryExpr(in)).expr(); |
766 String code = "$Luan.unm($luan," + exp.code + ")"; | 780 String code = "LuanImpl.unm(luan," + exp.code + ")"; |
767 exp = new ExpString(code,true,false); | 781 exp = new ExpString(code,true,false); |
768 return parser.success(exp); | 782 return parser.success(exp); |
769 } | 783 } |
770 if( Keyword("not",in) ) { | 784 if( Keyword("not",in) ) { |
771 Spaces(in); | 785 Spaces(in); |
772 ExpString exp = required(UnaryExpr(in)).expr(); | 786 ExpString exp = required(UnaryExpr(in)).expr(); |
773 String code = "$Luan.not(" + exp.code + ")"; | 787 String code = "!Luan.checkBoolean(" + exp.code + ")"; |
774 exp = new ExpString(code,true,false); | 788 exp = new ExpString(code,true,false); |
775 return parser.success(exp); | 789 return parser.success(exp); |
776 } | 790 } |
777 ExpString exp = PowExpr(in); | 791 ExpString exp = PowExpr(in); |
778 if( exp==null ) | 792 if( exp==null ) |
787 return parser.failure(null); | 801 return parser.failure(null); |
788 ExpString exp1 = new ExpString(exp); | 802 ExpString exp1 = new ExpString(exp); |
789 if( parser.match('^') ) { | 803 if( parser.match('^') ) { |
790 Spaces(in); | 804 Spaces(in); |
791 ExpString exp2 = required(PowExpr(in)); | 805 ExpString exp2 = required(PowExpr(in)); |
792 String code = "$Luan.pow($luan," + exp1.code + "," + exp2.code + ")"; | 806 String code = "LuanImpl.pow(luan," + exp1.code + "," + exp2.code + ")"; |
793 exp1 = new ExpString(code,true,false); | 807 exp1 = new ExpString(code,true,false); |
794 } | 808 } |
795 return parser.success(exp1); | 809 return parser.success(exp1); |
796 } | 810 } |
797 | 811 |
863 Field(fields,builder); | 877 Field(fields,builder); |
864 while( FieldSep() ) { | 878 while( FieldSep() ) { |
865 Spaces(In.NOTHING); | 879 Spaces(In.NOTHING); |
866 Field(fields,builder); | 880 Field(fields,builder); |
867 } | 881 } |
868 Expressions exp = TemplateExpressions(In.NOTHING); | 882 Expressions exp = exp(TemplateExpressions(In.NOTHING)); |
869 if( exp != null ) | 883 if( exp != null ) |
870 builder.add(exp); | 884 builder.add(exp); |
871 if( !parser.match('}') ) | 885 if( !parser.match('}') ) |
872 throw parser.exception("Expected table element or '}'"); | 886 throw parser.exception("Expected table element or '}'"); |
873 Spaces(in); | 887 Spaces(in); |
1071 return ExpList(in,builder) ? ExpList.build(expList(builder)) : null; | 1085 return ExpList(in,builder) ? ExpList.build(expList(builder)) : null; |
1072 } | 1086 } |
1073 | 1087 |
1074 private ExpString ExpStringList(In in) throws ParseException { | 1088 private ExpString ExpStringList(In in) throws ParseException { |
1075 List<ExpString> builder = new ArrayList<ExpString>(); | 1089 List<ExpString> builder = new ArrayList<ExpString>(); |
1076 return ExpList(in,builder) ? exp(builder) : null; | 1090 return ExpList(in,builder) ? expString(builder) : null; |
1077 } | 1091 } |
1078 | 1092 |
1079 private boolean ExpList(In in,List<ExpString> builder) throws ParseException { | 1093 private boolean ExpList(In in,List<ExpString> builder) throws ParseException { |
1080 parser.begin(); | 1094 parser.begin(); |
1081 Expressions exp = TemplateExpressions(in); | 1095 ExpString exp = TemplateExpressions(in); |
1082 if( exp != null ) { | 1096 if( exp != null ) { |
1083 builder.add(new ExpString(exp)); | 1097 builder.add(exp); |
1084 return parser.success(); | 1098 return parser.success(); |
1085 } | 1099 } |
1086 ExpString es = ExprZ(in); | 1100 exp = ExprZ(in); |
1087 if( es==null ) | 1101 if( exp==null ) |
1088 return parser.failure(); | 1102 return parser.failure(); |
1089 builder.add(es); | 1103 builder.add(exp); |
1090 while( parser.match(',') ) { | 1104 while( parser.match(',') ) { |
1091 Spaces(in); | 1105 Spaces(in); |
1092 exp = TemplateExpressions(in); | 1106 exp = TemplateExpressions(in); |
1093 if( exp != null ) { | 1107 if( exp != null ) { |
1094 builder.add(new ExpString(exp)); | 1108 builder.add(exp); |
1095 return parser.success(); | 1109 return parser.success(); |
1096 } | 1110 } |
1097 builder.add( RequiredExpr(in) ); | 1111 builder.add( RequiredExpr(in) ); |
1098 } | 1112 } |
1099 return parser.success(); | 1113 return parser.success(); |
1464 final boolean isExpr; | 1478 final boolean isExpr; |
1465 final boolean isStmt; | 1479 final boolean isStmt; |
1466 | 1480 |
1467 ExpString(Expressions exp) { | 1481 ExpString(Expressions exp) { |
1468 if( exp==null ) throw new NullPointerException(); | 1482 if( exp==null ) throw new NullPointerException(); |
1469 int i = $Luan.addExpressions(exp); | 1483 int i = LuanImpl.addExpressions(exp); |
1470 code = "$Luan.getExpressions(" + i + ").eval($luan)"; | 1484 code = "LuanImpl.getExpressions(" + i + ").eval(luan)"; |
1471 isExpr = exp instanceof Expr; | 1485 isExpr = exp instanceof Expr; |
1472 isStmt = exp instanceof StmtExp; | 1486 isStmt = exp instanceof StmtExp; |
1473 } | 1487 } |
1474 | 1488 |
1475 ExpString(String code,boolean isExpr,boolean isStmt) { | 1489 ExpString(String code,boolean isExpr,boolean isStmt) { |
1477 this.isExpr = isExpr; | 1491 this.isExpr = isExpr; |
1478 this.isStmt = isStmt; | 1492 this.isStmt = isStmt; |
1479 } | 1493 } |
1480 | 1494 |
1481 ExpString expr() { | 1495 ExpString expr() { |
1482 return isExpr ? this : new ExpString( "$Luan.first(" + code + ")", true, isStmt ); | 1496 return isExpr ? this : new ExpString( "Luan.first(" + code + ")", true, isStmt ); |
1483 } | 1497 } |
1484 | 1498 |
1485 Expressions toExpressions() { | 1499 Expressions toExpressions() { |
1486 String superClass = isStmt ? "StmtExp" : "Expressions"; | 1500 String superClass = isStmt ? "StmtExp" : "Expressions"; |
1487 String className = "EXP" + ++classCounter; | 1501 String className = "EXP" + ++classCounter; |
1488 String classCode = "" | 1502 String classCode = "" |
1489 +"package luan.impl;\n" | 1503 +"package luan.impl;\n" |
1504 +"import luan.Luan;\n" | |
1490 +"import luan.LuanException;\n" | 1505 +"import luan.LuanException;\n" |
1491 +"\n" | 1506 +"\n" |
1492 +"public class " + className +" implements " + superClass + " {\n" | 1507 +"public class " + className +" implements " + superClass + " {\n" |
1493 +" @Override public Object eval(LuanStateImpl $luan) throws LuanException {\n" | 1508 +" @Override public Object eval(LuanStateImpl luan) throws LuanException {\n" |
1494 +" Object $cnd;\n" | 1509 +" Object cnd;\n" |
1495 +" return " + code + ";\n" | 1510 +" return " + code + ";\n" |
1496 +" }\n" | 1511 +" }\n" |
1497 +"}\n" | 1512 +"}\n" |
1498 ; | 1513 ; |
1499 //System.out.println(code); | 1514 //System.out.println(code); |
1512 | 1527 |
1513 private static Expressions exp(ExpString expStr) { | 1528 private static Expressions exp(ExpString expStr) { |
1514 return expStr==null ? null : expStr.toExpressions(); | 1529 return expStr==null ? null : expStr.toExpressions(); |
1515 } | 1530 } |
1516 | 1531 |
1517 private ExpString exp(List<ExpString> list) { | 1532 private ExpString expString(List<ExpString> list) { |
1518 switch(list.size()) { | 1533 switch(list.size()) { |
1519 case 0: | 1534 case 0: |
1520 return new ExpString("LuanFunction.NOTHING",false,false); | 1535 return new ExpString("LuanFunction.NOTHING",false,false); |
1521 case 1: | 1536 case 1: |
1522 return list.get(0); | 1537 return list.get(0); |
1531 if( last.isExpr ) { | 1546 if( last.isExpr ) { |
1532 sb.append( last.code ).append( '}' ); | 1547 sb.append( last.code ).append( '}' ); |
1533 return new ExpString(sb.toString(),false,false); | 1548 return new ExpString(sb.toString(),false,false); |
1534 } else { | 1549 } else { |
1535 sb.append( '}' ); | 1550 sb.append( '}' ); |
1536 String s = "$Luan.concatArgs(" + sb + "," + last.code + ")"; | 1551 String s = "LuanImpl.concatArgs(" + sb + "," + last.code + ")"; |
1537 return new ExpString(s,false,false); | 1552 return new ExpString(s,false,false); |
1538 } | 1553 } |
1539 } | 1554 } |
1540 } | 1555 } |
1541 | 1556 |
1550 private static class StmtString { | 1565 private static class StmtString { |
1551 final String code; | 1566 final String code; |
1552 | 1567 |
1553 StmtString(Stmt stmt) { | 1568 StmtString(Stmt stmt) { |
1554 if( stmt==null ) throw new NullPointerException(); | 1569 if( stmt==null ) throw new NullPointerException(); |
1555 int i = $Luan.addStmt(stmt); | 1570 int i = LuanImpl.addStmt(stmt); |
1556 code = "$Luan.getStmt(" + i + ").eval($luan);\n"; | 1571 code = "LuanImpl.getStmt(" + i + ").eval(luan);\n"; |
1557 } | 1572 } |
1558 | 1573 |
1559 StmtString(String code) { | 1574 StmtString(String code) { |
1560 this.code = code; | 1575 this.code = code; |
1561 if( code.contains("LuanParser") ) throw new RuntimeException("\n"+code); | 1576 if( code.contains("LuanParser") ) throw new RuntimeException("\n"+code); |
1563 | 1578 |
1564 Stmt toStmt() { | 1579 Stmt toStmt() { |
1565 String className = "EXP" + ++classCounter; | 1580 String className = "EXP" + ++classCounter; |
1566 String classCode = "" | 1581 String classCode = "" |
1567 +"package luan.impl;\n" | 1582 +"package luan.impl;\n" |
1583 +"import luan.Luan;\n" | |
1568 +"import luan.LuanFunction;\n" | 1584 +"import luan.LuanFunction;\n" |
1569 +"import luan.LuanException;\n" | 1585 +"import luan.LuanException;\n" |
1570 +"\n" | 1586 +"\n" |
1571 +"public class " + className +" implements Stmt {\n" | 1587 +"public class " + className +" implements Stmt {\n" |
1572 +" @Override public void eval(LuanStateImpl $luan) throws LuanException {\n" | 1588 +" @Override public void eval(LuanStateImpl luan) throws LuanException {\n" |
1573 +" Object $cnd;\n" | 1589 +" Object cnd;\n" |
1574 +" " + code | 1590 +" " + code |
1575 +" }\n" | 1591 +" }\n" |
1576 +"}\n" | 1592 +"}\n" |
1577 ; | 1593 ; |
1578 //System.out.println(code); | 1594 //System.out.println(code); |
1603 private static class SettableString { | 1619 private static class SettableString { |
1604 final String code; | 1620 final String code; |
1605 | 1621 |
1606 SettableString(Settable settable) { | 1622 SettableString(Settable settable) { |
1607 if( settable==null ) throw new NullPointerException(); | 1623 if( settable==null ) throw new NullPointerException(); |
1608 int i = $Luan.addSettable(settable); | 1624 int i = LuanImpl.addSettable(settable); |
1609 code = "$Luan.getSettable(" + i + ")"; | 1625 code = "LuanImpl.getSettable(" + i + ")"; |
1610 } | 1626 } |
1611 | 1627 |
1612 SettableString(String code) { | 1628 SettableString(String code) { |
1613 this.code = code; | 1629 this.code = code; |
1614 } | 1630 } |