comparison parser/Parser.d @ 152:893f23a9de93

Formatting change
author Anders Halager <halager@gmail.com>
date Mon, 21 Jul 2008 21:30:44 +0200
parents aeeef0dea14e
children 0ea5d2f3e96b
comparison
equal deleted inserted replaced
151:aeeef0dea14e 152:893f23a9de93
497 } 497 }
498 498
499 return a; 499 return a;
500 } 500 }
501 501
502 enum : uint 502 enum : uint
503 { 503 {
504 Single, 504 Single,
505 Scope, 505 Scope,
506 All 506 All
507 } 507 }
508 508
509 struct Att 509 struct Att
510 { 510 {
511 Attribute a; 511 Attribute a;
512 uint nested; 512 uint nested;
513 } 513 }
514 514
515 /** 515 /**
516 Parse statements. 516 Parse statements.
517 517
518 This is the place to attack! 518 This is the place to attack!
519 */ 519 */
520 Stmt parseStatement() 520 Stmt parseStatement()
521 { 521 {
522 Token t = peek; 522 Token t = peek;
523 523
524 if (t.isReturn) 524 if (t.isReturn)
525 { 525 {
526 Token ret = next(); 526 Token ret = next();
527 Exp exp; 527 Exp exp;
528 if (peek.type != Tok.Seperator) 528 if (peek.type != Tok.Seperator)
529 exp = parseExpression(); 529 exp = parseExpression();
530 require(Tok.Seperator); 530 require(Tok.Seperator);
531 return action.actOnReturnStmt(ret, exp); 531 return action.actOnReturnStmt(ret, exp);
532 532 }
533 /* 533 /*
534 if (cond) 534 if (cond)
535 single statement | compound statement 535 single statement | compound statement
536 [else 536 [else
537 single statement | compound statement] 537 single statement | compound statement]
538 */ 538 */
539 } 539 else if (t.isIf)
540 else if (t.isIf) 540 {
541 { 541 Token _if = next();
542 Token _if = next(); 542
543 543 require(Tok.OpenParentheses);
544 require(Tok.OpenParentheses); 544 Exp cond = parseExpression();
545 Exp cond = parseExpression(); 545 require(Tok.CloseParentheses);
546 require(Tok.CloseParentheses); 546
547 547 Stmt thenB = parseSingleOrCompoundStatement();
548 Stmt thenB = parseSingleOrCompoundStatement(); 548
549 549 // if there is no else part we use the if as token, to have
550 // if there is no else part we use the if as token, to have 550 // something than can be passed along
551 // something than can be passed along 551 Token _else = _if;
552 Token _else = _if; 552 Stmt elseB;
553 Stmt elseB; 553 if (peek.type == Tok.Else)
554 if (peek.type == Tok.Else) 554 {
555 { 555 _else = next();
556 _else = next(); 556 elseB = parseSingleOrCompoundStatement();
557 elseB = parseSingleOrCompoundStatement(); 557 }
558 } 558
559 559 return action.actOnIfStmt(_if, cond, thenB, _else, elseB);
560 return action.actOnIfStmt(_if, cond, thenB, _else, elseB); 560
561 561 }
562 /* 562 /*
563 while (cond) 563 while (cond)
564 single statement | compound statement 564 single statement | compound statement
565 */ 565 */
566 } 566 else if (t.isWhile)
567 else if (t.isWhile) 567 {
568 { 568 Token _while = next();
569 Token _while = next(); 569 require(Tok.OpenParentheses);
570 require(Tok.OpenParentheses); 570 Exp cond = parseExpression();
571 Exp cond = parseExpression(); 571 require(Tok.CloseParentheses);
572 require(Tok.CloseParentheses); 572 Stmt bodyStmt = parseSingleOrCompoundStatement();
573 Stmt bodyStmt = parseSingleOrCompoundStatement(); 573 return action.actOnWhileStmt(_while, cond, bodyStmt);
574 return action.actOnWhileStmt(_while, cond, bodyStmt); 574
575 575 }
576 /* 576 else if (t.isFor)
577 One of four things: 577 {
578 A declaration of a function/variable `type id ...` 578 Token _for = next();
579 A direct assignment `id = exp;` 579 require(Tok.OpenParentheses);
580 An indirect assignment `id.id = exp` 580 Stmt init;
581 Some sort of free standing expression 581 if ( isa(Tok.Seperator))
582 582 require(Tok.Seperator);
583 The assignments should be handled as binary expressions? 583 else
584 */ 584 init = parseStatement();
585 } 585
586 else if (t.isFor) 586 Exp cond;
587 { 587 if ( !isa(Tok.Seperator))
588 Token _for = next(); 588 cond = parseExpression();
589 require(Tok.OpenParentheses); 589 require(Tok.Seperator);
590 Stmt init; 590
591 if ( isa(Tok.Seperator)) 591 Exp incre;
592 require(Tok.Seperator); 592 if ( !isa(Tok.CloseParentheses))
593 else 593 incre = parseExpression();
594 init = parseStatement(); 594 require(Tok.CloseParentheses);
595 595
596 Exp cond; 596 Stmt bodyStmt = parseSingleOrCompoundStatement();
597 if ( !isa(Tok.Seperator)) 597 return action.actOnForStmt(_for, init, cond, incre, bodyStmt);
598 cond = parseExpression(); 598 }
599 require(Tok.Seperator); 599 else if (t.isBasicType || t.isIdentifier)
600 600 {
601 Exp incre; 601 Token iden = peek;
602 if ( !isa(Tok.CloseParentheses)) 602 Token n = peek(1);
603 incre = parseExpression(); 603 // Must be an decl, if we start with a basic type, or two
604 require(Tok.CloseParentheses); 604 // identifiers in a row
605 605 if ( n.type == Tok.Star || n.type == Tok.OpenBracket)
606 Stmt bodyStmt = parseSingleOrCompoundStatement(); 606 {
607 return action.actOnForStmt(_for, init, cond, incre, bodyStmt); 607 int len = peekParseType;
608 } 608 if(peek(len).type == Tok.Identifier && len != 0)
609 else if (t.isBasicType || t.isIdentifier) 609 return action.actOnDeclStmt(parseVarDecl());
610 { 610
611 Token iden = peek; 611 Exp exp = parseExpression();
612 Token n = peek(1); 612 require(Tok.Seperator);
613 // Must be an decl, if we start with a basic type, or two 613 return action.actOnExprStmt(exp);
614 // identifiers in a row 614 }
615 if ( n.type == Tok.Star || n.type == Tok.OpenBracket) 615
616 { 616 if (n.isIdentifier())
617 int len = peekParseType; 617 return action.actOnDeclStmt(parseVarDecl());
618 if(peek(len).type == Tok.Identifier && len != 0) 618
619 return action.actOnDeclStmt(parseVarDecl()); 619 // Expression: a.b, a = b, a(b) etc.
620 620 Exp exp = parseExpression();
621 Exp exp = parseExpression(); 621 require(Tok.Seperator);
622 require(Tok.Seperator); 622 return action.actOnExprStmt(exp);
623 return action.actOnExprStmt(exp); 623 }
624 } 624 else if (t.isSwitch)
625 625 {
626 if (n.isIdentifier()) 626 next();
627 return action.actOnDeclStmt(parseVarDecl()); 627 require(Tok.OpenParentheses);
628 628 auto target = parseExpression();
629 // Expression: a.b, a = b, a(b) etc. 629 auto res = action.actOnStartOfSwitchStmt(t, target);
630 Exp exp = parseExpression(); 630 require(Tok.CloseParentheses);
631 require(Tok.Seperator); 631 require(Tok.OpenBrace);
632 return action.actOnExprStmt(exp); 632 while (true)
633 } 633 {
634 else if (t.isSwitch) 634 Stmt[] statements;
635 { 635 if (isa(Tok.Default))
636 next();
637 require(Tok.OpenParentheses);
638 auto target = parseExpression();
639 auto res = action.actOnStartOfSwitchStmt(t, target);
640 require(Tok.CloseParentheses);
641 require(Tok.OpenBrace);
642 while (true)
643 { 636 {
644 Stmt[] statements; 637 Token _default = next();
645 if (isa(Tok.Default))
646 {
647 Token _default = next();
648 require(Tok.Colon);
649 statements.length = 0;
650 while (peek.type != Tok.Case
651 && peek.type != Tok.Default
652 && peek.type != Tok.CloseBrace)
653 statements ~= parseStatement();
654 action.actOnDefaultStmt(res, _default, statements);
655 continue;
656 }
657
658 Token _case = peek;
659 if (_case.type != Tok.Case)
660 break;
661 next();
662
663 Exp[] literals;
664 do
665 {
666 Exp e = parseExpression();
667 literals ~= e;
668 }
669 while (skip(Tok.Comma));
670 require(Tok.Colon); 638 require(Tok.Colon);
671 639 statements.length = 0;
672 while (peek.type != Tok.Case 640 while (peek.type != Tok.Case
673 && peek.type != Tok.Default 641 && peek.type != Tok.Default
674 && peek.type != Tok.CloseBrace) 642 && peek.type != Tok.CloseBrace)
675 statements ~= parseStatement(); 643 statements ~= parseStatement();
676 644 action.actOnDefaultStmt(res, _default, statements);
677 action.actOnCaseStmt(res, _case, literals, statements); 645 continue;
678
679 if (peek.type == Tok.CloseBrace)
680 break;
681 } 646 }
682 require(Tok.CloseBrace); 647
683 return res; 648 Token _case = peek;
684 } 649 if (_case.type != Tok.Case)
685 else 650 break;
686 { 651 next();
687 if (t.type == Tok.Star) 652
688 { 653 Exp[] literals;
689 auto exp = parseExpression(); 654 do
690 require(Tok.Seperator); 655 {
691 return action.actOnExprStmt(exp); 656 Exp e = parseExpression();
692 } 657 literals ~= e;
693 messages.report(UnexpectedBeginStmt, t.location).arg(t.getType); 658 }
694 return null; 659 while (skip(Tok.Comma));
695 } 660 require(Tok.Colon);
696 messages.report(UnexpectedTok, t.location); 661
697 return null; 662 while (peek.type != Tok.Case
698 } 663 && peek.type != Tok.Default
699 664 && peek.type != Tok.CloseBrace)
700 Decl parseVarDecl() 665 statements ~= parseStatement();
701 { 666
702 // manually hardcoded to only support "type id [= exp];" 667 action.actOnCaseStmt(res, _case, literals, statements);
703 // as that is the only thing the codegen understands 668
704 Id type = parseType; 669 if (peek.type == Tok.CloseBrace)
705 Id id = Id(next()); 670 break;
706 Exp init; 671 }
707 if (skip(Tok.Assign)) 672 require(Tok.CloseBrace);
708 init = parseExpression(); 673 return res;
709 require(Tok.Seperator); 674 }
710 Attribute att; 675 else if (t.type == Tok.Star)
711 Decl d = action.actOnDeclarator(type, id, init, att); 676 {
712 return d; 677 auto exp = parseExpression();
713 } 678 require(Tok.Seperator);
714 679 return action.actOnExprStmt(exp);
715 /** 680 }
716 Parses a function/method given the already parsed return type and name 681 else
717 */ 682 {
718 Decl parseFunc(ref Id type, ref Id name, Attribute att) 683 messages.report(UnexpectedBeginStmt, t.location).arg(t.getType);
719 { 684 return null;
720 Decl func = action.actOnStartOfFunctionDef(type, name, att); 685 }
721 parseFuncArgs(func); 686 }
722 687
723 if(peek.type == Tok.Seperator) 688 Decl parseVarDecl()
724 { 689 {
725 next(); 690 // manually hardcoded to only support "type id [= exp];"
726 return func; 691 // as that is the only thing the codegen understands
727 } 692 Id type = parseType;
728 Stmt stmt = parseCompoundStatement(); 693 Id id = Id(next());
729 694 Exp init;
730 return action.actOnEndOfFunction(func, stmt); 695 if (skip(Tok.Assign))
731 } 696 init = parseExpression();
732 697 require(Tok.Seperator);
733 /** 698 Attribute att;
734 Parse the function arguments, assumes current token is (. 699 Decl d = action.actOnDeclarator(type, id, init, att);
735 700 return d;
736 Both the intitial paren and the ending paren is consumed. 701 }
737 */ 702
738 void parseFuncArgs(Decl func) 703 /**
739 { 704 Parses a function/method given the already parsed return type and name
740 require(Tok.OpenParentheses); // Remove the "(" token. 705 */
741 706 Decl parseFunc(ref Id type, ref Id name, Attribute att)
742 while(peek.type != Tok.CloseParentheses) 707 {
743 { 708 Decl func = action.actOnStartOfFunctionDef(type, name, att);
744 auto t = parseType(); 709 parseFuncArgs(func);
745 Id i; 710
746 if(peek.type == Tok.Identifier) 711 if(peek.type == Tok.Seperator)
747 i = parseIdentifier(); 712 {
748 action.addFuncArg(func, t, i); 713 next();
749 714 return func;
750 if(peek.type == Tok.Comma) 715 }
751 next(); 716 Stmt stmt = parseCompoundStatement();
752 } 717
753 718 return action.actOnEndOfFunction(func, stmt);
754 require(Tok.CloseParentheses); // Remove the ")" 719 }
755 } 720
756 721 /**
757 /** 722 Parse the function arguments, assumes current token is (.
758 Parse either a block, or a single statement as allowed after if, while 723
759 and for. 724 Both the intitial paren and the ending paren is consumed.
760 */ 725 */
761 Stmt parseSingleOrCompoundStatement() 726 void parseFuncArgs(Decl func)
762 { 727 {
763 if (peek.type == Tok.OpenBrace) 728 require(Tok.OpenParentheses); // Remove the "(" token.
764 return parseCompoundStatement(); 729
765 return parseStatement(); 730 while(peek.type != Tok.CloseParentheses)
766 } 731 {
767 732 auto t = parseType();
768 /** 733 Id i;
769 Parses a function-body or similar, expects an opening brace to be the 734 if(peek.type == Tok.Identifier)
770 current token. 735 i = parseIdentifier();
771 736 action.addFuncArg(func, t, i);
772 Will consume both the starting { and ending } 737
773 */ 738 if(peek.type == Tok.Comma)
774 Stmt parseCompoundStatement() 739 next();
775 { 740 }
776 Token lbrace = require(Tok.OpenBrace); 741
777 SmallArray!(Stmt, 32) stmts; // Try to use the stack only 742 require(Tok.CloseParentheses); // Remove the ")"
778 while ( !isa(Tok.CloseBrace) && !isa(Tok.EOF) ) 743 }
779 stmts ~= parseStatement(); 744
780 Token rbrace = require(Tok.CloseBrace); 745 /**
781 return action.actOnCompoundStmt(lbrace, rbrace, stmts.unsafe()); 746 Parse either a block, or a single statement as allowed after if, while
782 } 747 and for.
783 748 */
784 Id parseIdentifier() 749 Stmt parseSingleOrCompoundStatement()
785 { 750 {
786 Token tok = next(); 751 if (peek.type == Tok.OpenBrace)
787 752 return parseCompoundStatement();
788 if (tok.type is Tok.Identifier) 753 return parseStatement();
789 return Id(tok); 754 }
790 755
791 messages.report(UnexpectedTokSingle, tok.location) 756 /**
792 .arg(tok.getType) 757 Parses a function-body or similar, expects an opening brace to be the
793 .arg(Tok.Identifier); 758 current token.
794 } 759
795 760 Will consume both the starting { and ending }
796 ModuleName parseModuleName() 761 */
797 { 762 Stmt parseCompoundStatement()
798 auto id = parseIdentifier(); 763 {
799 ModuleName mod; 764 Token lbrace = require(Tok.OpenBrace);
800 while (skip(Tok.Dot)) 765 SmallArray!(Stmt, 32) stmts; // Try to use the stack only
801 { 766 while ( !isa(Tok.CloseBrace) && !isa(Tok.EOF) )
802 mod.packages ~= id; 767 stmts ~= parseStatement();
803 if (peek.type != Tok.Identifier) { 768 Token rbrace = require(Tok.CloseBrace);
804 messages.report(ExpectedIdAfterPackage, peek.location); 769 return action.actOnCompoundStmt(lbrace, rbrace, stmts.unsafe());
805 goto Lerror; 770 }
806 } 771
807 id = parseIdentifier(); 772 Id parseIdentifier()
808 } 773 {
809 mod.id = id; 774 Token tok = next();
810 return mod; 775
776 if (tok.type is Tok.Identifier)
777 return Id(tok);
778
779 messages.report(UnexpectedTokSingle, tok.location)
780 .arg(tok.getType)
781 .arg(Tok.Identifier);
782 }
783
784 ModuleName parseModuleName()
785 {
786 auto id = parseIdentifier();
787 ModuleName mod;
788 while (skip(Tok.Dot))
789 {
790 mod.packages ~= id;
791 if (peek.type != Tok.Identifier) {
792 messages.report(ExpectedIdAfterPackage, peek.location);
793 goto Lerror;
794 }
795 id = parseIdentifier();
796 }
797 mod.id = id;
798 return mod;
811 Lerror: 799 Lerror:
812 while (!skip(Tok.Seperator)) 800 while (!skip(Tok.Seperator))
813 next(); 801 next();
814 return mod; 802 return mod;
815 } 803 }
816 804
817 805
818 /** 806 /**
819 Parse a type - this includes pointer and array(at some point) types. 807 Parse a type - this includes pointer and array(at some point) types.
820 */ 808 */
821 Id parseType() 809 Id parseType()
822 { 810 {
823 Token type = next(); 811 Token type = next();
824 812
825 Id currentType; 813 Id currentType;
826 814
827 if ( !(type.isBasicType || type.type == Tok.Identifier) ) 815 if ( !(type.isBasicType || type.type == Tok.Identifier) )
828 messages.report(InvalidType, type.location); 816 messages.report(InvalidType, type.location);
829 817
830 currentType = Id(type); 818 currentType = Id(type);
831 type = peek; 819 type = peek;
832 820
833 while(type.type == Tok.Star || type.type == Tok.OpenBracket) 821 while(type.type == Tok.Star || type.type == Tok.OpenBracket)
834 { 822 {
835 if(type.type == Tok.Star) 823 if(type.type == Tok.Star)
836 { 824 {
837 currentType = PointerId(currentType); 825 currentType = PointerId(currentType);
838 next(); 826 next();
839 } 827 }
840 else 828 else
841 { 829 {
842 next(); 830 next();
843 if(peek.type == Tok.Integer) 831 if(peek.type == Tok.Integer)
844 currentType = StaticArrayId( 832 currentType = StaticArrayId(
845 currentType, 833 currentType,
846 action.actOnNumericConstant( 834 action.actOnNumericConstant(
847 require(Tok.Integer))); 835 require(Tok.Integer)));
848 require(Tok.CloseBracket); 836 require(Tok.CloseBracket);
849 837
850 } 838 }
851 type = peek; 839 type = peek;
852 } 840 }
853 841
854 return currentType; 842 return currentType;
855 } 843 }
856 844
857 int peekParseType() 845 int peekParseType()
858 { 846 {
859 int i; 847 int i;
860 Token type = peek(i); 848 Token type = peek(i);
861 849
862 Id currentType; 850 Id currentType;
863 851
864 if ( !(type.isBasicType || type.type == Tok.Identifier) ) 852 if ( !(type.isBasicType || type.type == Tok.Identifier) )
865 return 0; 853 return 0;
866 854
867 currentType = Id(type); 855 currentType = Id(type);
868 type = peek(++i); 856 type = peek(++i);
869 857
870 while(type.type == Tok.Star || type.type == Tok.OpenBracket) 858 while(type.type == Tok.Star || type.type == Tok.OpenBracket)
871 { 859 {
872 if(type.type == Tok.Star) 860 if(type.type == Tok.Star)
873 { 861 {
874 i++; 862 i++;
875 } 863 }
876 else 864 else
877 { 865 {
878 if(peek(i++).type != Tok.OpenBracket) 866 if(peek(i++).type != Tok.OpenBracket)
879 return 0; 867 return 0;
880 if(peek(i).type == Tok.Integer) 868 if(peek(i).type == Tok.Integer)
881 { 869 {
882 i++; 870 i++;
883 if(peek(i++).type != Tok.CloseBracket) 871 if(peek(i++).type != Tok.CloseBracket)
884 return 0; 872 return 0;
885 } 873 }
886 else 874 else
887 if(peek(i++).type != Tok.CloseBracket) 875 if(peek(i++).type != Tok.CloseBracket)
888 return 0; 876 return 0;
889 877
890 } 878 }
891 type = peek(i); 879 type = peek(i);
892 } 880 }
893 881
894 return i; 882 return i;
895 } 883 }
896 884
897 private: 885 private:
898 // -- Expression parsing -- // 886 // -- Expression parsing -- //
899 Exp parsePostfixExp(Exp target) 887 Exp parsePostfixExp(Exp target)
900 { 888 {
901 switch(peek.type) 889 switch(peek.type)
902 { 890 {
903 case Tok.Dot: 891 case Tok.Dot:
904 switch(peek(1).type) 892 switch(peek(1).type)
905 { 893 {
906 case Tok.Identifier: 894 case Tok.Identifier:
907 Token op = next(); 895 Token op = next();
908 Id member = Id(next()); 896 Id member = Id(next());
909 Exp exp = action.actOnMemberReference(target, op.location, member); 897 Exp exp = action.actOnMemberReference(target, op.location, member);
910 return parsePostfixExp(exp); 898 return parsePostfixExp(exp);
911 default: 899 default:
912 Token t = peek(1); 900 Token t = peek(1);
913 messages.report(ExpectedIdAfterDot, t.location); 901 messages.report(ExpectedIdAfterDot, t.location);
914 } 902 }
915 case Tok.OpenBracket: 903 case Tok.OpenBracket:
916 Token open = next(); 904 Token open = next();
917 Exp index = parseExpression(); 905 Exp index = parseExpression();
918 Token close = require(Tok.CloseBracket); 906 Token close = require(Tok.CloseBracket);
919 return action.actOnIndexEpr(target, open, index, close); 907 return action.actOnIndexEpr(target, open, index, close);
920 default: 908 default:
921 return target; 909 return target;
922 } 910 }
923 } 911 }
924 912
925 Exp parseExpression(int p = 0) 913 Exp parseExpression(int p = 0)
926 { 914 {
927 auto exp = P(); 915 auto exp = P();
928 Token n = peek(); 916 Token n = peek();
929 BinOp* op = null; 917 BinOp* op = null;
930 while ((op = binary(n.type)) != null && op.prec >= p) 918 while ((op = binary(n.type)) != null && op.prec >= p)
931 { 919 {
932 next(); 920 next();
933 int q = op.leftAssoc? 1 + op.prec : op.prec; 921 int q = op.leftAssoc? 1 + op.prec : op.prec;
934 auto exp2 = parseExpression(q); 922 auto exp2 = parseExpression(q);
935 exp = action.actOnBinaryOp(n.location, op.operator, exp, exp2); 923 exp = action.actOnBinaryOp(n.location, op.operator, exp, exp2);
936 n = peek(); 924 n = peek();
937 } 925 }
938 926
939 return exp; 927 return exp;
940 } 928 }
941 929
942 Exp P() 930 Exp P()
943 { 931 {
944 Token n = next(); 932 Token n = next();
945 if (auto op = unary(n.type)) 933 if (auto op = unary(n.type))
946 return action.actOnUnaryOp(n, parseExpression(op.prec)); 934 return action.actOnUnaryOp(n, parseExpression(op.prec));
947 else if (n.type == Tok.OpenParentheses) 935 else if (n.type == Tok.OpenParentheses)
948 { 936 {
949 auto e = parseExpression(0); 937 auto e = parseExpression(0);
950 require(Tok.CloseParentheses); 938 require(Tok.CloseParentheses);
951 return e; 939 return e;
952 } 940 }
953 else if (n.type == Tok.Identifier) 941 else if (n.type == Tok.Identifier)
954 { 942 {
955 Exp value = action.actOnIdentifierExp(Id(n)); 943 Exp value = action.actOnIdentifierExp(Id(n));
956 Exp iden = parsePostfixExp(value); 944 Exp iden = parsePostfixExp(value);
957 switch(peek.type) 945 switch(peek.type)
958 { 946 {
959 case Tok.OpenParentheses: 947 case Tok.OpenParentheses:
960 Token lp = next(); 948 Token lp = next();
961 SmallArray!(Exp, 8) args; 949 SmallArray!(Exp, 8) args;
962 while(peek.type != Tok.CloseParentheses) 950 while(peek.type != Tok.CloseParentheses)
963 { 951 {
964 if(peek.type == Tok.Comma) 952 if(peek.type == Tok.Comma)
965 next(); 953 next();
966 args ~= parseExpression(); 954 args ~= parseExpression();
967 } 955 }
968 956
969 Token rp = next(); 957 Token rp = next();
970 return action.actOnCallExpr(iden, lp, args.unsafe(), rp); 958 return action.actOnCallExpr(iden, lp, args.unsafe(), rp);
971 959
972 default: 960 default:
973 return iden; 961 return iden;
974 } 962 }
975 } 963 }
976 else if (n.type == Tok.Cast) 964 else if (n.type == Tok.Cast)
977 return parseCast(n); 965 return parseCast(n);
978 else if (n.type == Tok.Integer) 966 else if (n.type == Tok.Integer)
979 return action.actOnNumericConstant(n); 967 return action.actOnNumericConstant(n);
980 else if (n.type == Tok.String) 968 else if (n.type == Tok.String)
981 return action.actOnStringExp(n); 969 return action.actOnStringExp(n);
982 970
983 messages.report(ExpectedExp, n.location) 971 messages.report(ExpectedExp, n.location)
984 .fatal(ExitLevel.Parser); 972 .fatal(ExitLevel.Parser);
985 return null; 973 return null;
986 } 974 }
987 975
988 Exp parseCast(ref Token _cast) 976 Exp parseCast(ref Token _cast)
989 { 977 {
990 require(Tok.OpenParentheses); 978 require(Tok.OpenParentheses);
991 auto n = next(); 979 auto n = next();
992 if(!n.isBasicType && !n.isIdentifier) 980 if(!n.isBasicType && !n.isIdentifier)
993 messages.report(ExpectedCastType, n.location); 981 messages.report(ExpectedCastType, n.location);
994 982
995 require(Tok.CloseParentheses); 983 require(Tok.CloseParentheses);
996 auto exp = P(); 984 auto exp = P();
997 return action.actOnCastExpr(_cast, Id(n), exp); 985 return action.actOnCastExpr(_cast, Id(n), exp);
998 } 986 }
999 987
1000 struct UnOp 988 struct UnOp
1001 { 989 {
1002 Tok tokenType; 990 Tok tokenType;
1003 int prec; 991 int prec;
1004 } 992 }
1005 993
1006 static const UnOp[] _unary = 994 static const UnOp[] _unary =
1007 [ 995 [
1008 {Tok.Minus, 4}, 996 {Tok.Minus, 4},
1009 {Tok.Star, 4} 997 {Tok.Star, 4}
1010 ]; 998 ];
1011 UnOp* unary(Tok t) 999 UnOp* unary(Tok t)
1012 { 1000 {
1013 foreach (ref op; _unary) 1001 foreach (ref op; _unary)
1014 if (op.tokenType == t) 1002 if (op.tokenType == t)
1015 return &op; 1003 return &op;
1016 return null; 1004 return null;
1017 } 1005 }
1018 1006
1019 struct BinOp 1007 struct BinOp
1020 { 1008 {
1021 Tok tokenType; 1009 Tok tokenType;
1022 int prec; 1010 int prec;
1023 bool leftAssoc; 1011 bool leftAssoc;
1024 Operator operator; 1012 Operator operator;
1025 } 1013 }
1026 1014
1027 static const BinOp[] _binary = 1015 static const BinOp[] _binary =
1028 [ 1016 [
1029 {Tok.Assign, 1, false, Operator.Assign}, 1017 {Tok.Assign, 1, false, Operator.Assign},
1030 {Tok.PlusAssign, 1, false, Operator.AddAssign}, 1018 {Tok.PlusAssign, 1, false, Operator.AddAssign},
1031 {Tok.MinusAssign, 1, false, Operator.SubAssign}, 1019 {Tok.MinusAssign, 1, false, Operator.SubAssign},
1032 {Tok.StarAssign, 1, false, Operator.MulAssign}, 1020 {Tok.StarAssign, 1, false, Operator.MulAssign},
1033 {Tok.SlashAssign, 1, false, Operator.DivAssign}, 1021 {Tok.SlashAssign, 1, false, Operator.DivAssign},
1034 {Tok.PercentAssign, 1, false, Operator.ModAssign}, 1022 {Tok.PercentAssign, 1, false, Operator.ModAssign},
1035 1023
1036 // =, += etc. 1 1024 // =, += etc. 1
1037 // (need special-case for the ternary operator at this level) 1025 // (need special-case for the ternary operator at this level)
1038 // ||, 2 1026 // ||, 2
1039 // &&, 3 1027 // &&, 3
1040 // |, 4 1028 // |, 4
1041 // &, 5 1029 // &, 5
1042 // ^, 6 1030 // ^, 6
1043 // ==, !=, is, !is, 7 1031 // ==, !=, is, !is, 7
1044 // <, <= etc, 7 1032 // <, <= etc, 7
1045 // in, 7 1033 // in, 7
1046 // <<, >>, >>>, 8 1034 // <<, >>, >>>, 8
1047 // +, -, ~, 9 1035 // +, -, ~, 9
1048 // *, /, %, 10 1036 // *, /, %, 10
1049 // unary operators here 1037 // unary operators here
1050 1038
1051 {Tok.Eq, 2, true, Operator.Eq}, 1039 {Tok.Eq, 2, true, Operator.Eq},
1052 {Tok.Ne, 2, true, Operator.Ne}, 1040 {Tok.Ne, 2, true, Operator.Ne},
1053 1041
1054 {Tok.Lt, 2, true, Operator.Lt}, 1042 {Tok.Lt, 2, true, Operator.Lt},
1055 {Tok.Le, 2, true, Operator.Le}, 1043 {Tok.Le, 2, true, Operator.Le},
1056 {Tok.Gt, 2, true, Operator.Gt}, 1044 {Tok.Gt, 2, true, Operator.Gt},
1057 {Tok.Ge, 2, true, Operator.Ge}, 1045 {Tok.Ge, 2, true, Operator.Ge},
1058 1046
1059 {Tok.Plus, 3, true, Operator.Add}, 1047 {Tok.Plus, 3, true, Operator.Add},
1060 {Tok.Minus, 3, true, Operator.Sub}, 1048 {Tok.Minus, 3, true, Operator.Sub},
1061 1049
1062 {Tok.Star, 5, true, Operator.Mul}, 1050 {Tok.Star, 5, true, Operator.Mul},
1063 {Tok.Slash, 5, true, Operator.Div}, 1051 {Tok.Slash, 5, true, Operator.Div},
1064 {Tok.Percent, 5, true, Operator.Mod}, 1052 {Tok.Percent, 5, true, Operator.Mod},
1065 1053
1066 {Tok.LeftShift, 8, true, Operator.LeftShift}, 1054 {Tok.LeftShift, 8, true, Operator.LeftShift},
1067 {Tok.RightShift, 8, true, Operator.RightShift}, 1055 {Tok.RightShift, 8, true, Operator.RightShift},
1068 {Tok.UnsignedRightShift, 8, true, Operator.UnsignedRightShift} 1056 {Tok.UnsignedRightShift, 8, true, Operator.UnsignedRightShift}
1069 ]; 1057 ];
1070 BinOp* binary(Tok t) 1058 BinOp* binary(Tok t)
1071 { 1059 {
1072 foreach (ref op; _binary) 1060 foreach (ref op; _binary)
1073 if (op.tokenType == t) 1061 if (op.tokenType == t)
1074 return &op; 1062 return &op;
1075 return null; 1063 return null;
1076 } 1064 }
1077 1065
1078 private: 1066 private:
1079 1067
1080 Token require(Tok t) 1068 Token require(Tok t)
1081 { 1069 {
1082 if (peek().type != t) 1070 if (peek().type != t)
1083 messages.report(UnexpectedTokSingle, peek.location) 1071 messages.report(UnexpectedTokSingle, peek.location)
1084 .arg(peek.getType) 1072 .arg(peek.getType)
1085 .arg(t); 1073 .arg(t);
1086 return next(); 1074 return next();
1087 } 1075 }
1088 1076
1089 bool skip(Tok t) 1077 bool skip(Tok t)
1090 { 1078 {
1091 if (peek().type != t) 1079 if (peek().type != t)
1092 return false; 1080 return false;
1093 next(); 1081 next();
1094 return true; 1082 return true;
1095 } 1083 }
1096 1084
1097 bool isa(Tok t) 1085 bool isa(Tok t)
1098 { 1086 {
1099 return peek.type == t; 1087 return peek.type == t;
1100 } 1088 }
1101 1089
1102 Token next() 1090 Token next()
1103 { 1091 {
1104 return lexer.next; 1092 return lexer.next;
1105 } 1093 }
1106 1094
1107 Token peek(int i = 0) 1095 Token peek(int i = 0)
1108 { 1096 {
1109 return lexer.peek(i); 1097 return lexer.peek(i);
1110 } 1098 }
1111 1099
1112 Lexer lexer; 1100 Lexer lexer;
1113 SourceManager sm; 1101 SourceManager sm;
1114 } 1102 }
1115 1103