Mercurial Hosting > luan
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); |