|
|
@@ -583,1435 +583,1439 @@ Listing:
|
|
|
566 ParIdents<isV> ":" Type<t, TRUE> (. i := 0;
|
|
|
567 WHILE i < SymTab.PendCount() DO
|
|
|
568 SymTab.PendName(i, nm);
|
|
|
- 569 IF ~QbeGen.FuncParam(nm,
|
|
|
- 570 isV, t) THEN
|
|
|
- 571 SemError(233) END;
|
|
|
- 572 INC(i)
|
|
|
- 573 END;
|
|
|
- 574 SymTab.FixPending(t);
|
|
|
- 575 IF ~isV
|
|
|
- 576 & SymTab.IsOpenArray(t) THEN
|
|
|
- 577 SemError(230) END; .) .
|
|
|
- 578 (* Nested procedures lower like top-level ones (4.2): the
|
|
|
- 579 static link gives them their parent's frame. Methods keep
|
|
|
- 580 parse-now/230-later. *)
|
|
|
- 581 ProcDecl (. VAR pn: SymTab.Name; .)
|
|
|
- 582 = ProcHeading<pn> ";"
|
|
|
- 583 ( "FORWARD" (. SymTab.MarkFwd;
|
|
|
- 584 SymTab.CloseProc;
|
|
|
- 585 QbeGen.AbortFunc; .)
|
|
|
- 586 | "EXTERNAL" (. SymTab.MarkExternal("");
|
|
|
- 587 SymTab.CloseProc;
|
|
|
- 588 QbeGen.AbortFunc; .)
|
|
|
- 589 | (. QbeGen.EndFuncHeader; .)
|
|
|
- 590 Block<pn> (. SymTab.CloseProc;
|
|
|
- 591 QbeGen.EndFunc(
|
|
|
- 592 SymTab.ProcRes(pn)); .) ) .
|
|
|
- 593 Block<pn: SymTab.Name> (. VAR m2: SymTab.Name; .)
|
|
|
- 594 = DeclSeq
|
|
|
- 595 [ "BEGIN"
|
|
|
- 596 [ StatSeq ] ]
|
|
|
- 597 "END"
|
|
|
- 598 GetIdent<m2> (. IF ~SymTab.Equal(pn, m2) THEN
|
|
|
- 599 SemError(202) END; .) .
|
|
|
- 600 StatSeq
|
|
|
- 601 = Statement { ";" Statement } .
|
|
|
- 602 Statement (. VAR lx: QbeGen.QVal; .)
|
|
|
- 603 = AssOrCall
|
|
|
- 604 | IfStat
|
|
|
- 605 | WhileStat
|
|
|
- 606 | RepeatStat
|
|
|
- 607 | LoopStat
|
|
|
- 608 | ForStat
|
|
|
- 609 | CaseStat
|
|
|
- 610 | WithStat
|
|
|
- 611 | ReturnStat
|
|
|
- 612 | NewStat
|
|
|
- 613 | DisposeStat
|
|
|
- 614 | IncDecStat
|
|
|
- 615 | "EXIT" (. IF QbeGen.TopLoop(lx) THEN
|
|
|
- 616 QbeGen.Jmp(lx)
|
|
|
- 617 ELSE SemError(230) END; .) .
|
|
|
- 618 (* INC(v [,step]) / DEC(v [,step]) as builtin statements over an
|
|
|
- 619 integer designator. *)
|
|
|
- 620 IncDecStat (. VAR dt, et2: SymTab.TypeIndex;
|
|
|
- 621 dk: INTEGER;
|
|
|
- 622 qd, qv, qn2, qstep:
|
|
|
- 623 QbeGen.QVal;
|
|
|
- 624 qn: SymTab.Name;
|
|
|
- 625 sfx, isInc: BOOLEAN; .)
|
|
|
- 626 = (. isInc := TRUE; .)
|
|
|
- 627 ( "INC" (. isInc := TRUE; .)
|
|
|
- 628 | "DEC" (. isInc := FALSE; .) )
|
|
|
- 629 "(" (. QbeGen.CopyOp("1", qstep); .)
|
|
|
- 630 Design<dt, dk, qd, qn, sfx>
|
|
|
- 631 [ "," Expr<et2, qstep> ]
|
|
|
- 632 ")" (. IF dt = SymTab.InvalidType THEN
|
|
|
- 633 ELSIF (dk # SymTab.KindVar)
|
|
|
- 634 & (dk # SymTab.KindParam)
|
|
|
- 635 & (dk # SymTab.KindField) THEN
|
|
|
- 636 SemError(210)
|
|
|
- 637 ELSIF ~SymTab.IsIntFamily(dt) THEN
|
|
|
- 638 SemError(211)
|
|
|
- 639 ELSE
|
|
|
- 640 IF sfx
|
|
|
- 641 OR (dk = SymTab.KindField) THEN
|
|
|
- 642 QbeGen.ElemLoad(qd, dt, qv)
|
|
|
- 643 ELSE QbeGen.LoadVar(qn,
|
|
|
- 644 FALSE, qv)
|
|
|
- 645 END;
|
|
|
- 646 QbeGen.NewTemp(qn2);
|
|
|
- 647 IF isInc THEN
|
|
|
- 648 QbeGen.Op3("add", qn2, qv,
|
|
|
- 649 qstep, FALSE)
|
|
|
- 650 ELSE QbeGen.Op3("sub", qn2, qv,
|
|
|
- 651 qstep, FALSE)
|
|
|
- 652 END;
|
|
|
- 653 IF sfx
|
|
|
- 654 OR (dk = SymTab.KindField) THEN
|
|
|
- 655 QbeGen.ElemStore(qd, qn2,
|
|
|
- 656 dt)
|
|
|
- 657 ELSE QbeGen.StoreVar(qn,
|
|
|
- 658 qn2, FALSE)
|
|
|
- 659 END
|
|
|
- 660 END; .) .
|
|
|
- 661 (* NEW/DISPOSE as builtin statements (no call syntax until step 4).
|
|
|
- 662 Targets are pointer designators; DISPOSE nils afterwards (safer
|
|
|
- 663 than Wirth-undefined; documented). DISPOSE is shallow. *)
|
|
|
- 664 NewStat (. VAR dt: SymTab.TypeIndex;
|
|
|
- 665 dk: INTEGER;
|
|
|
- 666 qd, qm: QbeGen.QVal;
|
|
|
- 667 qn: SymTab.Name;
|
|
|
- 668 sfx: BOOLEAN;
|
|
|
- 669 bt: SymTab.TypeIndex; .)
|
|
|
- 670 = "NEW" "(" Design<dt, dk, qd, qn, sfx> ")"
|
|
|
- 671 (. IF dt = SymTab.InvalidType THEN
|
|
|
- 672 ELSIF (dk # SymTab.KindVar)
|
|
|
- 673 & (dk # SymTab.KindParam)
|
|
|
- 674 & (dk # SymTab.KindField) THEN
|
|
|
- 675 SemError(210)
|
|
|
- 676 ELSIF SymTab.ClassOf(dt) #
|
|
|
- 677 SymTab.ClPtr THEN
|
|
|
- 678 SemError(219)
|
|
|
- 679 ELSE bt := SymTab.PtrBase(dt);
|
|
|
- 680 IF bt #
|
|
|
- 681 SymTab.InvalidType THEN
|
|
|
- 682 QbeGen.NewHeap(bt, qm);
|
|
|
- 683 QbeGen.InitHeap(qm, bt);
|
|
|
- 684 IF sfx
|
|
|
- 685 OR (dk =
|
|
|
- 686 SymTab.KindField) THEN
|
|
|
- 687 QbeGen.ElemStore(qd, qm,
|
|
|
- 688 dt)
|
|
|
- 689 ELSE QbeGen.StorePtr(qn,
|
|
|
- 690 qm)
|
|
|
- 691 END
|
|
|
- 692 END
|
|
|
- 693 END; .) .
|
|
|
- 694 DisposeStat (. VAR dt: SymTab.TypeIndex;
|
|
|
- 695 dk: INTEGER;
|
|
|
- 696 qd, qv: QbeGen.QVal;
|
|
|
- 697 qn: SymTab.Name;
|
|
|
- 698 sfx: BOOLEAN; .)
|
|
|
- 699 = "DISPOSE" "(" Design<dt, dk, qd, qn, sfx> ")"
|
|
|
- 700 (. IF dt = SymTab.InvalidType THEN
|
|
|
- 701 ELSIF (dk # SymTab.KindVar)
|
|
|
- 702 & (dk # SymTab.KindParam)
|
|
|
- 703 & (dk # SymTab.KindField) THEN
|
|
|
- 704 SemError(210)
|
|
|
- 705 ELSIF SymTab.ClassOf(dt) #
|
|
|
- 706 SymTab.ClPtr THEN
|
|
|
- 707 SemError(219)
|
|
|
- 708 ELSE
|
|
|
- 709 IF sfx
|
|
|
- 710 OR (dk =
|
|
|
- 711 SymTab.KindField) THEN
|
|
|
- 712 QbeGen.ElemLoad(qd, dt,
|
|
|
- 713 qv)
|
|
|
- 714 ELSE QbeGen.LoadPtr(qn, qv)
|
|
|
- 715 END;
|
|
|
- 716 QbeGen.FreeHeap(qv);
|
|
|
- 717 IF sfx
|
|
|
- 718 OR (dk =
|
|
|
- 719 SymTab.KindField) THEN
|
|
|
- 720 QbeGen.ElemStore(qd, "0",
|
|
|
- 721 dt)
|
|
|
- 722 ELSE QbeGen.StorePtr(qn,
|
|
|
- 723 "0")
|
|
|
- 724 END
|
|
|
- 725 END; .) .
|
|
|
- 726 (* WITH pushes each record's fields (inner wins) plus its base
|
|
|
- 727 address; field designators resolve through both stacks. *)
|
|
|
- 728 WithStat (. VAR nW: CARDINAL; .)
|
|
|
- 729 = "WITH" (. nW := 0; .)
|
|
|
- 730 WithItem<nW> { "," WithItem<nW> }
|
|
|
- 731 "DO" StatSeq "END"
|
|
|
- 732 (. WHILE nW > 0 DO
|
|
|
- 733 SymTab.PopScope;
|
|
|
- 734 QbeGen.PopWith;
|
|
|
- 735 DEC(nW)
|
|
|
- 736 END; .) .
|
|
|
- 737 WithItem<VAR nW: CARDINAL> (. VAR dt: SymTab.TypeIndex;
|
|
|
- 738 dk: INTEGER;
|
|
|
- 739 qd, qe: QbeGen.QVal;
|
|
|
- 740 qn: SymTab.Name;
|
|
|
- 741 sfx: BOOLEAN; .)
|
|
|
- 742 = Design<dt, dk, qd, qn, sfx>
|
|
|
- 743 (. IF dt = SymTab.InvalidType THEN
|
|
|
- 744 ELSIF (SymTab.ClassOf(dt) #
|
|
|
- 745 SymTab.ClRecord)
|
|
|
- 746 & (SymTab.ClassOf(dt) #
|
|
|
- 747 SymTab.ClClass) THEN
|
|
|
- 748 SemError(215)
|
|
|
- 749 ELSIF SymTab.PushRecord(dt) THEN
|
|
|
- 750 QbeGen.PushWith(qd);
|
|
|
- 751 INC(nW)
|
|
|
- 752 END; .) .
|
|
|
- 753 (* Assignment or procedure-statement call (4.1, module level).
|
|
|
- 754 Bare `P;` is a syntax error; function-as-statement is 233. *)
|
|
|
- 755 AssOrCall (. VAR dt, et: SymTab.TypeIndex;
|
|
|
- 756 dk: INTEGER;
|
|
|
- 757 qd, qe, qt, ql: QbeGen.QVal;
|
|
|
- 758 qn: SymTab.Name;
|
|
|
- 759 ct2, res0: SymTab.TypeIndex;
|
|
|
- 760 q2, mg0: QbeGen.QVal;
|
|
|
- 761 isR, conv, wconv: BOOLEAN;
|
|
|
- 762 called, sfx: BOOLEAN; .)
|
|
|
- 763 = Design<dt, dk, qd, qn, sfx>
|
|
|
- 764 ( ":="
|
|
|
- 765 Expr<et, qe> (. IF (dt # SymTab.InvalidType)
|
|
|
- 766 & (dk # SymTab.KindVar)
|
|
|
- 767 & (dk # SymTab.KindParam)
|
|
|
- 768 & (dk # SymTab.KindField) THEN
|
|
|
- 769 SemError(210)
|
|
|
- 770 ELSIF ~SymTab.Assignable(et,
|
|
|
- 771 dt) THEN
|
|
|
- 772 SemError(210)
|
|
|
- 773 ELSIF (dt # SymTab.InvalidType)
|
|
|
- 774 & (SymTab.ClassOf(dt) =
|
|
|
- 775 SymTab.ClClass) THEN
|
|
|
- 776 SemError(230) END;
|
|
|
- 777 isR := (dt #
|
|
|
- 778 SymTab.InvalidType)
|
|
|
- 779 & (SymTab.ClassOf(dt)
|
|
|
- 780 = SymTab.ClReal);
|
|
|
- 781 conv := isR
|
|
|
- 782 & SymTab.IsIntFamily(et);
|
|
|
- 783 wconv := (dt #
|
|
|
- 784 SymTab.InvalidType)
|
|
|
- 785 & SymTab.IsLongFamily(dt)
|
|
|
- 786 & SymTab.IsIntFamily(et);
|
|
|
- 787 IF ((dk = SymTab.KindVar)
|
|
|
- 788 OR (dk = SymTab.KindParam)
|
|
|
- 789 OR (dk = SymTab.KindField))
|
|
|
- 790 & (dt # SymTab.InvalidType)
|
|
|
- 791 & (et # SymTab.InvalidType)
|
|
|
- 792 & (SymTab.ClassOf(dt) #
|
|
|
- 793 SymTab.ClClass) THEN
|
|
|
- 794 IF sfx
|
|
|
- 795 OR (dk = SymTab.KindField) THEN
|
|
|
- 796 IF SymTab.ClassOf(dt) =
|
|
|
- 797 SymTab.ClArray THEN
|
|
|
- 798 QbeGen.CopyArray(qd, qe,
|
|
|
- 799 dt)
|
|
|
- 800 ELSIF SymTab.ClassOf(dt) =
|
|
|
- 801 SymTab.ClSet THEN
|
|
|
- 802 QbeGen.CopySet(qd, qe,
|
|
|
- 803 SymTab.SetWords(dt),
|
|
|
- 804 SymTab.SetWords(et))
|
|
|
- 805 ELSIF SymTab.ClassOf(dt) =
|
|
|
- 806 SymTab.ClRecord THEN
|
|
|
- 807 QbeGen.CopyRecord(qd, qe,
|
|
|
- 808 dt)
|
|
|
- 809 ELSIF SymTab.IsLongFamily(dt) THEN
|
|
|
- 810 IF wconv THEN
|
|
|
- 811 QbeGen.WidenLong(qe, ql);
|
|
|
- 812 QbeGen.ElemStore(qd, ql,
|
|
|
- 813 dt)
|
|
|
- 814 ELSE QbeGen.ElemStore(qd, qe,
|
|
|
- 815 dt)
|
|
|
- 816 END
|
|
|
- 817 ELSIF conv THEN
|
|
|
- 818 QbeGen.ConvIR(qe, qt);
|
|
|
- 819 QbeGen.ElemStore(qd, qt,
|
|
|
- 820 dt)
|
|
|
- 821 ELSE QbeGen.ElemStore(qd, qe,
|
|
|
- 822 dt)
|
|
|
- 823 END
|
|
|
- 824 ELSIF SymTab.ClassOf(dt) =
|
|
|
- 825 SymTab.ClArray THEN
|
|
|
- 826 QbeGen.CopyArray(qd, qe, dt)
|
|
|
- 827 ELSIF SymTab.ClassOf(dt) =
|
|
|
- 828 SymTab.ClSet THEN
|
|
|
- 829 QbeGen.CopySet(qd, qe,
|
|
|
- 830 SymTab.SetWords(dt),
|
|
|
- 831 SymTab.SetWords(et))
|
|
|
- 832 ELSIF SymTab.ClassOf(dt) =
|
|
|
- 833 SymTab.ClRecord THEN
|
|
|
- 834 QbeGen.CopyRecord(qd, qe, dt)
|
|
|
- 835 ELSIF SymTab.ClassOf(dt) =
|
|
|
- 836 SymTab.ClPtr THEN
|
|
|
- 837 QbeGen.StorePtr(qn, qe)
|
|
|
- 838 ELSIF SymTab.IsLongFamily(dt) THEN
|
|
|
- 839 IF wconv THEN
|
|
|
- 840 QbeGen.WidenLong(qe, ql);
|
|
|
- 841 QbeGen.StoreLong(qn, ql)
|
|
|
- 842 ELSE QbeGen.StoreLong(qn, qe)
|
|
|
- 843 END
|
|
|
- 844 ELSIF conv THEN
|
|
|
- 845 QbeGen.ConvIR(qe, qt);
|
|
|
- 846 QbeGen.StoreVar(qn, qt, TRUE)
|
|
|
- 847 ELSE
|
|
|
- 848 QbeGen.StoreVar(qn, qe, isR)
|
|
|
- 849 END
|
|
|
- 850 END; .)
|
|
|
- 851 | ArgList<qn, FALSE, ct2, q2, called>
|
|
|
- 852 | (* bare `P;`: proper parameterless
|
|
|
- 853 procedure call; anything else
|
|
|
- 854 here is 233 (was a bare syntax
|
|
|
- 855 error before 4.2) *)
|
|
|
- 856 (. IF (dk = SymTab.KindProc)
|
|
|
- 857 & ~sfx THEN
|
|
|
- 858 res0 := SymTab.ProcRes(qn);
|
|
|
- 859 IF res0 #
|
|
|
- 860 SymTab.InvalidType THEN
|
|
|
- 861 SemError(233)
|
|
|
- 862 ELSIF SymTab.ProcNPar(qn) #
|
|
|
- 863 0 THEN
|
|
|
- 864 SemError(233)
|
|
|
- 865 ELSE QbeGen.Mangled(qn,
|
|
|
- 866 SymTab.ProcUid(qn), mg0);
|
|
|
- 867 QbeGen.CallBegin(mg0,
|
|
|
- 868 res0,
|
|
|
- 869 SymTab.ProcDepthOf(qn),
|
|
|
- 870 SymTab.IsExternal(qn));
|
|
|
- 871 QbeGen.CallEnd(FALSE, q2)
|
|
|
- 872 END
|
|
|
- 873 ELSE SemError(233)
|
|
|
- 874 END; .) ) .
|
|
|
- 875 (* Actual-parameter list shared by statement and expression calls.
|
|
|
- 876 want selects CallEnd's result handling; t/q carry the call
|
|
|
- 877 value (statement calls discard). Arity/type failures are 233;
|
|
|
- 878 evaluation code still emits so the .ssa stays assembleable. *)
|
|
|
- 879 ArgList<pn: SymTab.Name; want: BOOLEAN;
|
|
|
- 880 VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal;
|
|
|
- 881 VAR called: BOOLEAN> (. VAR i: CARDINAL;
|
|
|
- 882 res: SymTab.TypeIndex;
|
|
|
- 883 mg: QbeGen.QVal;
|
|
|
- 884 ok: BOOLEAN; .)
|
|
|
- 885 = "(" (. called := TRUE;
|
|
|
- 886 res := SymTab.ProcRes(pn);
|
|
|
- 887 ok := TRUE;
|
|
|
- 888 IF SymTab.SymKind(pn) #
|
|
|
- 889 SymTab.KindProc THEN
|
|
|
- 890 SemError(233); ok := FALSE
|
|
|
- 891 ELSE QbeGen.Mangled(pn,
|
|
|
- 892 SymTab.ProcUid(pn), mg);
|
|
|
- 893 QbeGen.CallBegin(mg, res,
|
|
|
- 894 SymTab.ProcDepthOf(pn),
|
|
|
- 895 SymTab.IsExternal(pn))
|
|
|
- 896 END;
|
|
|
- 897 i := 0; .)
|
|
|
- 898 [ ActParam<pn, i> (. INC(i); .)
|
|
|
- 899 { "," ActParam<pn, i> (. INC(i); .) } ]
|
|
|
- 900 ")" (. IF ok THEN
|
|
|
- 901 IF i #
|
|
|
- 902 SymTab.ProcNPar(pn) THEN
|
|
|
- 903 SemError(233); ok := FALSE
|
|
|
- 904 END
|
|
|
- 905 END;
|
|
|
- 906 IF ~ok THEN
|
|
|
- 907 t := SymTab.InvalidType;
|
|
|
- 908 QbeGen.CopyOp("0", q)
|
|
|
- 909 ELSIF want THEN
|
|
|
- 910 IF res =
|
|
|
- 911 SymTab.InvalidType THEN
|
|
|
- 912 SemError(233);
|
|
|
- 913 t := SymTab.InvalidType;
|
|
|
- 914 QbeGen.CopyOp("0", q)
|
|
|
- 915 ELSE t := res;
|
|
|
- 916 QbeGen.CallEnd(TRUE, q)
|
|
|
- 917 END
|
|
|
- 918 ELSE
|
|
|
- 919 IF res #
|
|
|
- 920 SymTab.InvalidType THEN
|
|
|
- 921 SemError(233)
|
|
|
- 922 END;
|
|
|
- 923 t := SymTab.InvalidType;
|
|
|
- 924 QbeGen.CopyOp("0", q);
|
|
|
- 925 QbeGen.CallEnd(FALSE, q)
|
|
|
- 926 END; .) .
|
|
|
- 927 (* One actual: VAR formals take recorded designator addresses
|
|
|
- 928 (233 otherwise); value formals take converted expressions. *)
|
|
|
- 929 ActParam<pn: SymTab.Name; i: CARDINAL>(. VAR at, ft: SymTab.TypeIndex;
|
|
|
- 930 qe, qa, qt: QbeGen.QVal;
|
|
|
- 931 isV, conv: BOOLEAN; .)
|
|
|
- 932 = Expr<at, qe> (. ft := SymTab.ParamType(pn, i);
|
|
|
- 933 isV := SymTab.ParamIsVar(pn, i);
|
|
|
- 934 IF (at = SymTab.InvalidType)
|
|
|
- 935 OR (ft =
|
|
|
- 936 SymTab.InvalidType) THEN
|
|
|
- 937 ELSIF isV THEN
|
|
|
- 938 IF ~QbeGen.AddrOfVal(qe,
|
|
|
- 939 qa) THEN
|
|
|
- 940 SemError(233)
|
|
|
- 941 ELSIF ~SymTab.VarParamOk(at,
|
|
|
- 942 ft) THEN
|
|
|
- 943 SemError(233)
|
|
|
- 944 ELSIF ~QbeGen.CallArg(qa,
|
|
|
- 945 "l") THEN
|
|
|
- 946 SemError(233)
|
|
|
- 947 END
|
|
|
- 948 ELSE
|
|
|
- 949 IF ~SymTab.Assignable(at,
|
|
|
- 950 ft) THEN
|
|
|
- 951 SemError(233)
|
|
|
- 952 ELSE
|
|
|
- 953 conv := (SymTab.ClassOf(
|
|
|
- 954 ft) = SymTab.ClReal)
|
|
|
- 955 & SymTab.IsIntFamily(at);
|
|
|
- 956 IF conv THEN
|
|
|
- 957 QbeGen.ConvIR(qe, qt);
|
|
|
- 958 IF ~QbeGen.CallArg(qt,
|
|
|
- 959 "d") THEN
|
|
|
- 960 SemError(233)
|
|
|
- 961 END
|
|
|
- 962 ELSIF ~QbeGen.CallArg(qe,
|
|
|
- 963 QbeGen.ArgClass(ft)) THEN
|
|
|
- 964 SemError(233)
|
|
|
- 965 END
|
|
|
- 966 END
|
|
|
- 967 END; .) .
|
|
|
- 968 IfStat (. VAR t: SymTab.TypeIndex;
|
|
|
- 969 q, lThen, lElse, lEnd:
|
|
|
- 970 QbeGen.QVal;
|
|
|
- 971 hasElse: BOOLEAN; .)
|
|
|
- 972 = "IF" (. hasElse := FALSE; .)
|
|
|
- 973 Expr<t, q> (. IF ~SymTab.BoolCheck(t) THEN
|
|
|
- 974 SemError(214) END;
|
|
|
- 975 QbeGen.NewLabel(lThen);
|
|
|
- 976 QbeGen.NewLabel(lElse);
|
|
|
- 977 QbeGen.NewLabel(lEnd);
|
|
|
- 978 QbeGen.Jnz(q, lThen, lElse);
|
|
|
- 979 QbeGen.EmitLabel(lThen); .)
|
|
|
- 980 "THEN" StatSeq (. QbeGen.Jmp(lEnd); .)
|
|
|
- 981 { "ELSIF" (. QbeGen.EmitLabel(lElse);
|
|
|
- 982 QbeGen.NewLabel(lElse); .)
|
|
|
- 983 Expr<t, q> (. IF ~SymTab.BoolCheck(t) THEN
|
|
|
- 984 SemError(214) END;
|
|
|
- 985 QbeGen.NewLabel(lThen);
|
|
|
- 986 QbeGen.Jnz(q, lThen, lElse);
|
|
|
- 987 QbeGen.EmitLabel(lThen); .)
|
|
|
- 988 "THEN" StatSeq (. QbeGen.Jmp(lEnd); .) }
|
|
|
- 989 [ "ELSE" (. QbeGen.EmitLabel(lElse);
|
|
|
- 990 hasElse := TRUE; .)
|
|
|
- 991 StatSeq ]
|
|
|
- 992 "END" (. IF hasElse THEN
|
|
|
- 993 QbeGen.EmitLabel(lEnd)
|
|
|
- 994 ELSE QbeGen.EmitLabel(lElse);
|
|
|
- 995 QbeGen.EmitLabel(lEnd)
|
|
|
- 996 END; .) .
|
|
|
- 997 WhileStat (. VAR t: SymTab.TypeIndex;
|
|
|
- 998 q, lTop, lBody, lEnd:
|
|
|
- 999 QbeGen.QVal; .)
|
|
|
- 1000 = "WHILE" (. QbeGen.NewLabel(lTop);
|
|
|
- 1001 QbeGen.NewLabel(lBody);
|
|
|
- 1002 QbeGen.NewLabel(lEnd);
|
|
|
- 1003 QbeGen.EmitLabel(lTop); .)
|
|
|
- 1004 Expr<t, q> (. IF ~SymTab.BoolCheck(t) THEN
|
|
|
- 1005 SemError(214) END;
|
|
|
- 1006 QbeGen.Jnz(q, lBody, lEnd);
|
|
|
- 1007 QbeGen.EmitLabel(lBody); .)
|
|
|
- 1008 "DO" StatSeq (. QbeGen.Jmp(lTop); .)
|
|
|
- 1009 "END" (. QbeGen.EmitLabel(lEnd); .) .
|
|
|
- 1010 RepeatStat (. VAR t: SymTab.TypeIndex;
|
|
|
- 1011 q, lTop, lEnd: QbeGen.QVal; .)
|
|
|
- 1012 = "REPEAT" (. QbeGen.NewLabel(lTop);
|
|
|
- 1013 QbeGen.NewLabel(lEnd);
|
|
|
- 1014 QbeGen.EmitLabel(lTop); .)
|
|
|
- 1015 StatSeq
|
|
|
- 1016 "UNTIL" Expr<t, q> (. IF ~SymTab.BoolCheck(t) THEN
|
|
|
- 1017 SemError(214) END;
|
|
|
- 1018 QbeGen.Jnz(q, lEnd, lTop);
|
|
|
- 1019 QbeGen.EmitLabel(lEnd); .) .
|
|
|
- 1020 LoopStat (. VAR lTop, lEnd: QbeGen.QVal; .)
|
|
|
- 1021 = "LOOP" (. QbeGen.NewLabel(lTop);
|
|
|
- 1022 QbeGen.NewLabel(lEnd);
|
|
|
- 1023 QbeGen.PushLoop(lEnd);
|
|
|
- 1024 QbeGen.EmitLabel(lTop); .)
|
|
|
- 1025 StatSeq
|
|
|
- 1026 "END" (. QbeGen.Jmp(lTop);
|
|
|
- 1027 QbeGen.PopLoop;
|
|
|
- 1028 QbeGen.EmitLabel(lEnd); .) .
|
|
|
- 1029 (* FOR with static-sign BY (literal, non-zero; 220 otherwise).
|
|
|
- 1030 Runtime direction would need a compare-select; the literal
|
|
|
- 1031 sign picks cslew/csegew at "DO" time. *)
|
|
|
- 1032 ForStat (. VAR lv: SymTab.Name;
|
|
|
- 1033 tlo, thi, tby:
|
|
|
- 1034 SymTab.TypeIndex;
|
|
|
- 1035 qlo, qhi, qby, qt, qk, qb:
|
|
|
- 1036 QbeGen.QVal;
|
|
|
- 1037 lTop, lBody, lEnd:
|
|
|
- 1038 QbeGen.QVal;
|
|
|
- 1039 by: INTEGER;
|
|
|
- 1040 ok: BOOLEAN; .)
|
|
|
- 1041 = "FOR" (. by := 1; .)
|
|
|
- 1042 GetIdent<lv> (. ok := SymTab.Lookup(lv);
|
|
|
- 1043 IF ~ok THEN
|
|
|
- 1044 SemError(201)
|
|
|
- 1045 ELSIF (SymTab.SymKind(lv) #
|
|
|
- 1046 SymTab.KindVar)
|
|
|
- 1047 & (SymTab.SymKind(lv) #
|
|
|
- 1048 SymTab.KindParam) THEN
|
|
|
- 1049 SemError(220); ok := FALSE
|
|
|
- 1050 ELSIF ~SymTab.IsIntFamily(
|
|
|
- 1051 SymTab.SymType(lv)) THEN
|
|
|
- 1052 SemError(220); ok := FALSE
|
|
|
- 1053 END; .)
|
|
|
- 1054 ":=" Expr<tlo, qlo> (. IF ~SymTab.IsIntFamily(tlo) THEN
|
|
|
- 1055 SemError(220); ok := FALSE
|
|
|
- 1056 END; .)
|
|
|
- 1057 "TO" Expr<thi, qhi> (. IF ~SymTab.IsIntFamily(thi) THEN
|
|
|
- 1058 SemError(220); ok := FALSE
|
|
|
- 1059 END; .)
|
|
|
- 1060 [ "BY" Expr<tby, qby> (. IF (tby #
|
|
|
- 1061 SymTab.InvalidType)
|
|
|
- 1062 & ~SymTab.IsIntFamily(tby) THEN
|
|
|
- 1063 SemError(220); ok := FALSE
|
|
|
- 1064 END;
|
|
|
- 1065 IF ~SymTab.ConstInt(qby, by) THEN
|
|
|
- 1066 SemError(230); by := 1
|
|
|
- 1067 ELSIF by = 0 THEN
|
|
|
- 1068 SemError(220); by := 1
|
|
|
- 1069 END; .) ]
|
|
|
- 1070 "DO" (. IF ok THEN
|
|
|
- 1071 QbeGen.StoreVar(lv, qlo,
|
|
|
- 1072 FALSE) END;
|
|
|
- 1073 QbeGen.NewLabel(lTop);
|
|
|
- 1074 QbeGen.NewLabel(lBody);
|
|
|
- 1075 QbeGen.NewLabel(lEnd);
|
|
|
- 1076 QbeGen.EmitLabel(lTop);
|
|
|
- 1077 QbeGen.LoadVar(lv, FALSE, qt);
|
|
|
- 1078 QbeGen.NewTemp(qk);
|
|
|
- 1079 IF by > 0 THEN
|
|
|
- 1080 QbeGen.Op3("cslew", qk,
|
|
|
- 1081 qt, qhi, FALSE)
|
|
|
- 1082 ELSE QbeGen.Op3("csgew", qk,
|
|
|
- 1083 qt, qhi, FALSE)
|
|
|
- 1084 END;
|
|
|
- 1085 QbeGen.Jnz(qk, lBody, lEnd);
|
|
|
- 1086 QbeGen.EmitLabel(lBody); .)
|
|
|
- 1087 StatSeq
|
|
|
- 1088 "END" (. IF ok THEN
|
|
|
- 1089 QbeGen.LoadVar(lv, FALSE,
|
|
|
- 1090 qt);
|
|
|
- 1091 QbeGen.IntStr(by, qb);
|
|
|
- 1092 QbeGen.NewTemp(qk);
|
|
|
- 1093 QbeGen.Op3("add", qk,
|
|
|
- 1094 qt, qb, FALSE);
|
|
|
- 1095 QbeGen.StoreVar(lv, qk,
|
|
|
- 1096 FALSE) END;
|
|
|
- 1097 QbeGen.Jmp(lTop);
|
|
|
- 1098 QbeGen.EmitLabel(lEnd); .) .
|
|
|
- 1099 CaseStat (. VAR tsel: SymTab.TypeIndex;
|
|
|
- 1100 qsel, lEnd: QbeGen.QVal; .)
|
|
|
- 1101 = "CASE" Expr<tsel, qsel> (. QbeGen.NewLabel(lEnd); .)
|
|
|
- 1102 "OF" CaseAlt<tsel, qsel, lEnd>
|
|
|
- 1103 { "|" CaseAlt<tsel, qsel, lEnd> }
|
|
|
- 1104 [ "ELSE" StatSeq ]
|
|
|
- 1105 "END" (. QbeGen.EmitLabel(lEnd); .) .
|
|
|
- 1106 (* Compare-chain lowering: each alternative ends its match-tests
|
|
|
- 1107 with "jmp lAfter", so the no-match fallthrough skips the body:
|
|
|
- 1108 "cmp; jnz(lBody,lF); lF: ... ; jmp lAfter; lBody: S; jmp lEnd;
|
|
|
- 1109 lAfter:". Falls into the next alternative, ELSE, or END. *)
|
|
|
- 1110 CaseAlt<tsel: SymTab.TypeIndex; qsel: QbeGen.QVal;
|
|
|
- 1111 lEnd: QbeGen.QVal> (. VAR lBody, lAfter: QbeGen.QVal; .)
|
|
|
- 1112 = (. QbeGen.NewLabel(lBody);
|
|
|
- 1113 QbeGen.NewLabel(lAfter); .)
|
|
|
- 1114 CaseLabel<tsel, qsel, lBody>
|
|
|
- 1115 { "," CaseLabel<tsel, qsel, lBody> }
|
|
|
- 1116 ":" (. QbeGen.Jmp(lAfter);
|
|
|
- 1117 QbeGen.EmitLabel(lBody); .)
|
|
|
- 1118 StatSeq (. QbeGen.Jmp(lEnd);
|
|
|
- 1119 QbeGen.EmitLabel(lAfter); .) .
|
|
|
- 1120 CaseLabel<tsel: SymTab.TypeIndex; qsel: QbeGen.QVal;
|
|
|
- 1121 lBody: QbeGen.QVal> (. VAR t2, t3: SymTab.TypeIndex;
|
|
|
- 1122 q2, q3, qc, qd, qe:
|
|
|
- 1123 QbeGen.QVal;
|
|
|
- 1124 lNext: QbeGen.QVal; .)
|
|
|
- 1125 = Expr<t2, q2> (. IF (t2 #
|
|
|
- 1126 SymTab.InvalidType)
|
|
|
- 1127 & (tsel #
|
|
|
- 1128 SymTab.InvalidType)
|
|
|
- 1129 & ((SymTab.ClassOf(t2) =
|
|
|
- 1130 SymTab.ClSet)
|
|
|
- 1131 OR (SymTab.ClassOf(tsel) =
|
|
|
- 1132 SymTab.ClSet)) THEN
|
|
|
- 1133 SemError(230)
|
|
|
- 1134 ELSIF (t2 #
|
|
|
- 1135 SymTab.InvalidType)
|
|
|
- 1136 & (tsel #
|
|
|
- 1137 SymTab.InvalidType)
|
|
|
- 1138 & ~SymTab.EqCheck(t2,
|
|
|
- 1139 tsel) THEN
|
|
|
- 1140 SemError(213) END;
|
|
|
- 1141 IF ~QbeGen.IsImm(q2) THEN
|
|
|
- 1142 SemError(230);
|
|
|
- 1143 QbeGen.CopyOp("0", q2)
|
|
|
- 1144 END;
|
|
|
- 1145 QbeGen.NewLabel(lNext);
|
|
|
- 1146 QbeGen.Cmp(SymTab.OpEq,
|
|
|
- 1147 qsel, q2, qc, FALSE);
|
|
|
- 1148 QbeGen.Jnz(qc, lBody, lNext);
|
|
|
- 1149 QbeGen.EmitLabel(lNext); .)
|
|
|
- 1150 [ ".." Expr<t3, q3> (. IF (t3 #
|
|
|
- 1151 SymTab.InvalidType)
|
|
|
- 1152 & (tsel #
|
|
|
- 1153 SymTab.InvalidType)
|
|
|
- 1154 & ~SymTab.EqCheck(t3,
|
|
|
- 1155 tsel) THEN
|
|
|
- 1156 SemError(213) END;
|
|
|
- 1157 IF ~QbeGen.IsImm(q3) THEN
|
|
|
- 1158 SemError(230);
|
|
|
- 1159 QbeGen.CopyOp("0", q3)
|
|
|
- 1160 END;
|
|
|
- 1161 QbeGen.Cmp(SymTab.OpGe,
|
|
|
- 1162 qsel, q2, qc, FALSE);
|
|
|
- 1163 QbeGen.Cmp(SymTab.OpLe,
|
|
|
- 1164 qsel, q3, qd, FALSE);
|
|
|
- 1165 QbeGen.NewTemp(qe);
|
|
|
- 1166 QbeGen.Op3("and", qe, qc, qd,
|
|
|
- 1167 FALSE);
|
|
|
- 1168 QbeGen.NewLabel(lNext);
|
|
|
- 1169 QbeGen.Jnz(qe, lBody, lNext);
|
|
|
- 1170 QbeGen.EmitLabel(lNext); .) ] .
|
|
|
- 1171 ReturnStat (. VAR t: SymTab.TypeIndex;
|
|
|
- 1172 q, qt: QbeGen.QVal;
|
|
|
- 1173 res: SymTab.TypeIndex;
|
|
|
- 1174 hadE, conv: BOOLEAN; .)
|
|
|
- 1175 = "RETURN" (. hadE := FALSE; .)
|
|
|
- 1176 [ Expr<t, q> (. hadE := TRUE; .) ]
|
|
|
- 1177 (. conv := FALSE;
|
|
|
- 1178 IF ~SymTab.InProc() THEN
|
|
|
- 1179 SemError(232)
|
|
|
- 1180 ELSE res := SymTab.CurRes();
|
|
|
- 1181 IF ~hadE THEN
|
|
|
- 1182 IF res #
|
|
|
- 1183 SymTab.InvalidType THEN
|
|
|
- 1184 SemError(232)
|
|
|
- 1185 ELSE QbeGen.EmitRet(q,
|
|
|
- 1186 FALSE)
|
|
|
- 1187 END
|
|
|
- 1188 ELSIF (res =
|
|
|
- 1189 SymTab.InvalidType)
|
|
|
- 1190 OR (t #
|
|
|
- 1191 SymTab.InvalidType)
|
|
|
- 1192 & ~SymTab.Assignable(t,
|
|
|
- 1193 res) THEN
|
|
|
- 1194 SemError(232)
|
|
|
- 1195 ELSE
|
|
|
- 1196 conv := (SymTab.ClassOf(
|
|
|
- 1197 res) = SymTab.ClReal)
|
|
|
- 1198 & SymTab.IsIntFamily(t);
|
|
|
- 1199 IF conv THEN
|
|
|
- 1200 QbeGen.ConvIR(q, qt);
|
|
|
- 1201 QbeGen.EmitRet(qt, TRUE)
|
|
|
- 1202 ELSE QbeGen.EmitRet(q, TRUE)
|
|
|
- 1203 END
|
|
|
- 1204 END
|
|
|
- 1205 END; .) .
|
|
|
- 1206 (* Designator: scalar loads, array addresses, and index suffixes.
|
|
|
- 1207 Each index descends one level (bounds-checked, trap on breach);
|
|
|
- 1208 nested levels reload the inner descriptor address. q ends as the
|
|
|
- 1209 value (scalars), the descriptor address (plain arrays), or the
|
|
|
- 1210 element address (indexed); sfx marks the indexed form. *)
|
|
|
- 1211 Design<VAR t: SymTab.TypeIndex; VAR k: INTEGER;
|
|
|
- 1212 VAR q: QbeGen.QVal; VAR qn: SymTab.Name; VAR sfx: BOOLEAN>
|
|
|
- 1213 (. VAR n, fn, mal: SymTab.Name;
|
|
|
- 1214 cls: INTEGER;
|
|
|
- 1215 curT, it, eT, bt:
|
|
|
- 1216 SymTab.TypeIndex;
|
|
|
- 1217 iq, ql, qlo, qhi, qe:
|
|
|
- 1218 QbeGen.QVal;
|
|
|
- 1219 lo, hi: INTEGER;
|
|
|
- 1220 fo: INTEGER;
|
|
|
- 1221 isOpen: BOOLEAN;
|
|
|
- 1222 qb: QbeGen.QVal; .)
|
|
|
- 1223 = GetIdent<n> (. QbeGen.CopyOp(n, qn);
|
|
|
- 1224 sfx := FALSE;
|
|
|
- 1225 IF ~SymTab.Lookup(n) THEN
|
|
|
- 1226 SemError(201);
|
|
|
- 1227 t := SymTab.InvalidType;
|
|
|
- 1228 k := -1;
|
|
|
- 1229 QbeGen.CopyOp("0", q)
|
|
|
- 1230 ELSE
|
|
|
- 1231 t := SymTab.SymType(n);
|
|
|
- 1232 k := SymTab.SymKind(n);
|
|
|
- 1233 IF k = SymTab.KindConst THEN
|
|
|
- 1234 IF SymTab.Equal(n,
|
|
|
- 1235 "TRUE") THEN
|
|
|
- 1236 t := SymTab.BoolType();
|
|
|
- 1237 QbeGen.CopyOp("1", q)
|
|
|
- 1238 ELSIF SymTab.Equal(n,
|
|
|
- 1239 "FALSE") THEN
|
|
|
+ 569 (* value open arrays are
|
|
|
+ 570 passed as descriptor
|
|
|
+ 571 addresses (no copy):
|
|
|
+ 572 same representation as
|
|
|
+ 573 VAR formals *)
|
|
|
+ 574 IF ~QbeGen.FuncParam(nm,
|
|
|
+ 575 isV
|
|
|
+ 576 OR SymTab.IsOpenArray(t),
|
|
|
+ 577 t) THEN
|
|
|
+ 578 SemError(233) END;
|
|
|
+ 579 INC(i)
|
|
|
+ 580 END;
|
|
|
+ 581 SymTab.FixPending(t); .) .
|
|
|
+ 582 (* Nested procedures lower like top-level ones (4.2): the
|
|
|
+ 583 static link gives them their parent's frame. Methods keep
|
|
|
+ 584 parse-now/230-later. *)
|
|
|
+ 585 ProcDecl (. VAR pn: SymTab.Name; .)
|
|
|
+ 586 = ProcHeading<pn> ";"
|
|
|
+ 587 ( "FORWARD" (. SymTab.MarkFwd;
|
|
|
+ 588 SymTab.CloseProc;
|
|
|
+ 589 QbeGen.AbortFunc; .)
|
|
|
+ 590 | "EXTERNAL" (. SymTab.MarkExternal("");
|
|
|
+ 591 SymTab.CloseProc;
|
|
|
+ 592 QbeGen.AbortFunc; .)
|
|
|
+ 593 | (. QbeGen.EndFuncHeader; .)
|
|
|
+ 594 Block<pn> (. SymTab.CloseProc;
|
|
|
+ 595 QbeGen.EndFunc(
|
|
|
+ 596 SymTab.ProcRes(pn)); .) ) .
|
|
|
+ 597 Block<pn: SymTab.Name> (. VAR m2: SymTab.Name; .)
|
|
|
+ 598 = DeclSeq
|
|
|
+ 599 [ "BEGIN"
|
|
|
+ 600 [ StatSeq ] ]
|
|
|
+ 601 "END"
|
|
|
+ 602 GetIdent<m2> (. IF ~SymTab.Equal(pn, m2) THEN
|
|
|
+ 603 SemError(202) END; .) .
|
|
|
+ 604 StatSeq
|
|
|
+ 605 = Statement { ";" Statement } .
|
|
|
+ 606 Statement (. VAR lx: QbeGen.QVal; .)
|
|
|
+ 607 = AssOrCall
|
|
|
+ 608 | IfStat
|
|
|
+ 609 | WhileStat
|
|
|
+ 610 | RepeatStat
|
|
|
+ 611 | LoopStat
|
|
|
+ 612 | ForStat
|
|
|
+ 613 | CaseStat
|
|
|
+ 614 | WithStat
|
|
|
+ 615 | ReturnStat
|
|
|
+ 616 | NewStat
|
|
|
+ 617 | DisposeStat
|
|
|
+ 618 | IncDecStat
|
|
|
+ 619 | "EXIT" (. IF QbeGen.TopLoop(lx) THEN
|
|
|
+ 620 QbeGen.Jmp(lx)
|
|
|
+ 621 ELSE SemError(230) END; .) .
|
|
|
+ 622 (* INC(v [,step]) / DEC(v [,step]) as builtin statements over an
|
|
|
+ 623 integer designator. *)
|
|
|
+ 624 IncDecStat (. VAR dt, et2: SymTab.TypeIndex;
|
|
|
+ 625 dk: INTEGER;
|
|
|
+ 626 qd, qv, qn2, qstep:
|
|
|
+ 627 QbeGen.QVal;
|
|
|
+ 628 qn: SymTab.Name;
|
|
|
+ 629 sfx, isInc: BOOLEAN; .)
|
|
|
+ 630 = (. isInc := TRUE; .)
|
|
|
+ 631 ( "INC" (. isInc := TRUE; .)
|
|
|
+ 632 | "DEC" (. isInc := FALSE; .) )
|
|
|
+ 633 "(" (. QbeGen.CopyOp("1", qstep); .)
|
|
|
+ 634 Design<dt, dk, qd, qn, sfx>
|
|
|
+ 635 [ "," Expr<et2, qstep> ]
|
|
|
+ 636 ")" (. IF dt = SymTab.InvalidType THEN
|
|
|
+ 637 ELSIF (dk # SymTab.KindVar)
|
|
|
+ 638 & (dk # SymTab.KindParam)
|
|
|
+ 639 & (dk # SymTab.KindField) THEN
|
|
|
+ 640 SemError(210)
|
|
|
+ 641 ELSIF ~SymTab.IsIntFamily(dt) THEN
|
|
|
+ 642 SemError(211)
|
|
|
+ 643 ELSE
|
|
|
+ 644 IF sfx
|
|
|
+ 645 OR (dk = SymTab.KindField) THEN
|
|
|
+ 646 QbeGen.ElemLoad(qd, dt, qv)
|
|
|
+ 647 ELSE QbeGen.LoadVar(qn,
|
|
|
+ 648 FALSE, qv)
|
|
|
+ 649 END;
|
|
|
+ 650 QbeGen.NewTemp(qn2);
|
|
|
+ 651 IF isInc THEN
|
|
|
+ 652 QbeGen.Op3("add", qn2, qv,
|
|
|
+ 653 qstep, FALSE)
|
|
|
+ 654 ELSE QbeGen.Op3("sub", qn2, qv,
|
|
|
+ 655 qstep, FALSE)
|
|
|
+ 656 END;
|
|
|
+ 657 IF sfx
|
|
|
+ 658 OR (dk = SymTab.KindField) THEN
|
|
|
+ 659 QbeGen.ElemStore(qd, qn2,
|
|
|
+ 660 dt)
|
|
|
+ 661 ELSE QbeGen.StoreVar(qn,
|
|
|
+ 662 qn2, FALSE)
|
|
|
+ 663 END
|
|
|
+ 664 END; .) .
|
|
|
+ 665 (* NEW/DISPOSE as builtin statements (no call syntax until step 4).
|
|
|
+ 666 Targets are pointer designators; DISPOSE nils afterwards (safer
|
|
|
+ 667 than Wirth-undefined; documented). DISPOSE is shallow. *)
|
|
|
+ 668 NewStat (. VAR dt: SymTab.TypeIndex;
|
|
|
+ 669 dk: INTEGER;
|
|
|
+ 670 qd, qm: QbeGen.QVal;
|
|
|
+ 671 qn: SymTab.Name;
|
|
|
+ 672 sfx: BOOLEAN;
|
|
|
+ 673 bt: SymTab.TypeIndex; .)
|
|
|
+ 674 = "NEW" "(" Design<dt, dk, qd, qn, sfx> ")"
|
|
|
+ 675 (. IF dt = SymTab.InvalidType THEN
|
|
|
+ 676 ELSIF (dk # SymTab.KindVar)
|
|
|
+ 677 & (dk # SymTab.KindParam)
|
|
|
+ 678 & (dk # SymTab.KindField) THEN
|
|
|
+ 679 SemError(210)
|
|
|
+ 680 ELSIF SymTab.ClassOf(dt) #
|
|
|
+ 681 SymTab.ClPtr THEN
|
|
|
+ 682 SemError(219)
|
|
|
+ 683 ELSE bt := SymTab.PtrBase(dt);
|
|
|
+ 684 IF bt #
|
|
|
+ 685 SymTab.InvalidType THEN
|
|
|
+ 686 QbeGen.NewHeap(bt, qm);
|
|
|
+ 687 QbeGen.InitHeap(qm, bt);
|
|
|
+ 688 IF sfx
|
|
|
+ 689 OR (dk =
|
|
|
+ 690 SymTab.KindField) THEN
|
|
|
+ 691 QbeGen.ElemStore(qd, qm,
|
|
|
+ 692 dt)
|
|
|
+ 693 ELSE QbeGen.StorePtr(qn,
|
|
|
+ 694 qm)
|
|
|
+ 695 END
|
|
|
+ 696 END
|
|
|
+ 697 END; .) .
|
|
|
+ 698 DisposeStat (. VAR dt: SymTab.TypeIndex;
|
|
|
+ 699 dk: INTEGER;
|
|
|
+ 700 qd, qv: QbeGen.QVal;
|
|
|
+ 701 qn: SymTab.Name;
|
|
|
+ 702 sfx: BOOLEAN; .)
|
|
|
+ 703 = "DISPOSE" "(" Design<dt, dk, qd, qn, sfx> ")"
|
|
|
+ 704 (. IF dt = SymTab.InvalidType THEN
|
|
|
+ 705 ELSIF (dk # SymTab.KindVar)
|
|
|
+ 706 & (dk # SymTab.KindParam)
|
|
|
+ 707 & (dk # SymTab.KindField) THEN
|
|
|
+ 708 SemError(210)
|
|
|
+ 709 ELSIF SymTab.ClassOf(dt) #
|
|
|
+ 710 SymTab.ClPtr THEN
|
|
|
+ 711 SemError(219)
|
|
|
+ 712 ELSE
|
|
|
+ 713 IF sfx
|
|
|
+ 714 OR (dk =
|
|
|
+ 715 SymTab.KindField) THEN
|
|
|
+ 716 QbeGen.ElemLoad(qd, dt,
|
|
|
+ 717 qv)
|
|
|
+ 718 ELSE QbeGen.LoadPtr(qn, qv)
|
|
|
+ 719 END;
|
|
|
+ 720 QbeGen.FreeHeap(qv);
|
|
|
+ 721 IF sfx
|
|
|
+ 722 OR (dk =
|
|
|
+ 723 SymTab.KindField) THEN
|
|
|
+ 724 QbeGen.ElemStore(qd, "0",
|
|
|
+ 725 dt)
|
|
|
+ 726 ELSE QbeGen.StorePtr(qn,
|
|
|
+ 727 "0")
|
|
|
+ 728 END
|
|
|
+ 729 END; .) .
|
|
|
+ 730 (* WITH pushes each record's fields (inner wins) plus its base
|
|
|
+ 731 address; field designators resolve through both stacks. *)
|
|
|
+ 732 WithStat (. VAR nW: CARDINAL; .)
|
|
|
+ 733 = "WITH" (. nW := 0; .)
|
|
|
+ 734 WithItem<nW> { "," WithItem<nW> }
|
|
|
+ 735 "DO" StatSeq "END"
|
|
|
+ 736 (. WHILE nW > 0 DO
|
|
|
+ 737 SymTab.PopScope;
|
|
|
+ 738 QbeGen.PopWith;
|
|
|
+ 739 DEC(nW)
|
|
|
+ 740 END; .) .
|
|
|
+ 741 WithItem<VAR nW: CARDINAL> (. VAR dt: SymTab.TypeIndex;
|
|
|
+ 742 dk: INTEGER;
|
|
|
+ 743 qd, qe: QbeGen.QVal;
|
|
|
+ 744 qn: SymTab.Name;
|
|
|
+ 745 sfx: BOOLEAN; .)
|
|
|
+ 746 = Design<dt, dk, qd, qn, sfx>
|
|
|
+ 747 (. IF dt = SymTab.InvalidType THEN
|
|
|
+ 748 ELSIF (SymTab.ClassOf(dt) #
|
|
|
+ 749 SymTab.ClRecord)
|
|
|
+ 750 & (SymTab.ClassOf(dt) #
|
|
|
+ 751 SymTab.ClClass) THEN
|
|
|
+ 752 SemError(215)
|
|
|
+ 753 ELSIF SymTab.PushRecord(dt) THEN
|
|
|
+ 754 QbeGen.PushWith(qd);
|
|
|
+ 755 INC(nW)
|
|
|
+ 756 END; .) .
|
|
|
+ 757 (* Assignment or procedure-statement call (4.1, module level).
|
|
|
+ 758 Bare `P;` is a syntax error; function-as-statement is 233. *)
|
|
|
+ 759 AssOrCall (. VAR dt, et: SymTab.TypeIndex;
|
|
|
+ 760 dk: INTEGER;
|
|
|
+ 761 qd, qe, qt, ql: QbeGen.QVal;
|
|
|
+ 762 qn: SymTab.Name;
|
|
|
+ 763 ct2, res0: SymTab.TypeIndex;
|
|
|
+ 764 q2, mg0: QbeGen.QVal;
|
|
|
+ 765 isR, conv, wconv: BOOLEAN;
|
|
|
+ 766 called, sfx: BOOLEAN; .)
|
|
|
+ 767 = Design<dt, dk, qd, qn, sfx>
|
|
|
+ 768 ( ":="
|
|
|
+ 769 Expr<et, qe> (. IF (dt # SymTab.InvalidType)
|
|
|
+ 770 & (dk # SymTab.KindVar)
|
|
|
+ 771 & (dk # SymTab.KindParam)
|
|
|
+ 772 & (dk # SymTab.KindField) THEN
|
|
|
+ 773 SemError(210)
|
|
|
+ 774 ELSIF ~SymTab.Assignable(et,
|
|
|
+ 775 dt) THEN
|
|
|
+ 776 SemError(210)
|
|
|
+ 777 ELSIF (dt # SymTab.InvalidType)
|
|
|
+ 778 & (SymTab.ClassOf(dt) =
|
|
|
+ 779 SymTab.ClClass) THEN
|
|
|
+ 780 SemError(230) END;
|
|
|
+ 781 isR := (dt #
|
|
|
+ 782 SymTab.InvalidType)
|
|
|
+ 783 & (SymTab.ClassOf(dt)
|
|
|
+ 784 = SymTab.ClReal);
|
|
|
+ 785 conv := isR
|
|
|
+ 786 & SymTab.IsIntFamily(et);
|
|
|
+ 787 wconv := (dt #
|
|
|
+ 788 SymTab.InvalidType)
|
|
|
+ 789 & SymTab.IsLongFamily(dt)
|
|
|
+ 790 & SymTab.IsIntFamily(et);
|
|
|
+ 791 IF ((dk = SymTab.KindVar)
|
|
|
+ 792 OR (dk = SymTab.KindParam)
|
|
|
+ 793 OR (dk = SymTab.KindField))
|
|
|
+ 794 & (dt # SymTab.InvalidType)
|
|
|
+ 795 & (et # SymTab.InvalidType)
|
|
|
+ 796 & (SymTab.ClassOf(dt) #
|
|
|
+ 797 SymTab.ClClass) THEN
|
|
|
+ 798 IF sfx
|
|
|
+ 799 OR (dk = SymTab.KindField) THEN
|
|
|
+ 800 IF SymTab.ClassOf(dt) =
|
|
|
+ 801 SymTab.ClArray THEN
|
|
|
+ 802 QbeGen.CopyArray(qd, qe,
|
|
|
+ 803 dt)
|
|
|
+ 804 ELSIF SymTab.ClassOf(dt) =
|
|
|
+ 805 SymTab.ClSet THEN
|
|
|
+ 806 QbeGen.CopySet(qd, qe,
|
|
|
+ 807 SymTab.SetWords(dt),
|
|
|
+ 808 SymTab.SetWords(et))
|
|
|
+ 809 ELSIF SymTab.ClassOf(dt) =
|
|
|
+ 810 SymTab.ClRecord THEN
|
|
|
+ 811 QbeGen.CopyRecord(qd, qe,
|
|
|
+ 812 dt)
|
|
|
+ 813 ELSIF SymTab.IsLongFamily(dt) THEN
|
|
|
+ 814 IF wconv THEN
|
|
|
+ 815 QbeGen.WidenLong(qe, ql);
|
|
|
+ 816 QbeGen.ElemStore(qd, ql,
|
|
|
+ 817 dt)
|
|
|
+ 818 ELSE QbeGen.ElemStore(qd, qe,
|
|
|
+ 819 dt)
|
|
|
+ 820 END
|
|
|
+ 821 ELSIF conv THEN
|
|
|
+ 822 QbeGen.ConvIR(qe, qt);
|
|
|
+ 823 QbeGen.ElemStore(qd, qt,
|
|
|
+ 824 dt)
|
|
|
+ 825 ELSE QbeGen.ElemStore(qd, qe,
|
|
|
+ 826 dt)
|
|
|
+ 827 END
|
|
|
+ 828 ELSIF SymTab.ClassOf(dt) =
|
|
|
+ 829 SymTab.ClArray THEN
|
|
|
+ 830 QbeGen.CopyArray(qd, qe, dt)
|
|
|
+ 831 ELSIF SymTab.ClassOf(dt) =
|
|
|
+ 832 SymTab.ClSet THEN
|
|
|
+ 833 QbeGen.CopySet(qd, qe,
|
|
|
+ 834 SymTab.SetWords(dt),
|
|
|
+ 835 SymTab.SetWords(et))
|
|
|
+ 836 ELSIF SymTab.ClassOf(dt) =
|
|
|
+ 837 SymTab.ClRecord THEN
|
|
|
+ 838 QbeGen.CopyRecord(qd, qe, dt)
|
|
|
+ 839 ELSIF SymTab.ClassOf(dt) =
|
|
|
+ 840 SymTab.ClPtr THEN
|
|
|
+ 841 QbeGen.StorePtr(qn, qe)
|
|
|
+ 842 ELSIF SymTab.IsLongFamily(dt) THEN
|
|
|
+ 843 IF wconv THEN
|
|
|
+ 844 QbeGen.WidenLong(qe, ql);
|
|
|
+ 845 QbeGen.StoreLong(qn, ql)
|
|
|
+ 846 ELSE QbeGen.StoreLong(qn, qe)
|
|
|
+ 847 END
|
|
|
+ 848 ELSIF conv THEN
|
|
|
+ 849 QbeGen.ConvIR(qe, qt);
|
|
|
+ 850 QbeGen.StoreVar(qn, qt, TRUE)
|
|
|
+ 851 ELSE
|
|
|
+ 852 QbeGen.StoreVar(qn, qe, isR)
|
|
|
+ 853 END
|
|
|
+ 854 END; .)
|
|
|
+ 855 | ArgList<qn, FALSE, ct2, q2, called>
|
|
|
+ 856 | (* bare `P;`: proper parameterless
|
|
|
+ 857 procedure call; anything else
|
|
|
+ 858 here is 233 (was a bare syntax
|
|
|
+ 859 error before 4.2) *)
|
|
|
+ 860 (. IF (dk = SymTab.KindProc)
|
|
|
+ 861 & ~sfx THEN
|
|
|
+ 862 res0 := SymTab.ProcRes(qn);
|
|
|
+ 863 IF res0 #
|
|
|
+ 864 SymTab.InvalidType THEN
|
|
|
+ 865 SemError(233)
|
|
|
+ 866 ELSIF SymTab.ProcNPar(qn) #
|
|
|
+ 867 0 THEN
|
|
|
+ 868 SemError(233)
|
|
|
+ 869 ELSE QbeGen.Mangled(qn,
|
|
|
+ 870 SymTab.ProcUid(qn), mg0);
|
|
|
+ 871 QbeGen.CallBegin(mg0,
|
|
|
+ 872 res0,
|
|
|
+ 873 SymTab.ProcDepthOf(qn),
|
|
|
+ 874 SymTab.IsExternal(qn));
|
|
|
+ 875 QbeGen.CallEnd(FALSE, q2)
|
|
|
+ 876 END
|
|
|
+ 877 ELSE SemError(233)
|
|
|
+ 878 END; .) ) .
|
|
|
+ 879 (* Actual-parameter list shared by statement and expression calls.
|
|
|
+ 880 want selects CallEnd's result handling; t/q carry the call
|
|
|
+ 881 value (statement calls discard). Arity/type failures are 233;
|
|
|
+ 882 evaluation code still emits so the .ssa stays assembleable. *)
|
|
|
+ 883 ArgList<pn: SymTab.Name; want: BOOLEAN;
|
|
|
+ 884 VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal;
|
|
|
+ 885 VAR called: BOOLEAN> (. VAR i: CARDINAL;
|
|
|
+ 886 res: SymTab.TypeIndex;
|
|
|
+ 887 mg: QbeGen.QVal;
|
|
|
+ 888 ok: BOOLEAN; .)
|
|
|
+ 889 = "(" (. called := TRUE;
|
|
|
+ 890 res := SymTab.ProcRes(pn);
|
|
|
+ 891 ok := TRUE;
|
|
|
+ 892 IF SymTab.SymKind(pn) #
|
|
|
+ 893 SymTab.KindProc THEN
|
|
|
+ 894 SemError(233); ok := FALSE
|
|
|
+ 895 ELSE QbeGen.Mangled(pn,
|
|
|
+ 896 SymTab.ProcUid(pn), mg);
|
|
|
+ 897 QbeGen.CallBegin(mg, res,
|
|
|
+ 898 SymTab.ProcDepthOf(pn),
|
|
|
+ 899 SymTab.IsExternal(pn))
|
|
|
+ 900 END;
|
|
|
+ 901 i := 0; .)
|
|
|
+ 902 [ ActParam<pn, i> (. INC(i); .)
|
|
|
+ 903 { "," ActParam<pn, i> (. INC(i); .) } ]
|
|
|
+ 904 ")" (. IF ok THEN
|
|
|
+ 905 IF i #
|
|
|
+ 906 SymTab.ProcNPar(pn) THEN
|
|
|
+ 907 SemError(233); ok := FALSE
|
|
|
+ 908 END
|
|
|
+ 909 END;
|
|
|
+ 910 IF ~ok THEN
|
|
|
+ 911 t := SymTab.InvalidType;
|
|
|
+ 912 QbeGen.CopyOp("0", q)
|
|
|
+ 913 ELSIF want THEN
|
|
|
+ 914 IF res =
|
|
|
+ 915 SymTab.InvalidType THEN
|
|
|
+ 916 SemError(233);
|
|
|
+ 917 t := SymTab.InvalidType;
|
|
|
+ 918 QbeGen.CopyOp("0", q)
|
|
|
+ 919 ELSE t := res;
|
|
|
+ 920 QbeGen.CallEnd(TRUE, q)
|
|
|
+ 921 END
|
|
|
+ 922 ELSE
|
|
|
+ 923 IF res #
|
|
|
+ 924 SymTab.InvalidType THEN
|
|
|
+ 925 SemError(233)
|
|
|
+ 926 END;
|
|
|
+ 927 t := SymTab.InvalidType;
|
|
|
+ 928 QbeGen.CopyOp("0", q);
|
|
|
+ 929 QbeGen.CallEnd(FALSE, q)
|
|
|
+ 930 END; .) .
|
|
|
+ 931 (* One actual: VAR formals take recorded designator addresses
|
|
|
+ 932 (233 otherwise); value formals take converted expressions. *)
|
|
|
+ 933 ActParam<pn: SymTab.Name; i: CARDINAL>(. VAR at, ft: SymTab.TypeIndex;
|
|
|
+ 934 qe, qa, qt: QbeGen.QVal;
|
|
|
+ 935 isV, conv: BOOLEAN; .)
|
|
|
+ 936 = Expr<at, qe> (. ft := SymTab.ParamType(pn, i);
|
|
|
+ 937 isV := SymTab.ParamIsVar(pn, i);
|
|
|
+ 938 IF (at = SymTab.InvalidType)
|
|
|
+ 939 OR (ft =
|
|
|
+ 940 SymTab.InvalidType) THEN
|
|
|
+ 941 ELSIF isV THEN
|
|
|
+ 942 IF ~QbeGen.AddrOfVal(qe,
|
|
|
+ 943 qa) THEN
|
|
|
+ 944 SemError(233)
|
|
|
+ 945 ELSIF ~SymTab.VarParamOk(at,
|
|
|
+ 946 ft) THEN
|
|
|
+ 947 SemError(233)
|
|
|
+ 948 ELSIF ~QbeGen.CallArg(qa,
|
|
|
+ 949 "l") THEN
|
|
|
+ 950 SemError(233)
|
|
|
+ 951 END
|
|
|
+ 952 ELSE
|
|
|
+ 953 IF ~SymTab.Assignable(at,
|
|
|
+ 954 ft) THEN
|
|
|
+ 955 SemError(233)
|
|
|
+ 956 ELSE
|
|
|
+ 957 conv := (SymTab.ClassOf(
|
|
|
+ 958 ft) = SymTab.ClReal)
|
|
|
+ 959 & SymTab.IsIntFamily(at);
|
|
|
+ 960 IF conv THEN
|
|
|
+ 961 QbeGen.ConvIR(qe, qt);
|
|
|
+ 962 IF ~QbeGen.CallArg(qt,
|
|
|
+ 963 "d") THEN
|
|
|
+ 964 SemError(233)
|
|
|
+ 965 END
|
|
|
+ 966 ELSIF ~QbeGen.CallArg(qe,
|
|
|
+ 967 QbeGen.ArgClass(ft)) THEN
|
|
|
+ 968 SemError(233)
|
|
|
+ 969 END
|
|
|
+ 970 END
|
|
|
+ 971 END; .) .
|
|
|
+ 972 IfStat (. VAR t: SymTab.TypeIndex;
|
|
|
+ 973 q, lThen, lElse, lEnd:
|
|
|
+ 974 QbeGen.QVal;
|
|
|
+ 975 hasElse: BOOLEAN; .)
|
|
|
+ 976 = "IF" (. hasElse := FALSE; .)
|
|
|
+ 977 Expr<t, q> (. IF ~SymTab.BoolCheck(t) THEN
|
|
|
+ 978 SemError(214) END;
|
|
|
+ 979 QbeGen.NewLabel(lThen);
|
|
|
+ 980 QbeGen.NewLabel(lElse);
|
|
|
+ 981 QbeGen.NewLabel(lEnd);
|
|
|
+ 982 QbeGen.Jnz(q, lThen, lElse);
|
|
|
+ 983 QbeGen.EmitLabel(lThen); .)
|
|
|
+ 984 "THEN" StatSeq (. QbeGen.Jmp(lEnd); .)
|
|
|
+ 985 { "ELSIF" (. QbeGen.EmitLabel(lElse);
|
|
|
+ 986 QbeGen.NewLabel(lElse); .)
|
|
|
+ 987 Expr<t, q> (. IF ~SymTab.BoolCheck(t) THEN
|
|
|
+ 988 SemError(214) END;
|
|
|
+ 989 QbeGen.NewLabel(lThen);
|
|
|
+ 990 QbeGen.Jnz(q, lThen, lElse);
|
|
|
+ 991 QbeGen.EmitLabel(lThen); .)
|
|
|
+ 992 "THEN" StatSeq (. QbeGen.Jmp(lEnd); .) }
|
|
|
+ 993 [ "ELSE" (. QbeGen.EmitLabel(lElse);
|
|
|
+ 994 hasElse := TRUE; .)
|
|
|
+ 995 StatSeq ]
|
|
|
+ 996 "END" (. IF hasElse THEN
|
|
|
+ 997 QbeGen.EmitLabel(lEnd)
|
|
|
+ 998 ELSE QbeGen.EmitLabel(lElse);
|
|
|
+ 999 QbeGen.EmitLabel(lEnd)
|
|
|
+ 1000 END; .) .
|
|
|
+ 1001 WhileStat (. VAR t: SymTab.TypeIndex;
|
|
|
+ 1002 q, lTop, lBody, lEnd:
|
|
|
+ 1003 QbeGen.QVal; .)
|
|
|
+ 1004 = "WHILE" (. QbeGen.NewLabel(lTop);
|
|
|
+ 1005 QbeGen.NewLabel(lBody);
|
|
|
+ 1006 QbeGen.NewLabel(lEnd);
|
|
|
+ 1007 QbeGen.EmitLabel(lTop); .)
|
|
|
+ 1008 Expr<t, q> (. IF ~SymTab.BoolCheck(t) THEN
|
|
|
+ 1009 SemError(214) END;
|
|
|
+ 1010 QbeGen.Jnz(q, lBody, lEnd);
|
|
|
+ 1011 QbeGen.EmitLabel(lBody); .)
|
|
|
+ 1012 "DO" StatSeq (. QbeGen.Jmp(lTop); .)
|
|
|
+ 1013 "END" (. QbeGen.EmitLabel(lEnd); .) .
|
|
|
+ 1014 RepeatStat (. VAR t: SymTab.TypeIndex;
|
|
|
+ 1015 q, lTop, lEnd: QbeGen.QVal; .)
|
|
|
+ 1016 = "REPEAT" (. QbeGen.NewLabel(lTop);
|
|
|
+ 1017 QbeGen.NewLabel(lEnd);
|
|
|
+ 1018 QbeGen.EmitLabel(lTop); .)
|
|
|
+ 1019 StatSeq
|
|
|
+ 1020 "UNTIL" Expr<t, q> (. IF ~SymTab.BoolCheck(t) THEN
|
|
|
+ 1021 SemError(214) END;
|
|
|
+ 1022 QbeGen.Jnz(q, lEnd, lTop);
|
|
|
+ 1023 QbeGen.EmitLabel(lEnd); .) .
|
|
|
+ 1024 LoopStat (. VAR lTop, lEnd: QbeGen.QVal; .)
|
|
|
+ 1025 = "LOOP" (. QbeGen.NewLabel(lTop);
|
|
|
+ 1026 QbeGen.NewLabel(lEnd);
|
|
|
+ 1027 QbeGen.PushLoop(lEnd);
|
|
|
+ 1028 QbeGen.EmitLabel(lTop); .)
|
|
|
+ 1029 StatSeq
|
|
|
+ 1030 "END" (. QbeGen.Jmp(lTop);
|
|
|
+ 1031 QbeGen.PopLoop;
|
|
|
+ 1032 QbeGen.EmitLabel(lEnd); .) .
|
|
|
+ 1033 (* FOR with static-sign BY (literal, non-zero; 220 otherwise).
|
|
|
+ 1034 Runtime direction would need a compare-select; the literal
|
|
|
+ 1035 sign picks cslew/csegew at "DO" time. *)
|
|
|
+ 1036 ForStat (. VAR lv: SymTab.Name;
|
|
|
+ 1037 tlo, thi, tby:
|
|
|
+ 1038 SymTab.TypeIndex;
|
|
|
+ 1039 qlo, qhi, qby, qt, qk, qb:
|
|
|
+ 1040 QbeGen.QVal;
|
|
|
+ 1041 lTop, lBody, lEnd:
|
|
|
+ 1042 QbeGen.QVal;
|
|
|
+ 1043 by: INTEGER;
|
|
|
+ 1044 ok: BOOLEAN; .)
|
|
|
+ 1045 = "FOR" (. by := 1; .)
|
|
|
+ 1046 GetIdent<lv> (. ok := SymTab.Lookup(lv);
|
|
|
+ 1047 IF ~ok THEN
|
|
|
+ 1048 SemError(201)
|
|
|
+ 1049 ELSIF (SymTab.SymKind(lv) #
|
|
|
+ 1050 SymTab.KindVar)
|
|
|
+ 1051 & (SymTab.SymKind(lv) #
|
|
|
+ 1052 SymTab.KindParam) THEN
|
|
|
+ 1053 SemError(220); ok := FALSE
|
|
|
+ 1054 ELSIF ~SymTab.IsIntFamily(
|
|
|
+ 1055 SymTab.SymType(lv)) THEN
|
|
|
+ 1056 SemError(220); ok := FALSE
|
|
|
+ 1057 END; .)
|
|
|
+ 1058 ":=" Expr<tlo, qlo> (. IF ~SymTab.IsIntFamily(tlo) THEN
|
|
|
+ 1059 SemError(220); ok := FALSE
|
|
|
+ 1060 END; .)
|
|
|
+ 1061 "TO" Expr<thi, qhi> (. IF ~SymTab.IsIntFamily(thi) THEN
|
|
|
+ 1062 SemError(220); ok := FALSE
|
|
|
+ 1063 END; .)
|
|
|
+ 1064 [ "BY" Expr<tby, qby> (. IF (tby #
|
|
|
+ 1065 SymTab.InvalidType)
|
|
|
+ 1066 & ~SymTab.IsIntFamily(tby) THEN
|
|
|
+ 1067 SemError(220); ok := FALSE
|
|
|
+ 1068 END;
|
|
|
+ 1069 IF ~SymTab.ConstInt(qby, by) THEN
|
|
|
+ 1070 SemError(230); by := 1
|
|
|
+ 1071 ELSIF by = 0 THEN
|
|
|
+ 1072 SemError(220); by := 1
|
|
|
+ 1073 END; .) ]
|
|
|
+ 1074 "DO" (. IF ok THEN
|
|
|
+ 1075 QbeGen.StoreVar(lv, qlo,
|
|
|
+ 1076 FALSE) END;
|
|
|
+ 1077 QbeGen.NewLabel(lTop);
|
|
|
+ 1078 QbeGen.NewLabel(lBody);
|
|
|
+ 1079 QbeGen.NewLabel(lEnd);
|
|
|
+ 1080 QbeGen.EmitLabel(lTop);
|
|
|
+ 1081 QbeGen.LoadVar(lv, FALSE, qt);
|
|
|
+ 1082 QbeGen.NewTemp(qk);
|
|
|
+ 1083 IF by > 0 THEN
|
|
|
+ 1084 QbeGen.Op3("cslew", qk,
|
|
|
+ 1085 qt, qhi, FALSE)
|
|
|
+ 1086 ELSE QbeGen.Op3("csgew", qk,
|
|
|
+ 1087 qt, qhi, FALSE)
|
|
|
+ 1088 END;
|
|
|
+ 1089 QbeGen.Jnz(qk, lBody, lEnd);
|
|
|
+ 1090 QbeGen.EmitLabel(lBody); .)
|
|
|
+ 1091 StatSeq
|
|
|
+ 1092 "END" (. IF ok THEN
|
|
|
+ 1093 QbeGen.LoadVar(lv, FALSE,
|
|
|
+ 1094 qt);
|
|
|
+ 1095 QbeGen.IntStr(by, qb);
|
|
|
+ 1096 QbeGen.NewTemp(qk);
|
|
|
+ 1097 QbeGen.Op3("add", qk,
|
|
|
+ 1098 qt, qb, FALSE);
|
|
|
+ 1099 QbeGen.StoreVar(lv, qk,
|
|
|
+ 1100 FALSE) END;
|
|
|
+ 1101 QbeGen.Jmp(lTop);
|
|
|
+ 1102 QbeGen.EmitLabel(lEnd); .) .
|
|
|
+ 1103 CaseStat (. VAR tsel: SymTab.TypeIndex;
|
|
|
+ 1104 qsel, lEnd: QbeGen.QVal; .)
|
|
|
+ 1105 = "CASE" Expr<tsel, qsel> (. QbeGen.NewLabel(lEnd); .)
|
|
|
+ 1106 "OF" CaseAlt<tsel, qsel, lEnd>
|
|
|
+ 1107 { "|" CaseAlt<tsel, qsel, lEnd> }
|
|
|
+ 1108 [ "ELSE" StatSeq ]
|
|
|
+ 1109 "END" (. QbeGen.EmitLabel(lEnd); .) .
|
|
|
+ 1110 (* Compare-chain lowering: each alternative ends its match-tests
|
|
|
+ 1111 with "jmp lAfter", so the no-match fallthrough skips the body:
|
|
|
+ 1112 "cmp; jnz(lBody,lF); lF: ... ; jmp lAfter; lBody: S; jmp lEnd;
|
|
|
+ 1113 lAfter:". Falls into the next alternative, ELSE, or END. *)
|
|
|
+ 1114 CaseAlt<tsel: SymTab.TypeIndex; qsel: QbeGen.QVal;
|
|
|
+ 1115 lEnd: QbeGen.QVal> (. VAR lBody, lAfter: QbeGen.QVal; .)
|
|
|
+ 1116 = (. QbeGen.NewLabel(lBody);
|
|
|
+ 1117 QbeGen.NewLabel(lAfter); .)
|
|
|
+ 1118 CaseLabel<tsel, qsel, lBody>
|
|
|
+ 1119 { "," CaseLabel<tsel, qsel, lBody> }
|
|
|
+ 1120 ":" (. QbeGen.Jmp(lAfter);
|
|
|
+ 1121 QbeGen.EmitLabel(lBody); .)
|
|
|
+ 1122 StatSeq (. QbeGen.Jmp(lEnd);
|
|
|
+ 1123 QbeGen.EmitLabel(lAfter); .) .
|
|
|
+ 1124 CaseLabel<tsel: SymTab.TypeIndex; qsel: QbeGen.QVal;
|
|
|
+ 1125 lBody: QbeGen.QVal> (. VAR t2, t3: SymTab.TypeIndex;
|
|
|
+ 1126 q2, q3, qc, qd, qe:
|
|
|
+ 1127 QbeGen.QVal;
|
|
|
+ 1128 lNext: QbeGen.QVal; .)
|
|
|
+ 1129 = Expr<t2, q2> (. IF (t2 #
|
|
|
+ 1130 SymTab.InvalidType)
|
|
|
+ 1131 & (tsel #
|
|
|
+ 1132 SymTab.InvalidType)
|
|
|
+ 1133 & ((SymTab.ClassOf(t2) =
|
|
|
+ 1134 SymTab.ClSet)
|
|
|
+ 1135 OR (SymTab.ClassOf(tsel) =
|
|
|
+ 1136 SymTab.ClSet)) THEN
|
|
|
+ 1137 SemError(230)
|
|
|
+ 1138 ELSIF (t2 #
|
|
|
+ 1139 SymTab.InvalidType)
|
|
|
+ 1140 & (tsel #
|
|
|
+ 1141 SymTab.InvalidType)
|
|
|
+ 1142 & ~SymTab.EqCheck(t2,
|
|
|
+ 1143 tsel) THEN
|
|
|
+ 1144 SemError(213) END;
|
|
|
+ 1145 IF ~QbeGen.IsImm(q2) THEN
|
|
|
+ 1146 SemError(230);
|
|
|
+ 1147 QbeGen.CopyOp("0", q2)
|
|
|
+ 1148 END;
|
|
|
+ 1149 QbeGen.NewLabel(lNext);
|
|
|
+ 1150 QbeGen.Cmp(SymTab.OpEq,
|
|
|
+ 1151 qsel, q2, qc, FALSE);
|
|
|
+ 1152 QbeGen.Jnz(qc, lBody, lNext);
|
|
|
+ 1153 QbeGen.EmitLabel(lNext); .)
|
|
|
+ 1154 [ ".." Expr<t3, q3> (. IF (t3 #
|
|
|
+ 1155 SymTab.InvalidType)
|
|
|
+ 1156 & (tsel #
|
|
|
+ 1157 SymTab.InvalidType)
|
|
|
+ 1158 & ~SymTab.EqCheck(t3,
|
|
|
+ 1159 tsel) THEN
|
|
|
+ 1160 SemError(213) END;
|
|
|
+ 1161 IF ~QbeGen.IsImm(q3) THEN
|
|
|
+ 1162 SemError(230);
|
|
|
+ 1163 QbeGen.CopyOp("0", q3)
|
|
|
+ 1164 END;
|
|
|
+ 1165 QbeGen.Cmp(SymTab.OpGe,
|
|
|
+ 1166 qsel, q2, qc, FALSE);
|
|
|
+ 1167 QbeGen.Cmp(SymTab.OpLe,
|
|
|
+ 1168 qsel, q3, qd, FALSE);
|
|
|
+ 1169 QbeGen.NewTemp(qe);
|
|
|
+ 1170 QbeGen.Op3("and", qe, qc, qd,
|
|
|
+ 1171 FALSE);
|
|
|
+ 1172 QbeGen.NewLabel(lNext);
|
|
|
+ 1173 QbeGen.Jnz(qe, lBody, lNext);
|
|
|
+ 1174 QbeGen.EmitLabel(lNext); .) ] .
|
|
|
+ 1175 ReturnStat (. VAR t: SymTab.TypeIndex;
|
|
|
+ 1176 q, qt: QbeGen.QVal;
|
|
|
+ 1177 res: SymTab.TypeIndex;
|
|
|
+ 1178 hadE, conv: BOOLEAN; .)
|
|
|
+ 1179 = "RETURN" (. hadE := FALSE; .)
|
|
|
+ 1180 [ Expr<t, q> (. hadE := TRUE; .) ]
|
|
|
+ 1181 (. conv := FALSE;
|
|
|
+ 1182 IF ~SymTab.InProc() THEN
|
|
|
+ 1183 SemError(232)
|
|
|
+ 1184 ELSE res := SymTab.CurRes();
|
|
|
+ 1185 IF ~hadE THEN
|
|
|
+ 1186 IF res #
|
|
|
+ 1187 SymTab.InvalidType THEN
|
|
|
+ 1188 SemError(232)
|
|
|
+ 1189 ELSE QbeGen.EmitRet(q,
|
|
|
+ 1190 FALSE)
|
|
|
+ 1191 END
|
|
|
+ 1192 ELSIF (res =
|
|
|
+ 1193 SymTab.InvalidType)
|
|
|
+ 1194 OR (t #
|
|
|
+ 1195 SymTab.InvalidType)
|
|
|
+ 1196 & ~SymTab.Assignable(t,
|
|
|
+ 1197 res) THEN
|
|
|
+ 1198 SemError(232)
|
|
|
+ 1199 ELSE
|
|
|
+ 1200 conv := (SymTab.ClassOf(
|
|
|
+ 1201 res) = SymTab.ClReal)
|
|
|
+ 1202 & SymTab.IsIntFamily(t);
|
|
|
+ 1203 IF conv THEN
|
|
|
+ 1204 QbeGen.ConvIR(q, qt);
|
|
|
+ 1205 QbeGen.EmitRet(qt, TRUE)
|
|
|
+ 1206 ELSE QbeGen.EmitRet(q, TRUE)
|
|
|
+ 1207 END
|
|
|
+ 1208 END
|
|
|
+ 1209 END; .) .
|
|
|
+ 1210 (* Designator: scalar loads, array addresses, and index suffixes.
|
|
|
+ 1211 Each index descends one level (bounds-checked, trap on breach);
|
|
|
+ 1212 nested levels reload the inner descriptor address. q ends as the
|
|
|
+ 1213 value (scalars), the descriptor address (plain arrays), or the
|
|
|
+ 1214 element address (indexed); sfx marks the indexed form. *)
|
|
|
+ 1215 Design<VAR t: SymTab.TypeIndex; VAR k: INTEGER;
|
|
|
+ 1216 VAR q: QbeGen.QVal; VAR qn: SymTab.Name; VAR sfx: BOOLEAN>
|
|
|
+ 1217 (. VAR n, fn, mal: SymTab.Name;
|
|
|
+ 1218 cls: INTEGER;
|
|
|
+ 1219 curT, it, eT, bt:
|
|
|
+ 1220 SymTab.TypeIndex;
|
|
|
+ 1221 iq, ql, qlo, qhi, qe:
|
|
|
+ 1222 QbeGen.QVal;
|
|
|
+ 1223 lo, hi: INTEGER;
|
|
|
+ 1224 fo: INTEGER;
|
|
|
+ 1225 isOpen: BOOLEAN;
|
|
|
+ 1226 qb: QbeGen.QVal; .)
|
|
|
+ 1227 = GetIdent<n> (. QbeGen.CopyOp(n, qn);
|
|
|
+ 1228 sfx := FALSE;
|
|
|
+ 1229 IF ~SymTab.Lookup(n) THEN
|
|
|
+ 1230 SemError(201);
|
|
|
+ 1231 t := SymTab.InvalidType;
|
|
|
+ 1232 k := -1;
|
|
|
+ 1233 QbeGen.CopyOp("0", q)
|
|
|
+ 1234 ELSE
|
|
|
+ 1235 t := SymTab.SymType(n);
|
|
|
+ 1236 k := SymTab.SymKind(n);
|
|
|
+ 1237 IF k = SymTab.KindConst THEN
|
|
|
+ 1238 IF SymTab.Equal(n,
|
|
|
+ 1239 "TRUE") THEN
|
|
|
1240 t := SymTab.BoolType();
|
|
|
- 1241 QbeGen.CopyOp("0", q)
|
|
|
+ 1241 QbeGen.CopyOp("1", q)
|
|
|
1242 ELSIF SymTab.Equal(n,
|
|
|
- 1243 "NIL") THEN
|
|
|
- 1244 QbeGen.CopyOp("0", q)
|
|
|
- 1245 ELSE
|
|
|
- 1246 cls :=
|
|
|
- 1247 SymTab.ClassOf(t);
|
|
|
- 1248 IF (t #
|
|
|
- 1249 SymTab.InvalidType)
|
|
|
- 1250 & ((cls = SymTab.ClInt)
|
|
|
- 1251 OR (cls
|
|
|
- 1252 = SymTab.ClChar)
|
|
|
- 1253 OR (cls
|
|
|
- 1254 = SymTab.ClReal)
|
|
|
+ 1243 "FALSE") THEN
|
|
|
+ 1244 t := SymTab.BoolType();
|
|
|
+ 1245 QbeGen.CopyOp("0", q)
|
|
|
+ 1246 ELSIF SymTab.Equal(n,
|
|
|
+ 1247 "NIL") THEN
|
|
|
+ 1248 QbeGen.CopyOp("0", q)
|
|
|
+ 1249 ELSE
|
|
|
+ 1250 cls :=
|
|
|
+ 1251 SymTab.ClassOf(t);
|
|
|
+ 1252 IF (t #
|
|
|
+ 1253 SymTab.InvalidType)
|
|
|
+ 1254 & ((cls = SymTab.ClInt)
|
|
|
1255 OR (cls
|
|
|
- 1256 = SymTab.ClNil)) THEN
|
|
|
- 1257 IF cls = SymTab.ClNil THEN
|
|
|
- 1258 QbeGen.CopyOp("0", q)
|
|
|
- 1259 ELSE
|
|
|
- 1260 QbeGen.LoadVar(n,
|
|
|
- 1261 cls = SymTab.ClReal,
|
|
|
- 1262 q)
|
|
|
- 1263 END
|
|
|
- 1264 ELSE
|
|
|
- 1265 IF t #
|
|
|
- 1266 SymTab.InvalidType THEN
|
|
|
- 1267 SemError(230)
|
|
|
- 1268 END;
|
|
|
- 1269 QbeGen.CopyOp("0", q)
|
|
|
- 1270 END
|
|
|
- 1271 END
|
|
|
- 1272 ELSIF (k = SymTab.KindVar)
|
|
|
- 1273 OR (k = SymTab.KindParam) THEN
|
|
|
- 1274 cls :=
|
|
|
- 1275 SymTab.ClassOf(t);
|
|
|
- 1276 IF (cls = SymTab.ClInt)
|
|
|
- 1277 OR (cls = SymTab.ClBool)
|
|
|
- 1278 OR (cls = SymTab.ClChar)
|
|
|
- 1279 OR (cls
|
|
|
- 1280 = SymTab.ClReal) THEN
|
|
|
- 1281 QbeGen.LoadVar(n,
|
|
|
- 1282 cls = SymTab.ClReal, q)
|
|
|
- 1283 ELSIF cls = SymTab.ClPtr THEN
|
|
|
- 1284 QbeGen.LoadPtr(n, q)
|
|
|
- 1285 ELSIF cls = SymTab.ClLong THEN
|
|
|
- 1286 QbeGen.LoadLong(n, q)
|
|
|
- 1287 ELSIF (cls
|
|
|
- 1288 = SymTab.ClArray)
|
|
|
- 1289 OR (cls
|
|
|
- 1290 = SymTab.ClSet)
|
|
|
- 1291 OR (cls
|
|
|
- 1292 = SymTab.ClRecord)
|
|
|
+ 1256 = SymTab.ClChar)
|
|
|
+ 1257 OR (cls
|
|
|
+ 1258 = SymTab.ClReal)
|
|
|
+ 1259 OR (cls
|
|
|
+ 1260 = SymTab.ClNil)) THEN
|
|
|
+ 1261 IF cls = SymTab.ClNil THEN
|
|
|
+ 1262 QbeGen.CopyOp("0", q)
|
|
|
+ 1263 ELSE
|
|
|
+ 1264 QbeGen.LoadVar(n,
|
|
|
+ 1265 cls = SymTab.ClReal,
|
|
|
+ 1266 q)
|
|
|
+ 1267 END
|
|
|
+ 1268 ELSE
|
|
|
+ 1269 IF t #
|
|
|
+ 1270 SymTab.InvalidType THEN
|
|
|
+ 1271 SemError(230)
|
|
|
+ 1272 END;
|
|
|
+ 1273 QbeGen.CopyOp("0", q)
|
|
|
+ 1274 END
|
|
|
+ 1275 END
|
|
|
+ 1276 ELSIF (k = SymTab.KindVar)
|
|
|
+ 1277 OR (k = SymTab.KindParam) THEN
|
|
|
+ 1278 cls :=
|
|
|
+ 1279 SymTab.ClassOf(t);
|
|
|
+ 1280 IF (cls = SymTab.ClInt)
|
|
|
+ 1281 OR (cls = SymTab.ClBool)
|
|
|
+ 1282 OR (cls = SymTab.ClChar)
|
|
|
+ 1283 OR (cls
|
|
|
+ 1284 = SymTab.ClReal) THEN
|
|
|
+ 1285 QbeGen.LoadVar(n,
|
|
|
+ 1286 cls = SymTab.ClReal, q)
|
|
|
+ 1287 ELSIF cls = SymTab.ClPtr THEN
|
|
|
+ 1288 QbeGen.LoadPtr(n, q)
|
|
|
+ 1289 ELSIF cls = SymTab.ClLong THEN
|
|
|
+ 1290 QbeGen.LoadLong(n, q)
|
|
|
+ 1291 ELSIF (cls
|
|
|
+ 1292 = SymTab.ClArray)
|
|
|
1293 OR (cls
|
|
|
- 1294 = SymTab.ClClass) THEN
|
|
|
- 1295 QbeGen.AddrOf(n, q)
|
|
|
- 1296 ELSE SemError(230);
|
|
|
- 1297 QbeGen.CopyOp("0", q)
|
|
|
- 1298 END
|
|
|
- 1299 ELSE QbeGen.CopyOp("0", q);
|
|
|
- 1300 IF k = SymTab.KindImport THEN
|
|
|
- 1301 SemError(230)
|
|
|
- 1302 ELSIF k =
|
|
|
- 1303 SymTab.KindProc THEN
|
|
|
- 1304 (* bare procedure name:
|
|
|
- 1305 a following ArgList
|
|
|
- 1306 makes it a call;
|
|
|
- 1307 otherwise Fact
|
|
|
- 1308 reports 230 *)
|
|
|
- 1309 ELSE
|
|
|
- 1310 IF k = SymTab.KindField THEN
|
|
|
- 1311 IF QbeGen.TopWith(qb) THEN
|
|
|
- 1312 fo :=
|
|
|
- 1313 SymTab.FieldOffset(
|
|
|
- 1314 SymTab.FieldOwner(n),
|
|
|
- 1315 n);
|
|
|
- 1316 QbeGen.FieldAddr(qb,
|
|
|
- 1317 fo, q);
|
|
|
- 1318 sfx := TRUE
|
|
|
- 1319 ELSE SemError(230);
|
|
|
- 1320 QbeGen.CopyOp("0", q)
|
|
|
- 1321 END
|
|
|
- 1322 END
|
|
|
- 1323 END
|
|
|
- 1324 END
|
|
|
- 1325 END; .)
|
|
|
- 1326 { "[" Expr<it, iq>
|
|
|
- 1327 (. IF t = SymTab.InvalidType THEN
|
|
|
- 1328 ELSIF SymTab.ClassOf(t) #
|
|
|
- 1329 SymTab.ClArray THEN
|
|
|
- 1330 SemError(217);
|
|
|
- 1331 t := SymTab.InvalidType
|
|
|
- 1332 ELSIF ~SymTab.IsIntFamily(it)
|
|
|
- 1333 & (SymTab.ClassOf(it) #
|
|
|
- 1334 SymTab.ClChar) THEN
|
|
|
- 1335 SemError(218);
|
|
|
- 1336 t := SymTab.InvalidType
|
|
|
- 1337 ELSE
|
|
|
- 1338 QbeGen.WidenIndex(iq, ql);
|
|
|
- 1339 isOpen :=
|
|
|
- 1340 SymTab.IsOpenArray(t);
|
|
|
- 1341 IF isOpen THEN
|
|
|
- 1342 QbeGen.CopyOp("0", qlo);
|
|
|
- 1343 QbeGen.OpenHi(q, qhi)
|
|
|
- 1344 ELSE
|
|
|
- 1345 lo := SymTab.ArrayLo(t);
|
|
|
- 1346 hi := SymTab.ArrayHi(t);
|
|
|
- 1347 QbeGen.IntStr(lo, qlo);
|
|
|
- 1348 QbeGen.IntStr(hi, qhi)
|
|
|
- 1349 END;
|
|
|
- 1350 QbeGen.CheckRange(ql, qlo,
|
|
|
- 1351 qhi);
|
|
|
- 1352 eT := SymTab.ArrayElem(t);
|
|
|
- 1353 QbeGen.ElemAddr(q, ql, qlo,
|
|
|
- 1354 t, qe);
|
|
|
- 1355 IF SymTab.ClassOf(eT) =
|
|
|
- 1356 SymTab.ClArray THEN
|
|
|
- 1357 QbeGen.ElemLoad(qe, eT, q)
|
|
|
- 1358 ELSE QbeGen.CopyOp(qe, q)
|
|
|
- 1359 END;
|
|
|
- 1360 t := eT; sfx := TRUE
|
|
|
- 1361 END; .)
|
|
|
- 1362 { "," Expr<it, iq>
|
|
|
- 1363 (. IF t = SymTab.InvalidType THEN
|
|
|
- 1364 ELSIF SymTab.ClassOf(t) #
|
|
|
- 1365 SymTab.ClArray THEN
|
|
|
- 1366 SemError(217);
|
|
|
- 1367 t := SymTab.InvalidType
|
|
|
- 1368 ELSIF ~SymTab.IsIntFamily(it)
|
|
|
- 1369 & (SymTab.ClassOf(it) #
|
|
|
- 1370 SymTab.ClChar) THEN
|
|
|
- 1371 SemError(218);
|
|
|
- 1372 t := SymTab.InvalidType
|
|
|
- 1373 ELSE
|
|
|
- 1374 QbeGen.WidenIndex(iq, ql);
|
|
|
- 1375 isOpen :=
|
|
|
- 1376 SymTab.IsOpenArray(t);
|
|
|
- 1377 IF isOpen THEN
|
|
|
- 1378 QbeGen.CopyOp("0", qlo);
|
|
|
- 1379 QbeGen.OpenHi(q, qhi)
|
|
|
- 1380 ELSE
|
|
|
- 1381 lo := SymTab.ArrayLo(t);
|
|
|
- 1382 hi := SymTab.ArrayHi(t);
|
|
|
- 1383 QbeGen.IntStr(lo, qlo);
|
|
|
- 1384 QbeGen.IntStr(hi, qhi)
|
|
|
- 1385 END;
|
|
|
- 1386 QbeGen.CheckRange(ql, qlo,
|
|
|
- 1387 qhi);
|
|
|
- 1388 eT := SymTab.ArrayElem(t);
|
|
|
- 1389 QbeGen.ElemAddr(q, ql, qlo,
|
|
|
- 1390 t, qe);
|
|
|
- 1391 IF SymTab.ClassOf(eT) =
|
|
|
- 1392 SymTab.ClArray THEN
|
|
|
- 1393 QbeGen.ElemLoad(qe, eT, q)
|
|
|
- 1394 ELSE QbeGen.CopyOp(qe, q)
|
|
|
- 1395 END;
|
|
|
- 1396 t := eT; sfx := TRUE
|
|
|
- 1397 END; .) }
|
|
|
- 1398 "]"
|
|
|
- 1399 | "." GetIdent<fn>
|
|
|
- 1400 (. IF k = SymTab.KindModule THEN
|
|
|
- 1401 (* qualified L.x: materialize
|
|
|
- 1402 the export, then load it *)
|
|
|
- 1403 IF ~SymTab.MaterializeAlias(n,
|
|
|
- 1404 fn, mal) THEN
|
|
|
- 1405 SemError(201);
|
|
|
- 1406 t := SymTab.InvalidType;
|
|
|
- 1407 QbeGen.CopyOp("0", q)
|
|
|
- 1408 ELSE
|
|
|
- 1409 QbeGen.CopyOp(mal, qn);
|
|
|
- 1410 t := SymTab.SymType(mal);
|
|
|
- 1411 k := SymTab.SymKind(mal);
|
|
|
- 1412 sfx := FALSE;
|
|
|
- 1413 IF k = SymTab.KindProc THEN
|
|
|
- 1414 (* call: ArgList supplies
|
|
|
- 1415 the value *)
|
|
|
- 1416 QbeGen.CopyOp("0", q)
|
|
|
- 1417 ELSIF ~QbeGen.LoadDesignator(
|
|
|
- 1418 mal, t, k, q) THEN
|
|
|
- 1419 SemError(230);
|
|
|
+ 1294 = SymTab.ClSet)
|
|
|
+ 1295 OR (cls
|
|
|
+ 1296 = SymTab.ClRecord)
|
|
|
+ 1297 OR (cls
|
|
|
+ 1298 = SymTab.ClClass) THEN
|
|
|
+ 1299 QbeGen.AddrOf(n, q)
|
|
|
+ 1300 ELSE SemError(230);
|
|
|
+ 1301 QbeGen.CopyOp("0", q)
|
|
|
+ 1302 END
|
|
|
+ 1303 ELSE QbeGen.CopyOp("0", q);
|
|
|
+ 1304 IF k = SymTab.KindImport THEN
|
|
|
+ 1305 SemError(230)
|
|
|
+ 1306 ELSIF k =
|
|
|
+ 1307 SymTab.KindProc THEN
|
|
|
+ 1308 (* bare procedure name:
|
|
|
+ 1309 a following ArgList
|
|
|
+ 1310 makes it a call;
|
|
|
+ 1311 otherwise Fact
|
|
|
+ 1312 reports 230 *)
|
|
|
+ 1313 ELSE
|
|
|
+ 1314 IF k = SymTab.KindField THEN
|
|
|
+ 1315 IF QbeGen.TopWith(qb) THEN
|
|
|
+ 1316 fo :=
|
|
|
+ 1317 SymTab.FieldOffset(
|
|
|
+ 1318 SymTab.FieldOwner(n),
|
|
|
+ 1319 n);
|
|
|
+ 1320 QbeGen.FieldAddr(qb,
|
|
|
+ 1321 fo, q);
|
|
|
+ 1322 sfx := TRUE
|
|
|
+ 1323 ELSE SemError(230);
|
|
|
+ 1324 QbeGen.CopyOp("0", q)
|
|
|
+ 1325 END
|
|
|
+ 1326 END
|
|
|
+ 1327 END
|
|
|
+ 1328 END
|
|
|
+ 1329 END; .)
|
|
|
+ 1330 { "[" Expr<it, iq>
|
|
|
+ 1331 (. IF t = SymTab.InvalidType THEN
|
|
|
+ 1332 ELSIF SymTab.ClassOf(t) #
|
|
|
+ 1333 SymTab.ClArray THEN
|
|
|
+ 1334 SemError(217);
|
|
|
+ 1335 t := SymTab.InvalidType
|
|
|
+ 1336 ELSIF ~SymTab.IsIntFamily(it)
|
|
|
+ 1337 & (SymTab.ClassOf(it) #
|
|
|
+ 1338 SymTab.ClChar) THEN
|
|
|
+ 1339 SemError(218);
|
|
|
+ 1340 t := SymTab.InvalidType
|
|
|
+ 1341 ELSE
|
|
|
+ 1342 QbeGen.WidenIndex(iq, ql);
|
|
|
+ 1343 isOpen :=
|
|
|
+ 1344 SymTab.IsOpenArray(t);
|
|
|
+ 1345 IF isOpen THEN
|
|
|
+ 1346 QbeGen.CopyOp("0", qlo);
|
|
|
+ 1347 QbeGen.OpenHi(q, qhi)
|
|
|
+ 1348 ELSE
|
|
|
+ 1349 lo := SymTab.ArrayLo(t);
|
|
|
+ 1350 hi := SymTab.ArrayHi(t);
|
|
|
+ 1351 QbeGen.IntStr(lo, qlo);
|
|
|
+ 1352 QbeGen.IntStr(hi, qhi)
|
|
|
+ 1353 END;
|
|
|
+ 1354 QbeGen.CheckRange(ql, qlo,
|
|
|
+ 1355 qhi);
|
|
|
+ 1356 eT := SymTab.ArrayElem(t);
|
|
|
+ 1357 QbeGen.ElemAddr(q, ql, qlo,
|
|
|
+ 1358 t, qe);
|
|
|
+ 1359 IF SymTab.ClassOf(eT) =
|
|
|
+ 1360 SymTab.ClArray THEN
|
|
|
+ 1361 QbeGen.ElemLoad(qe, eT, q)
|
|
|
+ 1362 ELSE QbeGen.CopyOp(qe, q)
|
|
|
+ 1363 END;
|
|
|
+ 1364 t := eT; sfx := TRUE
|
|
|
+ 1365 END; .)
|
|
|
+ 1366 { "," Expr<it, iq>
|
|
|
+ 1367 (. IF t = SymTab.InvalidType THEN
|
|
|
+ 1368 ELSIF SymTab.ClassOf(t) #
|
|
|
+ 1369 SymTab.ClArray THEN
|
|
|
+ 1370 SemError(217);
|
|
|
+ 1371 t := SymTab.InvalidType
|
|
|
+ 1372 ELSIF ~SymTab.IsIntFamily(it)
|
|
|
+ 1373 & (SymTab.ClassOf(it) #
|
|
|
+ 1374 SymTab.ClChar) THEN
|
|
|
+ 1375 SemError(218);
|
|
|
+ 1376 t := SymTab.InvalidType
|
|
|
+ 1377 ELSE
|
|
|
+ 1378 QbeGen.WidenIndex(iq, ql);
|
|
|
+ 1379 isOpen :=
|
|
|
+ 1380 SymTab.IsOpenArray(t);
|
|
|
+ 1381 IF isOpen THEN
|
|
|
+ 1382 QbeGen.CopyOp("0", qlo);
|
|
|
+ 1383 QbeGen.OpenHi(q, qhi)
|
|
|
+ 1384 ELSE
|
|
|
+ 1385 lo := SymTab.ArrayLo(t);
|
|
|
+ 1386 hi := SymTab.ArrayHi(t);
|
|
|
+ 1387 QbeGen.IntStr(lo, qlo);
|
|
|
+ 1388 QbeGen.IntStr(hi, qhi)
|
|
|
+ 1389 END;
|
|
|
+ 1390 QbeGen.CheckRange(ql, qlo,
|
|
|
+ 1391 qhi);
|
|
|
+ 1392 eT := SymTab.ArrayElem(t);
|
|
|
+ 1393 QbeGen.ElemAddr(q, ql, qlo,
|
|
|
+ 1394 t, qe);
|
|
|
+ 1395 IF SymTab.ClassOf(eT) =
|
|
|
+ 1396 SymTab.ClArray THEN
|
|
|
+ 1397 QbeGen.ElemLoad(qe, eT, q)
|
|
|
+ 1398 ELSE QbeGen.CopyOp(qe, q)
|
|
|
+ 1399 END;
|
|
|
+ 1400 t := eT; sfx := TRUE
|
|
|
+ 1401 END; .) }
|
|
|
+ 1402 "]"
|
|
|
+ 1403 | "." GetIdent<fn>
|
|
|
+ 1404 (. IF k = SymTab.KindModule THEN
|
|
|
+ 1405 (* qualified L.x: materialize
|
|
|
+ 1406 the export, then load it *)
|
|
|
+ 1407 IF ~SymTab.MaterializeAlias(n,
|
|
|
+ 1408 fn, mal) THEN
|
|
|
+ 1409 SemError(201);
|
|
|
+ 1410 t := SymTab.InvalidType;
|
|
|
+ 1411 QbeGen.CopyOp("0", q)
|
|
|
+ 1412 ELSE
|
|
|
+ 1413 QbeGen.CopyOp(mal, qn);
|
|
|
+ 1414 t := SymTab.SymType(mal);
|
|
|
+ 1415 k := SymTab.SymKind(mal);
|
|
|
+ 1416 sfx := FALSE;
|
|
|
+ 1417 IF k = SymTab.KindProc THEN
|
|
|
+ 1418 (* call: ArgList supplies
|
|
|
+ 1419 the value *)
|
|
|
1420 QbeGen.CopyOp("0", q)
|
|
|
- 1421 END
|
|
|
- 1422 END
|
|
|
- 1423 ELSIF t = SymTab.InvalidType THEN
|
|
|
- 1424 ELSIF (SymTab.ClassOf(t) #
|
|
|
- 1425 SymTab.ClRecord)
|
|
|
- 1426 & (SymTab.ClassOf(t) #
|
|
|
- 1427 SymTab.ClClass) THEN
|
|
|
- 1428 SemError(215);
|
|
|
- 1429 t := SymTab.InvalidType
|
|
|
- 1430 ELSIF ~SymTab.FieldExists(t,
|
|
|
- 1431 fn) THEN
|
|
|
- 1432 SemError(216);
|
|
|
+ 1421 ELSIF ~QbeGen.LoadDesignator(
|
|
|
+ 1422 mal, t, k, q) THEN
|
|
|
+ 1423 SemError(230);
|
|
|
+ 1424 QbeGen.CopyOp("0", q)
|
|
|
+ 1425 END
|
|
|
+ 1426 END
|
|
|
+ 1427 ELSIF t = SymTab.InvalidType THEN
|
|
|
+ 1428 ELSIF (SymTab.ClassOf(t) #
|
|
|
+ 1429 SymTab.ClRecord)
|
|
|
+ 1430 & (SymTab.ClassOf(t) #
|
|
|
+ 1431 SymTab.ClClass) THEN
|
|
|
+ 1432 SemError(215);
|
|
|
1433 t := SymTab.InvalidType
|
|
|
- 1434 ELSE
|
|
|
- 1435 fo := SymTab.FieldOffset(t,
|
|
|
- 1436 fn);
|
|
|
- 1437 t := SymTab.FieldType(t, fn);
|
|
|
- 1438 QbeGen.FieldAddr(q, fo, qe);
|
|
|
- 1439 IF SymTab.ClassOf(t) =
|
|
|
- 1440 SymTab.ClArray THEN
|
|
|
- 1441 QbeGen.ElemLoad(qe, t, q)
|
|
|
- 1442 ELSE QbeGen.CopyOp(qe, q)
|
|
|
- 1443 END;
|
|
|
- 1444 sfx := TRUE
|
|
|
- 1445 END; .)
|
|
|
- 1446 | "^"
|
|
|
- 1447 (. IF t = SymTab.InvalidType THEN
|
|
|
- 1448 ELSIF SymTab.ClassOf(t) #
|
|
|
- 1449 SymTab.ClPtr THEN
|
|
|
- 1450 SemError(219);
|
|
|
- 1451 t := SymTab.InvalidType
|
|
|
- 1452 ELSE
|
|
|
- 1453 bt := SymTab.PtrBase(t);
|
|
|
- 1454 IF bt = SymTab.InvalidType THEN
|
|
|
- 1455 ELSE
|
|
|
- 1456 IF sfx THEN
|
|
|
- 1457 QbeGen.ElemLoad(q, t,
|
|
|
- 1458 qb);
|
|
|
- 1459 QbeGen.CopyOp(qb, q)
|
|
|
- 1460 END;
|
|
|
- 1461 t := bt;
|
|
|
- 1462 IF (SymTab.ClassOf(bt) =
|
|
|
- 1463 SymTab.ClInt)
|
|
|
- 1464 OR (SymTab.ClassOf(bt) =
|
|
|
- 1465 SymTab.ClBool)
|
|
|
- 1466 OR (SymTab.ClassOf(bt) =
|
|
|
- 1467 SymTab.ClChar)
|
|
|
+ 1434 ELSIF ~SymTab.FieldExists(t,
|
|
|
+ 1435 fn) THEN
|
|
|
+ 1436 SemError(216);
|
|
|
+ 1437 t := SymTab.InvalidType
|
|
|
+ 1438 ELSE
|
|
|
+ 1439 fo := SymTab.FieldOffset(t,
|
|
|
+ 1440 fn);
|
|
|
+ 1441 t := SymTab.FieldType(t, fn);
|
|
|
+ 1442 QbeGen.FieldAddr(q, fo, qe);
|
|
|
+ 1443 IF SymTab.ClassOf(t) =
|
|
|
+ 1444 SymTab.ClArray THEN
|
|
|
+ 1445 QbeGen.ElemLoad(qe, t, q)
|
|
|
+ 1446 ELSE QbeGen.CopyOp(qe, q)
|
|
|
+ 1447 END;
|
|
|
+ 1448 sfx := TRUE
|
|
|
+ 1449 END; .)
|
|
|
+ 1450 | "^"
|
|
|
+ 1451 (. IF t = SymTab.InvalidType THEN
|
|
|
+ 1452 ELSIF SymTab.ClassOf(t) #
|
|
|
+ 1453 SymTab.ClPtr THEN
|
|
|
+ 1454 SemError(219);
|
|
|
+ 1455 t := SymTab.InvalidType
|
|
|
+ 1456 ELSE
|
|
|
+ 1457 bt := SymTab.PtrBase(t);
|
|
|
+ 1458 IF bt = SymTab.InvalidType THEN
|
|
|
+ 1459 ELSE
|
|
|
+ 1460 IF sfx THEN
|
|
|
+ 1461 QbeGen.ElemLoad(q, t,
|
|
|
+ 1462 qb);
|
|
|
+ 1463 QbeGen.CopyOp(qb, q)
|
|
|
+ 1464 END;
|
|
|
+ 1465 t := bt;
|
|
|
+ 1466 IF (SymTab.ClassOf(bt) =
|
|
|
+ 1467 SymTab.ClInt)
|
|
|
1468 OR (SymTab.ClassOf(bt) =
|
|
|
- 1469 SymTab.ClReal) THEN
|
|
|
- 1470 sfx := TRUE
|
|
|
- 1471 ELSE sfx := FALSE
|
|
|
- 1472 END
|
|
|
- 1473 END
|
|
|
- 1474 END; .) } .
|
|
|
- 1475 Expr<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
- 1476 (. VAR t2: SymTab.TypeIndex;
|
|
|
- 1477 op: INTEGER;
|
|
|
- 1478 q2, qt, wl: QbeGen.QVal;
|
|
|
- 1479 isR: BOOLEAN; .)
|
|
|
- 1480 = SimExpr<t, q>
|
|
|
- 1481 [ Rel<op> SimExpr<t2, q2>
|
|
|
- 1482 (. IF op = SymTab.OpIn THEN
|
|
|
- 1483 IF SymTab.InCheck(t, t2) THEN
|
|
|
- 1484 IF (t = SymTab.InvalidType)
|
|
|
- 1485 OR (t2 = SymTab.InvalidType) THEN
|
|
|
- 1486 t := SymTab.BoolType(); QbeGen.CopyOp("0", q)
|
|
|
- 1487 ELSE
|
|
|
- 1488 QbeGen.InSet(q, q2, SymTab.SetBaseLo(t2),
|
|
|
- 1489 SymTab.SetCount(t2), qt);
|
|
|
- 1490 t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
|
|
|
- 1491 END
|
|
|
- 1492 ELSE SemError(222); t := SymTab.InvalidType;
|
|
|
- 1493 QbeGen.CopyOp("0", q)
|
|
|
- 1494 END
|
|
|
- 1495 ELSIF SymTab.RelCheck(t, t2, op) THEN
|
|
|
- 1496 IF (t = SymTab.InvalidType)
|
|
|
- 1497 OR (t2 = SymTab.InvalidType) THEN
|
|
|
- 1498 t := SymTab.BoolType(); QbeGen.CopyOp("0", q)
|
|
|
- 1499 ELSIF (SymTab.ClassOf(t) = SymTab.ClPtr)
|
|
|
- 1500 OR (SymTab.ClassOf(t2) = SymTab.ClPtr) THEN
|
|
|
- 1501 IF (op # SymTab.OpEq) & (op # SymTab.OpNeq1)
|
|
|
- 1502 & (op # SymTab.OpNeq2) THEN
|
|
|
- 1503 SemError(213); t := SymTab.InvalidType;
|
|
|
- 1504 QbeGen.CopyOp("0", q)
|
|
|
- 1505 ELSE
|
|
|
- 1506 QbeGen.CmpL(op, q, q2, qt);
|
|
|
- 1507 t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
|
|
|
- 1508 END
|
|
|
- 1509 ELSIF (SymTab.ClassOf(t) = SymTab.ClSet)
|
|
|
- 1510 OR (SymTab.ClassOf(t2) = SymTab.ClSet) THEN
|
|
|
- 1511 QbeGen.CmpSet(op, q, q2,
|
|
|
- 1512 SymTab.SetWords(t), SymTab.SetWords(t2), qt);
|
|
|
- 1513 t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
|
|
|
- 1514 ELSIF SymTab.IsLongFamily(t)
|
|
|
- 1515 OR SymTab.IsLongFamily(t2) THEN
|
|
|
- 1516 IF SymTab.IsIntFamily(t) THEN
|
|
|
- 1517 QbeGen.WidenLong(q, wl); QbeGen.CopyOp(wl, q)
|
|
|
- 1518 END;
|
|
|
- 1519 IF SymTab.IsIntFamily(t2) THEN
|
|
|
- 1520 QbeGen.WidenLong(q2, wl); QbeGen.CopyOp(wl, q2)
|
|
|
- 1521 END;
|
|
|
- 1522 QbeGen.CmpLong(op, q, q2, qt);
|
|
|
- 1523 t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
|
|
|
- 1524 ELSE
|
|
|
- 1525 isR := SymTab.ClassOf(t) = SymTab.ClReal;
|
|
|
- 1526 t := SymTab.BoolType();
|
|
|
- 1527 QbeGen.Cmp(op, q, q2, qt, isR);
|
|
|
- 1528 QbeGen.CopyOp(qt, q)
|
|
|
- 1529 END
|
|
|
- 1530 ELSE SemError(213); t := SymTab.InvalidType;
|
|
|
- 1531 QbeGen.CopyOp("0", q)
|
|
|
- 1532 END; .) ] .
|
|
|
- 1533 Rel<VAR op: INTEGER>
|
|
|
- 1534 = "=" (. op := SymTab.OpEq; .)
|
|
|
- 1535 | "#" (. op := SymTab.OpNeq1; .)
|
|
|
- 1536 | "<" (. op := SymTab.OpLt; .)
|
|
|
- 1537 | "<=" (. op := SymTab.OpLe; .)
|
|
|
- 1538 | ">" (. op := SymTab.OpGt; .)
|
|
|
- 1539 | ">=" (. op := SymTab.OpGe; .)
|
|
|
- 1540 | "IN" (. op := SymTab.OpIn; .) .
|
|
|
- 1541 SimExpr<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
- 1542 (. VAR t2, res2, lt, rt:
|
|
|
- 1543 SymTab.TypeIndex;
|
|
|
- 1544 op: INTEGER;
|
|
|
- 1545 q2, qt, wq: QbeGen.QVal;
|
|
|
- 1546 neg, isR, isL: BOOLEAN;
|
|
|
- 1547 lw, rw, mw: CARDINAL; .)
|
|
|
- 1548 = (. neg := FALSE; .)
|
|
|
- 1549 [ "+" | "-" (. neg := TRUE; .) ]
|
|
|
- 1550 Term<t, q> (. IF neg THEN
|
|
|
- 1551 IF QbeGen.IsImm(q) THEN
|
|
|
- 1552 QbeGen.NegFold(q, q)
|
|
|
- 1553 ELSE QbeGen.NewTemp(qt);
|
|
|
- 1554 QbeGen.NegQ(q, qt,
|
|
|
- 1555 SymTab.ClassOf(t)
|
|
|
- 1556 = SymTab.ClReal);
|
|
|
- 1557 QbeGen.CopyOp(qt, q)
|
|
|
- 1558 END
|
|
|
- 1559 END; .)
|
|
|
- 1560 { AddOp<op> Term<t2, q2>
|
|
|
- 1561 (. IF op = SymTab.OpOr THEN
|
|
|
- 1562 IF SymTab.BoolCheck(t) & SymTab.BoolCheck(t2) THEN
|
|
|
- 1563 t := SymTab.BoolType()
|
|
|
- 1564 ELSE SemError(212); t := SymTab.InvalidType END;
|
|
|
- 1565 IF t # SymTab.InvalidType THEN
|
|
|
- 1566 QbeGen.NewTemp(qt);
|
|
|
- 1567 QbeGen.Op3("or", qt, q, q2, FALSE);
|
|
|
- 1568 QbeGen.CopyOp(qt, q)
|
|
|
- 1569 ELSE QbeGen.CopyOp("0", q)
|
|
|
- 1570 END
|
|
|
- 1571 ELSIF (t # SymTab.InvalidType) & (t2 # SymTab.InvalidType)
|
|
|
- 1572 & (SymTab.ClassOf(t) = SymTab.ClSet)
|
|
|
- 1573 & (SymTab.ClassOf(t2) = SymTab.ClSet) THEN
|
|
|
- 1574 lw := SymTab.SetWords(t); rw := SymTab.SetWords(t2);
|
|
|
- 1575 mw := lw;
|
|
|
- 1576 IF rw > mw THEN mw := rw END;
|
|
|
- 1577 IF op = SymTab.OpAdd THEN
|
|
|
- 1578 QbeGen.SetBinOp(0, q, q2, lw, rw, qt)
|
|
|
- 1579 ELSE
|
|
|
- 1580 QbeGen.SetBinOp(2, q, q2, lw, rw, qt)
|
|
|
- 1581 END;
|
|
|
- 1582 t := SymTab.NewSet(
|
|
|
- 1583 SymTab.NewSubR(0,
|
|
|
- 1584 VAL(INTEGER, mw) * 32 - 1));
|
|
|
- 1585 QbeGen.CopyOp(qt, q)
|
|
|
- 1586 ELSE
|
|
|
- 1587 IF SymTab.ArithCheck(t, t2, FALSE, res2) THEN
|
|
|
- 1588 lt := t; rt := t2; t := res2
|
|
|
- 1589 ELSE SemError(211); t := SymTab.InvalidType END;
|
|
|
- 1590 IF t # SymTab.InvalidType THEN
|
|
|
- 1591 isL := SymTab.IsLongFamily(t);
|
|
|
- 1592 isR := SymTab.ClassOf(t) = SymTab.ClReal;
|
|
|
- 1593 IF isL THEN
|
|
|
- 1594 IF SymTab.IsIntFamily(lt) THEN
|
|
|
- 1595 QbeGen.WidenLong(q, wq); QbeGen.CopyOp(wq, q)
|
|
|
- 1596 END;
|
|
|
- 1597 IF SymTab.IsIntFamily(rt) THEN
|
|
|
- 1598 QbeGen.WidenLong(q2, wq); QbeGen.CopyOp(wq, q2)
|
|
|
- 1599 END;
|
|
|
- 1600 QbeGen.NewTemp(qt);
|
|
|
- 1601 IF op = SymTab.OpAdd THEN
|
|
|
- 1602 QbeGen.Op3L("add", qt, q, q2)
|
|
|
- 1603 ELSE
|
|
|
- 1604 QbeGen.Op3L("sub", qt, q, q2)
|
|
|
- 1605 END
|
|
|
- 1606 ELSE
|
|
|
- 1607 QbeGen.NewTemp(qt);
|
|
|
- 1608 IF op = SymTab.OpAdd THEN
|
|
|
- 1609 QbeGen.Op3("add", qt, q, q2, isR)
|
|
|
- 1610 ELSE
|
|
|
- 1611 QbeGen.Op3("sub", qt, q, q2, isR)
|
|
|
- 1612 END
|
|
|
- 1613 END;
|
|
|
- 1614 QbeGen.CopyOp(qt, q)
|
|
|
- 1615 ELSE QbeGen.CopyOp("0", q)
|
|
|
- 1616 END
|
|
|
- 1617 END; .) } .
|
|
|
- 1618 AddOp<VAR op: INTEGER>
|
|
|
- 1619 = "+" (. op := SymTab.OpAdd; .)
|
|
|
- 1620 | "-" (. op := SymTab.OpSub; .)
|
|
|
- 1621 | "OR" (. op := SymTab.OpOr; .) .
|
|
|
- 1622 Term<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
- 1623 (. VAR t2, res2, lt, rt:
|
|
|
- 1624 SymTab.TypeIndex;
|
|
|
- 1625 op: INTEGER;
|
|
|
- 1626 q2, qt, wq: QbeGen.QVal;
|
|
|
- 1627 isR, isL: BOOLEAN;
|
|
|
- 1628 lw, rw, mw: CARDINAL; .)
|
|
|
- 1629 = Fact<t, q> { MulOp<op> Fact<t2, q2>
|
|
|
- 1630 (. IF op = SymTab.OpAnd THEN
|
|
|
- 1631 IF SymTab.BoolCheck(t) & SymTab.BoolCheck(t2) THEN
|
|
|
- 1632 t := SymTab.BoolType()
|
|
|
- 1633 ELSE SemError(212); t := SymTab.InvalidType END;
|
|
|
- 1634 IF t # SymTab.InvalidType THEN
|
|
|
- 1635 QbeGen.NewTemp(qt);
|
|
|
- 1636 QbeGen.Op3("and", qt, q, q2, FALSE);
|
|
|
- 1637 QbeGen.CopyOp(qt, q)
|
|
|
- 1638 ELSE QbeGen.CopyOp("0", q)
|
|
|
- 1639 END
|
|
|
- 1640 ELSIF (t # SymTab.InvalidType) & (t2 # SymTab.InvalidType)
|
|
|
- 1641 & (SymTab.ClassOf(t) = SymTab.ClSet)
|
|
|
- 1642 & (SymTab.ClassOf(t2) = SymTab.ClSet) THEN
|
|
|
- 1643 lw := SymTab.SetWords(t); rw := SymTab.SetWords(t2);
|
|
|
- 1644 mw := lw;
|
|
|
- 1645 IF rw > mw THEN mw := rw END;
|
|
|
- 1646 IF op = SymTab.OpTimes THEN
|
|
|
- 1647 QbeGen.SetBinOp(1, q, q2, lw, rw, qt)
|
|
|
- 1648 ELSE
|
|
|
- 1649 QbeGen.SetBinOp(3, q, q2, lw, rw, qt)
|
|
|
- 1650 END;
|
|
|
- 1651 t := SymTab.NewSet(
|
|
|
- 1652 SymTab.NewSubR(0,
|
|
|
- 1653 VAL(INTEGER, mw) * 32 - 1));
|
|
|
- 1654 QbeGen.CopyOp(qt, q)
|
|
|
- 1655 ELSE
|
|
|
- 1656 IF SymTab.ArithCheck(t, t2,
|
|
|
- 1657 (op = SymTab.OpDiv) OR (op = SymTab.OpMod),
|
|
|
- 1658 res2) THEN
|
|
|
- 1659 lt := t; rt := t2; t := res2
|
|
|
- 1660 ELSE SemError(211); t := SymTab.InvalidType END;
|
|
|
- 1661 IF t # SymTab.InvalidType THEN
|
|
|
- 1662 isL := SymTab.IsLongFamily(t);
|
|
|
- 1663 isR := SymTab.ClassOf(t) = SymTab.ClReal;
|
|
|
- 1664 IF isL THEN
|
|
|
- 1665 IF SymTab.IsIntFamily(lt) THEN
|
|
|
- 1666 QbeGen.WidenLong(q, wq); QbeGen.CopyOp(wq, q)
|
|
|
- 1667 END;
|
|
|
- 1668 IF SymTab.IsIntFamily(rt) THEN
|
|
|
- 1669 QbeGen.WidenLong(q2, wq); QbeGen.CopyOp(wq, q2)
|
|
|
- 1670 END;
|
|
|
- 1671 QbeGen.NewTemp(qt);
|
|
|
- 1672 IF op = SymTab.OpTimes THEN
|
|
|
- 1673 QbeGen.Op3L("mul", qt, q, q2)
|
|
|
- 1674 ELSIF (op = SymTab.OpDiv)
|
|
|
- 1675 OR (op = SymTab.OpSlash) THEN
|
|
|
- 1676 QbeGen.Op3L("div", qt, q, q2)
|
|
|
- 1677 ELSE
|
|
|
- 1678 QbeGen.Op3L("rem", qt, q, q2)
|
|
|
- 1679 END
|
|
|
- 1680 ELSE
|
|
|
- 1681 QbeGen.NewTemp(qt);
|
|
|
- 1682 IF op = SymTab.OpTimes THEN
|
|
|
- 1683 QbeGen.Op3("mul", qt, q, q2, isR)
|
|
|
- 1684 ELSIF (op = SymTab.OpDiv)
|
|
|
- 1685 OR (op = SymTab.OpSlash) THEN
|
|
|
- 1686 QbeGen.Op3("div", qt, q, q2, isR)
|
|
|
- 1687 ELSE
|
|
|
- 1688 QbeGen.Op3("rem", qt, q, q2, isR)
|
|
|
- 1689 END
|
|
|
- 1690 END;
|
|
|
- 1691 QbeGen.CopyOp(qt, q)
|
|
|
- 1692 ELSE QbeGen.CopyOp("0", q)
|
|
|
- 1693 END
|
|
|
- 1694 END; .) } .
|
|
|
- 1695 MulOp<VAR op: INTEGER>
|
|
|
- 1696 = "*" (. op := SymTab.OpTimes; .)
|
|
|
- 1697 | "/" (. op := SymTab.OpSlash; .)
|
|
|
- 1698 | "DIV" (. op := SymTab.OpDiv; .)
|
|
|
- 1699 | "MOD" (. op := SymTab.OpMod; .)
|
|
|
- 1700 | "AND" (. op := SymTab.OpAnd; .) .
|
|
|
- 1701 Fact<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
- 1702 (. VAR s: ARRAY [0 .. 255] OF CHAR;
|
|
|
- 1703 et, dt, t2, st, ct2:
|
|
|
- 1704 SymTab.TypeIndex;
|
|
|
- 1705 dk: INTEGER;
|
|
|
- 1706 qd, q2, sq, qa, qm0, qr:
|
|
|
- 1707 QbeGen.QVal;
|
|
|
- 1708 qn, vn: SymTab.Name;
|
|
|
- 1709 vt: SymTab.TypeIndex;
|
|
|
- 1710 c1, c2: INTEGER;
|
|
|
- 1711 called, isHigh, sfx:
|
|
|
- 1712 BOOLEAN; .)
|
|
|
- 1713 = integer (. LexString(s);
|
|
|
- 1714 QbeGen.NormInt(s, q);
|
|
|
- 1715 t := SymTab.IntType(); .)
|
|
|
- 1716 | real (. LexString(s);
|
|
|
- 1717 QbeGen.NormReal(s, q);
|
|
|
- 1718 t := SymTab.RealType(); .)
|
|
|
- 1719 | string (. LexString(s);
|
|
|
- 1720 IF SymTab.StrLen(s) = 3 THEN
|
|
|
- 1721 t := SymTab.CharType();
|
|
|
- 1722 QbeGen.IntStr(
|
|
|
- 1723 QbeGen.CharVal(s), q)
|
|
|
- 1724 ELSE t := SymTab.NewStr();
|
|
|
- 1725 QbeGen.DeclStr(s, q);
|
|
|
- 1726 (* a literal's value IS its
|
|
|
- 1727 static descriptor address *)
|
|
|
- 1728 QbeGen.NoteAddr(q, q)
|
|
|
- 1729 END; .)
|
|
|
- 1730 | Design<dt, dk, qd, qn, sfx> (. called := FALSE;
|
|
|
- 1731 t := dt;
|
|
|
- 1732 IF sfx THEN
|
|
|
- 1733 IF dt =
|
|
|
- 1734 SymTab.InvalidType THEN
|
|
|
- 1735 QbeGen.CopyOp("0", q)
|
|
|
- 1736 ELSIF (SymTab.ClassOf(dt) =
|
|
|
- 1737 SymTab.ClRecord)
|
|
|
- 1738 OR (SymTab.ClassOf(dt) =
|
|
|
- 1739 SymTab.ClSet)
|
|
|
- 1740 OR (SymTab.ClassOf(dt) =
|
|
|
- 1741 SymTab.ClClass) THEN
|
|
|
- 1742 QbeGen.CopyOp(qd, q)
|
|
|
- 1743 ELSE QbeGen.ElemLoad(qd, dt,
|
|
|
- 1744 q)
|
|
|
- 1745 END
|
|
|
- 1746 ELSE QbeGen.CopyOp(qd, q)
|
|
|
- 1747 END;
|
|
|
- 1748 IF (dk = SymTab.KindVar)
|
|
|
- 1749 OR (dk = SymTab.KindParam)
|
|
|
- 1750 OR (dk =
|
|
|
- 1751 SymTab.KindField) THEN
|
|
|
- 1752 IF sfx THEN
|
|
|
- 1753 QbeGen.NoteAddr(q, qd)
|
|
|
- 1754 ELSE
|
|
|
- 1755 QbeGen.AddrOf(qn, qa);
|
|
|
- 1756 QbeGen.NoteAddr(q, qa)
|
|
|
- 1757 END
|
|
|
- 1758 ELSIF sfx
|
|
|
- 1759 & (dt #
|
|
|
- 1760 SymTab.InvalidType)
|
|
|
- 1761 & ((SymTab.ClassOf(dt) =
|
|
|
- 1762 SymTab.ClArray)
|
|
|
- 1763 OR (SymTab.ClassOf(dt) =
|
|
|
- 1764 SymTab.ClSet)
|
|
|
- 1765 OR (SymTab.ClassOf(dt) =
|
|
|
- 1766 SymTab.ClRecord)) THEN
|
|
|
- 1767 QbeGen.NoteAddr(qd, qd)
|
|
|
- 1768 END; .)
|
|
|
- 1769 [ ArgList<qn, TRUE, ct2, q2, called>
|
|
|
- 1770 (. t := ct2;
|
|
|
- 1771 QbeGen.CopyOp(q2, q); .) ]
|
|
|
- 1772 (. IF ~called
|
|
|
- 1773 & (dk = SymTab.KindProc) THEN
|
|
|
- 1774 (* bare zero-arg function
|
|
|
- 1775 call (parentheses may be
|
|
|
- 1776 omitted); a proper or
|
|
|
- 1777 parameterised proc here
|
|
|
- 1778 is 230 *)
|
|
|
- 1779 IF (SymTab.ProcNPar(qn) = 0)
|
|
|
- 1780 & (SymTab.ProcRes(qn) #
|
|
|
- 1781 SymTab.InvalidType) THEN
|
|
|
- 1782 QbeGen.Mangled(qn,
|
|
|
- 1783 SymTab.ProcUid(qn), qm0);
|
|
|
- 1784 QbeGen.CallBegin(qm0,
|
|
|
- 1785 SymTab.ProcRes(qn),
|
|
|
- 1786 SymTab.ProcDepthOf(qn),
|
|
|
- 1787 SymTab.IsExternal(qn));
|
|
|
- 1788 QbeGen.CallEnd(TRUE, q);
|
|
|
- 1789 t := SymTab.ProcRes(qn)
|
|
|
- 1790 ELSE SemError(230)
|
|
|
- 1791 END
|
|
|
- 1792 END; .)
|
|
|
- 1793 | ( "HIGH" (. isHigh := TRUE; .)
|
|
|
- 1794 | "LEN" (. isHigh := FALSE; .) )
|
|
|
- 1795 "(" Design<dt, dk, qd, qn, sfx> ")"
|
|
|
- 1796 (. IF dt = SymTab.InvalidType THEN
|
|
|
- 1797 ELSIF SymTab.ClassOf(dt) #
|
|
|
- 1798 SymTab.ClArray THEN
|
|
|
- 1799 SemError(217);
|
|
|
- 1800 t := SymTab.InvalidType;
|
|
|
- 1801 QbeGen.CopyOp("0", q)
|
|
|
- 1802 ELSE
|
|
|
- 1803 IF isHigh THEN
|
|
|
- 1804 IF SymTab.IsOpenArray(dt) THEN
|
|
|
- 1805 QbeGen.OpenHi(qd, qr)
|
|
|
- 1806 ELSE
|
|
|
- 1807 QbeGen.IntStr(
|
|
|
- 1808 SymTab.ArrayHi(dt), qr)
|
|
|
- 1809 END
|
|
|
- 1810 ELSE
|
|
|
- 1811 IF SymTab.IsOpenArray(dt) THEN
|
|
|
- 1812 QbeGen.LoadCount(qd, qr)
|
|
|
- 1813 ELSE
|
|
|
- 1814 QbeGen.IntStr(VAL(
|
|
|
- 1815 INTEGER,
|
|
|
- 1816 SymTab.ArrayLen(dt)),
|
|
|
- 1817 qr)
|
|
|
- 1818 END
|
|
|
- 1819 END;
|
|
|
- 1820 t := SymTab.IntType();
|
|
|
- 1821 QbeGen.CopyOp(qr, q)
|
|
|
- 1822 END; .)
|
|
|
- 1823 | ( "SIZE" | "TSIZE" ) "(" Design<dt, dk, qd, qn, sfx> ")"
|
|
|
- 1824 (. IF dt = SymTab.InvalidType THEN
|
|
|
- 1825 t := SymTab.InvalidType;
|
|
|
- 1826 QbeGen.CopyOp("0", q)
|
|
|
- 1827 ELSE
|
|
|
- 1828 QbeGen.IntStr(VAL(INTEGER,
|
|
|
- 1829 SymTab.ObjectSize(dt)), q);
|
|
|
- 1830 t := SymTab.IntType()
|
|
|
- 1831 END; .)
|
|
|
- 1832 | "ADR" "(" Design<dt, dk, qd, qn, sfx> ")"
|
|
|
- 1833 (. IF dt = SymTab.InvalidType THEN
|
|
|
- 1834 t := SymTab.InvalidType;
|
|
|
- 1835 QbeGen.CopyOp("0", q)
|
|
|
- 1836 ELSE
|
|
|
- 1837 IF sfx THEN
|
|
|
- 1838 QbeGen.CopyOp(qd, q)
|
|
|
- 1839 ELSIF (dk = SymTab.KindVar)
|
|
|
- 1840 OR (dk = SymTab.KindParam) THEN
|
|
|
- 1841 QbeGen.AddrOf(qn, q)
|
|
|
- 1842 ELSE SemError(230);
|
|
|
- 1843 QbeGen.CopyOp("0", q)
|
|
|
- 1844 END;
|
|
|
- 1845 t := SymTab.AddrType()
|
|
|
- 1846 END; .)
|
|
|
- 1847 | "CHR" "(" Expr<et, q> ")"
|
|
|
- 1848 (. IF (et # SymTab.InvalidType)
|
|
|
- 1849 & ~SymTab.IsIntFamily(et) THEN
|
|
|
- 1850 SemError(211) END;
|
|
|
- 1851 t := SymTab.CharType(); .)
|
|
|
- 1852 | "ORD" "(" Expr<et, q> ")"
|
|
|
- 1853 (. IF et # SymTab.InvalidType THEN
|
|
|
- 1854 IF (SymTab.ClassOf(et) #
|
|
|
- 1855 SymTab.ClChar)
|
|
|
- 1856 & (SymTab.ClassOf(et) #
|
|
|
- 1857 SymTab.ClBool)
|
|
|
- 1858 & (SymTab.ClassOf(et) #
|
|
|
- 1859 SymTab.ClEnum)
|
|
|
- 1860 & ~SymTab.IsIntFamily(et) THEN
|
|
|
- 1861 SemError(211) END
|
|
|
- 1862 END;
|
|
|
- 1863 t := SymTab.IntType(); .)
|
|
|
- 1864 | "ABS" "(" Expr<et, q> ")"
|
|
|
- 1865 (. IF (et # SymTab.InvalidType)
|
|
|
- 1866 & ~SymTab.IsIntFamily(et)
|
|
|
- 1867 & (SymTab.ClassOf(et) #
|
|
|
- 1868 SymTab.ClReal) THEN
|
|
|
- 1869 SemError(211)
|
|
|
- 1870 ELSE QbeGen.AbsQ(q, qa,
|
|
|
- 1871 SymTab.ClassOf(et) =
|
|
|
- 1872 SymTab.ClReal)
|
|
|
- 1873 END;
|
|
|
- 1874 t := et; .)
|
|
|
- 1875 | "VAL" "(" GetIdent<vn> "," Expr<et, q> ")"
|
|
|
- 1876 (. IF ~SymTab.Lookup(vn) THEN
|
|
|
- 1877 SemError(201);
|
|
|
- 1878 t := SymTab.InvalidType
|
|
|
- 1879 ELSE vt := SymTab.SymType(vn);
|
|
|
- 1880 IF vt = SymTab.InvalidType THEN
|
|
|
- 1881 t := SymTab.InvalidType
|
|
|
- 1882 ELSIF et =
|
|
|
- 1883 SymTab.InvalidType THEN
|
|
|
- 1884 t := vt
|
|
|
- 1885 ELSE
|
|
|
- 1886 c1 := SymTab.ClassOf(et);
|
|
|
- 1887 c2 := SymTab.ClassOf(vt);
|
|
|
- 1888 IF ((c1 = SymTab.ClInt)
|
|
|
- 1889 OR (c1 =
|
|
|
- 1890 SymTab.ClChar)
|
|
|
- 1891 OR (c1 =
|
|
|
- 1892 SymTab.ClBool)
|
|
|
+ 1469 SymTab.ClBool)
|
|
|
+ 1470 OR (SymTab.ClassOf(bt) =
|
|
|
+ 1471 SymTab.ClChar)
|
|
|
+ 1472 OR (SymTab.ClassOf(bt) =
|
|
|
+ 1473 SymTab.ClReal) THEN
|
|
|
+ 1474 sfx := TRUE
|
|
|
+ 1475 ELSE sfx := FALSE
|
|
|
+ 1476 END
|
|
|
+ 1477 END
|
|
|
+ 1478 END; .) } .
|
|
|
+ 1479 Expr<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
+ 1480 (. VAR t2: SymTab.TypeIndex;
|
|
|
+ 1481 op: INTEGER;
|
|
|
+ 1482 q2, qt, wl: QbeGen.QVal;
|
|
|
+ 1483 isR: BOOLEAN; .)
|
|
|
+ 1484 = SimExpr<t, q>
|
|
|
+ 1485 [ Rel<op> SimExpr<t2, q2>
|
|
|
+ 1486 (. IF op = SymTab.OpIn THEN
|
|
|
+ 1487 IF SymTab.InCheck(t, t2) THEN
|
|
|
+ 1488 IF (t = SymTab.InvalidType)
|
|
|
+ 1489 OR (t2 = SymTab.InvalidType) THEN
|
|
|
+ 1490 t := SymTab.BoolType(); QbeGen.CopyOp("0", q)
|
|
|
+ 1491 ELSE
|
|
|
+ 1492 QbeGen.InSet(q, q2, SymTab.SetBaseLo(t2),
|
|
|
+ 1493 SymTab.SetCount(t2), qt);
|
|
|
+ 1494 t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
|
|
|
+ 1495 END
|
|
|
+ 1496 ELSE SemError(222); t := SymTab.InvalidType;
|
|
|
+ 1497 QbeGen.CopyOp("0", q)
|
|
|
+ 1498 END
|
|
|
+ 1499 ELSIF SymTab.RelCheck(t, t2, op) THEN
|
|
|
+ 1500 IF (t = SymTab.InvalidType)
|
|
|
+ 1501 OR (t2 = SymTab.InvalidType) THEN
|
|
|
+ 1502 t := SymTab.BoolType(); QbeGen.CopyOp("0", q)
|
|
|
+ 1503 ELSIF (SymTab.ClassOf(t) = SymTab.ClPtr)
|
|
|
+ 1504 OR (SymTab.ClassOf(t2) = SymTab.ClPtr) THEN
|
|
|
+ 1505 IF (op # SymTab.OpEq) & (op # SymTab.OpNeq1)
|
|
|
+ 1506 & (op # SymTab.OpNeq2) THEN
|
|
|
+ 1507 SemError(213); t := SymTab.InvalidType;
|
|
|
+ 1508 QbeGen.CopyOp("0", q)
|
|
|
+ 1509 ELSE
|
|
|
+ 1510 QbeGen.CmpL(op, q, q2, qt);
|
|
|
+ 1511 t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
|
|
|
+ 1512 END
|
|
|
+ 1513 ELSIF (SymTab.ClassOf(t) = SymTab.ClSet)
|
|
|
+ 1514 OR (SymTab.ClassOf(t2) = SymTab.ClSet) THEN
|
|
|
+ 1515 QbeGen.CmpSet(op, q, q2,
|
|
|
+ 1516 SymTab.SetWords(t), SymTab.SetWords(t2), qt);
|
|
|
+ 1517 t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
|
|
|
+ 1518 ELSIF SymTab.IsLongFamily(t)
|
|
|
+ 1519 OR SymTab.IsLongFamily(t2) THEN
|
|
|
+ 1520 IF SymTab.IsIntFamily(t) THEN
|
|
|
+ 1521 QbeGen.WidenLong(q, wl); QbeGen.CopyOp(wl, q)
|
|
|
+ 1522 END;
|
|
|
+ 1523 IF SymTab.IsIntFamily(t2) THEN
|
|
|
+ 1524 QbeGen.WidenLong(q2, wl); QbeGen.CopyOp(wl, q2)
|
|
|
+ 1525 END;
|
|
|
+ 1526 QbeGen.CmpLong(op, q, q2, qt);
|
|
|
+ 1527 t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
|
|
|
+ 1528 ELSE
|
|
|
+ 1529 isR := SymTab.ClassOf(t) = SymTab.ClReal;
|
|
|
+ 1530 t := SymTab.BoolType();
|
|
|
+ 1531 QbeGen.Cmp(op, q, q2, qt, isR);
|
|
|
+ 1532 QbeGen.CopyOp(qt, q)
|
|
|
+ 1533 END
|
|
|
+ 1534 ELSE SemError(213); t := SymTab.InvalidType;
|
|
|
+ 1535 QbeGen.CopyOp("0", q)
|
|
|
+ 1536 END; .) ] .
|
|
|
+ 1537 Rel<VAR op: INTEGER>
|
|
|
+ 1538 = "=" (. op := SymTab.OpEq; .)
|
|
|
+ 1539 | "#" (. op := SymTab.OpNeq1; .)
|
|
|
+ 1540 | "<" (. op := SymTab.OpLt; .)
|
|
|
+ 1541 | "<=" (. op := SymTab.OpLe; .)
|
|
|
+ 1542 | ">" (. op := SymTab.OpGt; .)
|
|
|
+ 1543 | ">=" (. op := SymTab.OpGe; .)
|
|
|
+ 1544 | "IN" (. op := SymTab.OpIn; .) .
|
|
|
+ 1545 SimExpr<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
+ 1546 (. VAR t2, res2, lt, rt:
|
|
|
+ 1547 SymTab.TypeIndex;
|
|
|
+ 1548 op: INTEGER;
|
|
|
+ 1549 q2, qt, wq: QbeGen.QVal;
|
|
|
+ 1550 neg, isR, isL: BOOLEAN;
|
|
|
+ 1551 lw, rw, mw: CARDINAL; .)
|
|
|
+ 1552 = (. neg := FALSE; .)
|
|
|
+ 1553 [ "+" | "-" (. neg := TRUE; .) ]
|
|
|
+ 1554 Term<t, q> (. IF neg THEN
|
|
|
+ 1555 IF QbeGen.IsImm(q) THEN
|
|
|
+ 1556 QbeGen.NegFold(q, q)
|
|
|
+ 1557 ELSE QbeGen.NewTemp(qt);
|
|
|
+ 1558 QbeGen.NegQ(q, qt,
|
|
|
+ 1559 SymTab.ClassOf(t)
|
|
|
+ 1560 = SymTab.ClReal);
|
|
|
+ 1561 QbeGen.CopyOp(qt, q)
|
|
|
+ 1562 END
|
|
|
+ 1563 END; .)
|
|
|
+ 1564 { AddOp<op> Term<t2, q2>
|
|
|
+ 1565 (. IF op = SymTab.OpOr THEN
|
|
|
+ 1566 IF SymTab.BoolCheck(t) & SymTab.BoolCheck(t2) THEN
|
|
|
+ 1567 t := SymTab.BoolType()
|
|
|
+ 1568 ELSE SemError(212); t := SymTab.InvalidType END;
|
|
|
+ 1569 IF t # SymTab.InvalidType THEN
|
|
|
+ 1570 QbeGen.NewTemp(qt);
|
|
|
+ 1571 QbeGen.Op3("or", qt, q, q2, FALSE);
|
|
|
+ 1572 QbeGen.CopyOp(qt, q)
|
|
|
+ 1573 ELSE QbeGen.CopyOp("0", q)
|
|
|
+ 1574 END
|
|
|
+ 1575 ELSIF (t # SymTab.InvalidType) & (t2 # SymTab.InvalidType)
|
|
|
+ 1576 & (SymTab.ClassOf(t) = SymTab.ClSet)
|
|
|
+ 1577 & (SymTab.ClassOf(t2) = SymTab.ClSet) THEN
|
|
|
+ 1578 lw := SymTab.SetWords(t); rw := SymTab.SetWords(t2);
|
|
|
+ 1579 mw := lw;
|
|
|
+ 1580 IF rw > mw THEN mw := rw END;
|
|
|
+ 1581 IF op = SymTab.OpAdd THEN
|
|
|
+ 1582 QbeGen.SetBinOp(0, q, q2, lw, rw, qt)
|
|
|
+ 1583 ELSE
|
|
|
+ 1584 QbeGen.SetBinOp(2, q, q2, lw, rw, qt)
|
|
|
+ 1585 END;
|
|
|
+ 1586 t := SymTab.NewSet(
|
|
|
+ 1587 SymTab.NewSubR(0,
|
|
|
+ 1588 VAL(INTEGER, mw) * 32 - 1));
|
|
|
+ 1589 QbeGen.CopyOp(qt, q)
|
|
|
+ 1590 ELSE
|
|
|
+ 1591 IF SymTab.ArithCheck(t, t2, FALSE, res2) THEN
|
|
|
+ 1592 lt := t; rt := t2; t := res2
|
|
|
+ 1593 ELSE SemError(211); t := SymTab.InvalidType END;
|
|
|
+ 1594 IF t # SymTab.InvalidType THEN
|
|
|
+ 1595 isL := SymTab.IsLongFamily(t);
|
|
|
+ 1596 isR := SymTab.ClassOf(t) = SymTab.ClReal;
|
|
|
+ 1597 IF isL THEN
|
|
|
+ 1598 IF SymTab.IsIntFamily(lt) THEN
|
|
|
+ 1599 QbeGen.WidenLong(q, wq); QbeGen.CopyOp(wq, q)
|
|
|
+ 1600 END;
|
|
|
+ 1601 IF SymTab.IsIntFamily(rt) THEN
|
|
|
+ 1602 QbeGen.WidenLong(q2, wq); QbeGen.CopyOp(wq, q2)
|
|
|
+ 1603 END;
|
|
|
+ 1604 QbeGen.NewTemp(qt);
|
|
|
+ 1605 IF op = SymTab.OpAdd THEN
|
|
|
+ 1606 QbeGen.Op3L("add", qt, q, q2)
|
|
|
+ 1607 ELSE
|
|
|
+ 1608 QbeGen.Op3L("sub", qt, q, q2)
|
|
|
+ 1609 END
|
|
|
+ 1610 ELSE
|
|
|
+ 1611 QbeGen.NewTemp(qt);
|
|
|
+ 1612 IF op = SymTab.OpAdd THEN
|
|
|
+ 1613 QbeGen.Op3("add", qt, q, q2, isR)
|
|
|
+ 1614 ELSE
|
|
|
+ 1615 QbeGen.Op3("sub", qt, q, q2, isR)
|
|
|
+ 1616 END
|
|
|
+ 1617 END;
|
|
|
+ 1618 QbeGen.CopyOp(qt, q)
|
|
|
+ 1619 ELSE QbeGen.CopyOp("0", q)
|
|
|
+ 1620 END
|
|
|
+ 1621 END; .) } .
|
|
|
+ 1622 AddOp<VAR op: INTEGER>
|
|
|
+ 1623 = "+" (. op := SymTab.OpAdd; .)
|
|
|
+ 1624 | "-" (. op := SymTab.OpSub; .)
|
|
|
+ 1625 | "OR" (. op := SymTab.OpOr; .) .
|
|
|
+ 1626 Term<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
+ 1627 (. VAR t2, res2, lt, rt:
|
|
|
+ 1628 SymTab.TypeIndex;
|
|
|
+ 1629 op: INTEGER;
|
|
|
+ 1630 q2, qt, wq: QbeGen.QVal;
|
|
|
+ 1631 isR, isL: BOOLEAN;
|
|
|
+ 1632 lw, rw, mw: CARDINAL; .)
|
|
|
+ 1633 = Fact<t, q> { MulOp<op> Fact<t2, q2>
|
|
|
+ 1634 (. IF op = SymTab.OpAnd THEN
|
|
|
+ 1635 IF SymTab.BoolCheck(t) & SymTab.BoolCheck(t2) THEN
|
|
|
+ 1636 t := SymTab.BoolType()
|
|
|
+ 1637 ELSE SemError(212); t := SymTab.InvalidType END;
|
|
|
+ 1638 IF t # SymTab.InvalidType THEN
|
|
|
+ 1639 QbeGen.NewTemp(qt);
|
|
|
+ 1640 QbeGen.Op3("and", qt, q, q2, FALSE);
|
|
|
+ 1641 QbeGen.CopyOp(qt, q)
|
|
|
+ 1642 ELSE QbeGen.CopyOp("0", q)
|
|
|
+ 1643 END
|
|
|
+ 1644 ELSIF (t # SymTab.InvalidType) & (t2 # SymTab.InvalidType)
|
|
|
+ 1645 & (SymTab.ClassOf(t) = SymTab.ClSet)
|
|
|
+ 1646 & (SymTab.ClassOf(t2) = SymTab.ClSet) THEN
|
|
|
+ 1647 lw := SymTab.SetWords(t); rw := SymTab.SetWords(t2);
|
|
|
+ 1648 mw := lw;
|
|
|
+ 1649 IF rw > mw THEN mw := rw END;
|
|
|
+ 1650 IF op = SymTab.OpTimes THEN
|
|
|
+ 1651 QbeGen.SetBinOp(1, q, q2, lw, rw, qt)
|
|
|
+ 1652 ELSE
|
|
|
+ 1653 QbeGen.SetBinOp(3, q, q2, lw, rw, qt)
|
|
|
+ 1654 END;
|
|
|
+ 1655 t := SymTab.NewSet(
|
|
|
+ 1656 SymTab.NewSubR(0,
|
|
|
+ 1657 VAL(INTEGER, mw) * 32 - 1));
|
|
|
+ 1658 QbeGen.CopyOp(qt, q)
|
|
|
+ 1659 ELSE
|
|
|
+ 1660 IF SymTab.ArithCheck(t, t2,
|
|
|
+ 1661 (op = SymTab.OpDiv) OR (op = SymTab.OpMod),
|
|
|
+ 1662 res2) THEN
|
|
|
+ 1663 lt := t; rt := t2; t := res2
|
|
|
+ 1664 ELSE SemError(211); t := SymTab.InvalidType END;
|
|
|
+ 1665 IF t # SymTab.InvalidType THEN
|
|
|
+ 1666 isL := SymTab.IsLongFamily(t);
|
|
|
+ 1667 isR := SymTab.ClassOf(t) = SymTab.ClReal;
|
|
|
+ 1668 IF isL THEN
|
|
|
+ 1669 IF SymTab.IsIntFamily(lt) THEN
|
|
|
+ 1670 QbeGen.WidenLong(q, wq); QbeGen.CopyOp(wq, q)
|
|
|
+ 1671 END;
|
|
|
+ 1672 IF SymTab.IsIntFamily(rt) THEN
|
|
|
+ 1673 QbeGen.WidenLong(q2, wq); QbeGen.CopyOp(wq, q2)
|
|
|
+ 1674 END;
|
|
|
+ 1675 QbeGen.NewTemp(qt);
|
|
|
+ 1676 IF op = SymTab.OpTimes THEN
|
|
|
+ 1677 QbeGen.Op3L("mul", qt, q, q2)
|
|
|
+ 1678 ELSIF (op = SymTab.OpDiv)
|
|
|
+ 1679 OR (op = SymTab.OpSlash) THEN
|
|
|
+ 1680 QbeGen.Op3L("div", qt, q, q2)
|
|
|
+ 1681 ELSE
|
|
|
+ 1682 QbeGen.Op3L("rem", qt, q, q2)
|
|
|
+ 1683 END
|
|
|
+ 1684 ELSE
|
|
|
+ 1685 QbeGen.NewTemp(qt);
|
|
|
+ 1686 IF op = SymTab.OpTimes THEN
|
|
|
+ 1687 QbeGen.Op3("mul", qt, q, q2, isR)
|
|
|
+ 1688 ELSIF (op = SymTab.OpDiv)
|
|
|
+ 1689 OR (op = SymTab.OpSlash) THEN
|
|
|
+ 1690 QbeGen.Op3("div", qt, q, q2, isR)
|
|
|
+ 1691 ELSE
|
|
|
+ 1692 QbeGen.Op3("rem", qt, q, q2, isR)
|
|
|
+ 1693 END
|
|
|
+ 1694 END;
|
|
|
+ 1695 QbeGen.CopyOp(qt, q)
|
|
|
+ 1696 ELSE QbeGen.CopyOp("0", q)
|
|
|
+ 1697 END
|
|
|
+ 1698 END; .) } .
|
|
|
+ 1699 MulOp<VAR op: INTEGER>
|
|
|
+ 1700 = "*" (. op := SymTab.OpTimes; .)
|
|
|
+ 1701 | "/" (. op := SymTab.OpSlash; .)
|
|
|
+ 1702 | "DIV" (. op := SymTab.OpDiv; .)
|
|
|
+ 1703 | "MOD" (. op := SymTab.OpMod; .)
|
|
|
+ 1704 | "AND" (. op := SymTab.OpAnd; .) .
|
|
|
+ 1705 Fact<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
+ 1706 (. VAR s: ARRAY [0 .. 255] OF CHAR;
|
|
|
+ 1707 et, dt, t2, st, ct2:
|
|
|
+ 1708 SymTab.TypeIndex;
|
|
|
+ 1709 dk: INTEGER;
|
|
|
+ 1710 qd, q2, sq, qa, qm0, qr:
|
|
|
+ 1711 QbeGen.QVal;
|
|
|
+ 1712 qn, vn: SymTab.Name;
|
|
|
+ 1713 vt: SymTab.TypeIndex;
|
|
|
+ 1714 c1, c2: INTEGER;
|
|
|
+ 1715 called, isHigh, sfx:
|
|
|
+ 1716 BOOLEAN; .)
|
|
|
+ 1717 = integer (. LexString(s);
|
|
|
+ 1718 QbeGen.NormInt(s, q);
|
|
|
+ 1719 t := SymTab.IntType(); .)
|
|
|
+ 1720 | real (. LexString(s);
|
|
|
+ 1721 QbeGen.NormReal(s, q);
|
|
|
+ 1722 t := SymTab.RealType(); .)
|
|
|
+ 1723 | string (. LexString(s);
|
|
|
+ 1724 IF SymTab.StrLen(s) = 3 THEN
|
|
|
+ 1725 t := SymTab.CharType();
|
|
|
+ 1726 QbeGen.IntStr(
|
|
|
+ 1727 QbeGen.CharVal(s), q)
|
|
|
+ 1728 ELSE t := SymTab.NewStr();
|
|
|
+ 1729 QbeGen.DeclStr(s, q);
|
|
|
+ 1730 (* a literal's value IS its
|
|
|
+ 1731 static descriptor address *)
|
|
|
+ 1732 QbeGen.NoteAddr(q, q)
|
|
|
+ 1733 END; .)
|
|
|
+ 1734 | Design<dt, dk, qd, qn, sfx> (. called := FALSE;
|
|
|
+ 1735 t := dt;
|
|
|
+ 1736 IF sfx THEN
|
|
|
+ 1737 IF dt =
|
|
|
+ 1738 SymTab.InvalidType THEN
|
|
|
+ 1739 QbeGen.CopyOp("0", q)
|
|
|
+ 1740 ELSIF (SymTab.ClassOf(dt) =
|
|
|
+ 1741 SymTab.ClRecord)
|
|
|
+ 1742 OR (SymTab.ClassOf(dt) =
|
|
|
+ 1743 SymTab.ClSet)
|
|
|
+ 1744 OR (SymTab.ClassOf(dt) =
|
|
|
+ 1745 SymTab.ClClass) THEN
|
|
|
+ 1746 QbeGen.CopyOp(qd, q)
|
|
|
+ 1747 ELSE QbeGen.ElemLoad(qd, dt,
|
|
|
+ 1748 q)
|
|
|
+ 1749 END
|
|
|
+ 1750 ELSE QbeGen.CopyOp(qd, q)
|
|
|
+ 1751 END;
|
|
|
+ 1752 IF (dk = SymTab.KindVar)
|
|
|
+ 1753 OR (dk = SymTab.KindParam)
|
|
|
+ 1754 OR (dk =
|
|
|
+ 1755 SymTab.KindField) THEN
|
|
|
+ 1756 IF sfx THEN
|
|
|
+ 1757 QbeGen.NoteAddr(q, qd)
|
|
|
+ 1758 ELSE
|
|
|
+ 1759 QbeGen.AddrOf(qn, qa);
|
|
|
+ 1760 QbeGen.NoteAddr(q, qa)
|
|
|
+ 1761 END
|
|
|
+ 1762 ELSIF sfx
|
|
|
+ 1763 & (dt #
|
|
|
+ 1764 SymTab.InvalidType)
|
|
|
+ 1765 & ((SymTab.ClassOf(dt) =
|
|
|
+ 1766 SymTab.ClArray)
|
|
|
+ 1767 OR (SymTab.ClassOf(dt) =
|
|
|
+ 1768 SymTab.ClSet)
|
|
|
+ 1769 OR (SymTab.ClassOf(dt) =
|
|
|
+ 1770 SymTab.ClRecord)) THEN
|
|
|
+ 1771 QbeGen.NoteAddr(qd, qd)
|
|
|
+ 1772 END; .)
|
|
|
+ 1773 [ ArgList<qn, TRUE, ct2, q2, called>
|
|
|
+ 1774 (. t := ct2;
|
|
|
+ 1775 QbeGen.CopyOp(q2, q); .) ]
|
|
|
+ 1776 (. IF ~called
|
|
|
+ 1777 & (dk = SymTab.KindProc) THEN
|
|
|
+ 1778 (* bare zero-arg function
|
|
|
+ 1779 call (parentheses may be
|
|
|
+ 1780 omitted); a proper or
|
|
|
+ 1781 parameterised proc here
|
|
|
+ 1782 is 230 *)
|
|
|
+ 1783 IF (SymTab.ProcNPar(qn) = 0)
|
|
|
+ 1784 & (SymTab.ProcRes(qn) #
|
|
|
+ 1785 SymTab.InvalidType) THEN
|
|
|
+ 1786 QbeGen.Mangled(qn,
|
|
|
+ 1787 SymTab.ProcUid(qn), qm0);
|
|
|
+ 1788 QbeGen.CallBegin(qm0,
|
|
|
+ 1789 SymTab.ProcRes(qn),
|
|
|
+ 1790 SymTab.ProcDepthOf(qn),
|
|
|
+ 1791 SymTab.IsExternal(qn));
|
|
|
+ 1792 QbeGen.CallEnd(TRUE, q);
|
|
|
+ 1793 t := SymTab.ProcRes(qn)
|
|
|
+ 1794 ELSE SemError(230)
|
|
|
+ 1795 END
|
|
|
+ 1796 END; .)
|
|
|
+ 1797 | ( "HIGH" (. isHigh := TRUE; .)
|
|
|
+ 1798 | "LEN" (. isHigh := FALSE; .) )
|
|
|
+ 1799 "(" Design<dt, dk, qd, qn, sfx> ")"
|
|
|
+ 1800 (. IF dt = SymTab.InvalidType THEN
|
|
|
+ 1801 ELSIF SymTab.ClassOf(dt) #
|
|
|
+ 1802 SymTab.ClArray THEN
|
|
|
+ 1803 SemError(217);
|
|
|
+ 1804 t := SymTab.InvalidType;
|
|
|
+ 1805 QbeGen.CopyOp("0", q)
|
|
|
+ 1806 ELSE
|
|
|
+ 1807 IF isHigh THEN
|
|
|
+ 1808 IF SymTab.IsOpenArray(dt) THEN
|
|
|
+ 1809 QbeGen.OpenHi(qd, qr)
|
|
|
+ 1810 ELSE
|
|
|
+ 1811 QbeGen.IntStr(
|
|
|
+ 1812 SymTab.ArrayHi(dt), qr)
|
|
|
+ 1813 END
|
|
|
+ 1814 ELSE
|
|
|
+ 1815 IF SymTab.IsOpenArray(dt) THEN
|
|
|
+ 1816 QbeGen.LoadCount(qd, qr)
|
|
|
+ 1817 ELSE
|
|
|
+ 1818 QbeGen.IntStr(VAL(
|
|
|
+ 1819 INTEGER,
|
|
|
+ 1820 SymTab.ArrayLen(dt)),
|
|
|
+ 1821 qr)
|
|
|
+ 1822 END
|
|
|
+ 1823 END;
|
|
|
+ 1824 t := SymTab.IntType();
|
|
|
+ 1825 QbeGen.CopyOp(qr, q)
|
|
|
+ 1826 END; .)
|
|
|
+ 1827 | ( "SIZE" | "TSIZE" ) "(" Design<dt, dk, qd, qn, sfx> ")"
|
|
|
+ 1828 (. IF dt = SymTab.InvalidType THEN
|
|
|
+ 1829 t := SymTab.InvalidType;
|
|
|
+ 1830 QbeGen.CopyOp("0", q)
|
|
|
+ 1831 ELSE
|
|
|
+ 1832 QbeGen.IntStr(VAL(INTEGER,
|
|
|
+ 1833 SymTab.ObjectSize(dt)), q);
|
|
|
+ 1834 t := SymTab.IntType()
|
|
|
+ 1835 END; .)
|
|
|
+ 1836 | "ADR" "(" Design<dt, dk, qd, qn, sfx> ")"
|
|
|
+ 1837 (. IF dt = SymTab.InvalidType THEN
|
|
|
+ 1838 t := SymTab.InvalidType;
|
|
|
+ 1839 QbeGen.CopyOp("0", q)
|
|
|
+ 1840 ELSE
|
|
|
+ 1841 IF sfx THEN
|
|
|
+ 1842 QbeGen.CopyOp(qd, q)
|
|
|
+ 1843 ELSIF (dk = SymTab.KindVar)
|
|
|
+ 1844 OR (dk = SymTab.KindParam) THEN
|
|
|
+ 1845 QbeGen.AddrOf(qn, q)
|
|
|
+ 1846 ELSE SemError(230);
|
|
|
+ 1847 QbeGen.CopyOp("0", q)
|
|
|
+ 1848 END;
|
|
|
+ 1849 t := SymTab.AddrType()
|
|
|
+ 1850 END; .)
|
|
|
+ 1851 | "CHR" "(" Expr<et, q> ")"
|
|
|
+ 1852 (. IF (et # SymTab.InvalidType)
|
|
|
+ 1853 & ~SymTab.IsIntFamily(et) THEN
|
|
|
+ 1854 SemError(211) END;
|
|
|
+ 1855 t := SymTab.CharType(); .)
|
|
|
+ 1856 | "ORD" "(" Expr<et, q> ")"
|
|
|
+ 1857 (. IF et # SymTab.InvalidType THEN
|
|
|
+ 1858 IF (SymTab.ClassOf(et) #
|
|
|
+ 1859 SymTab.ClChar)
|
|
|
+ 1860 & (SymTab.ClassOf(et) #
|
|
|
+ 1861 SymTab.ClBool)
|
|
|
+ 1862 & (SymTab.ClassOf(et) #
|
|
|
+ 1863 SymTab.ClEnum)
|
|
|
+ 1864 & ~SymTab.IsIntFamily(et) THEN
|
|
|
+ 1865 SemError(211) END
|
|
|
+ 1866 END;
|
|
|
+ 1867 t := SymTab.IntType(); .)
|
|
|
+ 1868 | "ABS" "(" Expr<et, q> ")"
|
|
|
+ 1869 (. IF (et # SymTab.InvalidType)
|
|
|
+ 1870 & ~SymTab.IsIntFamily(et)
|
|
|
+ 1871 & (SymTab.ClassOf(et) #
|
|
|
+ 1872 SymTab.ClReal) THEN
|
|
|
+ 1873 SemError(211)
|
|
|
+ 1874 ELSE QbeGen.AbsQ(q, qa,
|
|
|
+ 1875 SymTab.ClassOf(et) =
|
|
|
+ 1876 SymTab.ClReal)
|
|
|
+ 1877 END;
|
|
|
+ 1878 t := et; .)
|
|
|
+ 1879 | "VAL" "(" GetIdent<vn> "," Expr<et, q> ")"
|
|
|
+ 1880 (. IF ~SymTab.Lookup(vn) THEN
|
|
|
+ 1881 SemError(201);
|
|
|
+ 1882 t := SymTab.InvalidType
|
|
|
+ 1883 ELSE vt := SymTab.SymType(vn);
|
|
|
+ 1884 IF vt = SymTab.InvalidType THEN
|
|
|
+ 1885 t := SymTab.InvalidType
|
|
|
+ 1886 ELSIF et =
|
|
|
+ 1887 SymTab.InvalidType THEN
|
|
|
+ 1888 t := vt
|
|
|
+ 1889 ELSE
|
|
|
+ 1890 c1 := SymTab.ClassOf(et);
|
|
|
+ 1891 c2 := SymTab.ClassOf(vt);
|
|
|
+ 1892 IF ((c1 = SymTab.ClInt)
|
|
|
1893 OR (c1 =
|
|
|
- 1894 SymTab.ClEnum))
|
|
|
- 1895 & ((c2 = SymTab.ClInt)
|
|
|
- 1896 OR (c2 =
|
|
|
- 1897 SymTab.ClChar)
|
|
|
- 1898 OR (c2 =
|
|
|
- 1899 SymTab.ClBool)
|
|
|
+ 1894 SymTab.ClChar)
|
|
|
+ 1895 OR (c1 =
|
|
|
+ 1896 SymTab.ClBool)
|
|
|
+ 1897 OR (c1 =
|
|
|
+ 1898 SymTab.ClEnum))
|
|
|
+ 1899 & ((c2 = SymTab.ClInt)
|
|
|
1900 OR (c2 =
|
|
|
- 1901 SymTab.ClEnum)) THEN
|
|
|
- 1902 t := vt
|
|
|
- 1903 ELSIF (c1 = SymTab.ClPtr)
|
|
|
- 1904 & (c2 = SymTab.ClPtr) THEN
|
|
|
- 1905 t := vt
|
|
|
- 1906 ELSIF (c1 = SymTab.ClReal)
|
|
|
- 1907 & (c2 = SymTab.ClReal) THEN
|
|
|
- 1908 t := vt
|
|
|
- 1909 ELSE SemError(230);
|
|
|
- 1910 t := SymTab.InvalidType
|
|
|
- 1911 END
|
|
|
- 1912 END
|
|
|
- 1913 END; .)
|
|
|
- 1914 | "(" Expr<et, q> ")" (. t := et; .)
|
|
|
- 1915 | SetLit<st, sq> (. t := st;
|
|
|
- 1916 QbeGen.CopyOp(sq, q); .)
|
|
|
- 1917 | "NOT" Fact<t2, q2> (. IF SymTab.BoolCheck(t2) THEN
|
|
|
- 1918 t := SymTab.BoolType()
|
|
|
- 1919 ELSE SemError(212);
|
|
|
- 1920 t := SymTab.InvalidType END;
|
|
|
- 1921 IF t # SymTab.InvalidType THEN
|
|
|
- 1922 QbeGen.NotQ(q2, q)
|
|
|
- 1923 ELSE QbeGen.CopyOp("0", q)
|
|
|
- 1924 END; .) .
|
|
|
- 1925 (* Set literals are SET OF [0..255] (8 words); elements validated
|
|
|
- 1926 0..255 statically when foldable (222 otherwise), runtime trap
|
|
|
- 1927 for computed elements. Ranges always lower via SetRange. *)
|
|
|
- 1928 SetLit<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
- 1929 = "{" (. t := SymTab.NewSet(
|
|
|
- 1930 SymTab.NewSubR(0, 255));
|
|
|
- 1931 QbeGen.NewSetTemp(8, q);
|
|
|
- 1932 QbeGen.SetZero(q, 8); .)
|
|
|
- 1933 [ SetElem<t, q> { "," SetElem<t, q> } ]
|
|
|
- 1934 "}" .
|
|
|
- 1935 SetElem<st: SymTab.TypeIndex; sq: QbeGen.QVal> (. VAR et, et2: SymTab.TypeIndex;
|
|
|
- 1936 qe, q2: QbeGen.QVal;
|
|
|
- 1937 v, v2: INTEGER;
|
|
|
- 1938 lo: INTEGER;
|
|
|
- 1939 span: CARDINAL;
|
|
|
- 1940 cl, cl2: INTEGER;
|
|
|
- 1941 hasR: BOOLEAN; .)
|
|
|
- 1942 = (. hasR := FALSE; .)
|
|
|
- 1943 Expr<et, qe>
|
|
|
- 1944 [ ".." Expr<et2, q2> (. hasR := TRUE; .) ]
|
|
|
- 1945 (. lo := SymTab.SetBaseLo(st);
|
|
|
- 1946 span := SymTab.SetCount(st);
|
|
|
- 1947 IF (et = SymTab.InvalidType)
|
|
|
- 1948 OR (hasR & (et2 =
|
|
|
- 1949 SymTab.InvalidType)) THEN
|
|
|
- 1950 ELSE cl :=
|
|
|
- 1951 SymTab.ClassOf(et);
|
|
|
- 1952 IF hasR THEN
|
|
|
- 1953 cl2 :=
|
|
|
- 1954 SymTab.ClassOf(et2)
|
|
|
- 1955 ELSE cl2 := SymTab.ClInt
|
|
|
- 1956 END;
|
|
|
- 1957 IF ((cl # SymTab.ClInt)
|
|
|
- 1958 & (cl # SymTab.ClChar)
|
|
|
- 1959 & (cl # SymTab.ClBool))
|
|
|
- 1960 OR (hasR &
|
|
|
- 1961 ((cl2
|
|
|
- 1962 # SymTab.ClInt)
|
|
|
- 1963 & (cl2
|
|
|
- 1964 # SymTab.ClChar)
|
|
|
- 1965 & (cl2
|
|
|
- 1966 # SymTab.ClBool))) THEN
|
|
|
- 1967 SemError(222)
|
|
|
- 1968 ELSIF hasR
|
|
|
- 1969 & SymTab.ConstInt(qe, v)
|
|
|
- 1970 & SymTab.ConstInt(q2,
|
|
|
- 1971 v2)
|
|
|
- 1972 & ((v < lo)
|
|
|
- 1973 OR (v2 < lo)
|
|
|
- 1974 OR (v >= lo +
|
|
|
- 1975 VAL(INTEGER, span))
|
|
|
- 1976 OR (v2 >= lo +
|
|
|
- 1977 VAL(INTEGER, span))
|
|
|
- 1978 OR (v > v2)) THEN
|
|
|
- 1979 SemError(222)
|
|
|
- 1980 ELSIF hasR THEN
|
|
|
- 1981 QbeGen.SetRange(sq, qe, q2,
|
|
|
- 1982 lo, span)
|
|
|
- 1983 ELSIF SymTab.ConstInt(qe,
|
|
|
- 1984 v)
|
|
|
- 1985 & ((v < lo)
|
|
|
- 1986 OR (v >= lo +
|
|
|
- 1987 VAL(INTEGER,
|
|
|
- 1988 span))) THEN
|
|
|
- 1989 SemError(222)
|
|
|
- 1990 ELSE QbeGen.SetBit(sq, qe,
|
|
|
- 1991 lo, span)
|
|
|
- 1992 END
|
|
|
- 1993 END; .) .
|
|
|
- 1994 GetIdent<VAR n: SymTab.Name>
|
|
|
- 1995 = ident (. LexName(n); .) .
|
|
|
- 1996
|
|
|
- 1997 END M2.
|
|
|
+ 1901 SymTab.ClChar)
|
|
|
+ 1902 OR (c2 =
|
|
|
+ 1903 SymTab.ClBool)
|
|
|
+ 1904 OR (c2 =
|
|
|
+ 1905 SymTab.ClEnum)) THEN
|
|
|
+ 1906 t := vt
|
|
|
+ 1907 ELSIF (c1 = SymTab.ClPtr)
|
|
|
+ 1908 & (c2 = SymTab.ClPtr) THEN
|
|
|
+ 1909 t := vt
|
|
|
+ 1910 ELSIF (c1 = SymTab.ClReal)
|
|
|
+ 1911 & (c2 = SymTab.ClReal) THEN
|
|
|
+ 1912 t := vt
|
|
|
+ 1913 ELSE SemError(230);
|
|
|
+ 1914 t := SymTab.InvalidType
|
|
|
+ 1915 END
|
|
|
+ 1916 END
|
|
|
+ 1917 END; .)
|
|
|
+ 1918 | "(" Expr<et, q> ")" (. t := et; .)
|
|
|
+ 1919 | SetLit<st, sq> (. t := st;
|
|
|
+ 1920 QbeGen.CopyOp(sq, q); .)
|
|
|
+ 1921 | "NOT" Fact<t2, q2> (. IF SymTab.BoolCheck(t2) THEN
|
|
|
+ 1922 t := SymTab.BoolType()
|
|
|
+ 1923 ELSE SemError(212);
|
|
|
+ 1924 t := SymTab.InvalidType END;
|
|
|
+ 1925 IF t # SymTab.InvalidType THEN
|
|
|
+ 1926 QbeGen.NotQ(q2, q)
|
|
|
+ 1927 ELSE QbeGen.CopyOp("0", q)
|
|
|
+ 1928 END; .) .
|
|
|
+ 1929 (* Set literals are SET OF [0..255] (8 words); elements validated
|
|
|
+ 1930 0..255 statically when foldable (222 otherwise), runtime trap
|
|
|
+ 1931 for computed elements. Ranges always lower via SetRange. *)
|
|
|
+ 1932 SetLit<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
+ 1933 = "{" (. t := SymTab.NewSet(
|
|
|
+ 1934 SymTab.NewSubR(0, 255));
|
|
|
+ 1935 QbeGen.NewSetTemp(8, q);
|
|
|
+ 1936 QbeGen.SetZero(q, 8); .)
|
|
|
+ 1937 [ SetElem<t, q> { "," SetElem<t, q> } ]
|
|
|
+ 1938 "}" .
|
|
|
+ 1939 SetElem<st: SymTab.TypeIndex; sq: QbeGen.QVal> (. VAR et, et2: SymTab.TypeIndex;
|
|
|
+ 1940 qe, q2: QbeGen.QVal;
|
|
|
+ 1941 v, v2: INTEGER;
|
|
|
+ 1942 lo: INTEGER;
|
|
|
+ 1943 span: CARDINAL;
|
|
|
+ 1944 cl, cl2: INTEGER;
|
|
|
+ 1945 hasR: BOOLEAN; .)
|
|
|
+ 1946 = (. hasR := FALSE; .)
|
|
|
+ 1947 Expr<et, qe>
|
|
|
+ 1948 [ ".." Expr<et2, q2> (. hasR := TRUE; .) ]
|
|
|
+ 1949 (. lo := SymTab.SetBaseLo(st);
|
|
|
+ 1950 span := SymTab.SetCount(st);
|
|
|
+ 1951 IF (et = SymTab.InvalidType)
|
|
|
+ 1952 OR (hasR & (et2 =
|
|
|
+ 1953 SymTab.InvalidType)) THEN
|
|
|
+ 1954 ELSE cl :=
|
|
|
+ 1955 SymTab.ClassOf(et);
|
|
|
+ 1956 IF hasR THEN
|
|
|
+ 1957 cl2 :=
|
|
|
+ 1958 SymTab.ClassOf(et2)
|
|
|
+ 1959 ELSE cl2 := SymTab.ClInt
|
|
|
+ 1960 END;
|
|
|
+ 1961 IF ((cl # SymTab.ClInt)
|
|
|
+ 1962 & (cl # SymTab.ClChar)
|
|
|
+ 1963 & (cl # SymTab.ClBool))
|
|
|
+ 1964 OR (hasR &
|
|
|
+ 1965 ((cl2
|
|
|
+ 1966 # SymTab.ClInt)
|
|
|
+ 1967 & (cl2
|
|
|
+ 1968 # SymTab.ClChar)
|
|
|
+ 1969 & (cl2
|
|
|
+ 1970 # SymTab.ClBool))) THEN
|
|
|
+ 1971 SemError(222)
|
|
|
+ 1972 ELSIF hasR
|
|
|
+ 1973 & SymTab.ConstInt(qe, v)
|
|
|
+ 1974 & SymTab.ConstInt(q2,
|
|
|
+ 1975 v2)
|
|
|
+ 1976 & ((v < lo)
|
|
|
+ 1977 OR (v2 < lo)
|
|
|
+ 1978 OR (v >= lo +
|
|
|
+ 1979 VAL(INTEGER, span))
|
|
|
+ 1980 OR (v2 >= lo +
|
|
|
+ 1981 VAL(INTEGER, span))
|
|
|
+ 1982 OR (v > v2)) THEN
|
|
|
+ 1983 SemError(222)
|
|
|
+ 1984 ELSIF hasR THEN
|
|
|
+ 1985 QbeGen.SetRange(sq, qe, q2,
|
|
|
+ 1986 lo, span)
|
|
|
+ 1987 ELSIF SymTab.ConstInt(qe,
|
|
|
+ 1988 v)
|
|
|
+ 1989 & ((v < lo)
|
|
|
+ 1990 OR (v >= lo +
|
|
|
+ 1991 VAL(INTEGER,
|
|
|
+ 1992 span))) THEN
|
|
|
+ 1993 SemError(222)
|
|
|
+ 1994 ELSE QbeGen.SetBit(sq, qe,
|
|
|
+ 1995 lo, span)
|
|
|
+ 1996 END
|
|
|
+ 1997 END; .) .
|
|
|
+ 1998 GetIdent<VAR n: SymTab.Name>
|
|
|
+ 1999 = ident (. LexName(n); .) .
|
|
|
+ 2000
|
|
|
+ 2001 END M2.
|
|
|
|
|
|
0 errors
|
|
|
|