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