Mercurial Hosting > luan
comparison src/luan/impl/LuanParser.java @ 1384:f5368cd8c056
remove template expressions and String.concat
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Thu, 15 Aug 2019 14:33:35 -0600 |
parents | e0cf0d108a77 |
children | 221eedb0f54e |
comparison
equal
deleted
inserted
replaced
1383:a3d0d1c2ce89 | 1384:f5368cd8c056 |
---|---|
166 return sym != null ? sym : getUpSym(name); | 166 return sym != null ? sym : getUpSym(name); |
167 } | 167 } |
168 | 168 |
169 } | 169 } |
170 | 170 |
171 private static class In { | |
172 static final In NOTHING = new In(false); | |
173 | |
174 final boolean template; | |
175 | |
176 private In(boolean template) { | |
177 this.template = template; | |
178 } | |
179 | |
180 In template() { | |
181 return template ? this : new In(true); | |
182 } | |
183 } | |
184 | |
185 private Frame frame; | 171 private Frame frame; |
186 private final Parser parser; | 172 private final Parser parser; |
187 private final Stmts top; | 173 private final Stmts top; |
188 | 174 |
189 LuanParser(String sourceText,String sourceName) { | 175 LuanParser(String sourceText,String sourceName) { |
248 } | 234 } |
249 /* | 235 /* |
250 Class Expression() throws ParseException { | 236 Class Expression() throws ParseException { |
251 Spaces(); | 237 Spaces(); |
252 parser.begin(); | 238 parser.begin(); |
253 Expr expr = ExprZ(In.NOTHING); | 239 Expr expr = ExprZ(); |
254 if( expr != null && parser.endOfInput() ) { | 240 if( expr != null && parser.endOfInput() ) { |
255 top.add( "return " ); | 241 top.add( "return " ); |
256 top.addAll( expr ); | 242 top.addAll( expr ); |
257 top.add( "; " ); | 243 top.add( "; " ); |
258 top.hasReturn = true; | 244 top.hasReturn = true; |
371 exp.add( ")" ); | 357 exp.add( ")" ); |
372 return exp; | 358 return exp; |
373 } | 359 } |
374 | 360 |
375 private Stmts TemplateStmt() throws ParseException { | 361 private Stmts TemplateStmt() throws ParseException { |
376 Expr exprs = TemplateExpressions(In.NOTHING); | 362 Expr exprs = TemplateExpressions(); |
377 if( exprs == null ) | 363 if( exprs == null ) |
378 return null; | 364 return null; |
379 Stmts stmt = new Stmts(); | 365 Stmts stmt = new Stmts(); |
380 stmt.add( "Luan.checkFunction(luan.index(PackageLuan.require(luan,\"luan:Io.luan\"),\"template_write\")).call(" ); | 366 stmt.add( "Luan.checkFunction(luan.index(PackageLuan.require(luan,\"luan:Io.luan\"),\"template_write\")).call(" ); |
381 stmt.addAll( exprs.array() ); | 367 stmt.addAll( exprs.array() ); |
382 stmt.add( "); " ); | 368 stmt.add( "); " ); |
383 return stmt; | 369 return stmt; |
384 } | 370 } |
385 | 371 |
386 private Expr TemplateExpressions(In in) throws ParseException { | 372 private Expr TemplateExpressions() throws ParseException { |
387 if( in.template ) | |
388 return null; | |
389 int start = parser.begin(); | 373 int start = parser.begin(); |
390 if( !parser.match( "%>" ) ) | 374 if( !parser.match( "%>" ) ) |
391 return parser.failure(null); | 375 return parser.failure(null); |
392 EndOfLine(); | 376 EndOfLine(); |
393 In inTemplate = in.template(); | |
394 List<Expr> builder = new ArrayList<Expr>(); | 377 List<Expr> builder = new ArrayList<Expr>(); |
395 while(true) { | 378 while(true) { |
396 if( parser.match( "<%=" ) ) { | 379 if( parser.match( "<%=" ) ) { |
397 Spaces(); | 380 Spaces(); |
398 Expr exp = new Expr(Val.SINGLE,false); | 381 Expr exp = new Expr(Val.SINGLE,false); |
399 exp.addAll( RequiredExpr(inTemplate).single() ); | 382 exp.addAll( RequiredExpr().single() ); |
400 builder.add(exp); | 383 builder.add(exp); |
401 RequiredMatch( "%>" ); | 384 RequiredMatch( "%>" ); |
402 } else if( parser.match( "<%" ) ) { | 385 } else if( parser.match( "<%" ) ) { |
403 Spaces(); | 386 Spaces(); |
404 return parser.success(expString(builder)); | 387 return parser.success(expString(builder)); |
424 | 407 |
425 private Stmts ReturnStmt() throws ParseException { | 408 private Stmts ReturnStmt() throws ParseException { |
426 parser.begin(); | 409 parser.begin(); |
427 if( !Keyword("return") ) | 410 if( !Keyword("return") ) |
428 return parser.failure(null); | 411 return parser.failure(null); |
429 Expr exprs = ExpStringList(In.NOTHING); | 412 Expr exprs = ExpStringList(); |
430 Stmts stmt = new Stmts(); | 413 Stmts stmt = new Stmts(); |
431 stmt.add( "return " ); | 414 stmt.add( "return " ); |
432 if( exprs != null ) | 415 if( exprs != null ) |
433 stmt.addAll( exprs ); | 416 stmt.addAll( exprs ); |
434 else | 417 else |
501 if( !Keyword("for") ) | 484 if( !Keyword("for") ) |
502 return parser.failure(null); | 485 return parser.failure(null); |
503 List<String> names = RequiredNameList(); | 486 List<String> names = RequiredNameList(); |
504 if( !Keyword("in") ) | 487 if( !Keyword("in") ) |
505 return parser.failure(null); | 488 return parser.failure(null); |
506 Expr expr = RequiredExpr(In.NOTHING).single(); | 489 Expr expr = RequiredExpr().single(); |
507 RequiredKeyword("do"); | 490 RequiredKeyword("do"); |
508 | 491 |
509 String fnVar = "fn"+ ++forCounter; | 492 String fnVar = "fn"+ ++forCounter; |
510 Expr fnExp = new Expr(null,false); | 493 Expr fnExp = new Expr(null,false); |
511 fnExp.add( fnVar + ".call()" ); | 494 fnExp.add( fnVar + ".call()" ); |
548 throw parser.exception("Invalid local statement"); | 531 throw parser.exception("Invalid local statement"); |
549 } | 532 } |
550 Stmts stmt = new Stmts(); | 533 Stmts stmt = new Stmts(); |
551 if( parser.match( '=' ) ) { | 534 if( parser.match( '=' ) ) { |
552 Spaces(); | 535 Spaces(); |
553 Expr values = ExpStringList(In.NOTHING); | 536 Expr values = ExpStringList(); |
554 if( values==null ) | 537 if( values==null ) |
555 throw parser.exception("Expressions expected"); | 538 throw parser.exception("Expressions expected"); |
556 stmt.addAll( makeLocalSetStmt(names,values) ); | 539 stmt.addAll( makeLocalSetStmt(names,values) ); |
557 } else { | 540 } else { |
558 Expr value = new Expr(Val.SINGLE,false); | 541 Expr value = new Expr(Val.SINGLE,false); |
597 | 580 |
598 private Stmts WhileStmt() throws ParseException { | 581 private Stmts WhileStmt() throws ParseException { |
599 parser.begin(); | 582 parser.begin(); |
600 if( !Keyword("while") ) | 583 if( !Keyword("while") ) |
601 return parser.failure(null); | 584 return parser.failure(null); |
602 Expr cnd = RequiredExpr(In.NOTHING).single(); | 585 Expr cnd = RequiredExpr().single(); |
603 RequiredKeyword("do"); | 586 RequiredKeyword("do"); |
604 Stmts loop = RequiredLoopBlock(); | 587 Stmts loop = RequiredLoopBlock(); |
605 RequiredEnd("end_while"); | 588 RequiredEnd("end_while"); |
606 Stmts stmt = new Stmts(); | 589 Stmts stmt = new Stmts(); |
607 stmt.add( "while( Luan.checkBoolean(" ); | 590 stmt.add( "while( Luan.checkBoolean(" ); |
616 parser.begin(); | 599 parser.begin(); |
617 if( !Keyword("repeat") ) | 600 if( !Keyword("repeat") ) |
618 return parser.failure(null); | 601 return parser.failure(null); |
619 Stmts loop =RequiredLoopBlock(); | 602 Stmts loop =RequiredLoopBlock(); |
620 RequiredKeyword("until"); | 603 RequiredKeyword("until"); |
621 Expr cnd = RequiredExpr(In.NOTHING).single(); | 604 Expr cnd = RequiredExpr().single(); |
622 Stmts stmt = new Stmts(); | 605 Stmts stmt = new Stmts(); |
623 stmt.add( "do { " ); | 606 stmt.add( "do { " ); |
624 stmt.addAll( loop ); | 607 stmt.addAll( loop ); |
625 stmt.add( "} while( !Luan.checkBoolean(" ); | 608 stmt.add( "} while( !Luan.checkBoolean(" ); |
626 stmt.addAll( cnd ); | 609 stmt.addAll( cnd ); |
641 return parser.failure(null); | 624 return parser.failure(null); |
642 Stmts stmt = new Stmts(); | 625 Stmts stmt = new Stmts(); |
643 Expr cnd; | 626 Expr cnd; |
644 Stmts block; | 627 Stmts block; |
645 boolean hasReturn = true; | 628 boolean hasReturn = true; |
646 cnd = RequiredExpr(In.NOTHING).single(); | 629 cnd = RequiredExpr().single(); |
647 RequiredKeyword("then"); | 630 RequiredKeyword("then"); |
648 block = RequiredBlock(); | 631 block = RequiredBlock(); |
649 stmt.add( "if( Luan.checkBoolean(" ); | 632 stmt.add( "if( Luan.checkBoolean(" ); |
650 stmt.addAll( cnd ); | 633 stmt.addAll( cnd ); |
651 stmt.add( ") ) { " ); | 634 stmt.add( ") ) { " ); |
652 stmt.addAll( block ); | 635 stmt.addAll( block ); |
653 if( !block.hasReturn ) | 636 if( !block.hasReturn ) |
654 hasReturn = false; | 637 hasReturn = false; |
655 while( Keyword("elseif") ) { | 638 while( Keyword("elseif") ) { |
656 cnd = RequiredExpr(In.NOTHING).single(); | 639 cnd = RequiredExpr().single(); |
657 RequiredKeyword("then"); | 640 RequiredKeyword("then"); |
658 block = RequiredBlock(); | 641 block = RequiredBlock(); |
659 stmt.add( "} else if( Luan.checkBoolean(" ); | 642 stmt.add( "} else if( Luan.checkBoolean(" ); |
660 stmt.addAll( cnd ); | 643 stmt.addAll( cnd ); |
661 stmt.add( ") ) { " ); | 644 stmt.add( ") ) { " ); |
693 vars.add(v); | 676 vars.add(v); |
694 } | 677 } |
695 if( !parser.match( '=' ) ) | 678 if( !parser.match( '=' ) ) |
696 return parser.failure(null); | 679 return parser.failure(null); |
697 Spaces(); | 680 Spaces(); |
698 Expr values = ExpStringList(In.NOTHING); | 681 Expr values = ExpStringList(); |
699 if( values==null ) | 682 if( values==null ) |
700 // throw parser.exception("Expressions expected"); | 683 // throw parser.exception("Expressions expected"); |
701 return parser.failure(null); | 684 return parser.failure(null); |
702 return parser.success( makeSetStmt(vars,values) ); | 685 return parser.success( makeSetStmt(vars,values) ); |
703 } | 686 } |
744 return stmt; | 727 return stmt; |
745 } | 728 } |
746 | 729 |
747 private Stmts ExpressionsStmt() throws ParseException { | 730 private Stmts ExpressionsStmt() throws ParseException { |
748 parser.begin(); | 731 parser.begin(); |
749 Expr exp = ExprZ(In.NOTHING); | 732 Expr exp = ExprZ(); |
750 if( exp != null && exp.isStmt ) { | 733 if( exp != null && exp.isStmt ) { |
751 Stmts stmt = new Stmts(); | 734 Stmts stmt = new Stmts(); |
752 if( exp.valType==Val.SINGLE ) { | 735 if( exp.valType==Val.SINGLE ) { |
753 stmt.add( "LuanImpl.nop(" ); | 736 stmt.add( "LuanImpl.nop(" ); |
754 stmt.addAll( exp ); | 737 stmt.addAll( exp ); |
762 return parser.failure(null); | 745 return parser.failure(null); |
763 } | 746 } |
764 | 747 |
765 private Var SettableVar() throws ParseException { | 748 private Var SettableVar() throws ParseException { |
766 int start = parser.begin(); | 749 int start = parser.begin(); |
767 Var var = VarZ(In.NOTHING); | 750 Var var = VarZ(); |
768 if( var==null || !var.isSettable() ) | 751 if( var==null || !var.isSettable() ) |
769 return parser.failure(null); | 752 return parser.failure(null); |
770 return parser.success( var ); | 753 return parser.success( var ); |
771 } | 754 } |
772 | 755 |
773 private Expr RequiredExpr(In in) throws ParseException { | 756 private Expr RequiredExpr() throws ParseException { |
774 parser.begin(); | 757 parser.begin(); |
775 return parser.success(required(ExprZ(in),"Bad expression")); | 758 return parser.success(required(ExprZ(),"Bad expression")); |
776 } | 759 } |
777 | 760 |
778 private Expr ExprZ(In in) throws ParseException { | 761 private Expr ExprZ() throws ParseException { |
779 return OrExpr(in); | 762 return OrExpr(); |
780 } | 763 } |
781 | 764 |
782 private Expr OrExpr(In in) throws ParseException { | 765 private Expr OrExpr() throws ParseException { |
783 parser.begin(); | 766 parser.begin(); |
784 Expr exp = AndExpr(in); | 767 Expr exp = AndExpr(); |
785 if( exp==null ) | 768 if( exp==null ) |
786 return parser.failure(null); | 769 return parser.failure(null); |
787 while( Keyword("or") ) { | 770 while( Keyword("or") ) { |
788 exp = exp.single(); | 771 exp = exp.single(); |
789 Expr exp2 = required(AndExpr(in)).single(); | 772 Expr exp2 = required(AndExpr()).single(); |
790 Expr newExp = new Expr(Val.SINGLE,true); | 773 Expr newExp = new Expr(Val.SINGLE,true); |
791 newExp.add( "(LuanImpl.cnd(t = " ); | 774 newExp.add( "(LuanImpl.cnd(t = " ); |
792 newExp.addAll( exp ); | 775 newExp.addAll( exp ); |
793 newExp.add( ") ? t : (" ); | 776 newExp.add( ") ? t : (" ); |
794 newExp.addAll( exp2 ); | 777 newExp.addAll( exp2 ); |
796 exp = newExp; | 779 exp = newExp; |
797 } | 780 } |
798 return parser.success(exp); | 781 return parser.success(exp); |
799 } | 782 } |
800 | 783 |
801 private Expr AndExpr(In in) throws ParseException { | 784 private Expr AndExpr() throws ParseException { |
802 parser.begin(); | 785 parser.begin(); |
803 Expr exp = RelExpr(in); | 786 Expr exp = RelExpr(); |
804 if( exp==null ) | 787 if( exp==null ) |
805 return parser.failure(null); | 788 return parser.failure(null); |
806 while( Keyword("and") ) { | 789 while( Keyword("and") ) { |
807 exp = exp.single(); | 790 exp = exp.single(); |
808 Expr exp2 = required(RelExpr(in)).single(); | 791 Expr exp2 = required(RelExpr()).single(); |
809 Expr newExp = new Expr(Val.SINGLE,true); | 792 Expr newExp = new Expr(Val.SINGLE,true); |
810 newExp.add( "(LuanImpl.cnd(t = " ); | 793 newExp.add( "(LuanImpl.cnd(t = " ); |
811 newExp.addAll( exp ); | 794 newExp.addAll( exp ); |
812 newExp.add( ") ? (" ); | 795 newExp.add( ") ? (" ); |
813 newExp.addAll( exp2 ); | 796 newExp.addAll( exp2 ); |
815 exp = newExp; | 798 exp = newExp; |
816 } | 799 } |
817 return parser.success(exp); | 800 return parser.success(exp); |
818 } | 801 } |
819 | 802 |
820 private Expr RelExpr(In in) throws ParseException { | 803 private Expr RelExpr() throws ParseException { |
821 parser.begin(); | 804 parser.begin(); |
822 Expr exp = ConcatExpr(in); | 805 Expr exp = ConcatExpr(); |
823 if( exp==null ) | 806 if( exp==null ) |
824 return parser.failure(null); | 807 return parser.failure(null); |
825 while(true) { | 808 while(true) { |
826 if( parser.match("==") ) { | 809 if( parser.match("==") ) { |
827 Spaces(); | 810 Spaces(); |
828 exp = exp.single(); | 811 exp = exp.single(); |
829 Expr exp2 = required(ConcatExpr(in)).single(); | 812 Expr exp2 = required(ConcatExpr()).single(); |
830 Expr newExp = new Expr(Val.SINGLE,false); | 813 Expr newExp = new Expr(Val.SINGLE,false); |
831 newExp.add( "LuanImpl.eq(" ); | 814 newExp.add( "LuanImpl.eq(" ); |
832 newExp.addAll( exp ); | 815 newExp.addAll( exp ); |
833 newExp.add( "," ); | 816 newExp.add( "," ); |
834 newExp.addAll( exp2 ); | 817 newExp.addAll( exp2 ); |
835 newExp.add( ")" ); | 818 newExp.add( ")" ); |
836 exp = newExp; | 819 exp = newExp; |
837 } else if( parser.match("~=") ) { | 820 } else if( parser.match("~=") ) { |
838 Spaces(); | 821 Spaces(); |
839 exp = exp.single(); | 822 exp = exp.single(); |
840 Expr exp2 = required(ConcatExpr(in)).single(); | 823 Expr exp2 = required(ConcatExpr()).single(); |
841 Expr newExp = new Expr(Val.SINGLE,false); | 824 Expr newExp = new Expr(Val.SINGLE,false); |
842 newExp.add( "!LuanImpl.eq(" ); | 825 newExp.add( "!LuanImpl.eq(" ); |
843 newExp.addAll( exp ); | 826 newExp.addAll( exp ); |
844 newExp.add( "," ); | 827 newExp.add( "," ); |
845 newExp.addAll( exp2 ); | 828 newExp.addAll( exp2 ); |
846 newExp.add( ")" ); | 829 newExp.add( ")" ); |
847 exp = newExp; | 830 exp = newExp; |
848 } else if( parser.match("<=") ) { | 831 } else if( parser.match("<=") ) { |
849 Spaces(); | 832 Spaces(); |
850 exp = exp.single(); | 833 exp = exp.single(); |
851 Expr exp2 = required(ConcatExpr(in)).single(); | 834 Expr exp2 = required(ConcatExpr()).single(); |
852 Expr newExp = new Expr(Val.SINGLE,false); | 835 Expr newExp = new Expr(Val.SINGLE,false); |
853 newExp.add( "LuanImpl.le(" ); | 836 newExp.add( "LuanImpl.le(" ); |
854 newExp.addAll( exp ); | 837 newExp.addAll( exp ); |
855 newExp.add( "," ); | 838 newExp.add( "," ); |
856 newExp.addAll( exp2 ); | 839 newExp.addAll( exp2 ); |
857 newExp.add( ")" ); | 840 newExp.add( ")" ); |
858 exp = newExp; | 841 exp = newExp; |
859 } else if( parser.match(">=") ) { | 842 } else if( parser.match(">=") ) { |
860 Spaces(); | 843 Spaces(); |
861 exp = exp.single(); | 844 exp = exp.single(); |
862 Expr exp2 = required(ConcatExpr(in)).single(); | 845 Expr exp2 = required(ConcatExpr()).single(); |
863 Expr newExp = new Expr(Val.SINGLE,false); | 846 Expr newExp = new Expr(Val.SINGLE,false); |
864 newExp.add( "LuanImpl.le(" ); | 847 newExp.add( "LuanImpl.le(" ); |
865 newExp.addAll( exp2 ); | 848 newExp.addAll( exp2 ); |
866 newExp.add( "," ); | 849 newExp.add( "," ); |
867 newExp.addAll( exp ); | 850 newExp.addAll( exp ); |
868 newExp.add( ")" ); | 851 newExp.add( ")" ); |
869 exp = newExp; | 852 exp = newExp; |
870 } else if( parser.match("<") ) { | 853 } else if( parser.match("<") ) { |
871 Spaces(); | 854 Spaces(); |
872 exp = exp.single(); | 855 exp = exp.single(); |
873 Expr exp2 = required(ConcatExpr(in)).single(); | 856 Expr exp2 = required(ConcatExpr()).single(); |
874 Expr newExp = new Expr(Val.SINGLE,false); | 857 Expr newExp = new Expr(Val.SINGLE,false); |
875 newExp.add( "LuanImpl.lt(" ); | 858 newExp.add( "LuanImpl.lt(" ); |
876 newExp.addAll( exp ); | 859 newExp.addAll( exp ); |
877 newExp.add( "," ); | 860 newExp.add( "," ); |
878 newExp.addAll( exp2 ); | 861 newExp.addAll( exp2 ); |
879 newExp.add( ")" ); | 862 newExp.add( ")" ); |
880 exp = newExp; | 863 exp = newExp; |
881 } else if( parser.match(">") ) { | 864 } else if( parser.match(">") ) { |
882 Spaces(); | 865 Spaces(); |
883 exp = exp.single(); | 866 exp = exp.single(); |
884 Expr exp2 = required(ConcatExpr(in)).single(); | 867 Expr exp2 = required(ConcatExpr()).single(); |
885 Expr newExp = new Expr(Val.SINGLE,false); | 868 Expr newExp = new Expr(Val.SINGLE,false); |
886 newExp.add( "LuanImpl.lt(" ); | 869 newExp.add( "LuanImpl.lt(" ); |
887 newExp.addAll( exp2 ); | 870 newExp.addAll( exp2 ); |
888 newExp.add( "," ); | 871 newExp.add( "," ); |
889 newExp.addAll( exp ); | 872 newExp.addAll( exp ); |
893 break; | 876 break; |
894 } | 877 } |
895 return parser.success(exp); | 878 return parser.success(exp); |
896 } | 879 } |
897 | 880 |
898 private Expr ConcatExpr(In in) throws ParseException { | 881 private Expr ConcatExpr() throws ParseException { |
899 parser.begin(); | 882 parser.begin(); |
900 Expr exp = SumExpr(in); | 883 Expr exp = SumExpr(); |
901 if( exp==null ) | 884 if( exp==null ) |
902 return parser.failure(null); | 885 return parser.failure(null); |
903 if( parser.match("..") ) { | 886 if( parser.match("..") ) { |
904 Spaces(); | 887 Spaces(); |
905 exp = exp.single(); | 888 exp = exp.single(); |
906 Expr exp2 = required(ConcatExpr(in)).single(); | 889 Expr exp2 = required(ConcatExpr()).single(); |
907 Expr newExp = new Expr(Val.SINGLE,false); | 890 Expr newExp = new Expr(Val.SINGLE,false); |
908 newExp.add( "LuanImpl.concat(" ); | 891 newExp.add( "LuanImpl.concat(" ); |
909 newExp.addAll( exp ); | 892 newExp.addAll( exp ); |
910 newExp.add( "," ); | 893 newExp.add( "," ); |
911 newExp.addAll( exp2 ); | 894 newExp.addAll( exp2 ); |
913 exp = newExp; | 896 exp = newExp; |
914 } | 897 } |
915 return parser.success(exp); | 898 return parser.success(exp); |
916 } | 899 } |
917 | 900 |
918 private Expr SumExpr(In in) throws ParseException { | 901 private Expr SumExpr() throws ParseException { |
919 parser.begin(); | 902 parser.begin(); |
920 Expr exp = TermExpr(in); | 903 Expr exp = TermExpr(); |
921 if( exp==null ) | 904 if( exp==null ) |
922 return parser.failure(null); | 905 return parser.failure(null); |
923 while(true) { | 906 while(true) { |
924 if( parser.match('+') ) { | 907 if( parser.match('+') ) { |
925 Spaces(); | 908 Spaces(); |
926 exp = exp.single(); | 909 exp = exp.single(); |
927 Expr exp2 = required(TermExpr(in)).single(); | 910 Expr exp2 = required(TermExpr()).single(); |
928 Expr newExp = new Expr(Val.SINGLE,false); | 911 Expr newExp = new Expr(Val.SINGLE,false); |
929 newExp.add( "LuanImpl.add(" ); | 912 newExp.add( "LuanImpl.add(" ); |
930 newExp.addAll( exp ); | 913 newExp.addAll( exp ); |
931 newExp.add( "," ); | 914 newExp.add( "," ); |
932 newExp.addAll( exp2 ); | 915 newExp.addAll( exp2 ); |
933 newExp.add( ")" ); | 916 newExp.add( ")" ); |
934 exp = newExp; | 917 exp = newExp; |
935 } else if( Minus() ) { | 918 } else if( Minus() ) { |
936 Spaces(); | 919 Spaces(); |
937 exp = exp.single(); | 920 exp = exp.single(); |
938 Expr exp2 = required(TermExpr(in)).single(); | 921 Expr exp2 = required(TermExpr()).single(); |
939 Expr newExp = new Expr(Val.SINGLE,false); | 922 Expr newExp = new Expr(Val.SINGLE,false); |
940 newExp.add( "LuanImpl.sub(" ); | 923 newExp.add( "LuanImpl.sub(" ); |
941 newExp.addAll( exp ); | 924 newExp.addAll( exp ); |
942 newExp.add( "," ); | 925 newExp.add( "," ); |
943 newExp.addAll( exp2 ); | 926 newExp.addAll( exp2 ); |
952 private boolean Minus() { | 935 private boolean Minus() { |
953 parser.begin(); | 936 parser.begin(); |
954 return parser.match('-') && !parser.match('-') ? parser.success() : parser.failure(); | 937 return parser.match('-') && !parser.match('-') ? parser.success() : parser.failure(); |
955 } | 938 } |
956 | 939 |
957 private Expr TermExpr(In in) throws ParseException { | 940 private Expr TermExpr() throws ParseException { |
958 parser.begin(); | 941 parser.begin(); |
959 Expr exp = UnaryExpr(in); | 942 Expr exp = UnaryExpr(); |
960 if( exp==null ) | 943 if( exp==null ) |
961 return parser.failure(null); | 944 return parser.failure(null); |
962 while(true) { | 945 while(true) { |
963 if( parser.match('*') ) { | 946 if( parser.match('*') ) { |
964 Spaces(); | 947 Spaces(); |
965 exp = exp.single(); | 948 exp = exp.single(); |
966 Expr exp2 = required(UnaryExpr(in)).single(); | 949 Expr exp2 = required(UnaryExpr()).single(); |
967 Expr newExp = new Expr(Val.SINGLE,false); | 950 Expr newExp = new Expr(Val.SINGLE,false); |
968 newExp.add( "LuanImpl.mul(" ); | 951 newExp.add( "LuanImpl.mul(" ); |
969 newExp.addAll( exp ); | 952 newExp.addAll( exp ); |
970 newExp.add( "," ); | 953 newExp.add( "," ); |
971 newExp.addAll( exp2 ); | 954 newExp.addAll( exp2 ); |
972 newExp.add( ")" ); | 955 newExp.add( ")" ); |
973 exp = newExp; | 956 exp = newExp; |
974 } else if( parser.match('/') ) { | 957 } else if( parser.match('/') ) { |
975 Spaces(); | 958 Spaces(); |
976 exp = exp.single(); | 959 exp = exp.single(); |
977 Expr exp2 = required(UnaryExpr(in)).single(); | 960 Expr exp2 = required(UnaryExpr()).single(); |
978 Expr newExp = new Expr(Val.SINGLE,false); | 961 Expr newExp = new Expr(Val.SINGLE,false); |
979 newExp.add( "LuanImpl.div(" ); | 962 newExp.add( "LuanImpl.div(" ); |
980 newExp.addAll( exp ); | 963 newExp.addAll( exp ); |
981 newExp.add( "," ); | 964 newExp.add( "," ); |
982 newExp.addAll( exp2 ); | 965 newExp.addAll( exp2 ); |
983 newExp.add( ")" ); | 966 newExp.add( ")" ); |
984 exp = newExp; | 967 exp = newExp; |
985 } else if( Mod() ) { | 968 } else if( Mod() ) { |
986 Spaces(); | 969 Spaces(); |
987 exp = exp.single(); | 970 exp = exp.single(); |
988 Expr exp2 = required(UnaryExpr(in)).single(); | 971 Expr exp2 = required(UnaryExpr()).single(); |
989 Expr newExp = new Expr(Val.SINGLE,false); | 972 Expr newExp = new Expr(Val.SINGLE,false); |
990 newExp.add( "LuanImpl.mod(" ); | 973 newExp.add( "LuanImpl.mod(" ); |
991 newExp.addAll( exp ); | 974 newExp.addAll( exp ); |
992 newExp.add( "," ); | 975 newExp.add( "," ); |
993 newExp.addAll( exp2 ); | 976 newExp.addAll( exp2 ); |
1002 private boolean Mod() { | 985 private boolean Mod() { |
1003 parser.begin(); | 986 parser.begin(); |
1004 return parser.match('%') && !parser.match('>') ? parser.success() : parser.failure(); | 987 return parser.match('%') && !parser.match('>') ? parser.success() : parser.failure(); |
1005 } | 988 } |
1006 | 989 |
1007 private Expr UnaryExpr(In in) throws ParseException { | 990 private Expr UnaryExpr() throws ParseException { |
1008 parser.begin(); | 991 parser.begin(); |
1009 if( parser.match('#') ) { | 992 if( parser.match('#') ) { |
1010 Spaces(); | 993 Spaces(); |
1011 Expr exp = required(UnaryExpr(in)).single(); | 994 Expr exp = required(UnaryExpr()).single(); |
1012 Expr newExp = new Expr(Val.SINGLE,false); | 995 Expr newExp = new Expr(Val.SINGLE,false); |
1013 newExp.add( "LuanImpl.len(" ); | 996 newExp.add( "LuanImpl.len(" ); |
1014 newExp.addAll( exp ); | 997 newExp.addAll( exp ); |
1015 newExp.add( ")" ); | 998 newExp.add( ")" ); |
1016 return parser.success(newExp); | 999 return parser.success(newExp); |
1017 } | 1000 } |
1018 if( Minus() ) { | 1001 if( Minus() ) { |
1019 Spaces(); | 1002 Spaces(); |
1020 Expr exp = required(UnaryExpr(in)).single(); | 1003 Expr exp = required(UnaryExpr()).single(); |
1021 Expr newExp = new Expr(Val.SINGLE,false); | 1004 Expr newExp = new Expr(Val.SINGLE,false); |
1022 newExp.add( "LuanImpl.unm(" ); | 1005 newExp.add( "LuanImpl.unm(" ); |
1023 newExp.addAll( exp ); | 1006 newExp.addAll( exp ); |
1024 newExp.add( ")" ); | 1007 newExp.add( ")" ); |
1025 return parser.success(newExp); | 1008 return parser.success(newExp); |
1026 } | 1009 } |
1027 if( Keyword("not") ) { | 1010 if( Keyword("not") ) { |
1028 Spaces(); | 1011 Spaces(); |
1029 Expr exp = required(UnaryExpr(in)).single(); | 1012 Expr exp = required(UnaryExpr()).single(); |
1030 Expr newExp = new Expr(Val.SINGLE,false); | 1013 Expr newExp = new Expr(Val.SINGLE,false); |
1031 newExp.add( "!Luan.checkBoolean(" ); | 1014 newExp.add( "!Luan.checkBoolean(" ); |
1032 newExp.addAll( exp ); | 1015 newExp.addAll( exp ); |
1033 newExp.add( ")" ); | 1016 newExp.add( ")" ); |
1034 return parser.success(newExp); | 1017 return parser.success(newExp); |
1035 } | 1018 } |
1036 Expr exp = PowExpr(in); | 1019 Expr exp = PowExpr(); |
1037 if( exp==null ) | 1020 if( exp==null ) |
1038 return parser.failure(null); | 1021 return parser.failure(null); |
1039 return parser.success(exp); | 1022 return parser.success(exp); |
1040 } | 1023 } |
1041 | 1024 |
1042 private Expr PowExpr(In in) throws ParseException { | 1025 private Expr PowExpr() throws ParseException { |
1043 parser.begin(); | 1026 parser.begin(); |
1044 Expr exp1 = SingleExpr(in); | 1027 Expr exp1 = SingleExpr(); |
1045 if( exp1==null ) | 1028 if( exp1==null ) |
1046 return parser.failure(null); | 1029 return parser.failure(null); |
1047 if( parser.match('^') ) { | 1030 if( parser.match('^') ) { |
1048 Spaces(); | 1031 Spaces(); |
1049 Expr exp2 = required(PowExpr(in)); | 1032 Expr exp2 = required(PowExpr()); |
1050 Expr newExp = new Expr(Val.SINGLE,false); | 1033 Expr newExp = new Expr(Val.SINGLE,false); |
1051 newExp.add( "LuanImpl.pow(" ); | 1034 newExp.add( "LuanImpl.pow(" ); |
1052 newExp.addAll( exp1.single() ); | 1035 newExp.addAll( exp1.single() ); |
1053 newExp.add( "," ); | 1036 newExp.add( "," ); |
1054 newExp.addAll( exp2.single() ); | 1037 newExp.addAll( exp2.single() ); |
1056 exp1 = newExp; | 1039 exp1 = newExp; |
1057 } | 1040 } |
1058 return parser.success(exp1); | 1041 return parser.success(exp1); |
1059 } | 1042 } |
1060 | 1043 |
1061 private Expr SingleExpr(In in) throws ParseException { | 1044 private Expr SingleExpr() throws ParseException { |
1062 parser.begin(); | 1045 parser.begin(); |
1063 Expr exp = FunctionExpr(); | 1046 Expr exp = FunctionExpr(); |
1064 if( exp != null ) | 1047 if( exp != null ) |
1065 return parser.success(exp); | 1048 return parser.success(exp); |
1066 exp = VarExp(in); | 1049 exp = VarExp(); |
1067 if( exp != null ) | 1050 if( exp != null ) |
1068 return parser.success(exp); | 1051 return parser.success(exp); |
1069 exp = VarArgs(); | 1052 exp = VarArgs(); |
1070 if( exp != null ) | 1053 if( exp != null ) |
1071 return parser.success(exp); | 1054 return parser.success(exp); |
1160 builder.add(exp); | 1143 builder.add(exp); |
1161 lastExp = exp; | 1144 lastExp = exp; |
1162 Spaces(); lastExp.addNewLines(); | 1145 Spaces(); lastExp.addNewLines(); |
1163 } | 1146 } |
1164 } while( FieldSep() ); | 1147 } while( FieldSep() ); |
1165 Expr exp = TemplateExpressions(In.NOTHING); | |
1166 if( exp != null ) | |
1167 builder.add(exp); | |
1168 if( !parser.match('}') ) | 1148 if( !parser.match('}') ) |
1169 throw parser.exception("Expected table element or '}'"); | 1149 throw parser.exception("Expected table element or '}'"); |
1170 tblExp.addAll( expString(builder).array() ); | 1150 tblExp.addAll( expString(builder).array() ); |
1171 tblExp.add( ")" ); | 1151 tblExp.add( ")" ); |
1172 Spaces(); | 1152 Spaces(); |
1178 return parser.anyOf(",;") || EndOfLine(); | 1158 return parser.anyOf(",;") || EndOfLine(); |
1179 } | 1159 } |
1180 | 1160 |
1181 private Expr Field() throws ParseException { | 1161 private Expr Field() throws ParseException { |
1182 parser.begin(); | 1162 parser.begin(); |
1183 Expr exp = SubExpr(In.NOTHING); | 1163 Expr exp = SubExpr(); |
1184 if( exp==null ) | 1164 if( exp==null ) |
1185 exp = NameExpr(); | 1165 exp = NameExpr(); |
1186 if( exp!=null && parser.match('=') ) { | 1166 if( exp!=null && parser.match('=') ) { |
1187 Spaces(); | 1167 Spaces(); |
1188 Expr val = RequiredExpr(In.NOTHING).single(); | 1168 Expr val = RequiredExpr().single(); |
1189 Expr newExp = new Expr(Val.SINGLE,false); | 1169 Expr newExp = new Expr(Val.SINGLE,false); |
1190 newExp.add( "new TableField(" ); | 1170 newExp.add( "new TableField(" ); |
1191 newExp.addAll( exp ); | 1171 newExp.addAll( exp ); |
1192 newExp.add( "," ); | 1172 newExp.add( "," ); |
1193 newExp.addAll( val ); | 1173 newExp.addAll( val ); |
1194 newExp.add( ")" ); | 1174 newExp.add( ")" ); |
1195 return parser.success(newExp); | 1175 return parser.success(newExp); |
1196 } | 1176 } |
1197 parser.rollback(); | 1177 parser.rollback(); |
1198 Expr exprs = ExprZ(In.NOTHING); | 1178 Expr exprs = ExprZ(); |
1199 if( exprs != null ) { | 1179 if( exprs != null ) { |
1200 return parser.success(exprs); | 1180 return parser.success(exprs); |
1201 } | 1181 } |
1202 return parser.failure(null); | 1182 return parser.failure(null); |
1203 } | 1183 } |
1204 | 1184 |
1205 private Expr VarExp(In in) throws ParseException { | 1185 private Expr VarExp() throws ParseException { |
1206 Var var = VarZ(in); | 1186 Var var = VarZ(); |
1207 return var==null ? null : var.exp(); | 1187 return var==null ? null : var.exp(); |
1208 } | 1188 } |
1209 | 1189 |
1210 private Var VarZ(In in) throws ParseException { | 1190 private Var VarZ() throws ParseException { |
1211 parser.begin(); | 1191 parser.begin(); |
1212 Var var = VarStart(in); | 1192 Var var = VarStart(); |
1213 if( var==null ) | 1193 if( var==null ) |
1214 return parser.failure(null); | 1194 return parser.failure(null); |
1215 Var var2; | 1195 Var var2; |
1216 while( (var2=Var2(in,var.exp())) != null ) { | 1196 while( (var2=Var2(var.exp())) != null ) { |
1217 var = var2; | 1197 var = var2; |
1218 } | 1198 } |
1219 return parser.success(var); | 1199 return parser.success(var); |
1220 } | 1200 } |
1221 | 1201 |
1222 private Var VarStart(In in) throws ParseException { | 1202 private Var VarStart() throws ParseException { |
1223 if( parser.match('(') ) { | 1203 if( parser.match('(') ) { |
1224 Spaces(); | 1204 Spaces(); |
1225 Expr exp = RequiredExpr(in).single(); | 1205 Expr exp = RequiredExpr().single(); |
1226 RequiredMatch(')'); | 1206 RequiredMatch(')'); |
1227 Spaces(); | 1207 Spaces(); |
1228 return exprVar(exp); | 1208 return exprVar(exp); |
1229 } | 1209 } |
1230 String name = Name(); | 1210 String name = Name(); |
1238 if( exp != null ) | 1218 if( exp != null ) |
1239 return exprVar(exp); | 1219 return exprVar(exp); |
1240 return null; | 1220 return null; |
1241 } | 1221 } |
1242 | 1222 |
1243 private Var Var2(In in,Expr exp1) throws ParseException { | 1223 private Var Var2(Expr exp1) throws ParseException { |
1244 parser.begin(); | 1224 parser.begin(); |
1245 Expr exp2 = SubExpr(in); | 1225 Expr exp2 = SubExpr(); |
1246 if( exp2 != null ) | 1226 if( exp2 != null ) |
1247 return parser.success(indexVar(exp1,exp2)); | 1227 return parser.success(indexVar(exp1,exp2)); |
1248 if( parser.match('.') ) { | 1228 if( parser.match('.') ) { |
1249 Spaces(); | 1229 Spaces(); |
1250 exp2 = NameExpr(); | 1230 exp2 = NameExpr(); |
1251 if( exp2!=null ) | 1231 if( exp2!=null ) |
1252 return parser.success(indexVar(exp1,exp2)); | 1232 return parser.success(indexVar(exp1,exp2)); |
1253 return parser.failure(null); | 1233 return parser.failure(null); |
1254 } | 1234 } |
1255 Expr fnCall = Args( in, exp1, new ArrayList<Expr>() ); | 1235 Expr fnCall = Args( exp1, new ArrayList<Expr>() ); |
1256 if( fnCall != null ) | 1236 if( fnCall != null ) |
1257 return parser.success(exprVar(fnCall)); | 1237 return parser.success(exprVar(fnCall)); |
1258 return parser.failure(null); | 1238 return parser.failure(null); |
1259 } | 1239 } |
1260 | 1240 |
1361 return stmt; | 1341 return stmt; |
1362 } | 1342 } |
1363 }; | 1343 }; |
1364 } | 1344 } |
1365 | 1345 |
1366 private Expr Args(In in,Expr fn,List<Expr> builder) throws ParseException { | 1346 private Expr Args(Expr fn,List<Expr> builder) throws ParseException { |
1367 parser.begin(); | 1347 parser.begin(); |
1368 return args(in,builder) | 1348 return args(builder) |
1369 ? parser.success( callExpStr( fn, expString(builder) ) ) | 1349 ? parser.success( callExpStr( fn, expString(builder) ) ) |
1370 : parser.failure((Expr)null); | 1350 : parser.failure((Expr)null); |
1371 } | 1351 } |
1372 | 1352 |
1373 private boolean args(In in,List<Expr> builder) throws ParseException { | 1353 private boolean args(List<Expr> builder) throws ParseException { |
1374 parser.begin(); | 1354 parser.begin(); |
1375 if( parser.match('(') ) { | 1355 if( parser.match('(') ) { |
1376 Spaces(); | 1356 Spaces(); |
1377 ExpList(in,builder); // optional | 1357 ExpList(builder); // optional |
1378 if( !parser.match(')') ) | 1358 if( !parser.match(')') ) |
1379 throw parser.exception("Expression or ')' expected"); | 1359 throw parser.exception("Expression or ')' expected"); |
1380 Spaces(); | 1360 Spaces(); |
1381 parser.upSb(); | 1361 parser.upSb(); |
1382 return parser.success(); | 1362 return parser.success(); |
1392 return parser.success(); | 1372 return parser.success(); |
1393 } | 1373 } |
1394 return parser.failure(); | 1374 return parser.failure(); |
1395 } | 1375 } |
1396 | 1376 |
1397 private Expr ExpStringList(In in) throws ParseException { | 1377 private Expr ExpStringList() throws ParseException { |
1398 List<Expr> builder = new ArrayList<Expr>(); | 1378 List<Expr> builder = new ArrayList<Expr>(); |
1399 return ExpList(in,builder) ? expString(builder) : null; | 1379 return ExpList(builder) ? expString(builder) : null; |
1400 } | 1380 } |
1401 | 1381 |
1402 private boolean ExpList(In in,List<Expr> builder) throws ParseException { | 1382 private boolean ExpList(List<Expr> builder) throws ParseException { |
1403 parser.begin(); | 1383 parser.begin(); |
1404 Expr exp = TemplateExpressions(in); | 1384 Expr exp = ExprZ(); |
1405 if( exp != null ) { | |
1406 builder.add(exp); | |
1407 return parser.success(); | |
1408 } | |
1409 exp = ExprZ(in); | |
1410 if( exp==null ) | 1385 if( exp==null ) |
1411 return parser.failure(); | 1386 return parser.failure(); |
1412 exp.addNewLines(); | 1387 exp.addNewLines(); |
1413 builder.add(exp); | 1388 builder.add(exp); |
1414 while( parser.match(',') ) { | 1389 while( parser.match(',') ) { |
1415 Spaces(); | 1390 Spaces(); |
1416 exp = TemplateExpressions(in); | 1391 exp = RequiredExpr(); |
1417 if( exp != null ) { | |
1418 builder.add(exp); | |
1419 return parser.success(); | |
1420 } | |
1421 exp = RequiredExpr(in); | |
1422 exp.prependNewLines(); | 1392 exp.prependNewLines(); |
1423 builder.add(exp); | 1393 builder.add(exp); |
1424 } | 1394 } |
1425 return parser.success(); | 1395 return parser.success(); |
1426 } | 1396 } |
1427 | 1397 |
1428 private Expr SubExpr(In in) throws ParseException { | 1398 private Expr SubExpr() throws ParseException { |
1429 parser.begin(); | 1399 parser.begin(); |
1430 if( !parser.match('[') || parser.test("[") || parser.test("=") ) | 1400 if( !parser.match('[') || parser.test("[") || parser.test("=") ) |
1431 return parser.failure(null); | 1401 return parser.failure(null); |
1432 Spaces(); | 1402 Spaces(); |
1433 Expr exp = RequiredExpr(In.NOTHING).single(); | 1403 Expr exp = RequiredExpr().single(); |
1434 RequiredMatch(']'); | 1404 RequiredMatch(']'); |
1435 Spaces(); | 1405 Spaces(); |
1436 return parser.success(exp); | 1406 return parser.success(exp); |
1437 } | 1407 } |
1438 | 1408 |