comparison src/luan/interp/LuanParser.java @ 154:c2e5101682ae

Expr extends Expressions git-svn-id: https://luan-java.googlecode.com/svn/trunk@155 21e917c8-12df-6dd8-5cb6-c86387c605b9
author fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
date Tue, 17 Jun 2014 09:55:43 +0000
parents fa03671f59a0
children db7b3902e01c
comparison
equal deleted inserted replaced
153:fa03671f59a0 154:c2e5101682ae
168 if( t==null ) 168 if( t==null )
169 throw parser.exception(msg); 169 throw parser.exception(msg);
170 return t; 170 return t;
171 } 171 }
172 172
173 private static Expr expr(Code code) { 173 private static Expr expr(Expressions exprs) {
174 if( code instanceof Expressions ) 174 if( exprs instanceof Expr )
175 return new ExpressionsExpr((Expressions)code); 175 return (Expr)exprs;
176 return (Expr)code; 176 return new ExpressionsExpr(exprs);
177 } 177 }
178 178
179 private FnDef newFnDef(int start,Stmt stmt) { 179 private FnDef newFnDef(int start,Stmt stmt) {
180 return new FnDef( se(start), stmt, frame.stackSize, symbolsSize(), frame.isVarArg, frame.upValueGetters.toArray(NO_UP_VALUE_GETTERS) ); 180 return new FnDef( se(start), stmt, frame.stackSize, symbolsSize(), frame.isVarArg, frame.upValueGetters.toArray(NO_UP_VALUE_GETTERS) );
181 } 181 }
261 int start = parser.begin(); 261 int start = parser.begin();
262 if( !parser.match( "%>" ) ) 262 if( !parser.match( "%>" ) )
263 return parser.failure(null); 263 return parser.failure(null);
264 EndOfLine(); 264 EndOfLine();
265 In inJsp = in.jsp(); 265 In inJsp = in.jsp();
266 ExpList.Builder builder = new ExpList.Builder(); 266 List<Expressions> builder = new ArrayList<Expressions>();
267 while(true) { 267 while(true) {
268 if( parser.match( "<%=" ) ) { 268 if( parser.match( "<%=" ) ) {
269 Spaces(inJsp); 269 Spaces(inJsp);
270 builder.add( RequiredExpr(inJsp) ); 270 builder.add( RequiredExpr(inJsp) );
271 RequiredMatch( "%>" ); 271 RequiredMatch( "%>" );
272 } else if( parser.match( "<%" ) ) { 272 } else if( parser.match( "<%" ) ) {
273 Spaces(inJsp); 273 Spaces(inJsp);
274 return parser.success(builder.build()); 274 return parser.success(ExpList.build(builder));
275 } else { 275 } else {
276 int i = parser.currentIndex(); 276 int i = parser.currentIndex();
277 do { 277 do {
278 if( parser.match( "%>" ) ) 278 if( parser.match( "%>" ) )
279 throw parser.exception("'%>' unexpected"); 279 throw parser.exception("'%>' unexpected");
331 String modName = StringLiteral(In.NOTHING); 331 String modName = StringLiteral(In.NOTHING);
332 if( modName==null ) 332 if( modName==null )
333 return parser.failure(null); 333 return parser.failure(null);
334 String varName = modName.substring(modName.lastIndexOf('.')+1); 334 String varName = modName.substring(modName.lastIndexOf('.')+1);
335 LuanSource.Element se = se(start); 335 LuanSource.Element se = se(start);
336 FnCall require = new FnCall( se, importExpr, new ExpList.SingleExpList(new ConstExpr(modName)) ); 336 FnCall require = new FnCall( se, importExpr, new ConstExpr(modName) );
337 Settable settable; 337 Settable settable;
338 if( interactive ) { 338 if( interactive ) {
339 settable = new SetTableEntry( se(start), env(), new ConstExpr(varName) ); 339 settable = new SetTableEntry( se(start), env(), new ConstExpr(varName) );
340 } else { 340 } else {
341 addSymbol( varName ); 341 addSymbol( varName );
538 if( var==null ) 538 if( var==null )
539 return null; 539 return null;
540 return var.settable(); 540 return var.settable();
541 } 541 }
542 542
543 private Code RequiredExpr(In in) throws ParseException { 543 private Expressions RequiredExpr(In in) throws ParseException {
544 parser.begin(); 544 parser.begin();
545 return parser.success(required(Expr(in),"Bad expression")); 545 return parser.success(required(Expr(in),"Bad expression"));
546 } 546 }
547 547
548 private Code Expr(In in) throws ParseException { 548 private Expressions Expr(In in) throws ParseException {
549 parser.begin(); 549 parser.begin();
550 Code exp; 550 Expressions exp;
551 return (exp = VarArgs(in)) != null 551 return (exp = VarArgs(in)) != null
552 || (exp = JspExpressions(in)) != null 552 || (exp = JspExpressions(in)) != null
553 || (exp = OrExpr(in)) != null 553 || (exp = OrExpr(in)) != null
554 ? parser.success(exp) 554 ? parser.success(exp)
555 : parser.failure((Code)null) 555 : parser.failure((Expressions)null)
556 ; 556 ;
557 } 557 }
558 558
559 private Code OrExpr(In in) throws ParseException { 559 private Expressions OrExpr(In in) throws ParseException {
560 int start = parser.begin(); 560 int start = parser.begin();
561 Code exp = AndExpr(in); 561 Expressions exp = AndExpr(in);
562 if( exp==null ) 562 if( exp==null )
563 return parser.failure(null); 563 return parser.failure(null);
564 while( Keyword("or",in) ) { 564 while( Keyword("or",in) ) {
565 exp = new OrExpr( se(start), expr(exp), required(expr(AndExpr(in))) ); 565 exp = new OrExpr( se(start), expr(exp), required(expr(AndExpr(in))) );
566 } 566 }
567 return parser.success(exp); 567 return parser.success(exp);
568 } 568 }
569 569
570 private Code AndExpr(In in) throws ParseException { 570 private Expressions AndExpr(In in) throws ParseException {
571 int start = parser.begin(); 571 int start = parser.begin();
572 Code exp = RelExpr(in); 572 Expressions exp = RelExpr(in);
573 if( exp==null ) 573 if( exp==null )
574 return parser.failure(null); 574 return parser.failure(null);
575 while( Keyword("and",in) ) { 575 while( Keyword("and",in) ) {
576 exp = new AndExpr( se(start), expr(exp), required(expr(RelExpr(in))) ); 576 exp = new AndExpr( se(start), expr(exp), required(expr(RelExpr(in))) );
577 } 577 }
578 return parser.success(exp); 578 return parser.success(exp);
579 } 579 }
580 580
581 private Code RelExpr(In in) throws ParseException { 581 private Expressions RelExpr(In in) throws ParseException {
582 int start = parser.begin(); 582 int start = parser.begin();
583 Code exp = ConcatExpr(in); 583 Expressions exp = ConcatExpr(in);
584 if( exp==null ) 584 if( exp==null )
585 return parser.failure(null); 585 return parser.failure(null);
586 while(true) { 586 while(true) {
587 if( parser.match("==") ) { 587 if( parser.match("==") ) {
588 Spaces(in); 588 Spaces(in);
606 break; 606 break;
607 } 607 }
608 return parser.success(exp); 608 return parser.success(exp);
609 } 609 }
610 610
611 private Code ConcatExpr(In in) throws ParseException { 611 private Expressions ConcatExpr(In in) throws ParseException {
612 int start = parser.begin(); 612 int start = parser.begin();
613 Code exp = SumExpr(in); 613 Expressions exp = SumExpr(in);
614 if( exp==null ) 614 if( exp==null )
615 return parser.failure(null); 615 return parser.failure(null);
616 if( parser.match("..") ) { 616 if( parser.match("..") ) {
617 Spaces(in); 617 Spaces(in);
618 exp = new ConcatExpr( se(start), expr(exp), required(expr(ConcatExpr(in))) ); 618 exp = new ConcatExpr( se(start), expr(exp), required(expr(ConcatExpr(in))) );
619 } 619 }
620 return parser.success(exp); 620 return parser.success(exp);
621 } 621 }
622 622
623 private Code SumExpr(In in) throws ParseException { 623 private Expressions SumExpr(In in) throws ParseException {
624 int start = parser.begin(); 624 int start = parser.begin();
625 Code exp = TermExpr(in); 625 Expressions exp = TermExpr(in);
626 if( exp==null ) 626 if( exp==null )
627 return parser.failure(null); 627 return parser.failure(null);
628 while(true) { 628 while(true) {
629 if( parser.match('+') ) { 629 if( parser.match('+') ) {
630 Spaces(in); 630 Spaces(in);
641 private boolean Minus() { 641 private boolean Minus() {
642 parser.begin(); 642 parser.begin();
643 return parser.match('-') && !parser.match('-') ? parser.success() : parser.failure(); 643 return parser.match('-') && !parser.match('-') ? parser.success() : parser.failure();
644 } 644 }
645 645
646 private Code TermExpr(In in) throws ParseException { 646 private Expressions TermExpr(In in) throws ParseException {
647 int start = parser.begin(); 647 int start = parser.begin();
648 Code exp = UnaryExpr(in); 648 Expressions exp = UnaryExpr(in);
649 if( exp==null ) 649 if( exp==null )
650 return parser.failure(null); 650 return parser.failure(null);
651 while(true) { 651 while(true) {
652 if( parser.match('*') ) { 652 if( parser.match('*') ) {
653 Spaces(in); 653 Spaces(in);
667 private boolean Mod() { 667 private boolean Mod() {
668 parser.begin(); 668 parser.begin();
669 return parser.match('%') && !parser.match('>') ? parser.success() : parser.failure(); 669 return parser.match('%') && !parser.match('>') ? parser.success() : parser.failure();
670 } 670 }
671 671
672 private Code UnaryExpr(In in) throws ParseException { 672 private Expressions UnaryExpr(In in) throws ParseException {
673 int start = parser.begin(); 673 int start = parser.begin();
674 if( parser.match('#') ) { 674 if( parser.match('#') ) {
675 Spaces(in); 675 Spaces(in);
676 return parser.success( new LenExpr( se(start), required(expr(UnaryExpr(in))) ) ); 676 return parser.success( new LenExpr( se(start), required(expr(UnaryExpr(in))) ) );
677 } 677 }
681 } 681 }
682 if( Keyword("not",in) ) { 682 if( Keyword("not",in) ) {
683 Spaces(in); 683 Spaces(in);
684 return parser.success( new NotExpr( se(start), required(expr(UnaryExpr(in))) ) ); 684 return parser.success( new NotExpr( se(start), required(expr(UnaryExpr(in))) ) );
685 } 685 }
686 Code exp = PowExpr(in); 686 Expressions exp = PowExpr(in);
687 if( exp==null ) 687 if( exp==null )
688 return parser.failure(null); 688 return parser.failure(null);
689 return parser.success(exp); 689 return parser.success(exp);
690 } 690 }
691 691
692 private Code PowExpr(In in) throws ParseException { 692 private Expressions PowExpr(In in) throws ParseException {
693 int start = parser.begin(); 693 int start = parser.begin();
694 Code exp = SingleExpr(in); 694 Expressions exp = SingleExpr(in);
695 if( exp==null ) 695 if( exp==null )
696 return parser.failure(null); 696 return parser.failure(null);
697 if( parser.match('^') ) { 697 if( parser.match('^') ) {
698 Spaces(in); 698 Spaces(in);
699 exp = new ConcatExpr( se(start), expr(exp), required(expr(PowExpr(in))) ); 699 exp = new ConcatExpr( se(start), expr(exp), required(expr(PowExpr(in))) );
700 } 700 }
701 return parser.success(exp); 701 return parser.success(exp);
702 } 702 }
703 703
704 private Code SingleExpr(In in) throws ParseException { 704 private Expressions SingleExpr(In in) throws ParseException {
705 parser.begin(); 705 parser.begin();
706 Code exp; 706 Expressions exp;
707 exp = FunctionExpr(in); 707 exp = FunctionExpr(in);
708 if( exp != null ) 708 if( exp != null )
709 return parser.success(exp); 709 return parser.success(exp);
710 exp = TableExpr(in); 710 exp = TableExpr(in);
711 if( exp != null ) 711 if( exp != null )
766 if( !parser.match('{') ) 766 if( !parser.match('{') )
767 return parser.failure(null); 767 return parser.failure(null);
768 In inParens = in.parens(); 768 In inParens = in.parens();
769 Spaces(inParens); 769 Spaces(inParens);
770 List<TableExpr.Field> fields = new ArrayList<TableExpr.Field>(); 770 List<TableExpr.Field> fields = new ArrayList<TableExpr.Field>();
771 ExpList.Builder builder = new ExpList.Builder(); 771 List<Expressions> builder = new ArrayList<Expressions>();
772 while( Field(fields,builder,in) && FieldSep(inParens) ); 772 while( Field(fields,builder,in) && FieldSep(inParens) );
773 Spaces(inParens); 773 Spaces(inParens);
774 if( !parser.match('}') ) 774 if( !parser.match('}') )
775 throw parser.exception("Expected table element or '}'"); 775 throw parser.exception("Expected table element or '}'");
776 return parser.success( new TableExpr( se(start), fields.toArray(new TableExpr.Field[0]), builder.build() ) ); 776 return parser.success( new TableExpr( se(start), fields.toArray(new TableExpr.Field[0]), ExpList.build(builder) ) );
777 } 777 }
778 778
779 private boolean FieldSep(In in) throws ParseException { 779 private boolean FieldSep(In in) throws ParseException {
780 if( !parser.anyOf(",;") ) 780 if( !parser.anyOf(",;") )
781 return false; 781 return false;
782 Spaces(in); 782 Spaces(in);
783 return true; 783 return true;
784 } 784 }
785 785
786 private boolean Field(List<TableExpr.Field> fields,ExpList.Builder builder,In in) throws ParseException { 786 private boolean Field(List<TableExpr.Field> fields,List<Expressions> builder,In in) throws ParseException {
787 parser.begin(); 787 parser.begin();
788 Expr exp = SubExpr(in); 788 Expr exp = SubExpr(in);
789 if( exp==null ) 789 if( exp==null )
790 exp = NameExpr(in); 790 exp = NameExpr(in);
791 if( exp!=null && parser.match('=') ) { 791 if( exp!=null && parser.match('=') ) {
792 Spaces(in); 792 Spaces(in);
793 fields.add( new TableExpr.Field( exp, required(expr(Expr(in))) ) ); 793 fields.add( new TableExpr.Field( exp, required(expr(Expr(in))) ) );
794 return parser.success(); 794 return parser.success();
795 } 795 }
796 parser.rollback(); 796 parser.rollback();
797 Code code = Expr(in); 797 Expressions exprs = Expr(in);
798 if( code != null ) { 798 if( exprs != null ) {
799 builder.add(code); 799 builder.add(exprs);
800 return parser.success(); 800 return parser.success();
801 } 801 }
802 return parser.failure(); 802 return parser.failure();
803 } 803 }
804 804
805 private Code VarExp(In in) throws ParseException { 805 private Expressions VarExp(In in) throws ParseException {
806 Var var = VarZ(in); 806 Var var = VarZ(in);
807 return var==null ? null : var.expr(); 807 return var==null ? null : var.expr();
808 } 808 }
809 809
810 private Var VarZ(In in) throws ParseException { 810 private Var VarZ(In in) throws ParseException {
817 var = var2; 817 var = var2;
818 } 818 }
819 return parser.success(var); 819 return parser.success(var);
820 } 820 }
821 821
822 private Var Var2(In in,int start,Code exp1) throws ParseException { 822 private Var Var2(In in,int start,Expressions exp1) throws ParseException {
823 Var var = VarExt(in,start,exp1); 823 Var var = VarExt(in,start,exp1);
824 if( var != null ) 824 if( var != null )
825 return var; 825 return var;
826 if( parser.match("->") ) { 826 if( parser.match("->") ) {
827 Spaces(in); 827 Spaces(in);
828 ExpList.Builder builder = new ExpList.Builder(); 828 List<Expressions> builder = new ArrayList<Expressions>();
829 builder.add(exp1); 829 builder.add(exp1);
830 Expr exp2 = expr(RequiredVarExpB(in)); 830 Expr exp2 = expr(RequiredVarExpB(in));
831 FnCall fnCall = required(Args( in, start, exp2, builder )); 831 FnCall fnCall = required(Args( in, start, exp2, builder ));
832 return exprVar(fnCall); 832 return exprVar(fnCall);
833 } 833 }
834 FnCall fnCall = Args( in, start, expr(exp1), new ExpList.Builder() ); 834 FnCall fnCall = Args( in, start, expr(exp1), new ArrayList<Expressions>() );
835 if( fnCall != null ) 835 if( fnCall != null )
836 return exprVar(fnCall); 836 return exprVar(fnCall);
837 return null; 837 return null;
838 } 838 }
839 839
840 private Code RequiredVarExpB(In in) throws ParseException { 840 private Expressions RequiredVarExpB(In in) throws ParseException {
841 int start = parser.begin(); 841 int start = parser.begin();
842 Var var = required(VarStart(in)); 842 Var var = required(VarStart(in));
843 Var var2; 843 Var var2;
844 while( (var2=VarExt(in,start,var.expr())) != null ) { 844 while( (var2=VarExt(in,start,var.expr())) != null ) {
845 var = var2; 845 var = var2;
846 } 846 }
847 return parser.success(var.expr()); 847 return parser.success(var.expr());
848 } 848 }
849 849
850 private Var VarExt(In in,int start,Code exp1) throws ParseException { 850 private Var VarExt(In in,int start,Expressions exp1) throws ParseException {
851 parser.begin(); 851 parser.begin();
852 Expr exp2 = SubExpr(in); 852 Expr exp2 = SubExpr(in);
853 if( exp2 != null ) 853 if( exp2 != null )
854 return parser.success(indexVar(start,expr(exp1),exp2)); 854 return parser.success(indexVar(start,expr(exp1),exp2));
855 if( parser.match('.') ) { 855 if( parser.match('.') ) {
886 return new GetUpVar(null,index); 886 return new GetUpVar(null,index);
887 throw new RuntimeException("_ENV not found"); 887 throw new RuntimeException("_ENV not found");
888 } 888 }
889 889
890 private interface Var { 890 private interface Var {
891 public Code expr(); 891 public Expressions expr();
892 public Settable settable(); 892 public Settable settable();
893 } 893 }
894 894
895 private Var nameVar(final int start,final String name) { 895 private Var nameVar(final int start,final String name) {
896 return new Var() { 896 return new Var() {
915 return new SetTableEntry( se(start), env(), new ConstExpr(name) ); 915 return new SetTableEntry( se(start), env(), new ConstExpr(name) );
916 } 916 }
917 }; 917 };
918 } 918 }
919 919
920 private Var exprVar(final Code expr) { 920 private Var exprVar(final Expressions expr) {
921 return new Var() { 921 return new Var() {
922 922
923 public Code expr() { 923 public Expressions expr() {
924 return expr; 924 return expr;
925 } 925 }
926 926
927 public Settable settable() { 927 public Settable settable() {
928 return null; 928 return null;
941 return new SetTableEntry(se(start),table,key); 941 return new SetTableEntry(se(start),table,key);
942 } 942 }
943 }; 943 };
944 } 944 }
945 945
946 private FnCall Args(In in,int start,Expr fn,ExpList.Builder builder) throws ParseException { 946 private FnCall Args(In in,int start,Expr fn,List<Expressions> builder) throws ParseException {
947 parser.begin(); 947 parser.begin();
948 return args(in,builder) 948 return args(in,builder)
949 ? parser.success( new FnCall( se(start), fn, builder.build() ) ) 949 ? parser.success( new FnCall( se(start), fn, ExpList.build(builder) ) )
950 : parser.failure((FnCall)null); 950 : parser.failure((FnCall)null);
951 } 951 }
952 952
953 private boolean args(In in,ExpList.Builder builder) throws ParseException { 953 private boolean args(In in,List<Expressions> builder) throws ParseException {
954 if( parser.match('(') ) { 954 if( parser.match('(') ) {
955 In inParens = in.parens(); 955 In inParens = in.parens();
956 Spaces(inParens); 956 Spaces(inParens);
957 ExpList(inParens,builder); // optional 957 ExpList(inParens,builder); // optional
958 if( !parser.match(')') ) 958 if( !parser.match(')') )
977 } 977 }
978 return false; 978 return false;
979 } 979 }
980 980
981 private Expressions ExpList(In in) throws ParseException { 981 private Expressions ExpList(In in) throws ParseException {
982 ExpList.Builder builder = new ExpList.Builder(); 982 List<Expressions> builder = new ArrayList<Expressions>();
983 return ExpList(in,builder) ? builder.build() : null; 983 return ExpList(in,builder) ? ExpList.build(builder) : null;
984 } 984 }
985 985
986 private boolean ExpList(In in,ExpList.Builder builder) throws ParseException { 986 private boolean ExpList(In in,List<Expressions> builder) throws ParseException {
987 parser.begin(); 987 parser.begin();
988 Code exp = Expr(in); 988 Expressions exp = Expr(in);
989 if( exp==null ) 989 if( exp==null )
990 return parser.failure(); 990 return parser.failure();
991 builder.add(exp); 991 builder.add(exp);
992 while( parser.match(',') ) { 992 while( parser.match(',') ) {
993 Spaces(in); 993 Spaces(in);