|
|
@@ -1648,1949 +1648,1842 @@ Listing:
|
|
|
1630 isMeth := methCls #
|
|
|
1631 SymTab.InvalidType;
|
|
|
1632 IF isMeth THEN
|
|
|
- 1633 (* class method: the
|
|
|
- 1634 receiver is armed.
|
|
|
- 1635 Virtual -> dispatch
|
|
|
- 1636 through the vtable;
|
|
|
- 1637 otherwise a static
|
|
|
- 1638 call. *)
|
|
|
- 1639 res := SymTab.ClassMethodRes(
|
|
|
- 1640 methCls, pn);
|
|
|
- 1641 vs := SymTab.VirtSlot(
|
|
|
- 1642 methCls, pn);
|
|
|
- 1643 IF vs >= 0 THEN
|
|
|
- 1644 QbeGen.VirtCallBegin(
|
|
|
- 1645 callee, vs, res)
|
|
|
- 1646 ELSE
|
|
|
- 1647 QbeGen.Mangled(pn,
|
|
|
- 1648 SymTab.ClassMethodUid(
|
|
|
- 1649 methCls, pn), mg);
|
|
|
- 1650 QbeGen.CallBegin(mg, res, 0,
|
|
|
- 1651 FALSE)
|
|
|
- 1652 END
|
|
|
- 1653 ELSIF SymTab.SymKind(pn) =
|
|
|
- 1654 SymTab.KindProc THEN
|
|
|
- 1655 res := SymTab.ProcRes(pn);
|
|
|
- 1656 QbeGen.Mangled(pn,
|
|
|
- 1657 SymTab.ProcUid(pn), mg);
|
|
|
- 1658 QbeGen.CallBegin(mg, res,
|
|
|
- 1659 SymTab.ProcDepthOf(pn),
|
|
|
- 1660 SymTab.IsExternal(pn))
|
|
|
- 1661 ELSIF (pt # SymTab.InvalidType)
|
|
|
- 1662 AND (SymTab.ClassOf(pt) = SymTab.ClProc) THEN
|
|
|
- 1663 ind := TRUE;
|
|
|
- 1664 res :=
|
|
|
- 1665 SymTab.ProcTypeRes(pt);
|
|
|
- 1666 QbeGen.CallBeginInd(callee,
|
|
|
- 1667 res, FALSE)
|
|
|
- 1668 ELSE SemError(233);
|
|
|
- 1669 ok := FALSE;
|
|
|
- 1670 res := SymTab.InvalidType
|
|
|
- 1671 END;
|
|
|
- 1672 i := 0; .)
|
|
|
- 1673 [ ActParam<pn, pt, ind, methCls, i> (. INC(i); .)
|
|
|
- 1674 { "," ActParam<pn, pt, ind, methCls, i> (. INC(i); .) } ]
|
|
|
- 1675 ")" (. IF ok THEN
|
|
|
- 1676 IF isMeth THEN
|
|
|
- 1677 np := SymTab.ClassMethodNPar(
|
|
|
- 1678 methCls, pn)
|
|
|
- 1679 ELSIF ind THEN
|
|
|
- 1680 np := SymTab.ProcTypeNPar(pt)
|
|
|
- 1681 ELSE np := SymTab.ProcNPar(pn)
|
|
|
- 1682 END;
|
|
|
- 1683 va := (NOT isMeth) AND (NOT ind)
|
|
|
- 1684 AND (SymTab.SymKind(pn) =
|
|
|
- 1685 SymTab.KindProc)
|
|
|
- 1686 AND SymTab.Varargs(pn);
|
|
|
- 1687 IF (i # np) AND NOT va THEN
|
|
|
- 1688 SemError(233); ok := FALSE
|
|
|
- 1689 END
|
|
|
- 1690 END;
|
|
|
- 1691 IF NOT ok THEN
|
|
|
- 1692 t := SymTab.InvalidType;
|
|
|
- 1693 QbeGen.CopyOp("0", q)
|
|
|
- 1694 ELSIF want THEN
|
|
|
- 1695 IF res =
|
|
|
- 1696 SymTab.InvalidType THEN
|
|
|
- 1697 SemError(233);
|
|
|
- 1698 t := SymTab.InvalidType;
|
|
|
- 1699 QbeGen.CopyOp("0", q)
|
|
|
- 1700 ELSE t := res;
|
|
|
- 1701 QbeGen.CallEnd(TRUE, q)
|
|
|
- 1702 END
|
|
|
- 1703 ELSE
|
|
|
- 1704 IF res #
|
|
|
- 1705 SymTab.InvalidType THEN
|
|
|
- 1706 SemError(233)
|
|
|
- 1707 END;
|
|
|
- 1708 t := SymTab.InvalidType;
|
|
|
- 1709 QbeGen.CopyOp("0", q);
|
|
|
- 1710 QbeGen.CallEnd(FALSE, q)
|
|
|
- 1711 END; .) .
|
|
|
- 1712 (* One actual: VAR formals take recorded designator addresses
|
|
|
- 1713 (233 otherwise); value formals take converted expressions. *)
|
|
|
- 1714 ActParam<pn: SymTab.Name; pt: SymTab.TypeIndex; ind: BOOLEAN;
|
|
|
- 1715 methCls: SymTab.TypeIndex; i: CARDINAL>
|
|
|
- 1716 (. VAR at, ft: SymTab.TypeIndex;
|
|
|
- 1717 qe, qa, qt: QbeGen.QVal;
|
|
|
- 1718 isV, conv, va: BOOLEAN;
|
|
|
- 1719 cl: CHAR;
|
|
|
- 1720 savedN, aj: CARDINAL;
|
|
|
- 1721 savedArgs: ARRAY [0 .. 31]
|
|
|
- 1722 OF AST.Node; .)
|
|
|
- 1723 = (. (* Parsing the actual can clobber
|
|
|
- 1724 the enclosing call's argument
|
|
|
- 1725 list (Factor resets astNArgs),
|
|
|
- 1726 so save/restore it. *)
|
|
|
- 1727 savedN := astNArgs; aj := 0;
|
|
|
- 1728 WHILE aj <= HIGH(astArgs) DO
|
|
|
- 1729 savedArgs[aj] := astArgs[aj];
|
|
|
- 1730 INC(aj)
|
|
|
- 1731 END; .)
|
|
|
- 1732 Expr<at, qe> (. astNArgs := savedN; aj := 0;
|
|
|
- 1733 WHILE aj <= HIGH(astArgs) DO
|
|
|
- 1734 astArgs[aj] := savedArgs[aj];
|
|
|
- 1735 INC(aj)
|
|
|
- 1736 END;
|
|
|
- 1737 IF astNArgs <= HIGH(astArgs) THEN
|
|
|
- 1738 astArgs[astNArgs] := astCur;
|
|
|
- 1739 INC(astNArgs)
|
|
|
- 1740 END;
|
|
|
- 1741 va := (NOT ind)
|
|
|
- 1742 AND (methCls =
|
|
|
- 1743 SymTab.InvalidType)
|
|
|
- 1744 AND (SymTab.SymKind(pn) =
|
|
|
- 1745 SymTab.KindProc)
|
|
|
- 1746 AND SymTab.Varargs(pn);
|
|
|
- 1747 IF ind THEN
|
|
|
- 1748 ft :=
|
|
|
- 1749 SymTab.ProcTypeParamType(pt,
|
|
|
- 1750 i);
|
|
|
- 1751 isV :=
|
|
|
- 1752 SymTab.ProcTypeParamIsVar(pt,
|
|
|
- 1753 i)
|
|
|
- 1754 ELSIF methCls #
|
|
|
- 1755 SymTab.InvalidType THEN
|
|
|
- 1756 ft :=
|
|
|
- 1757 SymTab.ClassMethodParamType(
|
|
|
- 1758 methCls, pn, i);
|
|
|
- 1759 isV :=
|
|
|
- 1760 SymTab.ClassMethodParamIsVar(
|
|
|
- 1761 methCls, pn, i)
|
|
|
- 1762 ELSE
|
|
|
- 1763 ft := SymTab.ParamType(pn, i);
|
|
|
- 1764 isV := SymTab.ParamIsVar(pn, i)
|
|
|
- 1765 END;
|
|
|
- 1766 IF (at = SymTab.InvalidType) THEN
|
|
|
- 1767 ELSIF ft = SymTab.InvalidType THEN
|
|
|
- 1768 IF va THEN
|
|
|
- 1769 QbeGen.CArgAdd(qe, at, qa, cl)
|
|
|
- 1770 END
|
|
|
- 1771 ELSIF isV THEN
|
|
|
- 1772 IF (SymTab.ClassOf(at)
|
|
|
- 1773 = SymTab.ClChar)
|
|
|
- 1774 AND (SymTab.ClassOf(ft) = SymTab.ClArray)
|
|
|
- 1775 AND (SymTab.ClassOf(SymTab.ArrayElem(ft))
|
|
|
- 1776 = SymTab.ClChar)
|
|
|
- 1777 AND QbeGen.IsImm(qe) THEN
|
|
|
- 1778 (* 1-char string
|
|
|
- 1779 literal passed to
|
|
|
- 1780 a VAR ARRAY OF CHAR *)
|
|
|
- 1781 QbeGen.DeclCharStr(qe,
|
|
|
- 1782 qa);
|
|
|
- 1783 IF NOT QbeGen.CallArg(qa,
|
|
|
- 1784 "l") THEN
|
|
|
- 1785 SemError(233)
|
|
|
- 1786 END
|
|
|
- 1787 ELSIF NOT QbeGen.AddrOfVal(qe,
|
|
|
- 1788 qa) THEN
|
|
|
- 1789 SemError(233)
|
|
|
- 1790 ELSIF NOT SymTab.VarParamOk(at,
|
|
|
- 1791 ft) THEN
|
|
|
- 1792 SemError(233)
|
|
|
- 1793 ELSIF NOT QbeGen.CallArg(qa,
|
|
|
- 1794 "l") THEN
|
|
|
- 1795 SemError(233)
|
|
|
- 1796 END
|
|
|
- 1797 ELSE
|
|
|
- 1798 IF (SymTab.ClassOf(at)
|
|
|
- 1799 = SymTab.ClChar)
|
|
|
- 1800 AND (SymTab.ClassOf(ft) = SymTab.ClArray)
|
|
|
- 1801 AND (SymTab.ClassOf(SymTab.ArrayElem(ft))
|
|
|
- 1802 = SymTab.ClChar)
|
|
|
- 1803 AND QbeGen.IsImm(qe) THEN
|
|
|
- 1804 (* 1-char string
|
|
|
- 1805 literal passed to
|
|
|
- 1806 ARRAY OF CHAR *)
|
|
|
- 1807 QbeGen.DeclCharStr(qe,
|
|
|
- 1808 qa);
|
|
|
- 1809 IF NOT QbeGen.CallArg(qa,
|
|
|
- 1810 "l") THEN
|
|
|
- 1811 SemError(233)
|
|
|
- 1812 END
|
|
|
- 1813 ELSIF NOT SymTab.Assignable(at,
|
|
|
- 1814 ft) THEN
|
|
|
- 1815 SemError(233)
|
|
|
- 1816 ELSE
|
|
|
- 1817 conv := (SymTab.ClassOf(
|
|
|
- 1818 ft) = SymTab.ClReal)
|
|
|
- 1819 AND SymTab.IsIntFamily(at);
|
|
|
- 1820 IF conv THEN
|
|
|
- 1821 QbeGen.ConvIR(qe, qt);
|
|
|
- 1822 IF NOT QbeGen.CallArg(qt,
|
|
|
- 1823 "d") THEN
|
|
|
- 1824 SemError(233)
|
|
|
- 1825 END
|
|
|
- 1826 ELSIF NOT QbeGen.CallArg(qe,
|
|
|
- 1827 QbeGen.ArgClass(ft)) THEN
|
|
|
- 1828 SemError(233)
|
|
|
- 1829 END
|
|
|
- 1830 END
|
|
|
- 1831 END; .) .
|
|
|
- 1832 IfStat (. VAR t: SymTab.TypeIndex;
|
|
|
- 1833 q: QbeGen.QVal;
|
|
|
- 1834 hasElse: BOOLEAN;
|
|
|
- 1835 astCond, astIf, astLast,
|
|
|
+ 1633 res := SymTab.ClassMethodRes(methCls, pn)
|
|
|
+ 1634 ELSIF SymTab.SymKind(pn) = SymTab.KindProc THEN
|
|
|
+ 1635 res := SymTab.ProcRes(pn)
|
|
|
+ 1636 ELSIF (pt # SymTab.InvalidType)
|
|
|
+ 1637 AND (SymTab.ClassOf(pt) = SymTab.ClProc) THEN
|
|
|
+ 1638 ind := TRUE;
|
|
|
+ 1639 res := SymTab.ProcTypeRes(pt)
|
|
|
+ 1640 ELSE SemError(233);
|
|
|
+ 1641 ok := FALSE;
|
|
|
+ 1642 res := SymTab.InvalidType
|
|
|
+ 1643 END;
|
|
|
+ 1644 i := 0; .)
|
|
|
+ 1645 [ ActParam<pn, pt, ind, methCls, i> (. INC(i); .)
|
|
|
+ 1646 { "," ActParam<pn, pt, ind, methCls, i> (. INC(i); .) } ]
|
|
|
+ 1647 ")" (. IF ok THEN
|
|
|
+ 1648 IF isMeth THEN
|
|
|
+ 1649 np := SymTab.ClassMethodNPar(
|
|
|
+ 1650 methCls, pn)
|
|
|
+ 1651 ELSIF ind THEN
|
|
|
+ 1652 np := SymTab.ProcTypeNPar(pt)
|
|
|
+ 1653 ELSE np := SymTab.ProcNPar(pn)
|
|
|
+ 1654 END;
|
|
|
+ 1655 va := (NOT isMeth) AND (NOT ind)
|
|
|
+ 1656 AND (SymTab.SymKind(pn) =
|
|
|
+ 1657 SymTab.KindProc)
|
|
|
+ 1658 AND SymTab.Varargs(pn);
|
|
|
+ 1659 IF (i # np) AND NOT va THEN
|
|
|
+ 1660 SemError(233); ok := FALSE
|
|
|
+ 1661 END
|
|
|
+ 1662 END;
|
|
|
+ 1663 IF NOT ok THEN
|
|
|
+ 1664 t := SymTab.InvalidType;
|
|
|
+ 1665 QbeGen.CopyOp("0", q)
|
|
|
+ 1666 ELSIF want THEN
|
|
|
+ 1667 IF res =
|
|
|
+ 1668 SymTab.InvalidType THEN
|
|
|
+ 1669 SemError(233);
|
|
|
+ 1670 t := SymTab.InvalidType;
|
|
|
+ 1671 QbeGen.CopyOp("0", q)
|
|
|
+ 1672 ELSE t := res;
|
|
|
+ 1673 QbeGen.CopyOp("@", q)
|
|
|
+ 1674 END
|
|
|
+ 1675 ELSE
|
|
|
+ 1676 IF res #
|
|
|
+ 1677 SymTab.InvalidType THEN
|
|
|
+ 1678 SemError(233)
|
|
|
+ 1679 END;
|
|
|
+ 1680 t := SymTab.InvalidType;
|
|
|
+ 1681 QbeGen.CopyOp("0", q);
|
|
|
+ 1682 END; .) .
|
|
|
+ 1683 (* One actual: VAR formals take recorded designator addresses
|
|
|
+ 1684 (233 otherwise); value formals take converted expressions. *)
|
|
|
+ 1685 ActParam<pn: SymTab.Name; pt: SymTab.TypeIndex; ind: BOOLEAN;
|
|
|
+ 1686 methCls: SymTab.TypeIndex; i: CARDINAL>
|
|
|
+ 1687 (. VAR at, ft: SymTab.TypeIndex;
|
|
|
+ 1688 qe, qa, qt: QbeGen.QVal;
|
|
|
+ 1689 isV, conv, va: BOOLEAN;
|
|
|
+ 1690 cl: CHAR;
|
|
|
+ 1691 savedN, aj: CARDINAL;
|
|
|
+ 1692 savedArgs: ARRAY [0 .. 31]
|
|
|
+ 1693 OF AST.Node;
|
|
|
+ 1694 astActual: AST.Node; .)
|
|
|
+ 1695 = (. (* Parsing the actual can clobber
|
|
|
+ 1696 the enclosing call's argument
|
|
|
+ 1697 list (Factor resets astNArgs),
|
|
|
+ 1698 so save/restore it. *)
|
|
|
+ 1699 savedN := astNArgs; aj := 0;
|
|
|
+ 1700 WHILE aj <= HIGH(astArgs) DO
|
|
|
+ 1701 savedArgs[aj] := astArgs[aj];
|
|
|
+ 1702 INC(aj)
|
|
|
+ 1703 END; .)
|
|
|
+ 1704 Expr<at, qe> (. astActual := astCur;
|
|
|
+ 1705 astNArgs := savedN; aj := 0;
|
|
|
+ 1706 WHILE aj <= HIGH(astArgs) DO
|
|
|
+ 1707 astArgs[aj] := savedArgs[aj];
|
|
|
+ 1708 INC(aj)
|
|
|
+ 1709 END;
|
|
|
+ 1710 IF astNArgs <= HIGH(astArgs) THEN
|
|
|
+ 1711 astArgs[astNArgs] := astCur;
|
|
|
+ 1712 INC(astNArgs)
|
|
|
+ 1713 END;
|
|
|
+ 1714 va := (NOT ind)
|
|
|
+ 1715 AND (methCls =
|
|
|
+ 1716 SymTab.InvalidType)
|
|
|
+ 1717 AND (SymTab.SymKind(pn) =
|
|
|
+ 1718 SymTab.KindProc)
|
|
|
+ 1719 AND SymTab.Varargs(pn);
|
|
|
+ 1720 IF ind THEN
|
|
|
+ 1721 ft :=
|
|
|
+ 1722 SymTab.ProcTypeParamType(pt,
|
|
|
+ 1723 i);
|
|
|
+ 1724 isV :=
|
|
|
+ 1725 SymTab.ProcTypeParamIsVar(pt,
|
|
|
+ 1726 i)
|
|
|
+ 1727 ELSIF methCls #
|
|
|
+ 1728 SymTab.InvalidType THEN
|
|
|
+ 1729 ft :=
|
|
|
+ 1730 SymTab.ClassMethodParamType(
|
|
|
+ 1731 methCls, pn, i);
|
|
|
+ 1732 isV :=
|
|
|
+ 1733 SymTab.ClassMethodParamIsVar(
|
|
|
+ 1734 methCls, pn, i)
|
|
|
+ 1735 ELSE
|
|
|
+ 1736 ft := SymTab.ParamType(pn, i);
|
|
|
+ 1737 isV := SymTab.ParamIsVar(pn, i)
|
|
|
+ 1738 END;
|
|
|
+ 1739 IF (at = SymTab.InvalidType) THEN
|
|
|
+ 1740 ELSIF ft = SymTab.InvalidType THEN
|
|
|
+ 1741 ELSIF isV THEN
|
|
|
+ 1742 IF (SymTab.ClassOf(at) = SymTab.ClChar)
|
|
|
+ 1743 AND (SymTab.ClassOf(ft) = SymTab.ClArray)
|
|
|
+ 1744 AND (SymTab.ClassOf(SymTab.ArrayElem(ft)) = SymTab.ClChar)
|
|
|
+ 1745 AND QbeGen.IsImm(qe) THEN
|
|
|
+ 1746 ELSIF (AST.Kind(astActual) #
|
|
|
+ 1747 AST.NkDesignator)
|
|
|
+ 1748 AND (AST.Kind(astActual) # AST.NkStrLit) THEN
|
|
|
+ 1749 SemError(233)
|
|
|
+ 1750 ELSIF NOT SymTab.VarParamOk(at, ft) THEN
|
|
|
+ 1751 SemError(233)
|
|
|
+ 1752 END
|
|
|
+ 1753 ELSE
|
|
|
+ 1754 IF (SymTab.ClassOf(at) = SymTab.ClChar)
|
|
|
+ 1755 AND (SymTab.ClassOf(ft) = SymTab.ClArray)
|
|
|
+ 1756 AND (SymTab.ClassOf(SymTab.ArrayElem(ft)) = SymTab.ClChar)
|
|
|
+ 1757 AND QbeGen.IsImm(qe) THEN
|
|
|
+ 1758 ELSIF NOT SymTab.Assignable(at, ft) THEN
|
|
|
+ 1759 SemError(233)
|
|
|
+ 1760 END
|
|
|
+ 1761 END; .) .
|
|
|
+ 1762 IfStat (. VAR t: SymTab.TypeIndex;
|
|
|
+ 1763 q: QbeGen.QVal;
|
|
|
+ 1764 hasElse: BOOLEAN;
|
|
|
+ 1765 astCond, astIf, astLast,
|
|
|
+ 1766 astNode: AST.Node; .)
|
|
|
+ 1767 = "IF" (. hasElse := FALSE; .)
|
|
|
+ 1768 Expr<t, q> (. astCond := astCur; astStmt := AST.NoNode;
|
|
|
+ 1769 IF NOT SymTab.BoolCheck(t) THEN
|
|
|
+ 1770 SemError(214) END; .)
|
|
|
+ 1771 "THEN" [ StatSeq ] (. astNode := AST.MakeNode(AST.NkIf);
|
|
|
+ 1772 AST.SetChild(astNode, 0, astCond);
|
|
|
+ 1773 AST.SetChild(astNode, 1, astStmt);
|
|
|
+ 1774 astIf := astNode;
|
|
|
+ 1775 astLast := astNode; .)
|
|
|
+ 1776 { "ELSIF"
|
|
|
+ 1777 Expr<t, q> (. astCond := astCur; astStmt := AST.NoNode;
|
|
|
+ 1778 IF NOT SymTab.BoolCheck(t) THEN
|
|
|
+ 1779 SemError(214) END; .)
|
|
|
+ 1780 "THEN" [ StatSeq ] (. astNode := AST.MakeNode(AST.NkIf);
|
|
|
+ 1781 AST.SetChild(astNode, 0, astCond);
|
|
|
+ 1782 AST.SetChild(astNode, 1, astStmt);
|
|
|
+ 1783 AST.SetChild(astLast, 2, astNode);
|
|
|
+ 1784 astLast := astNode; .) }
|
|
|
+ 1785 [ "ELSE" (. hasElse := TRUE;
|
|
|
+ 1786 astStmt := AST.NoNode; .)
|
|
|
+ 1787 [ StatSeq ] (. AST.SetChild(astLast, 2, astStmt); .) ]
|
|
|
+ 1788 "END" (. astStmt := astIf; .) .
|
|
|
+ 1789 WhileStat (. VAR t: SymTab.TypeIndex;
|
|
|
+ 1790 q: QbeGen.QVal;
|
|
|
+ 1791 astCond, astNode: AST.Node; .)
|
|
|
+ 1792 = "WHILE" (. astStmt := AST.NoNode; .)
|
|
|
+ 1793 Expr<t, q> (. astCond := astCur;
|
|
|
+ 1794 IF NOT SymTab.BoolCheck(t) THEN
|
|
|
+ 1795 SemError(214) END; .)
|
|
|
+ 1796 "DO" [ StatSeq ] (. astNode := AST.MakeNode(AST.NkWhile);
|
|
|
+ 1797 AST.SetChild(astNode, 0, astCond);
|
|
|
+ 1798 AST.SetChild(astNode, 1, astStmt);
|
|
|
+ 1799 astStmt := astNode; .)
|
|
|
+ 1800 "END" .
|
|
|
+ 1801 RepeatStat (. VAR t: SymTab.TypeIndex;
|
|
|
+ 1802 q: QbeGen.QVal;
|
|
|
+ 1803 astCond, astBody, astNode:
|
|
|
+ 1804 AST.Node; .)
|
|
|
+ 1805 = "REPEAT" (. astStmt := AST.NoNode; .)
|
|
|
+ 1806 [ StatSeq ] (. astBody := astStmt; .)
|
|
|
+ 1807 "UNTIL" Expr<t, q> (. astCond := astCur;
|
|
|
+ 1808 astNode := AST.MakeNode(AST.NkRepeat);
|
|
|
+ 1809 AST.SetChild(astNode, 0, astBody);
|
|
|
+ 1810 AST.SetChild(astNode, 1, astCond);
|
|
|
+ 1811 astStmt := astNode;
|
|
|
+ 1812 IF NOT SymTab.BoolCheck(t) THEN
|
|
|
+ 1813 SemError(214) END; .) .
|
|
|
+ 1814 LoopStat (. VAR lEnd: QbeGen.QVal; astNode: AST.Node; .)
|
|
|
+ 1815 = "LOOP" (. astStmt := AST.NoNode;
|
|
|
+ 1816 QbeGen.NewLabel(lEnd);
|
|
|
+ 1817 QbeGen.PushLoop(lEnd); .)
|
|
|
+ 1818 [ StatSeq ]
|
|
|
+ 1819 "END" (. astNode := AST.MakeNode(AST.NkLoop);
|
|
|
+ 1820 AST.SetChild(astNode, 0, astStmt);
|
|
|
+ 1821 astStmt := astNode;
|
|
|
+ 1822 QbeGen.PopLoop; .) .
|
|
|
+ 1823 (* FOR with static-sign BY (literal, non-zero; 220 otherwise).
|
|
|
+ 1824 Runtime direction would need a compare-select; the literal
|
|
|
+ 1825 sign picks cslew/csegew at "DO" time. *)
|
|
|
+ 1826 ForStat (. VAR lv: SymTab.Name;
|
|
|
+ 1827 tlo, thi, tby:
|
|
|
+ 1828 SymTab.TypeIndex;
|
|
|
+ 1829 qlo, qhi, qby, qt, qk, qb:
|
|
|
+ 1830 QbeGen.QVal;
|
|
|
+ 1831 lTop, lBody, lEnd:
|
|
|
+ 1832 QbeGen.QVal;
|
|
|
+ 1833 by: INTEGER;
|
|
|
+ 1834 ok: BOOLEAN;
|
|
|
+ 1835 astVar, astLo, astHi, astBy,
|
|
|
1836 astNode: AST.Node; .)
|
|
|
- 1837 = "IF" (. hasElse := FALSE; .)
|
|
|
- 1838 Expr<t, q> (. astCond := astCur; astStmt := AST.NoNode;
|
|
|
- 1839 IF NOT SymTab.BoolCheck(t) THEN
|
|
|
- 1840 SemError(214) END; .)
|
|
|
- 1841 "THEN" [ StatSeq ] (. astNode := AST.MakeNode(AST.NkIf);
|
|
|
- 1842 AST.SetChild(astNode, 0, astCond);
|
|
|
- 1843 AST.SetChild(astNode, 1, astStmt);
|
|
|
- 1844 astIf := astNode;
|
|
|
- 1845 astLast := astNode; .)
|
|
|
- 1846 { "ELSIF"
|
|
|
- 1847 Expr<t, q> (. astCond := astCur; astStmt := AST.NoNode;
|
|
|
- 1848 IF NOT SymTab.BoolCheck(t) THEN
|
|
|
- 1849 SemError(214) END; .)
|
|
|
- 1850 "THEN" [ StatSeq ] (. astNode := AST.MakeNode(AST.NkIf);
|
|
|
- 1851 AST.SetChild(astNode, 0, astCond);
|
|
|
- 1852 AST.SetChild(astNode, 1, astStmt);
|
|
|
- 1853 AST.SetChild(astLast, 2, astNode);
|
|
|
- 1854 astLast := astNode; .) }
|
|
|
- 1855 [ "ELSE" (. hasElse := TRUE;
|
|
|
- 1856 astStmt := AST.NoNode; .)
|
|
|
- 1857 [ StatSeq ] (. AST.SetChild(astLast, 2, astStmt); .) ]
|
|
|
- 1858 "END" (. astStmt := astIf; .) .
|
|
|
- 1859 WhileStat (. VAR t: SymTab.TypeIndex;
|
|
|
- 1860 q: QbeGen.QVal;
|
|
|
- 1861 astCond, astNode: AST.Node; .)
|
|
|
- 1862 = "WHILE" (. astStmt := AST.NoNode; .)
|
|
|
- 1863 Expr<t, q> (. astCond := astCur;
|
|
|
- 1864 IF NOT SymTab.BoolCheck(t) THEN
|
|
|
- 1865 SemError(214) END; .)
|
|
|
- 1866 "DO" [ StatSeq ] (. astNode := AST.MakeNode(AST.NkWhile);
|
|
|
- 1867 AST.SetChild(astNode, 0, astCond);
|
|
|
- 1868 AST.SetChild(astNode, 1, astStmt);
|
|
|
- 1869 astStmt := astNode; .)
|
|
|
- 1870 "END" .
|
|
|
- 1871 RepeatStat (. VAR t: SymTab.TypeIndex;
|
|
|
- 1872 q: QbeGen.QVal;
|
|
|
- 1873 astCond, astBody, astNode:
|
|
|
- 1874 AST.Node; .)
|
|
|
- 1875 = "REPEAT" (. astStmt := AST.NoNode; .)
|
|
|
- 1876 [ StatSeq ] (. astBody := astStmt; .)
|
|
|
- 1877 "UNTIL" Expr<t, q> (. astCond := astCur;
|
|
|
- 1878 astNode := AST.MakeNode(AST.NkRepeat);
|
|
|
- 1879 AST.SetChild(astNode, 0, astBody);
|
|
|
- 1880 AST.SetChild(astNode, 1, astCond);
|
|
|
- 1881 astStmt := astNode;
|
|
|
- 1882 IF NOT SymTab.BoolCheck(t) THEN
|
|
|
- 1883 SemError(214) END; .) .
|
|
|
- 1884 LoopStat (. VAR lEnd: QbeGen.QVal; astNode: AST.Node; .)
|
|
|
- 1885 = "LOOP" (. astStmt := AST.NoNode;
|
|
|
- 1886 QbeGen.NewLabel(lEnd);
|
|
|
- 1887 QbeGen.PushLoop(lEnd); .)
|
|
|
- 1888 [ StatSeq ]
|
|
|
- 1889 "END" (. astNode := AST.MakeNode(AST.NkLoop);
|
|
|
- 1890 AST.SetChild(astNode, 0, astStmt);
|
|
|
- 1891 astStmt := astNode;
|
|
|
- 1892 QbeGen.PopLoop; .) .
|
|
|
- 1893 (* FOR with static-sign BY (literal, non-zero; 220 otherwise).
|
|
|
- 1894 Runtime direction would need a compare-select; the literal
|
|
|
- 1895 sign picks cslew/csegew at "DO" time. *)
|
|
|
- 1896 ForStat (. VAR lv: SymTab.Name;
|
|
|
- 1897 tlo, thi, tby:
|
|
|
- 1898 SymTab.TypeIndex;
|
|
|
- 1899 qlo, qhi, qby, qt, qk, qb:
|
|
|
- 1900 QbeGen.QVal;
|
|
|
- 1901 lTop, lBody, lEnd:
|
|
|
- 1902 QbeGen.QVal;
|
|
|
- 1903 by: INTEGER;
|
|
|
- 1904 ok: BOOLEAN;
|
|
|
- 1905 astVar, astLo, astHi, astBy,
|
|
|
- 1906 astNode: AST.Node; .)
|
|
|
- 1907 = "FOR" (. by := 1; .)
|
|
|
- 1908 GetIdent<lv> (. astVar := AST.MakeLeaf(AST.NkIdent, lv);
|
|
|
- 1909 astStmt := AST.NoNode;
|
|
|
- 1910 astBy := AST.NoNode;
|
|
|
- 1911 ok := SymTab.Lookup(lv);
|
|
|
- 1912 IF NOT ok THEN
|
|
|
- 1913 SemError(201)
|
|
|
- 1914 ELSIF (SymTab.SymKind(lv) #
|
|
|
- 1915 SymTab.KindVar)
|
|
|
- 1916 AND (SymTab.SymKind(lv) #
|
|
|
- 1917 SymTab.KindParam) THEN
|
|
|
- 1918 SemError(220); ok := FALSE
|
|
|
- 1919 ELSIF NOT SymTab.IsIntFamily(
|
|
|
- 1920 SymTab.SymType(lv)) THEN
|
|
|
- 1921 SemError(220); ok := FALSE
|
|
|
- 1922 END; .)
|
|
|
- 1923 ":=" Expr<tlo, qlo> (. astLo := astCur;
|
|
|
- 1924 IF NOT SymTab.IsIntFamily(tlo) THEN
|
|
|
- 1925 SemError(220); ok := FALSE
|
|
|
- 1926 END; .)
|
|
|
- 1927 "TO" Expr<thi, qhi> (. astHi := astCur;
|
|
|
- 1928 IF NOT SymTab.IsIntFamily(thi) THEN
|
|
|
- 1929 SemError(220); ok := FALSE
|
|
|
- 1930 END; .)
|
|
|
- 1931 [ "BY" Expr<tby, qby> (. astBy := astCur;
|
|
|
- 1932 IF (tby #
|
|
|
- 1933 SymTab.InvalidType)
|
|
|
- 1934 AND NOT SymTab.IsIntFamily(tby) THEN
|
|
|
- 1935 SemError(220); ok := FALSE
|
|
|
- 1936 END;
|
|
|
- 1937 IF NOT SymTab.ConstInt(qby, by) THEN
|
|
|
- 1938 SemError(230); by := 1
|
|
|
- 1939 ELSIF by = 0 THEN
|
|
|
- 1940 SemError(220); by := 1
|
|
|
- 1941 END; .) ]
|
|
|
- 1942 "DO"
|
|
|
- 1943 [ StatSeq ]
|
|
|
- 1944 "END" (. astNode := AST.MakeNode(AST.NkFor);
|
|
|
- 1945 AST.SetChild(astNode, 0, astVar);
|
|
|
- 1946 AST.SetChild(astNode, 1, astLo);
|
|
|
- 1947 AST.SetChild(astNode, 2, astHi);
|
|
|
- 1948 AST.SetChild(astNode, 3, astBy);
|
|
|
- 1949 AST.SetChild(astNode, 4, astStmt);
|
|
|
- 1950 astStmt := astNode;
|
|
|
- 1951 .) .
|
|
|
- 1952 CaseStat (. VAR tsel: SymTab.TypeIndex;
|
|
|
- 1953 qsel, lEnd: QbeGen.QVal;
|
|
|
- 1954 arm, astNode, astArms,
|
|
|
- 1955 astArmsTail: AST.Node; .)
|
|
|
- 1956 = "CASE" Expr<tsel, qsel> (. astNode := AST.MakeNode(AST.NkCase);
|
|
|
- 1957 AST.SetChild(astNode, 0, astCur);
|
|
|
- 1958 astArms := AST.NoNode;
|
|
|
- 1959 astArmsTail := AST.NoNode;
|
|
|
- 1960 .)
|
|
|
- 1961 "OF" CaseAlt<tsel, qsel, lEnd, astArms, astArmsTail>
|
|
|
- 1962 { "|" CaseAlt<tsel, qsel, lEnd, astArms, astArmsTail> }
|
|
|
- 1963 [ "ELSE" (. astStmt := AST.NoNode; .)
|
|
|
- 1964 [ StatSeq ] (. arm := AST.MakeNode(AST.NkCaseArm);
|
|
|
- 1965 AST.SetOp(arm, 1);
|
|
|
- 1966 AST.SetChild(arm, 0, astStmt);
|
|
|
- 1967 AstAppend(AST.NkBlock,
|
|
|
- 1968 astArms, astArmsTail, arm); .) ]
|
|
|
- 1969 "END" (. AST.SetChild(astNode, 1, astArms);
|
|
|
+ 1837 = "FOR" (. by := 1; .)
|
|
|
+ 1838 GetIdent<lv> (. astVar := AST.MakeLeaf(AST.NkIdent, lv);
|
|
|
+ 1839 astStmt := AST.NoNode;
|
|
|
+ 1840 astBy := AST.NoNode;
|
|
|
+ 1841 ok := SymTab.Lookup(lv);
|
|
|
+ 1842 IF NOT ok THEN
|
|
|
+ 1843 SemError(201)
|
|
|
+ 1844 ELSIF (SymTab.SymKind(lv) #
|
|
|
+ 1845 SymTab.KindVar)
|
|
|
+ 1846 AND (SymTab.SymKind(lv) #
|
|
|
+ 1847 SymTab.KindParam) THEN
|
|
|
+ 1848 SemError(220); ok := FALSE
|
|
|
+ 1849 ELSIF NOT SymTab.IsIntFamily(
|
|
|
+ 1850 SymTab.SymType(lv)) THEN
|
|
|
+ 1851 SemError(220); ok := FALSE
|
|
|
+ 1852 END; .)
|
|
|
+ 1853 ":=" Expr<tlo, qlo> (. astLo := astCur;
|
|
|
+ 1854 IF NOT SymTab.IsIntFamily(tlo) THEN
|
|
|
+ 1855 SemError(220); ok := FALSE
|
|
|
+ 1856 END; .)
|
|
|
+ 1857 "TO" Expr<thi, qhi> (. astHi := astCur;
|
|
|
+ 1858 IF NOT SymTab.IsIntFamily(thi) THEN
|
|
|
+ 1859 SemError(220); ok := FALSE
|
|
|
+ 1860 END; .)
|
|
|
+ 1861 [ "BY" Expr<tby, qby> (. astBy := astCur;
|
|
|
+ 1862 IF (tby #
|
|
|
+ 1863 SymTab.InvalidType)
|
|
|
+ 1864 AND NOT SymTab.IsIntFamily(tby) THEN
|
|
|
+ 1865 SemError(220); ok := FALSE
|
|
|
+ 1866 END;
|
|
|
+ 1867 IF NOT SymTab.ConstInt(qby, by) THEN
|
|
|
+ 1868 SemError(230); by := 1
|
|
|
+ 1869 ELSIF by = 0 THEN
|
|
|
+ 1870 SemError(220); by := 1
|
|
|
+ 1871 END; .) ]
|
|
|
+ 1872 "DO"
|
|
|
+ 1873 [ StatSeq ]
|
|
|
+ 1874 "END" (. astNode := AST.MakeNode(AST.NkFor);
|
|
|
+ 1875 AST.SetChild(astNode, 0, astVar);
|
|
|
+ 1876 AST.SetChild(astNode, 1, astLo);
|
|
|
+ 1877 AST.SetChild(astNode, 2, astHi);
|
|
|
+ 1878 AST.SetChild(astNode, 3, astBy);
|
|
|
+ 1879 AST.SetChild(astNode, 4, astStmt);
|
|
|
+ 1880 astStmt := astNode;
|
|
|
+ 1881 .) .
|
|
|
+ 1882 CaseStat (. VAR tsel: SymTab.TypeIndex;
|
|
|
+ 1883 qsel, lEnd: QbeGen.QVal;
|
|
|
+ 1884 arm, astNode, astArms,
|
|
|
+ 1885 astArmsTail: AST.Node; .)
|
|
|
+ 1886 = "CASE" Expr<tsel, qsel> (. astNode := AST.MakeNode(AST.NkCase);
|
|
|
+ 1887 AST.SetChild(astNode, 0, astCur);
|
|
|
+ 1888 astArms := AST.NoNode;
|
|
|
+ 1889 astArmsTail := AST.NoNode;
|
|
|
+ 1890 .)
|
|
|
+ 1891 "OF" CaseAlt<tsel, qsel, lEnd, astArms, astArmsTail>
|
|
|
+ 1892 { "|" CaseAlt<tsel, qsel, lEnd, astArms, astArmsTail> }
|
|
|
+ 1893 [ "ELSE" (. astStmt := AST.NoNode; .)
|
|
|
+ 1894 [ StatSeq ] (. arm := AST.MakeNode(AST.NkCaseArm);
|
|
|
+ 1895 AST.SetOp(arm, 1);
|
|
|
+ 1896 AST.SetChild(arm, 0, astStmt);
|
|
|
+ 1897 AstAppend(AST.NkBlock,
|
|
|
+ 1898 astArms, astArmsTail, arm); .) ]
|
|
|
+ 1899 "END" (. AST.SetChild(astNode, 1, astArms);
|
|
|
+ 1900 astStmt := astNode;
|
|
|
+ 1901 .) .
|
|
|
+ 1902 (* Compare-chain lowering: each alternative ends its match-tests
|
|
|
+ 1903 with "jmp lAfter", so the no-match fallthrough skips the body:
|
|
|
+ 1904 "cmp; jnz(lBody,lF); lF: ... ; jmp lAfter; lBody: S; jmp lEnd;
|
|
|
+ 1905 lAfter:". Falls into the next alternative, ELSE, or END. *)
|
|
|
+ 1906 CaseAlt<tsel: SymTab.TypeIndex; qsel: QbeGen.QVal;
|
|
|
+ 1907 lEnd: QbeGen.QVal; VAR arms, armsTail: AST.Node>
|
|
|
+ 1908 (. VAR arm: AST.Node; .)
|
|
|
+ 1909 = (. arm := AST.MakeNode(AST.NkCaseArm); .)
|
|
|
+ 1910 CaseLabel<tsel, qsel, arm>
|
|
|
+ 1911 { "," CaseLabel<tsel, qsel, arm> }
|
|
|
+ 1912 ":" (. astStmt := AST.NoNode; .)
|
|
|
+ 1913 [ StatSeq ] (. AST.SetChild(arm, AST.NChild(arm),
|
|
|
+ 1914 astStmt);
|
|
|
+ 1915 AstAppend(AST.NkBlock,
|
|
|
+ 1916 arms, armsTail, arm);
|
|
|
+ 1917 .) .
|
|
|
+ 1918 CaseLabel<tsel: SymTab.TypeIndex; qsel: QbeGen.QVal;
|
|
|
+ 1919 arm: AST.Node>
|
|
|
+ 1920 (. VAR t2, t3: SymTab.TypeIndex;
|
|
|
+ 1921 q2, q3, qc, qd, qe:
|
|
|
+ 1922 QbeGen.QVal;
|
|
|
+ 1923 astLab: AST.Node;
|
|
|
+ 1924 lNext: QbeGen.QVal; .)
|
|
|
+ 1925 = Expr<t2, q2> (. astLab := astCur;
|
|
|
+ 1926 IF (t2 #
|
|
|
+ 1927 SymTab.InvalidType)
|
|
|
+ 1928 AND (tsel #
|
|
|
+ 1929 SymTab.InvalidType)
|
|
|
+ 1930 AND ((SymTab.ClassOf(t2) =
|
|
|
+ 1931 SymTab.ClSet)
|
|
|
+ 1932 OR (SymTab.ClassOf(tsel) =
|
|
|
+ 1933 SymTab.ClSet)) THEN
|
|
|
+ 1934 SemError(230)
|
|
|
+ 1935 ELSIF (t2 #
|
|
|
+ 1936 SymTab.InvalidType)
|
|
|
+ 1937 AND (tsel #
|
|
|
+ 1938 SymTab.InvalidType)
|
|
|
+ 1939 AND NOT SymTab.EqCheck(t2,
|
|
|
+ 1940 tsel) THEN
|
|
|
+ 1941 SemError(213) END;
|
|
|
+ 1942 IF NOT QbeGen.IsImm(q2) THEN
|
|
|
+ 1943 SemError(230)
|
|
|
+ 1944 END; .)
|
|
|
+ 1945 [ ".." Expr<t3, q3> (. astLab := AST.MakeBin(
|
|
|
+ 1946 AST.NkSubrange, 0, astLab, astCur);
|
|
|
+ 1947 IF (t3 #
|
|
|
+ 1948 SymTab.InvalidType)
|
|
|
+ 1949 AND (tsel #
|
|
|
+ 1950 SymTab.InvalidType)
|
|
|
+ 1951 AND NOT SymTab.EqCheck(t3,
|
|
|
+ 1952 tsel) THEN
|
|
|
+ 1953 SemError(213) END;
|
|
|
+ 1954 IF NOT QbeGen.IsImm(q3) THEN
|
|
|
+ 1955 SemError(230)
|
|
|
+ 1956 END; .) ]
|
|
|
+ 1957 (. AST.SetChild(arm,
|
|
|
+ 1958 AST.NChild(arm), astLab); .) .
|
|
|
+ 1959 ReturnStat (. VAR t: SymTab.TypeIndex;
|
|
|
+ 1960 q, qt: QbeGen.QVal;
|
|
|
+ 1961 res: SymTab.TypeIndex;
|
|
|
+ 1962 hadE, conv: BOOLEAN;
|
|
|
+ 1963 astVal, astNode: AST.Node; .)
|
|
|
+ 1964 = "RETURN" (. hadE := FALSE; astStmt := AST.NoNode; .)
|
|
|
+ 1965 [ Expr<t, q> (. hadE := TRUE; astVal := astCur; .) ]
|
|
|
+ 1966 (. astNode := AST.MakeNode(AST.NkReturn);
|
|
|
+ 1967 IF hadE THEN
|
|
|
+ 1968 AST.SetChild(astNode, 0, astVal)
|
|
|
+ 1969 END;
|
|
|
1970 astStmt := astNode;
|
|
|
- 1971 .) .
|
|
|
- 1972 (* Compare-chain lowering: each alternative ends its match-tests
|
|
|
- 1973 with "jmp lAfter", so the no-match fallthrough skips the body:
|
|
|
- 1974 "cmp; jnz(lBody,lF); lF: ... ; jmp lAfter; lBody: S; jmp lEnd;
|
|
|
- 1975 lAfter:". Falls into the next alternative, ELSE, or END. *)
|
|
|
- 1976 CaseAlt<tsel: SymTab.TypeIndex; qsel: QbeGen.QVal;
|
|
|
- 1977 lEnd: QbeGen.QVal; VAR arms, armsTail: AST.Node>
|
|
|
- 1978 (. VAR arm: AST.Node; .)
|
|
|
- 1979 = (. arm := AST.MakeNode(AST.NkCaseArm); .)
|
|
|
- 1980 CaseLabel<tsel, qsel, arm>
|
|
|
- 1981 { "," CaseLabel<tsel, qsel, arm> }
|
|
|
- 1982 ":" (. astStmt := AST.NoNode; .)
|
|
|
- 1983 [ StatSeq ] (. AST.SetChild(arm, AST.NChild(arm),
|
|
|
- 1984 astStmt);
|
|
|
- 1985 AstAppend(AST.NkBlock,
|
|
|
- 1986 arms, armsTail, arm);
|
|
|
- 1987 .) .
|
|
|
- 1988 CaseLabel<tsel: SymTab.TypeIndex; qsel: QbeGen.QVal;
|
|
|
- 1989 arm: AST.Node>
|
|
|
- 1990 (. VAR t2, t3: SymTab.TypeIndex;
|
|
|
- 1991 q2, q3, qc, qd, qe:
|
|
|
- 1992 QbeGen.QVal;
|
|
|
- 1993 astLab: AST.Node;
|
|
|
- 1994 lNext: QbeGen.QVal; .)
|
|
|
- 1995 = Expr<t2, q2> (. astLab := astCur;
|
|
|
- 1996 IF (t2 #
|
|
|
- 1997 SymTab.InvalidType)
|
|
|
- 1998 AND (tsel #
|
|
|
- 1999 SymTab.InvalidType)
|
|
|
- 2000 AND ((SymTab.ClassOf(t2) =
|
|
|
- 2001 SymTab.ClSet)
|
|
|
- 2002 OR (SymTab.ClassOf(tsel) =
|
|
|
- 2003 SymTab.ClSet)) THEN
|
|
|
- 2004 SemError(230)
|
|
|
- 2005 ELSIF (t2 #
|
|
|
- 2006 SymTab.InvalidType)
|
|
|
- 2007 AND (tsel #
|
|
|
- 2008 SymTab.InvalidType)
|
|
|
- 2009 AND NOT SymTab.EqCheck(t2,
|
|
|
- 2010 tsel) THEN
|
|
|
- 2011 SemError(213) END;
|
|
|
- 2012 IF NOT QbeGen.IsImm(q2) THEN
|
|
|
- 2013 SemError(230)
|
|
|
- 2014 END; .)
|
|
|
- 2015 [ ".." Expr<t3, q3> (. astLab := AST.MakeBin(
|
|
|
- 2016 AST.NkSubrange, 0, astLab, astCur);
|
|
|
- 2017 IF (t3 #
|
|
|
- 2018 SymTab.InvalidType)
|
|
|
- 2019 AND (tsel #
|
|
|
- 2020 SymTab.InvalidType)
|
|
|
- 2021 AND NOT SymTab.EqCheck(t3,
|
|
|
- 2022 tsel) THEN
|
|
|
- 2023 SemError(213) END;
|
|
|
- 2024 IF NOT QbeGen.IsImm(q3) THEN
|
|
|
- 2025 SemError(230)
|
|
|
- 2026 END; .) ]
|
|
|
- 2027 (. AST.SetChild(arm,
|
|
|
- 2028 AST.NChild(arm), astLab); .) .
|
|
|
- 2029 ReturnStat (. VAR t: SymTab.TypeIndex;
|
|
|
- 2030 q, qt: QbeGen.QVal;
|
|
|
- 2031 res: SymTab.TypeIndex;
|
|
|
- 2032 hadE, conv: BOOLEAN;
|
|
|
- 2033 astVal, astNode: AST.Node; .)
|
|
|
- 2034 = "RETURN" (. hadE := FALSE; astStmt := AST.NoNode; .)
|
|
|
- 2035 [ Expr<t, q> (. hadE := TRUE; astVal := astCur; .) ]
|
|
|
- 2036 (. astNode := AST.MakeNode(AST.NkReturn);
|
|
|
- 2037 IF hadE THEN
|
|
|
- 2038 AST.SetChild(astNode, 0, astVal)
|
|
|
- 2039 END;
|
|
|
- 2040 astStmt := astNode;
|
|
|
- 2041 conv := FALSE;
|
|
|
- 2042 IF NOT SymTab.InProc() THEN
|
|
|
- 2043 SemError(232)
|
|
|
- 2044 ELSE res := SymTab.CurRes();
|
|
|
- 2045 IF NOT hadE THEN
|
|
|
- 2046 IF res #
|
|
|
- 2047 SymTab.InvalidType THEN
|
|
|
- 2048 SemError(232)
|
|
|
- 2049 END
|
|
|
- 2050 ELSIF (res =
|
|
|
- 2051 SymTab.InvalidType)
|
|
|
- 2052 OR (t #
|
|
|
- 2053 SymTab.InvalidType)
|
|
|
- 2054 AND NOT SymTab.Assignable(t,
|
|
|
- 2055 res) THEN
|
|
|
- 2056 SemError(232)
|
|
|
- 2057 END
|
|
|
- 2058 END; .) .
|
|
|
- 2059 HaltStat (. VAR t: SymTab.TypeIndex;
|
|
|
- 2060 q: QbeGen.QVal;
|
|
|
- 2061 astVal, astNode: AST.Node; .)
|
|
|
- 2062 = "HALT" (. astVal := AST.NoNode; .)
|
|
|
- 2063 [ "(" Expr<t, q> (. astVal := astCur; .) ")" ]
|
|
|
- 2064 (. astNode := AST.MakeNode(AST.NkHalt);
|
|
|
- 2065 IF astVal # AST.NoNode THEN
|
|
|
- 2066 AST.SetChild(astNode, 0, astVal)
|
|
|
- 2067 END;
|
|
|
- 2068 astStmt := astNode;
|
|
|
- 2069 .) .
|
|
|
- 2070 (* Designator: scalar loads, array addresses, and index suffixes.
|
|
|
- 2071 Each index descends one level (bounds-checked, trap on breach);
|
|
|
- 2072 nested levels reload the inner descriptor address. q ends as the
|
|
|
- 2073 value (scalars), the descriptor address (plain arrays), or the
|
|
|
- 2074 element address (indexed); sfx marks the indexed form. *)
|
|
|
- 2075 Design<VAR t: SymTab.TypeIndex; VAR k: INTEGER;
|
|
|
- 2076 VAR q: QbeGen.QVal; VAR qn: SymTab.Name; VAR sfx: BOOLEAN>
|
|
|
- 2077 (. VAR n, fn, mal: SymTab.Name;
|
|
|
- 2078 cls: INTEGER;
|
|
|
- 2079 ic: SymTab.TypeIndex;
|
|
|
- 2080 curT, it, eT, bt:
|
|
|
- 2081 SymTab.TypeIndex;
|
|
|
- 2082 iq, ql, qlo, qhi, qe:
|
|
|
- 2083 QbeGen.QVal;
|
|
|
- 2084 lo, hi: INTEGER;
|
|
|
- 2085 fo: INTEGER;
|
|
|
- 2086 isOpen: BOOLEAN;
|
|
|
- 2087 qb, cv: QbeGen.QVal;
|
|
|
- 2088 fid, fref, slot: INTEGER;
|
|
|
- 2089 r: BOOLEAN;
|
|
|
- 2090 astDes, astSel: AST.Node;
|
|
|
- 2091 fwd: BOOLEAN; .)
|
|
|
- 2092 = GetIdent<n> (. methCls := SymTab.InvalidType;
|
|
|
- 2093 QbeGen.CopyOp(n, qn);
|
|
|
- 2094 sfx := FALSE; fwd := FALSE;
|
|
|
- 2095 fid := 0; fref := 0; slot := 0;
|
|
|
- 2096 IF NOT SymTab.Lookup(n) THEN
|
|
|
- 2097 (* a bare method name inside
|
|
|
- 2098 a CLASS IMPLEMENTATION
|
|
|
- 2099 is a sibling call on
|
|
|
- 2100 THIS *)
|
|
|
- 2101 ic := SymTab.CurImplClass();
|
|
|
- 2102 IF (ic #
|
|
|
- 2103 SymTab.InvalidType)
|
|
|
- 2104 AND SymTab.MethodExists(ic, n) THEN
|
|
|
- 2105 sfx := FALSE;
|
|
|
- 2106 QbeGen.ThisBase(q);
|
|
|
- 2107 QbeGen.ArmRecv(q);
|
|
|
- 2108 methCls := ic;
|
|
|
- 2109 k := SymTab.KindProc;
|
|
|
- 2110 t := SymTab.InvalidType
|
|
|
- 2111 ELSIF SymTab.InProc() THEN
|
|
|
- 2112 (* not declared yet: a
|
|
|
- 2113 forward reference to a
|
|
|
- 2114 module-level variable
|
|
|
- 2115 declared further down. *)
|
|
|
- 2116 k := SymTab.KindVar;
|
|
|
- 2117 r := SymTab.FwdVarRef(n, k,
|
|
|
- 2118 fref, t);
|
|
|
- 2119 slot := QbeGen.FwdDesignator();
|
|
|
- 2120 FwdVarNote(fref, slot);
|
|
|
- 2121 fid := slot;
|
|
|
- 2122 QbeGen.FwdAddrOper(fid, q);
|
|
|
- 2123 sfx := TRUE; fwd := TRUE
|
|
|
- 2124 ELSE
|
|
|
- 2125 SemError(201);
|
|
|
- 2126 t :=
|
|
|
- 2127 SymTab.InvalidType;
|
|
|
- 2128 k := -1;
|
|
|
- 2129 QbeGen.CopyOp("0", q)
|
|
|
- 2130 END
|
|
|
- 2131 ELSE
|
|
|
- 2132 t := SymTab.SymType(n);
|
|
|
- 2133 k := SymTab.SymKind(n);
|
|
|
- 2134 IF k = SymTab.KindConst THEN
|
|
|
- 2135 IF SymTab.Equal(n,
|
|
|
- 2136 "TRUE") THEN
|
|
|
- 2137 t := SymTab.BoolType();
|
|
|
- 2138 QbeGen.CopyOp("1", q)
|
|
|
- 2139 ELSIF SymTab.Equal(n,
|
|
|
- 2140 "FALSE") THEN
|
|
|
- 2141 t := SymTab.BoolType();
|
|
|
- 2142 QbeGen.CopyOp("0", q)
|
|
|
- 2143 ELSIF SymTab.Equal(n,
|
|
|
- 2144 "NIL") THEN
|
|
|
- 2145 QbeGen.CopyOp("0", q)
|
|
|
- 2146 ELSE
|
|
|
- 2147 cls :=
|
|
|
- 2148 SymTab.ClassOf(t);
|
|
|
- 2149 IF (t #
|
|
|
- 2150 SymTab.InvalidType)
|
|
|
- 2151 AND ((cls = SymTab.ClInt)
|
|
|
- 2152 OR (cls
|
|
|
- 2153 = SymTab.ClChar)
|
|
|
- 2154 OR (cls
|
|
|
- 2155 = SymTab.ClEnum)
|
|
|
- 2156 OR (cls
|
|
|
- 2157 = SymTab.ClReal)
|
|
|
- 2158 OR (cls
|
|
|
- 2159 = SymTab.ClLong)
|
|
|
- 2160 OR (cls
|
|
|
- 2161 = SymTab.ClNil)) THEN
|
|
|
- 2162 IF cls = SymTab.ClNil THEN
|
|
|
- 2163 QbeGen.CopyOp("0", q)
|
|
|
- 2164 ELSIF ((cls
|
|
|
- 2165 = SymTab.ClInt)
|
|
|
- 2166 OR (cls
|
|
|
- 2167 = SymTab.ClChar)
|
|
|
- 2168 OR (cls
|
|
|
- 2169 = SymTab.ClEnum)
|
|
|
- 2170 OR (cls
|
|
|
- 2171 = SymTab.ClLong))
|
|
|
- 2172 AND SymTab.GetSymVal(n, cv)
|
|
|
- 2173 AND QbeGen.IsImm(cv) THEN
|
|
|
- 2174 QbeGen.CopyOp(cv, q)
|
|
|
- 2175 ELSE
|
|
|
- 2176 QbeGen.LoadVar(n,
|
|
|
- 2177 cls = SymTab.ClReal,
|
|
|
- 2178 q)
|
|
|
- 2179 END
|
|
|
- 2180 ELSIF (cls = SymTab.ClArray)
|
|
|
- 2181 OR (cls = SymTab.ClRecord)
|
|
|
- 2182 OR (cls = SymTab.ClClass)
|
|
|
- 2183 OR (cls = SymTab.ClStr)
|
|
|
- 2184 OR (cls = SymTab.ClUStr) THEN
|
|
|
- 2185 (* aggregate constant:
|
|
|
- 2186 its value IS the
|
|
|
- 2187 descriptor address *)
|
|
|
- 2188 IF SymTab.GetSymVal(n, cv) THEN
|
|
|
- 2189 QbeGen.CopyOp(cv, q)
|
|
|
- 2190 ELSE
|
|
|
- 2191 QbeGen.CopyOp("0", q)
|
|
|
- 2192 END
|
|
|
- 2193 ELSE
|
|
|
- 2194 IF t #
|
|
|
- 2195 SymTab.InvalidType THEN
|
|
|
- 2196 SemError(230)
|
|
|
- 2197 END;
|
|
|
- 2198 QbeGen.CopyOp("0", q)
|
|
|
- 2199 END
|
|
|
- 2200 END
|
|
|
- 2201 ELSIF (k = SymTab.KindVar)
|
|
|
- 2202 OR (k = SymTab.KindParam) THEN
|
|
|
- 2203 cls :=
|
|
|
- 2204 SymTab.ClassOf(t);
|
|
|
- 2205 IF (cls = SymTab.ClInt)
|
|
|
- 2206 OR (cls = SymTab.ClBool)
|
|
|
- 2207 OR (cls = SymTab.ClChar)
|
|
|
- 2208 OR (cls = SymTab.ClUChar)
|
|
|
- 2209 OR (cls = SymTab.ClEnum)
|
|
|
- 2210 OR (cls
|
|
|
- 2211 = SymTab.ClReal) THEN
|
|
|
- 2212 QbeGen.LoadVar(n,
|
|
|
- 2213 cls = SymTab.ClReal, q)
|
|
|
- 2214 ELSIF (cls = SymTab.ClPtr)
|
|
|
- 2215 OR (cls = SymTab.ClProc) THEN
|
|
|
- 2216 QbeGen.LoadPtr(n, q)
|
|
|
- 2217 ELSIF cls = SymTab.ClLong THEN
|
|
|
- 2218 QbeGen.LoadLong(n, q)
|
|
|
- 2219 ELSIF (cls
|
|
|
- 2220 = SymTab.ClArray)
|
|
|
- 2221 OR (cls
|
|
|
- 2222 = SymTab.ClSet)
|
|
|
- 2223 OR (cls
|
|
|
- 2224 = SymTab.ClRecord)
|
|
|
- 2225 OR (cls
|
|
|
- 2226 = SymTab.ClUStr)
|
|
|
- 2227 OR (cls
|
|
|
- 2228 = SymTab.ClClass) THEN
|
|
|
- 2229 QbeGen.AddrOf(n, q)
|
|
|
- 2230 ELSE SemError(230);
|
|
|
- 2231 QbeGen.CopyOp("0", q)
|
|
|
- 2232 END
|
|
|
- 2233 ELSE QbeGen.CopyOp("0", q);
|
|
|
- 2234 IF k = SymTab.KindImport THEN
|
|
|
- 2235 SemError(230)
|
|
|
- 2236 ELSIF k =
|
|
|
- 2237 SymTab.KindProc THEN
|
|
|
- 2238 (* bare procedure name:
|
|
|
- 2239 a following ArgList
|
|
|
- 2240 makes it a call;
|
|
|
- 2241 otherwise Fact
|
|
|
- 2242 reports 230 *)
|
|
|
- 2243 ELSE
|
|
|
- 2244 IF k = SymTab.KindField THEN
|
|
|
- 2245 IF QbeGen.TopWith(qb) THEN
|
|
|
- 2246 fo :=
|
|
|
- 2247 SymTab.FieldOffset(
|
|
|
- 2248 SymTab.FieldOwner(n),
|
|
|
- 2249 n);
|
|
|
- 2250 QbeGen.FieldAddr(qb,
|
|
|
- 2251 fo, q);
|
|
|
- 2252 sfx := TRUE
|
|
|
- 2253 ELSE SemError(230);
|
|
|
- 2254 QbeGen.CopyOp("0", q)
|
|
|
- 2255 END
|
|
|
- 2256 END
|
|
|
- 2257 END
|
|
|
- 2258 END
|
|
|
- 2259 END; .)
|
|
|
- 2260 (. astDes := AST.MakeNode(AST.NkDesignator);
|
|
|
- 2261 AST.SetChild(astDes, AST.NChild(astDes), AST.MakeLeaf(AST.NkIdent, n));
|
|
|
- 2262 IF fwd THEN AST.SetOp(astDes, 1) END; .)
|
|
|
- 2263 { "[" Expr<it, iq>
|
|
|
- 2264 (. AST.SetChild(astDes, AST.NChild(astDes),
|
|
|
- 2265 AST.MakeUn(AST.NkSelector, AST.SelIndex, astCur)); IF t = SymTab.InvalidType THEN
|
|
|
- 2266 ELSIF SymTab.ClassOf(t) #
|
|
|
- 2267 SymTab.ClArray THEN
|
|
|
- 2268 SemError(217);
|
|
|
- 2269 t := SymTab.InvalidType
|
|
|
- 2270 ELSIF NOT SymTab.IsIntFamily(it)
|
|
|
- 2271 AND (SymTab.ClassOf(it) #
|
|
|
- 2272 SymTab.ClChar)
|
|
|
- 2273 AND (SymTab.ClassOf(it) #
|
|
|
- 2274 SymTab.ClEnum) THEN
|
|
|
- 2275 SemError(218);
|
|
|
- 2276 t := SymTab.InvalidType
|
|
|
- 2277 ELSE
|
|
|
- 2278 QbeGen.WidenIndex(iq, ql);
|
|
|
- 2279 isOpen :=
|
|
|
- 2280 SymTab.IsOpenArray(t);
|
|
|
- 2281 IF isOpen THEN
|
|
|
- 2282 QbeGen.CopyOp("0", qlo);
|
|
|
- 2283 IF SymTab.IsCharArray(t)
|
|
|
- 2284 OR SymTab.IsUCharArray(t) THEN
|
|
|
- 2285 QbeGen.OpenHiChar(q, qhi)
|
|
|
- 2286 ELSE QbeGen.OpenHi(q, qhi)
|
|
|
- 2287 END
|
|
|
- 2288 ELSE
|
|
|
- 2289 lo := SymTab.ArrayLo(t);
|
|
|
- 2290 hi := SymTab.ArrayHi(t);
|
|
|
- 2291 IF SymTab.IsCharArray(t)
|
|
|
- 2292 OR SymTab.IsUCharArray(t) THEN
|
|
|
- 2293 hi := hi + 1
|
|
|
- 2294 END;
|
|
|
- 2295 QbeGen.IntStr(lo, qlo);
|
|
|
- 2296 QbeGen.IntStr(hi, qhi)
|
|
|
- 2297 END;
|
|
|
- 2298 QbeGen.CheckRange(ql, qlo,
|
|
|
- 2299 qhi);
|
|
|
- 2300 eT := SymTab.ArrayElem(t);
|
|
|
- 2301 QbeGen.ElemAddr(q, ql, qlo,
|
|
|
- 2302 t, qe);
|
|
|
- 2303 IF SymTab.ClassOf(eT) =
|
|
|
- 2304 SymTab.ClArray THEN
|
|
|
- 2305 QbeGen.ElemLoad(qe, eT, q)
|
|
|
- 2306 ELSE QbeGen.CopyOp(qe, q)
|
|
|
- 2307 END;
|
|
|
- 2308 t := eT; sfx := TRUE
|
|
|
- 2309 END; .)
|
|
|
- 2310 { "," Expr<it, iq>
|
|
|
- 2311 (. AST.SetChild(astDes, AST.NChild(astDes),
|
|
|
- 2312 AST.MakeUn(AST.NkSelector, AST.SelIndex, astCur)); IF t = SymTab.InvalidType THEN
|
|
|
- 2313 ELSIF SymTab.ClassOf(t) #
|
|
|
- 2314 SymTab.ClArray THEN
|
|
|
- 2315 SemError(217);
|
|
|
- 2316 t := SymTab.InvalidType
|
|
|
- 2317 ELSIF NOT SymTab.IsIntFamily(it)
|
|
|
- 2318 AND (SymTab.ClassOf(it) #
|
|
|
- 2319 SymTab.ClChar)
|
|
|
- 2320 AND (SymTab.ClassOf(it) #
|
|
|
- 2321 SymTab.ClEnum) THEN
|
|
|
- 2322 SemError(218);
|
|
|
- 2323 t := SymTab.InvalidType
|
|
|
- 2324 ELSE
|
|
|
- 2325 QbeGen.WidenIndex(iq, ql);
|
|
|
- 2326 isOpen :=
|
|
|
- 2327 SymTab.IsOpenArray(t);
|
|
|
- 2328 IF isOpen THEN
|
|
|
- 2329 QbeGen.CopyOp("0", qlo);
|
|
|
- 2330 IF SymTab.IsCharArray(t)
|
|
|
- 2331 OR SymTab.IsUCharArray(t) THEN
|
|
|
- 2332 QbeGen.OpenHiChar(q, qhi)
|
|
|
- 2333 ELSE QbeGen.OpenHi(q, qhi)
|
|
|
- 2334 END
|
|
|
- 2335 ELSE
|
|
|
- 2336 lo := SymTab.ArrayLo(t);
|
|
|
- 2337 hi := SymTab.ArrayHi(t);
|
|
|
- 2338 IF SymTab.IsCharArray(t)
|
|
|
- 2339 OR SymTab.IsUCharArray(t) THEN
|
|
|
- 2340 hi := hi + 1
|
|
|
- 2341 END;
|
|
|
- 2342 QbeGen.IntStr(lo, qlo);
|
|
|
- 2343 QbeGen.IntStr(hi, qhi)
|
|
|
- 2344 END;
|
|
|
- 2345 QbeGen.CheckRange(ql, qlo,
|
|
|
- 2346 qhi);
|
|
|
- 2347 eT := SymTab.ArrayElem(t);
|
|
|
- 2348 QbeGen.ElemAddr(q, ql, qlo,
|
|
|
- 2349 t, qe);
|
|
|
- 2350 IF SymTab.ClassOf(eT) =
|
|
|
- 2351 SymTab.ClArray THEN
|
|
|
- 2352 QbeGen.ElemLoad(qe, eT, q)
|
|
|
- 2353 ELSE QbeGen.CopyOp(qe, q)
|
|
|
- 2354 END;
|
|
|
- 2355 t := eT; sfx := TRUE
|
|
|
- 2356 END; .) }
|
|
|
- 2357 "]"
|
|
|
- 2358 | "." GetIdent<fn>
|
|
|
- 2359 (. astSel := AST.MakeNode(AST.NkSelector);
|
|
|
- 2360 AST.SetOp(astSel, AST.SelField);
|
|
|
- 2361 AST.SetChild(astSel, 0, AST.MakeLeaf(AST.NkIdent, fn));
|
|
|
- 2362 AST.SetChild(astDes, AST.NChild(astDes), astSel); IF k = SymTab.KindModule THEN
|
|
|
- 2363 (* qualified L.x: materialize
|
|
|
- 2364 the export, then load it *)
|
|
|
- 2365 IF NOT SymTab.MaterializeAlias(n,
|
|
|
- 2366 fn, mal) THEN
|
|
|
- 2367 SemError(201);
|
|
|
- 2368 t := SymTab.InvalidType;
|
|
|
- 2369 QbeGen.CopyOp("0", q)
|
|
|
- 2370 ELSE
|
|
|
- 2371 QbeGen.CopyOp(mal, qn);
|
|
|
- 2372 t := SymTab.SymType(mal);
|
|
|
- 2373 k := SymTab.SymKind(mal);
|
|
|
- 2374 sfx := FALSE;
|
|
|
- 2375 IF k = SymTab.KindProc THEN
|
|
|
- 2376 (* call: ArgList supplies
|
|
|
- 2377 the value *)
|
|
|
- 2378 QbeGen.CopyOp("0", q)
|
|
|
- 2379 ELSIF NOT QbeGen.LoadDesignator(
|
|
|
- 2380 mal, t, k, q) THEN
|
|
|
- 2381 SemError(230);
|
|
|
- 2382 QbeGen.CopyOp("0", q)
|
|
|
- 2383 END
|
|
|
- 2384 END
|
|
|
- 2385 ELSIF t = SymTab.InvalidType THEN
|
|
|
- 2386 ELSIF (SymTab.ClassOf(t) #
|
|
|
- 2387 SymTab.ClRecord)
|
|
|
- 2388 AND (SymTab.ClassOf(t) #
|
|
|
- 2389 SymTab.ClClass) THEN
|
|
|
- 2390 SemError(215);
|
|
|
- 2391 t := SymTab.InvalidType
|
|
|
- 2392 ELSIF (SymTab.ClassOf(t) =
|
|
|
- 2393 SymTab.ClClass)
|
|
|
- 2394 AND SymTab.MethodExists(t, fn) THEN
|
|
|
- 2395 (* obj.Method: bind the
|
|
|
- 2396 method and pass obj as
|
|
|
- 2397 the hidden receiver; q
|
|
|
- 2398 already holds the
|
|
|
- 2399 object's address *)
|
|
|
- 2400 QbeGen.ArmRecv(q);
|
|
|
- 2401 QbeGen.CopyOp(fn, n);
|
|
|
- 2402 QbeGen.CopyOp(fn, qn);
|
|
|
- 2403 methCls := t;
|
|
|
- 2404 k := SymTab.KindProc;
|
|
|
- 2405 t := SymTab.InvalidType
|
|
|
- 2406 ELSIF NOT SymTab.FieldExists(t,
|
|
|
- 2407 fn) THEN
|
|
|
- 2408 SemError(216);
|
|
|
- 2409 t := SymTab.InvalidType
|
|
|
- 2410 ELSE
|
|
|
- 2411 fo := SymTab.FieldOffset(t,
|
|
|
- 2412 fn);
|
|
|
- 2413 t := SymTab.FieldType(t, fn);
|
|
|
- 2414 QbeGen.FieldAddr(q, fo, qe);
|
|
|
- 2415 (* array fields are inline:
|
|
|
- 2416 the field address is the
|
|
|
- 2417 descriptor, like records *)
|
|
|
- 2418 QbeGen.CopyOp(qe, q);
|
|
|
- 2419 sfx := TRUE
|
|
|
- 2420 END; .)
|
|
|
- 2421 | "^"
|
|
|
- 2422 (. astSel := AST.MakeNode(AST.NkSelector);
|
|
|
- 2423 AST.SetOp(astSel, AST.SelDeref);
|
|
|
- 2424 AST.SetChild(astDes, AST.NChild(astDes), astSel); IF t = SymTab.InvalidType THEN
|
|
|
- 2425 ELSIF SymTab.ClassOf(t) #
|
|
|
- 2426 SymTab.ClPtr THEN
|
|
|
- 2427 SemError(219);
|
|
|
- 2428 t := SymTab.InvalidType
|
|
|
- 2429 ELSE
|
|
|
- 2430 bt := SymTab.PtrBase(t);
|
|
|
- 2431 IF bt = SymTab.InvalidType THEN
|
|
|
- 2432 ELSE
|
|
|
- 2433 IF sfx THEN
|
|
|
- 2434 QbeGen.ElemLoad(q, t,
|
|
|
- 2435 qb);
|
|
|
- 2436 QbeGen.CopyOp(qb, q)
|
|
|
- 2437 END;
|
|
|
- 2438 t := bt;
|
|
|
- 2439 (* q holds the pointee
|
|
|
- 2440 address: Fact loads
|
|
|
- 2441 scalars/pointers and uses
|
|
|
- 2442 the address for
|
|
|
- 2443 aggregates; the VAR-actual
|
|
|
- 2444 note is q itself. *)
|
|
|
- 2445 sfx := TRUE
|
|
|
- 2446 END
|
|
|
- 2447 END; .) } (. astCur := astDes; .) .
|
|
|
- 2448 (* Result suffix (ISO component after a function call): `F()^`,
|
|
|
- 2449 `F()[i]`, `F().field`. The call result is in t/q with sfx FALSE
|
|
|
- 2450 (a value, or a descriptor address for aggregates); each component
|
|
|
- 2451 descends one level exactly like the Design components. *)
|
|
|
- 2452 ResultComp<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal;
|
|
|
- 2453 VAR sfx: BOOLEAN; VAR node: AST.Node> (. VAR it, eT, bt: SymTab.TypeIndex;
|
|
|
- 2454 iq, ql, qlo, qhi, qe, qb:
|
|
|
- 2455 QbeGen.QVal;
|
|
|
- 2456 lo, hi, fo: INTEGER;
|
|
|
- 2457 isOpen: BOOLEAN;
|
|
|
- 2458 fname: SymTab.Name;
|
|
|
- 2459 astWrap, astSel: AST.Node; .)
|
|
|
- 2460 = "[" Expr<it, iq>
|
|
|
- 2461 (. IF AST.Kind(node) # AST.NkDesignator THEN
|
|
|
- 2462 astWrap := AST.MakeNode(
|
|
|
- 2463 AST.NkDesignator);
|
|
|
- 2464 AST.SetChild(astWrap, 0, node);
|
|
|
- 2465 node := astWrap
|
|
|
- 2466 END;
|
|
|
- 2467 AST.SetChild(node, AST.NChild(node),
|
|
|
- 2468 AST.MakeUn(AST.NkSelector,
|
|
|
- 2469 AST.SelIndex, astCur)); IF t = SymTab.InvalidType THEN
|
|
|
- 2470 ELSIF SymTab.ClassOf(t) #
|
|
|
- 2471 SymTab.ClArray THEN
|
|
|
- 2472 SemError(217);
|
|
|
- 2473 t := SymTab.InvalidType
|
|
|
- 2474 ELSIF NOT SymTab.IsIntFamily(it)
|
|
|
- 2475 AND (SymTab.ClassOf(it) # SymTab.ClChar)
|
|
|
- 2476 AND (SymTab.ClassOf(it) # SymTab.ClEnum) THEN
|
|
|
- 2477 SemError(218);
|
|
|
- 2478 t := SymTab.InvalidType
|
|
|
- 2479 ELSE
|
|
|
- 2480 QbeGen.WidenIndex(iq, ql);
|
|
|
- 2481 isOpen :=
|
|
|
- 2482 SymTab.IsOpenArray(t);
|
|
|
- 2483 IF isOpen THEN
|
|
|
- 2484 QbeGen.CopyOp("0", qlo);
|
|
|
- 2485 IF SymTab.IsCharArray(t)
|
|
|
- 2486 OR SymTab.IsUCharArray(t) THEN
|
|
|
- 2487 QbeGen.OpenHiChar(q, qhi)
|
|
|
- 2488 ELSE QbeGen.OpenHi(q, qhi)
|
|
|
- 2489 END
|
|
|
- 2490 ELSE
|
|
|
- 2491 lo := SymTab.ArrayLo(t);
|
|
|
- 2492 hi := SymTab.ArrayHi(t);
|
|
|
- 2493 IF SymTab.IsCharArray(t)
|
|
|
- 2494 OR SymTab.IsUCharArray(t) THEN
|
|
|
- 2495 hi := hi + 1
|
|
|
- 2496 END;
|
|
|
- 2497 QbeGen.IntStr(lo, qlo);
|
|
|
- 2498 QbeGen.IntStr(hi, qhi)
|
|
|
- 2499 END;
|
|
|
- 2500 QbeGen.CheckRange(ql, qlo,
|
|
|
- 2501 qhi);
|
|
|
- 2502 eT := SymTab.ArrayElem(t);
|
|
|
- 2503 QbeGen.ElemAddr(q, ql, qlo,
|
|
|
- 2504 t, qe);
|
|
|
- 2505 IF SymTab.ClassOf(eT) =
|
|
|
- 2506 SymTab.ClArray THEN
|
|
|
- 2507 QbeGen.ElemLoad(qe, eT, q)
|
|
|
- 2508 ELSE QbeGen.CopyOp(qe, q)
|
|
|
- 2509 END;
|
|
|
- 2510 t := eT; sfx := TRUE
|
|
|
- 2511 END; .)
|
|
|
- 2512 "]"
|
|
|
- 2513 | "." GetIdent<fname>
|
|
|
- 2514 (. IF AST.Kind(node) # AST.NkDesignator THEN
|
|
|
- 2515 astWrap := AST.MakeNode(
|
|
|
- 2516 AST.NkDesignator);
|
|
|
- 2517 AST.SetChild(astWrap, 0, node);
|
|
|
- 2518 node := astWrap
|
|
|
- 2519 END;
|
|
|
- 2520 AST.SetChild(node, AST.NChild(node),
|
|
|
- 2521 AST.MakeUn(AST.NkSelector,
|
|
|
- 2522 AST.SelField,
|
|
|
- 2523 AST.MakeLeaf(AST.NkIdent,
|
|
|
- 2524 fname))); IF t = SymTab.InvalidType THEN
|
|
|
- 2525 ELSIF (SymTab.ClassOf(t) #
|
|
|
- 2526 SymTab.ClRecord)
|
|
|
- 2527 AND (SymTab.ClassOf(t) # SymTab.ClClass) THEN
|
|
|
- 2528 SemError(215);
|
|
|
- 2529 t := SymTab.InvalidType
|
|
|
- 2530 ELSIF NOT SymTab.FieldExists(t,
|
|
|
- 2531 fname) THEN
|
|
|
- 2532 SemError(216);
|
|
|
- 2533 t := SymTab.InvalidType
|
|
|
- 2534 ELSE
|
|
|
- 2535 fo := SymTab.FieldOffset(t,
|
|
|
- 2536 fname);
|
|
|
- 2537 t := SymTab.FieldType(t, fname);
|
|
|
- 2538 QbeGen.FieldAddr(q, fo, qe);
|
|
|
- 2539 QbeGen.CopyOp(qe, q);
|
|
|
- 2540 sfx := TRUE
|
|
|
- 2541 END; .)
|
|
|
- 2542 | "^" (. IF AST.Kind(node) # AST.NkDesignator THEN
|
|
|
- 2543 astWrap := AST.MakeNode(
|
|
|
- 2544 AST.NkDesignator);
|
|
|
- 2545 AST.SetChild(astWrap, 0, node);
|
|
|
- 2546 node := astWrap
|
|
|
- 2547 END;
|
|
|
- 2548 astSel := AST.MakeNode(AST.NkSelector);
|
|
|
- 2549 AST.SetOp(astSel, AST.SelDeref);
|
|
|
- 2550 AST.SetChild(node,
|
|
|
- 2551 AST.NChild(node), astSel); IF t = SymTab.InvalidType THEN
|
|
|
- 2552 ELSIF SymTab.ClassOf(t) #
|
|
|
- 2553 SymTab.ClPtr THEN
|
|
|
- 2554 SemError(219);
|
|
|
- 2555 t := SymTab.InvalidType
|
|
|
- 2556 ELSE
|
|
|
- 2557 bt := SymTab.PtrBase(t);
|
|
|
- 2558 IF bt # SymTab.InvalidType THEN
|
|
|
- 2559 IF sfx THEN
|
|
|
- 2560 QbeGen.ElemLoad(q, t, qb);
|
|
|
- 2561 QbeGen.CopyOp(qb, q)
|
|
|
- 2562 END;
|
|
|
- 2563 t := bt; sfx := TRUE
|
|
|
- 2564 END
|
|
|
- 2565 END; .) .
|
|
|
- 2566 Expr<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
- 2567 (. VAR t2: SymTab.TypeIndex;
|
|
|
- 2568 op: INTEGER;
|
|
|
- 2569 q2, qt, wl: QbeGen.QVal;
|
|
|
- 2570 astA, astB: AST.Node;
|
|
|
- 2571 astOp: INTEGER;
|
|
|
- 2572 astMade: BOOLEAN;
|
|
|
- 2573 isR: BOOLEAN; .)
|
|
|
- 2574 = SimExpr<t, q> (. astA := astCur; astMade := FALSE; .)
|
|
|
- 2575 [ Rel<op> SimExpr<t2, q2>
|
|
|
- 2576 (. astB := astCur; astMade := TRUE;
|
|
|
- 2577 astOp := AST.OpEq;
|
|
|
- 2578 IF op = SymTab.OpNeq1 THEN astOp := AST.OpNe
|
|
|
- 2579 ELSIF op = SymTab.OpNeq2 THEN astOp := AST.OpNe
|
|
|
- 2580 ELSIF op = SymTab.OpLt THEN astOp := AST.OpLt
|
|
|
- 2581 ELSIF op = SymTab.OpLe THEN astOp := AST.OpLe
|
|
|
- 2582 ELSIF op = SymTab.OpGt THEN astOp := AST.OpGt
|
|
|
- 2583 ELSIF op = SymTab.OpGe THEN astOp := AST.OpGe
|
|
|
- 2584 ELSIF op = SymTab.OpIn THEN astOp := AST.OpIn
|
|
|
- 2585 END;
|
|
|
- 2586 IF op = SymTab.OpIn THEN
|
|
|
- 2587 IF SymTab.InCheck(t, t2) THEN
|
|
|
- 2588 IF (t = SymTab.InvalidType)
|
|
|
- 2589 OR (t2 = SymTab.InvalidType) THEN
|
|
|
- 2590 t := SymTab.BoolType(); QbeGen.CopyOp("0", q)
|
|
|
- 2591 ELSE
|
|
|
- 2592 t := SymTab.BoolType(); QbeGen.CopyOp("@", q)
|
|
|
- 2593 END
|
|
|
- 2594 ELSE SemError(222); t := SymTab.InvalidType;
|
|
|
- 2595 QbeGen.CopyOp("0", q)
|
|
|
- 2596 END
|
|
|
- 2597 ELSIF SymTab.RelCheck(t, t2, op) THEN
|
|
|
- 2598 IF (t = SymTab.InvalidType)
|
|
|
- 2599 OR (t2 = SymTab.InvalidType) THEN
|
|
|
- 2600 t := SymTab.BoolType(); QbeGen.CopyOp("0", q)
|
|
|
- 2601 ELSIF (SymTab.ClassOf(t) = SymTab.ClPtr)
|
|
|
- 2602 OR (SymTab.ClassOf(t2) = SymTab.ClPtr) THEN
|
|
|
- 2603 IF SymTab.IsFwdVar(t) OR SymTab.IsFwdVar(t2) THEN
|
|
|
- 2604 t := SymTab.BoolType(); QbeGen.CopyOp("@", q)
|
|
|
- 2605 ELSIF (op # SymTab.OpEq) AND (op # SymTab.OpNeq1)
|
|
|
- 2606 AND (op # SymTab.OpNeq2) THEN
|
|
|
- 2607 SemError(213); t := SymTab.InvalidType;
|
|
|
- 2608 QbeGen.CopyOp("0", q)
|
|
|
- 2609 ELSE
|
|
|
- 2610 t := SymTab.BoolType(); QbeGen.CopyOp("@", q)
|
|
|
- 2611 END
|
|
|
- 2612 ELSIF (SymTab.ClassOf(t) = SymTab.ClSet)
|
|
|
- 2613 OR (SymTab.ClassOf(t2) = SymTab.ClSet) THEN
|
|
|
- 2614 t := SymTab.BoolType(); QbeGen.CopyOp("@", q)
|
|
|
- 2615 ELSIF SymTab.StrCompat(t, t2) THEN
|
|
|
- 2616 QbeGen.StrEq(op, q, q2, qt);
|
|
|
- 2617 t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
|
|
|
- 2618 ELSIF SymTab.IsLongFamily(t)
|
|
|
- 2619 OR SymTab.IsLongFamily(t2) THEN
|
|
|
- 2620 t := SymTab.BoolType(); QbeGen.CopyOp("@", q)
|
|
|
- 2621 ELSE
|
|
|
- 2622 t := SymTab.BoolType();
|
|
|
- 2623 QbeGen.CopyOp("@", q)
|
|
|
- 2624 END
|
|
|
- 2625 ELSE SemError(213); t := SymTab.InvalidType;
|
|
|
- 2626 QbeGen.CopyOp("0", q)
|
|
|
- 2627 END;
|
|
|
- 2628 astCur := AST.MakeBin(AST.NkBinExpr, astOp, astA, astB); .) ]
|
|
|
- 2629 (. IF NOT astMade THEN astCur := astA END; .) .
|
|
|
- 2630 Rel<VAR op: INTEGER>
|
|
|
- 2631 = "=" (. op := SymTab.OpEq; .)
|
|
|
- 2632 | "#" (. op := SymTab.OpNeq1; .)
|
|
|
- 2633 | "<" (. op := SymTab.OpLt; .)
|
|
|
- 2634 | "<=" (. op := SymTab.OpLe; .)
|
|
|
- 2635 | ">" (. op := SymTab.OpGt; .)
|
|
|
- 2636 | ">=" (. op := SymTab.OpGe; .)
|
|
|
- 2637 | "IN" (. op := SymTab.OpIn; .) .
|
|
|
- 2638 SimExpr<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
- 2639 (. VAR t2, res2, lt, rt:
|
|
|
- 2640 SymTab.TypeIndex;
|
|
|
- 2641 op: INTEGER;
|
|
|
- 2642 q2, qt, wq, qf, q2a, q2b:
|
|
|
- 2643 QbeGen.QVal;
|
|
|
- 2644 neg, isR, isL, folded:
|
|
|
- 2645 BOOLEAN;
|
|
|
- 2646 fok: BOOLEAN;
|
|
|
- 2647 lw, rw, mw: CARDINAL;
|
|
|
- 2648 lTrue, lNext, lDone, qr, qs: QbeGen.QVal;
|
|
|
- 2649 astA, astB: AST.Node;
|
|
|
- 2650 astSign, astOp: INTEGER; .)
|
|
|
- 2651 = (. neg := FALSE; astSign := 0; .)
|
|
|
- 2652 [ "+" (. neg := TRUE; astSign := 1; .)
|
|
|
- 2653 | "-" (. neg := TRUE; astSign := -1; .) ]
|
|
|
- 2654 Term<t, q> (. astA := astCur;
|
|
|
- 2655 IF neg AND QbeGen.IsImm(q) THEN
|
|
|
- 2656 QbeGen.NegFold(q, q)
|
|
|
- 2657 END;
|
|
|
- 2658 IF astSign < 0 THEN
|
|
|
- 2659 astCur := AST.MakeUn(
|
|
|
- 2660 AST.NkUnary, AST.OpSub, astA);
|
|
|
- 2661 astA := astCur
|
|
|
- 2662 END; .)
|
|
|
- 2663 { AddOp<op> (. IF op = SymTab.OpOr THEN
|
|
|
- 2664 QbeGen.DelayBegin END; .)
|
|
|
- 2665 Term<t2, q2> (. astB := astCur; IF op = SymTab.OpOr THEN
|
|
|
- 2666 QbeGen.DelayEnd END; .)
|
|
|
- 2667 (. astOp := AST.OpAdd;
|
|
|
- 2668 IF op = SymTab.OpSub THEN astOp := AST.OpSub
|
|
|
- 2669 ELSIF op = SymTab.OpOr THEN astOp := AST.OpOr END;
|
|
|
- 2670 astA := AST.MakeBin(AST.NkBinExpr, astOp, astA, astB);
|
|
|
- 2671 astCur := astA;
|
|
|
- 2672 IF op = SymTab.OpOr THEN
|
|
|
- 2673 (* short-circuit: if q is true the RHS is skipped *)
|
|
|
- 2674 IF SymTab.BoolCheck(t) AND SymTab.BoolCheck(t2) THEN
|
|
|
- 2675 t := SymTab.BoolType()
|
|
|
- 2676 ELSE SemError(212); t := SymTab.InvalidType END;
|
|
|
- 2677 IF t # SymTab.InvalidType THEN
|
|
|
- 2678 QbeGen.CopyOp("@", q)
|
|
|
- 2679 ELSE QbeGen.CopyOp("0", q)
|
|
|
- 2680 END
|
|
|
- 2681 ELSIF (op = SymTab.OpAdd)
|
|
|
- 2682 AND (SymTab.UStrCompat(t, t2)
|
|
|
- 2683 OR ((SymTab.ClassOf(t) = SymTab.ClUChar)
|
|
|
- 2684 AND (SymTab.ClassOf(t2) = SymTab.ClUStr))
|
|
|
- 2685 OR ((SymTab.ClassOf(t) = SymTab.ClUStr)
|
|
|
- 2686 AND (SymTab.ClassOf(t2) = SymTab.ClUChar))
|
|
|
- 2687 OR ((SymTab.ClassOf(t) = SymTab.ClUChar)
|
|
|
- 2688 AND (SymTab.ClassOf(t2) = SymTab.ClUChar))) THEN
|
|
|
- 2689 (* UString concatenation: a UCHAR operand becomes a
|
|
|
- 2690 1-codepoint UString; the result is a descriptor in the
|
|
|
- 2691 shim's concat buffer. Work on copies so neither
|
|
|
- 2692 operand is clobbered. *)
|
|
|
- 2693 t := SymTab.NewUStr();
|
|
|
- 2694 QbeGen.CopyOp("@", q)
|
|
|
- 2695 ELSIF (op = SymTab.OpAdd)
|
|
|
- 2696 AND (SymTab.StrCompat(t, t2)
|
|
|
- 2697 OR (SymTab.IsStrType(t)
|
|
|
- 2698 AND (SymTab.ClassOf(t2) = SymTab.ClChar))
|
|
|
- 2699 OR ((SymTab.ClassOf(t) = SymTab.ClChar)
|
|
|
- 2700 AND SymTab.IsStrType(t2))) THEN
|
|
|
- 2701 (* string concatenation; a CHAR operand becomes a
|
|
|
- 2702 1-character string literal. When both operands are
|
|
|
- 2703 constants, fold to a single string literal so a
|
|
|
- 2704 constructor element stays compile-time. *)
|
|
|
- 2705 QbeGen.StrFold(q, q2, SymTab.ClassOf(t), SymTab.ClassOf(t2),
|
|
|
- 2706 qt, fok);
|
|
|
- 2707 IF fok THEN QbeGen.CopyOp(qt, q)
|
|
|
- 2708 ELSE QbeGen.CopyOp("@", q)
|
|
|
- 2709 END;
|
|
|
- 2710 t := SymTab.NewStr()
|
|
|
- 2711 ELSIF (t # SymTab.InvalidType) AND (t2 # SymTab.InvalidType)
|
|
|
- 2712 AND (SymTab.ClassOf(t) = SymTab.ClSet)
|
|
|
- 2713 AND (SymTab.ClassOf(t2) = SymTab.ClSet) THEN
|
|
|
- 2714 lw := SymTab.SetWords(t); rw := SymTab.SetWords(t2);
|
|
|
- 2715 mw := lw;
|
|
|
- 2716 IF rw > mw THEN mw := rw END;
|
|
|
- 2717 t := SymTab.NewSet(
|
|
|
- 2718 SymTab.NewSubR(0,
|
|
|
- 2719 VAL(INTEGER, mw) * 32 - 1));
|
|
|
- 2720 QbeGen.CopyOp("@", q)
|
|
|
- 2721 ELSE
|
|
|
- 2722 IF SymTab.ArithCheck(t, t2, FALSE, res2) THEN
|
|
|
- 2723 lt := t; rt := t2; t := res2
|
|
|
- 2724 ELSE SemError(211); t := SymTab.InvalidType END;
|
|
|
- 2725 IF t # SymTab.InvalidType THEN
|
|
|
- 2726 isL := SymTab.IsLongFamily(t);
|
|
|
- 2727 isR := SymTab.ClassOf(t) = SymTab.ClReal;
|
|
|
- 2728 folded := FALSE;
|
|
|
- 2729 IF (NOT isL) AND (NOT isR)
|
|
|
- 2730 AND QbeGen.IsImm(q) AND QbeGen.IsImm(q2) THEN
|
|
|
- 2731 IF op = SymTab.OpAdd THEN
|
|
|
- 2732 folded := QbeGen.Fold2(0, q, q2, qf)
|
|
|
- 2733 ELSE
|
|
|
- 2734 folded := QbeGen.Fold2(1, q, q2, qf)
|
|
|
- 2735 END
|
|
|
- 2736 END;
|
|
|
- 2737 IF folded THEN QbeGen.CopyOp(qf, q)
|
|
|
- 2738 ELSE
|
|
|
- 2739 QbeGen.CopyOp("@", q)
|
|
|
- 2740 END
|
|
|
- 2741 ELSE QbeGen.CopyOp("0", q)
|
|
|
- 2742 END
|
|
|
- 2743 END; .) } .
|
|
|
- 2744 AddOp<VAR op: INTEGER>
|
|
|
- 2745 = "+" (. op := SymTab.OpAdd; .)
|
|
|
- 2746 | "-" (. op := SymTab.OpSub; .)
|
|
|
- 2747 | "OR" (. op := SymTab.OpOr; .) .
|
|
|
- 2748 Term<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
- 2749 (. VAR t2, res2, lt, rt:
|
|
|
- 2750 SymTab.TypeIndex;
|
|
|
- 2751 op: INTEGER;
|
|
|
- 2752 q2, qt, wq, qf:
|
|
|
- 2753 QbeGen.QVal;
|
|
|
- 2754 isR, isL, folded: BOOLEAN;
|
|
|
- 2755 lw, rw, mw: CARDINAL;
|
|
|
- 2756 lNext, lFalse, lDone, qr, qs: QbeGen.QVal;
|
|
|
- 2757 astA, astB: AST.Node;
|
|
|
- 2758 astOp: INTEGER; .)
|
|
|
- 2759 = Fact<t, q> (. astA := astCur; .) { MulOp<op>
|
|
|
- 2760 Fact<t2, q2> (. astB := astCur; .)
|
|
|
- 2761 (. astOp := AST.OpMul;
|
|
|
- 2762 IF op = SymTab.OpSlash THEN astOp := AST.OpDiv
|
|
|
- 2763 ELSIF op = SymTab.OpDiv THEN astOp := AST.OpDiv
|
|
|
- 2764 ELSIF op = SymTab.OpMod THEN astOp := AST.OpMod
|
|
|
- 2765 ELSIF op = SymTab.OpAnd THEN astOp := AST.OpAnd END;
|
|
|
- 2766 astA := AST.MakeBin(AST.NkBinExpr, astOp, astA, astB);
|
|
|
- 2767 astCur := astA;
|
|
|
- 2768 IF op = SymTab.OpAnd THEN
|
|
|
- 2769 (* short-circuit: if q is false the RHS is skipped *)
|
|
|
- 2770 IF SymTab.BoolCheck(t) AND SymTab.BoolCheck(t2) THEN
|
|
|
- 2771 t := SymTab.BoolType()
|
|
|
- 2772 ELSE SemError(212); t := SymTab.InvalidType END;
|
|
|
- 2773 IF t # SymTab.InvalidType THEN QbeGen.CopyOp("@", q)
|
|
|
- 2774 ELSE QbeGen.CopyOp("0", q)
|
|
|
- 2775 END
|
|
|
- 2776 ELSIF (t # SymTab.InvalidType) AND (t2 # SymTab.InvalidType)
|
|
|
- 2777 AND (SymTab.ClassOf(t) = SymTab.ClSet)
|
|
|
- 2778 AND (SymTab.ClassOf(t2) = SymTab.ClSet) THEN
|
|
|
- 2779 lw := SymTab.SetWords(t); rw := SymTab.SetWords(t2);
|
|
|
- 2780 mw := lw;
|
|
|
- 2781 IF rw > mw THEN mw := rw END;
|
|
|
- 2782 t := SymTab.NewSet(
|
|
|
- 2783 SymTab.NewSubR(0,
|
|
|
- 2784 VAL(INTEGER, mw) * 32 - 1));
|
|
|
- 2785 QbeGen.CopyOp("@", q)
|
|
|
- 2786 ELSE
|
|
|
- 2787 IF SymTab.ArithCheck(t, t2,
|
|
|
- 2788 (op = SymTab.OpDiv) OR (op = SymTab.OpMod),
|
|
|
- 2789 res2) THEN
|
|
|
- 2790 lt := t; rt := t2; t := res2
|
|
|
- 2791 ELSE SemError(211); t := SymTab.InvalidType END;
|
|
|
- 2792 IF t # SymTab.InvalidType THEN
|
|
|
- 2793 isL := SymTab.IsLongFamily(t);
|
|
|
- 2794 isR := SymTab.ClassOf(t) = SymTab.ClReal;
|
|
|
- 2795 folded := FALSE;
|
|
|
- 2796 IF (NOT isL) AND (NOT isR)
|
|
|
- 2797 AND QbeGen.IsImm(q) AND QbeGen.IsImm(q2) THEN
|
|
|
- 2798 IF op = SymTab.OpTimes THEN
|
|
|
- 2799 folded := QbeGen.Fold2(2, q, q2, qf)
|
|
|
- 2800 ELSIF op = SymTab.OpDiv THEN
|
|
|
- 2801 folded := QbeGen.Fold2(3, q, q2, qf)
|
|
|
- 2802 ELSIF op = SymTab.OpMod THEN
|
|
|
- 2803 folded := QbeGen.Fold2(4, q, q2, qf)
|
|
|
- 2804 END
|
|
|
- 2805 END;
|
|
|
- 2806 IF folded THEN QbeGen.CopyOp(qf, q)
|
|
|
- 2807 ELSE
|
|
|
- 2808 QbeGen.CopyOp("@", q)
|
|
|
- 2809 END
|
|
|
- 2810 ELSE QbeGen.CopyOp("0", q)
|
|
|
- 2811 END
|
|
|
- 2812 END; .) } .
|
|
|
- 2813 MulOp<VAR op: INTEGER>
|
|
|
- 2814 = "*" (. op := SymTab.OpTimes; .)
|
|
|
- 2815 | "/" (. op := SymTab.OpSlash; .)
|
|
|
- 2816 | "DIV" (. op := SymTab.OpDiv; .)
|
|
|
- 2817 | "MOD" (. op := SymTab.OpMod; .)
|
|
|
- 2818 | ( "AND" | "&" ) (. op := SymTab.OpAnd; .) .
|
|
|
- 2819 Fact<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
- 2820 (. VAR s: ARRAY [0 .. 255] OF CHAR;
|
|
|
- 2821 et, dt, t2, st, ct2, et2:
|
|
|
- 2822 SymTab.TypeIndex;
|
|
|
- 2823 dk: INTEGER;
|
|
|
- 2824 qd, q2, sq, qa, qm0, qr, qt:
|
|
|
- 2825 QbeGen.QVal;
|
|
|
- 2826 qn, vn: SymTab.Name;
|
|
|
- 2827 vt: SymTab.TypeIndex;
|
|
|
- 2828 c1, c2: INTEGER;
|
|
|
- 2829 lo, hi: INTEGER;
|
|
|
- 2830 isMax: BOOLEAN;
|
|
|
- 2831 called, isHigh, sfx, isCh,
|
|
|
- 2832 isU, uok, isStr: BOOLEAN;
|
|
|
- 2833 ucp: INTEGER; astIsLit: BOOLEAN;
|
|
|
- 2834 astD: AST.Node;
|
|
|
- 2835 astCall: BOOLEAN;
|
|
|
- 2836 astNode, astNot: AST.Node;
|
|
|
- 2837 j: CARDINAL;
|
|
|
- 2838 astArg2: AST.Node;
|
|
|
- 2839 astBrace: AST.Node;
|
|
|
- 2840 astRes: AST.Node; .)
|
|
|
- 2841 = (. astIsLit := FALSE; .)
|
|
|
- 2842 ( integer (. LexString(s);
|
|
|
- 2843 QbeGen.NormInt(s, q); IF twoPhase THEN astIsLit := TRUE; astCur := AST.MakeLeaf(AST.NkIntLit, s) END;
|
|
|
- 2844 t := SymTab.IntType(); .)
|
|
|
- 2845 | charConst (. LexString(s);
|
|
|
- 2846 QbeGen.NormLit(s, q, isCh);
|
|
|
- 2847 IF twoPhase THEN
|
|
|
- 2848 astIsLit := TRUE;
|
|
|
- 2849 astCur := AST.MakeLeaf(
|
|
|
- 2850 AST.NkCharLit, s)
|
|
|
- 2851 END;
|
|
|
- 2852 t := SymTab.CharType(); .)
|
|
|
- 2853 | real (. LexString(s);
|
|
|
- 2854 QbeGen.NormReal(s, q);
|
|
|
- 2855 IF twoPhase THEN
|
|
|
- 2856 astIsLit := TRUE;
|
|
|
- 2857 astCur := AST.MakeLeaf(
|
|
|
- 2858 AST.NkRealLit, s)
|
|
|
- 2859 END;
|
|
|
- 2860 t := SymTab.RealType(); .)
|
|
|
- 2861 | string (. LexString(s);
|
|
|
- 2862 IF twoPhase THEN
|
|
|
- 2863 astIsLit := TRUE;
|
|
|
- 2864 astCur := AST.MakeLeaf(
|
|
|
- 2865 AST.NkStrLit, s)
|
|
|
- 2866 END;
|
|
|
- 2867 IF SymTab.StrLen(s) = 3 THEN
|
|
|
- 2868 t := SymTab.CharType();
|
|
|
- 2869 QbeGen.IntStr(
|
|
|
- 2870 QbeGen.CharVal(s), q)
|
|
|
- 2871 ELSE t := SymTab.NewStr();
|
|
|
- 2872 QbeGen.DeclStr(s, q);
|
|
|
- 2873 (* a literal's value IS its
|
|
|
- 2874 static descriptor address *)
|
|
|
- 2875 QbeGen.NoteAddr(q, q)
|
|
|
- 2876 END; .)
|
|
|
- 2877 | ustring (. LexString(s);
|
|
|
- 2878 IF twoPhase THEN
|
|
|
- 2879 astIsLit := TRUE;
|
|
|
- 2880 astCur := AST.MakeLeaf(
|
|
|
- 2881 AST.NkStrLit, s)
|
|
|
- 2882 END;
|
|
|
- 2883 QbeGen.DeclUStr(s, q, isU, ucp,
|
|
|
- 2884 uok);
|
|
|
- 2885 IF NOT uok THEN
|
|
|
- 2886 SemError(234);
|
|
|
- 2887 t := SymTab.InvalidType
|
|
|
- 2888 ELSIF isU THEN
|
|
|
- 2889 t := SymTab.UCharType();
|
|
|
- 2890 QbeGen.IntStr(ucp, q)
|
|
|
- 2891 ELSE
|
|
|
- 2892 t := SymTab.NewUStr();
|
|
|
- 2893 QbeGen.NoteAddr(q, q)
|
|
|
- 2894 END; .)
|
|
|
- 2895 | Design<dt, dk, qd, qn, sfx> (. astD := astCur; astCall := FALSE; astBrace := AST.NoNode;
|
|
|
- 2896 astNArgs := 0; called := FALSE;
|
|
|
- 2897 t := dt;
|
|
|
- 2898 IF sfx THEN
|
|
|
- 2899 IF dt =
|
|
|
- 2900 SymTab.InvalidType THEN
|
|
|
- 2901 QbeGen.CopyOp("0", q)
|
|
|
- 2902 ELSIF (SymTab.ClassOf(dt) =
|
|
|
- 2903 SymTab.ClRecord)
|
|
|
- 2904 OR (SymTab.ClassOf(dt) =
|
|
|
- 2905 SymTab.ClSet)
|
|
|
- 2906 OR (SymTab.ClassOf(dt) =
|
|
|
- 2907 SymTab.ClArray)
|
|
|
- 2908 OR (SymTab.ClassOf(dt) =
|
|
|
- 2909 SymTab.ClClass) THEN
|
|
|
- 2910 QbeGen.CopyOp(qd, q)
|
|
|
- 2911 ELSE QbeGen.ElemLoad(qd, dt,
|
|
|
- 2912 q)
|
|
|
- 2913 END
|
|
|
- 2914 ELSE QbeGen.CopyOp(qd, q)
|
|
|
- 2915 END;
|
|
|
- 2916 IF (dk = SymTab.KindVar)
|
|
|
- 2917 OR (dk = SymTab.KindParam)
|
|
|
- 2918 OR (dk =
|
|
|
- 2919 SymTab.KindField) THEN
|
|
|
- 2920 IF sfx THEN
|
|
|
- 2921 QbeGen.NoteAddr(q, qd)
|
|
|
- 2922 ELSE
|
|
|
- 2923 QbeGen.AddrOf(qn, qa);
|
|
|
- 2924 QbeGen.NoteAddr(q, qa)
|
|
|
- 2925 END
|
|
|
- 2926 ELSIF sfx
|
|
|
- 2927 AND (dt #
|
|
|
- 2928 SymTab.InvalidType)
|
|
|
- 2929 AND ((SymTab.ClassOf(dt) =
|
|
|
- 2930 SymTab.ClArray)
|
|
|
- 2931 OR (SymTab.ClassOf(dt) =
|
|
|
- 2932 SymTab.ClSet)
|
|
|
- 2933 OR (SymTab.ClassOf(dt) =
|
|
|
- 2934 SymTab.ClRecord)) THEN
|
|
|
- 2935 QbeGen.NoteAddr(qd, qd)
|
|
|
- 2936 END; .)
|
|
|
- 2937 [ TypedBraceLit<dt, q> (. t := dt; astCall := TRUE;
|
|
|
- 2938 astBrace := astCur; .) ]
|
|
|
- 2939 [ ArgList<qn, dt, qd, TRUE, FALSE, methCls, ct2, q2, called>
|
|
|
- 2940 (. astCall := TRUE;
|
|
|
- 2941 astNode := AstCallNode(astD);
|
|
|
- 2942 astRes := astNode;
|
|
|
- 2943 t := ct2;
|
|
|
- 2944 QbeGen.CopyOp(q2, q);
|
|
|
- 2945 sfx := FALSE; .)
|
|
|
- 2946 { ResultComp<t, q, sfx, astRes> }
|
|
|
- 2947 (. IF sfx THEN
|
|
|
- 2948 IF t = SymTab.InvalidType THEN
|
|
|
- 2949 QbeGen.CopyOp("0", q)
|
|
|
- 2950 ELSIF (SymTab.ClassOf(t) #
|
|
|
- 2951 SymTab.ClRecord)
|
|
|
- 2952 AND (SymTab.ClassOf(t) # SymTab.ClSet)
|
|
|
- 2953 AND (SymTab.ClassOf(t) # SymTab.ClArray)
|
|
|
- 2954 AND (SymTab.ClassOf(t) # SymTab.ClClass) THEN
|
|
|
- 2955 QbeGen.CopyOp("@", q)
|
|
|
- 2956 END
|
|
|
- 2957 END; .) ]
|
|
|
- 2958 (. IF called THEN
|
|
|
- 2959 astCur := astRes
|
|
|
- 2960 ELSIF astCall THEN
|
|
|
- 2961 astCur := astBrace
|
|
|
- 2962 ELSE astCur := astD
|
|
|
- 2963 END;
|
|
|
- 2964 astIsLit := TRUE;
|
|
|
- 2965 IF NOT called
|
|
|
- 2966 AND (dk = SymTab.KindProc) THEN
|
|
|
- 2967 (* bare zero-arg function
|
|
|
- 2968 call (parentheses may be
|
|
|
- 2969 omitted); a proper or
|
|
|
- 2970 parameterised proc here
|
|
|
- 2971 is 230 *)
|
|
|
- 2972 IF (SymTab.ProcNPar(qn) = 0)
|
|
|
- 2973 AND (SymTab.ProcRes(qn) # SymTab.InvalidType) THEN
|
|
|
- 2974 t := SymTab.ProcRes(qn);
|
|
|
- 2975 QbeGen.CopyOp("@", q);
|
|
|
- 2976 astCur := AST.MakeNode(AST.NkCall);
|
|
|
- 2977 AST.SetChild(astCur, 0, astD)
|
|
|
- 2978 ELSE
|
|
|
- 2979 t := SymTab.ProcTypeOf(qn);
|
|
|
- 2980 QbeGen.CopyOp("@", q)
|
|
|
+ 1971 conv := FALSE;
|
|
|
+ 1972 IF NOT SymTab.InProc() THEN
|
|
|
+ 1973 SemError(232)
|
|
|
+ 1974 ELSE res := SymTab.CurRes();
|
|
|
+ 1975 IF NOT hadE THEN
|
|
|
+ 1976 IF res #
|
|
|
+ 1977 SymTab.InvalidType THEN
|
|
|
+ 1978 SemError(232)
|
|
|
+ 1979 END
|
|
|
+ 1980 ELSIF (res =
|
|
|
+ 1981 SymTab.InvalidType)
|
|
|
+ 1982 OR (t #
|
|
|
+ 1983 SymTab.InvalidType)
|
|
|
+ 1984 AND NOT SymTab.Assignable(t,
|
|
|
+ 1985 res) THEN
|
|
|
+ 1986 SemError(232)
|
|
|
+ 1987 END
|
|
|
+ 1988 END; .) .
|
|
|
+ 1989 HaltStat (. VAR t: SymTab.TypeIndex;
|
|
|
+ 1990 q: QbeGen.QVal;
|
|
|
+ 1991 astVal, astNode: AST.Node; .)
|
|
|
+ 1992 = "HALT" (. astVal := AST.NoNode; .)
|
|
|
+ 1993 [ "(" Expr<t, q> (. astVal := astCur; .) ")" ]
|
|
|
+ 1994 (. astNode := AST.MakeNode(AST.NkHalt);
|
|
|
+ 1995 IF astVal # AST.NoNode THEN
|
|
|
+ 1996 AST.SetChild(astNode, 0, astVal)
|
|
|
+ 1997 END;
|
|
|
+ 1998 astStmt := astNode;
|
|
|
+ 1999 .) .
|
|
|
+ 2000 (* Designator: scalar loads, array addresses, and index suffixes.
|
|
|
+ 2001 Each index descends one level (bounds-checked, trap on breach);
|
|
|
+ 2002 nested levels reload the inner descriptor address. q ends as the
|
|
|
+ 2003 value (scalars), the descriptor address (plain arrays), or the
|
|
|
+ 2004 element address (indexed); sfx marks the indexed form. *)
|
|
|
+ 2005 Design<VAR t: SymTab.TypeIndex; VAR k: INTEGER;
|
|
|
+ 2006 VAR q: QbeGen.QVal; VAR qn: SymTab.Name; VAR sfx: BOOLEAN>
|
|
|
+ 2007 (. VAR n, fn, mal: SymTab.Name;
|
|
|
+ 2008 cls: INTEGER;
|
|
|
+ 2009 ic: SymTab.TypeIndex;
|
|
|
+ 2010 curT, it, eT, bt:
|
|
|
+ 2011 SymTab.TypeIndex;
|
|
|
+ 2012 iq, ql, qlo, qhi, qe:
|
|
|
+ 2013 QbeGen.QVal;
|
|
|
+ 2014 lo, hi: INTEGER;
|
|
|
+ 2015 fo: INTEGER;
|
|
|
+ 2016 isOpen: BOOLEAN;
|
|
|
+ 2017 qb, cv: QbeGen.QVal;
|
|
|
+ 2018 fid, fref, slot: INTEGER;
|
|
|
+ 2019 r: BOOLEAN;
|
|
|
+ 2020 astDes, astSel: AST.Node;
|
|
|
+ 2021 fwd: BOOLEAN; .)
|
|
|
+ 2022 = GetIdent<n> (. methCls := SymTab.InvalidType;
|
|
|
+ 2023 QbeGen.CopyOp(n, qn);
|
|
|
+ 2024 sfx := FALSE; fwd := FALSE;
|
|
|
+ 2025 fid := 0; fref := 0; slot := 0;
|
|
|
+ 2026 IF NOT SymTab.Lookup(n) THEN
|
|
|
+ 2027 (* a bare method name inside
|
|
|
+ 2028 a CLASS IMPLEMENTATION
|
|
|
+ 2029 is a sibling call on
|
|
|
+ 2030 THIS *)
|
|
|
+ 2031 ic := SymTab.CurImplClass();
|
|
|
+ 2032 IF (ic #
|
|
|
+ 2033 SymTab.InvalidType)
|
|
|
+ 2034 AND SymTab.MethodExists(ic, n) THEN
|
|
|
+ 2035 sfx := FALSE;
|
|
|
+ 2036 QbeGen.ThisBase(q);
|
|
|
+ 2037 QbeGen.ArmRecv(q);
|
|
|
+ 2038 methCls := ic;
|
|
|
+ 2039 k := SymTab.KindProc;
|
|
|
+ 2040 t := SymTab.InvalidType
|
|
|
+ 2041 ELSIF SymTab.InProc() THEN
|
|
|
+ 2042 (* not declared yet: a
|
|
|
+ 2043 forward reference to a
|
|
|
+ 2044 module-level variable
|
|
|
+ 2045 declared further down. *)
|
|
|
+ 2046 k := SymTab.KindVar;
|
|
|
+ 2047 r := SymTab.FwdVarRef(n, k,
|
|
|
+ 2048 fref, t);
|
|
|
+ 2049 slot := QbeGen.FwdDesignator();
|
|
|
+ 2050 FwdVarNote(fref, slot);
|
|
|
+ 2051 fid := slot;
|
|
|
+ 2052 QbeGen.FwdAddrOper(fid, q);
|
|
|
+ 2053 sfx := TRUE; fwd := TRUE
|
|
|
+ 2054 ELSE
|
|
|
+ 2055 SemError(201);
|
|
|
+ 2056 t :=
|
|
|
+ 2057 SymTab.InvalidType;
|
|
|
+ 2058 k := -1;
|
|
|
+ 2059 QbeGen.CopyOp("0", q)
|
|
|
+ 2060 END
|
|
|
+ 2061 ELSE
|
|
|
+ 2062 t := SymTab.SymType(n);
|
|
|
+ 2063 k := SymTab.SymKind(n);
|
|
|
+ 2064 IF k = SymTab.KindConst THEN
|
|
|
+ 2065 IF SymTab.Equal(n,
|
|
|
+ 2066 "TRUE") THEN
|
|
|
+ 2067 t := SymTab.BoolType();
|
|
|
+ 2068 QbeGen.CopyOp("1", q)
|
|
|
+ 2069 ELSIF SymTab.Equal(n,
|
|
|
+ 2070 "FALSE") THEN
|
|
|
+ 2071 t := SymTab.BoolType();
|
|
|
+ 2072 QbeGen.CopyOp("0", q)
|
|
|
+ 2073 ELSIF SymTab.Equal(n,
|
|
|
+ 2074 "NIL") THEN
|
|
|
+ 2075 QbeGen.CopyOp("0", q)
|
|
|
+ 2076 ELSE
|
|
|
+ 2077 cls :=
|
|
|
+ 2078 SymTab.ClassOf(t);
|
|
|
+ 2079 IF (t #
|
|
|
+ 2080 SymTab.InvalidType)
|
|
|
+ 2081 AND ((cls = SymTab.ClInt)
|
|
|
+ 2082 OR (cls
|
|
|
+ 2083 = SymTab.ClChar)
|
|
|
+ 2084 OR (cls
|
|
|
+ 2085 = SymTab.ClEnum)
|
|
|
+ 2086 OR (cls
|
|
|
+ 2087 = SymTab.ClReal)
|
|
|
+ 2088 OR (cls
|
|
|
+ 2089 = SymTab.ClLong)
|
|
|
+ 2090 OR (cls
|
|
|
+ 2091 = SymTab.ClNil)) THEN
|
|
|
+ 2092 IF cls = SymTab.ClNil THEN
|
|
|
+ 2093 QbeGen.CopyOp("0", q)
|
|
|
+ 2094 ELSIF ((cls
|
|
|
+ 2095 = SymTab.ClInt)
|
|
|
+ 2096 OR (cls
|
|
|
+ 2097 = SymTab.ClChar)
|
|
|
+ 2098 OR (cls
|
|
|
+ 2099 = SymTab.ClEnum)
|
|
|
+ 2100 OR (cls
|
|
|
+ 2101 = SymTab.ClLong))
|
|
|
+ 2102 AND SymTab.GetSymVal(n, cv)
|
|
|
+ 2103 AND QbeGen.IsImm(cv) THEN
|
|
|
+ 2104 QbeGen.CopyOp(cv, q)
|
|
|
+ 2105 ELSE
|
|
|
+ 2106 QbeGen.LoadVar(n,
|
|
|
+ 2107 cls = SymTab.ClReal,
|
|
|
+ 2108 q)
|
|
|
+ 2109 END
|
|
|
+ 2110 ELSIF (cls = SymTab.ClArray)
|
|
|
+ 2111 OR (cls = SymTab.ClRecord)
|
|
|
+ 2112 OR (cls = SymTab.ClClass)
|
|
|
+ 2113 OR (cls = SymTab.ClStr)
|
|
|
+ 2114 OR (cls = SymTab.ClUStr) THEN
|
|
|
+ 2115 (* aggregate constant:
|
|
|
+ 2116 its value IS the
|
|
|
+ 2117 descriptor address *)
|
|
|
+ 2118 IF SymTab.GetSymVal(n, cv) THEN
|
|
|
+ 2119 QbeGen.CopyOp(cv, q)
|
|
|
+ 2120 ELSE
|
|
|
+ 2121 QbeGen.CopyOp("0", q)
|
|
|
+ 2122 END
|
|
|
+ 2123 ELSE
|
|
|
+ 2124 IF t #
|
|
|
+ 2125 SymTab.InvalidType THEN
|
|
|
+ 2126 SemError(230)
|
|
|
+ 2127 END;
|
|
|
+ 2128 QbeGen.CopyOp("0", q)
|
|
|
+ 2129 END
|
|
|
+ 2130 END
|
|
|
+ 2131 ELSIF (k = SymTab.KindVar)
|
|
|
+ 2132 OR (k = SymTab.KindParam) THEN
|
|
|
+ 2133 cls :=
|
|
|
+ 2134 SymTab.ClassOf(t);
|
|
|
+ 2135 IF (cls = SymTab.ClInt)
|
|
|
+ 2136 OR (cls = SymTab.ClBool)
|
|
|
+ 2137 OR (cls = SymTab.ClChar)
|
|
|
+ 2138 OR (cls = SymTab.ClUChar)
|
|
|
+ 2139 OR (cls = SymTab.ClEnum)
|
|
|
+ 2140 OR (cls
|
|
|
+ 2141 = SymTab.ClReal) THEN
|
|
|
+ 2142 QbeGen.LoadVar(n,
|
|
|
+ 2143 cls = SymTab.ClReal, q)
|
|
|
+ 2144 ELSIF (cls = SymTab.ClPtr)
|
|
|
+ 2145 OR (cls = SymTab.ClProc) THEN
|
|
|
+ 2146 QbeGen.LoadPtr(n, q)
|
|
|
+ 2147 ELSIF cls = SymTab.ClLong THEN
|
|
|
+ 2148 QbeGen.LoadLong(n, q)
|
|
|
+ 2149 ELSIF (cls
|
|
|
+ 2150 = SymTab.ClArray)
|
|
|
+ 2151 OR (cls
|
|
|
+ 2152 = SymTab.ClSet)
|
|
|
+ 2153 OR (cls
|
|
|
+ 2154 = SymTab.ClRecord)
|
|
|
+ 2155 OR (cls
|
|
|
+ 2156 = SymTab.ClUStr)
|
|
|
+ 2157 OR (cls
|
|
|
+ 2158 = SymTab.ClClass) THEN
|
|
|
+ 2159 QbeGen.AddrOf(n, q)
|
|
|
+ 2160 ELSE SemError(230);
|
|
|
+ 2161 QbeGen.CopyOp("0", q)
|
|
|
+ 2162 END
|
|
|
+ 2163 ELSE QbeGen.CopyOp("0", q);
|
|
|
+ 2164 IF k = SymTab.KindImport THEN
|
|
|
+ 2165 SemError(230)
|
|
|
+ 2166 ELSIF k =
|
|
|
+ 2167 SymTab.KindProc THEN
|
|
|
+ 2168 (* bare procedure name:
|
|
|
+ 2169 a following ArgList
|
|
|
+ 2170 makes it a call;
|
|
|
+ 2171 otherwise Fact
|
|
|
+ 2172 reports 230 *)
|
|
|
+ 2173 ELSE
|
|
|
+ 2174 IF k = SymTab.KindField THEN
|
|
|
+ 2175 IF QbeGen.TopWith(qb) THEN
|
|
|
+ 2176 fo :=
|
|
|
+ 2177 SymTab.FieldOffset(
|
|
|
+ 2178 SymTab.FieldOwner(n),
|
|
|
+ 2179 n);
|
|
|
+ 2180 QbeGen.FieldAddr(qb,
|
|
|
+ 2181 fo, q);
|
|
|
+ 2182 sfx := TRUE
|
|
|
+ 2183 ELSE SemError(230);
|
|
|
+ 2184 QbeGen.CopyOp("0", q)
|
|
|
+ 2185 END
|
|
|
+ 2186 END
|
|
|
+ 2187 END
|
|
|
+ 2188 END
|
|
|
+ 2189 END; .)
|
|
|
+ 2190 (. astDes := AST.MakeNode(AST.NkDesignator);
|
|
|
+ 2191 AST.SetChild(astDes, AST.NChild(astDes), AST.MakeLeaf(AST.NkIdent, n));
|
|
|
+ 2192 IF fwd THEN AST.SetOp(astDes, 1) END; .)
|
|
|
+ 2193 { "[" Expr<it, iq>
|
|
|
+ 2194 (. AST.SetChild(astDes, AST.NChild(astDes),
|
|
|
+ 2195 AST.MakeUn(AST.NkSelector, AST.SelIndex, astCur)); IF t = SymTab.InvalidType THEN
|
|
|
+ 2196 ELSIF SymTab.ClassOf(t) #
|
|
|
+ 2197 SymTab.ClArray THEN
|
|
|
+ 2198 SemError(217);
|
|
|
+ 2199 t := SymTab.InvalidType
|
|
|
+ 2200 ELSIF NOT SymTab.IsIntFamily(it)
|
|
|
+ 2201 AND (SymTab.ClassOf(it) #
|
|
|
+ 2202 SymTab.ClChar)
|
|
|
+ 2203 AND (SymTab.ClassOf(it) #
|
|
|
+ 2204 SymTab.ClEnum) THEN
|
|
|
+ 2205 SemError(218);
|
|
|
+ 2206 t := SymTab.InvalidType
|
|
|
+ 2207 ELSE
|
|
|
+ 2208 QbeGen.WidenIndex(iq, ql);
|
|
|
+ 2209 isOpen :=
|
|
|
+ 2210 SymTab.IsOpenArray(t);
|
|
|
+ 2211 IF isOpen THEN
|
|
|
+ 2212 QbeGen.CopyOp("0", qlo);
|
|
|
+ 2213 IF SymTab.IsCharArray(t)
|
|
|
+ 2214 OR SymTab.IsUCharArray(t) THEN
|
|
|
+ 2215 QbeGen.OpenHiChar(q, qhi)
|
|
|
+ 2216 ELSE QbeGen.OpenHi(q, qhi)
|
|
|
+ 2217 END
|
|
|
+ 2218 ELSE
|
|
|
+ 2219 lo := SymTab.ArrayLo(t);
|
|
|
+ 2220 hi := SymTab.ArrayHi(t);
|
|
|
+ 2221 IF SymTab.IsCharArray(t)
|
|
|
+ 2222 OR SymTab.IsUCharArray(t) THEN
|
|
|
+ 2223 hi := hi + 1
|
|
|
+ 2224 END;
|
|
|
+ 2225 QbeGen.IntStr(lo, qlo);
|
|
|
+ 2226 QbeGen.IntStr(hi, qhi)
|
|
|
+ 2227 END;
|
|
|
+ 2228 QbeGen.CheckRange(ql, qlo,
|
|
|
+ 2229 qhi);
|
|
|
+ 2230 eT := SymTab.ArrayElem(t);
|
|
|
+ 2231 QbeGen.ElemAddr(q, ql, qlo,
|
|
|
+ 2232 t, qe);
|
|
|
+ 2233 IF SymTab.ClassOf(eT) =
|
|
|
+ 2234 SymTab.ClArray THEN
|
|
|
+ 2235 QbeGen.ElemLoad(qe, eT, q)
|
|
|
+ 2236 ELSE QbeGen.CopyOp(qe, q)
|
|
|
+ 2237 END;
|
|
|
+ 2238 t := eT; sfx := TRUE
|
|
|
+ 2239 END; .)
|
|
|
+ 2240 { "," Expr<it, iq>
|
|
|
+ 2241 (. AST.SetChild(astDes, AST.NChild(astDes),
|
|
|
+ 2242 AST.MakeUn(AST.NkSelector, AST.SelIndex, astCur)); IF t = SymTab.InvalidType THEN
|
|
|
+ 2243 ELSIF SymTab.ClassOf(t) #
|
|
|
+ 2244 SymTab.ClArray THEN
|
|
|
+ 2245 SemError(217);
|
|
|
+ 2246 t := SymTab.InvalidType
|
|
|
+ 2247 ELSIF NOT SymTab.IsIntFamily(it)
|
|
|
+ 2248 AND (SymTab.ClassOf(it) #
|
|
|
+ 2249 SymTab.ClChar)
|
|
|
+ 2250 AND (SymTab.ClassOf(it) #
|
|
|
+ 2251 SymTab.ClEnum) THEN
|
|
|
+ 2252 SemError(218);
|
|
|
+ 2253 t := SymTab.InvalidType
|
|
|
+ 2254 ELSE
|
|
|
+ 2255 QbeGen.WidenIndex(iq, ql);
|
|
|
+ 2256 isOpen :=
|
|
|
+ 2257 SymTab.IsOpenArray(t);
|
|
|
+ 2258 IF isOpen THEN
|
|
|
+ 2259 QbeGen.CopyOp("0", qlo);
|
|
|
+ 2260 IF SymTab.IsCharArray(t)
|
|
|
+ 2261 OR SymTab.IsUCharArray(t) THEN
|
|
|
+ 2262 QbeGen.OpenHiChar(q, qhi)
|
|
|
+ 2263 ELSE QbeGen.OpenHi(q, qhi)
|
|
|
+ 2264 END
|
|
|
+ 2265 ELSE
|
|
|
+ 2266 lo := SymTab.ArrayLo(t);
|
|
|
+ 2267 hi := SymTab.ArrayHi(t);
|
|
|
+ 2268 IF SymTab.IsCharArray(t)
|
|
|
+ 2269 OR SymTab.IsUCharArray(t) THEN
|
|
|
+ 2270 hi := hi + 1
|
|
|
+ 2271 END;
|
|
|
+ 2272 QbeGen.IntStr(lo, qlo);
|
|
|
+ 2273 QbeGen.IntStr(hi, qhi)
|
|
|
+ 2274 END;
|
|
|
+ 2275 QbeGen.CheckRange(ql, qlo,
|
|
|
+ 2276 qhi);
|
|
|
+ 2277 eT := SymTab.ArrayElem(t);
|
|
|
+ 2278 QbeGen.ElemAddr(q, ql, qlo,
|
|
|
+ 2279 t, qe);
|
|
|
+ 2280 IF SymTab.ClassOf(eT) =
|
|
|
+ 2281 SymTab.ClArray THEN
|
|
|
+ 2282 QbeGen.ElemLoad(qe, eT, q)
|
|
|
+ 2283 ELSE QbeGen.CopyOp(qe, q)
|
|
|
+ 2284 END;
|
|
|
+ 2285 t := eT; sfx := TRUE
|
|
|
+ 2286 END; .) }
|
|
|
+ 2287 "]"
|
|
|
+ 2288 | "." GetIdent<fn>
|
|
|
+ 2289 (. astSel := AST.MakeNode(AST.NkSelector);
|
|
|
+ 2290 AST.SetOp(astSel, AST.SelField);
|
|
|
+ 2291 AST.SetChild(astSel, 0, AST.MakeLeaf(AST.NkIdent, fn));
|
|
|
+ 2292 AST.SetChild(astDes, AST.NChild(astDes), astSel); IF k = SymTab.KindModule THEN
|
|
|
+ 2293 (* qualified L.x: materialize
|
|
|
+ 2294 the export, then load it *)
|
|
|
+ 2295 IF NOT SymTab.MaterializeAlias(n,
|
|
|
+ 2296 fn, mal) THEN
|
|
|
+ 2297 SemError(201);
|
|
|
+ 2298 t := SymTab.InvalidType;
|
|
|
+ 2299 QbeGen.CopyOp("0", q)
|
|
|
+ 2300 ELSE
|
|
|
+ 2301 QbeGen.CopyOp(mal, qn);
|
|
|
+ 2302 t := SymTab.SymType(mal);
|
|
|
+ 2303 k := SymTab.SymKind(mal);
|
|
|
+ 2304 sfx := FALSE;
|
|
|
+ 2305 IF k = SymTab.KindProc THEN
|
|
|
+ 2306 (* call: ArgList supplies
|
|
|
+ 2307 the value *)
|
|
|
+ 2308 QbeGen.CopyOp("0", q)
|
|
|
+ 2309 ELSIF NOT QbeGen.LoadDesignator(
|
|
|
+ 2310 mal, t, k, q) THEN
|
|
|
+ 2311 SemError(230);
|
|
|
+ 2312 QbeGen.CopyOp("0", q)
|
|
|
+ 2313 END
|
|
|
+ 2314 END
|
|
|
+ 2315 ELSIF t = SymTab.InvalidType THEN
|
|
|
+ 2316 ELSIF (SymTab.ClassOf(t) #
|
|
|
+ 2317 SymTab.ClRecord)
|
|
|
+ 2318 AND (SymTab.ClassOf(t) #
|
|
|
+ 2319 SymTab.ClClass) THEN
|
|
|
+ 2320 SemError(215);
|
|
|
+ 2321 t := SymTab.InvalidType
|
|
|
+ 2322 ELSIF (SymTab.ClassOf(t) =
|
|
|
+ 2323 SymTab.ClClass)
|
|
|
+ 2324 AND SymTab.MethodExists(t, fn) THEN
|
|
|
+ 2325 (* obj.Method: bind the
|
|
|
+ 2326 method and pass obj as
|
|
|
+ 2327 the hidden receiver; q
|
|
|
+ 2328 already holds the
|
|
|
+ 2329 object's address *)
|
|
|
+ 2330 QbeGen.ArmRecv(q);
|
|
|
+ 2331 QbeGen.CopyOp(fn, n);
|
|
|
+ 2332 QbeGen.CopyOp(fn, qn);
|
|
|
+ 2333 methCls := t;
|
|
|
+ 2334 k := SymTab.KindProc;
|
|
|
+ 2335 t := SymTab.InvalidType
|
|
|
+ 2336 ELSIF NOT SymTab.FieldExists(t,
|
|
|
+ 2337 fn) THEN
|
|
|
+ 2338 SemError(216);
|
|
|
+ 2339 t := SymTab.InvalidType
|
|
|
+ 2340 ELSE
|
|
|
+ 2341 fo := SymTab.FieldOffset(t,
|
|
|
+ 2342 fn);
|
|
|
+ 2343 t := SymTab.FieldType(t, fn);
|
|
|
+ 2344 QbeGen.FieldAddr(q, fo, qe);
|
|
|
+ 2345 (* array fields are inline:
|
|
|
+ 2346 the field address is the
|
|
|
+ 2347 descriptor, like records *)
|
|
|
+ 2348 QbeGen.CopyOp(qe, q);
|
|
|
+ 2349 sfx := TRUE
|
|
|
+ 2350 END; .)
|
|
|
+ 2351 | "^"
|
|
|
+ 2352 (. astSel := AST.MakeNode(AST.NkSelector);
|
|
|
+ 2353 AST.SetOp(astSel, AST.SelDeref);
|
|
|
+ 2354 AST.SetChild(astDes, AST.NChild(astDes), astSel); IF t = SymTab.InvalidType THEN
|
|
|
+ 2355 ELSIF SymTab.ClassOf(t) #
|
|
|
+ 2356 SymTab.ClPtr THEN
|
|
|
+ 2357 SemError(219);
|
|
|
+ 2358 t := SymTab.InvalidType
|
|
|
+ 2359 ELSE
|
|
|
+ 2360 bt := SymTab.PtrBase(t);
|
|
|
+ 2361 IF bt = SymTab.InvalidType THEN
|
|
|
+ 2362 ELSE
|
|
|
+ 2363 IF sfx THEN
|
|
|
+ 2364 QbeGen.ElemLoad(q, t,
|
|
|
+ 2365 qb);
|
|
|
+ 2366 QbeGen.CopyOp(qb, q)
|
|
|
+ 2367 END;
|
|
|
+ 2368 t := bt;
|
|
|
+ 2369 (* q holds the pointee
|
|
|
+ 2370 address: Fact loads
|
|
|
+ 2371 scalars/pointers and uses
|
|
|
+ 2372 the address for
|
|
|
+ 2373 aggregates; the VAR-actual
|
|
|
+ 2374 note is q itself. *)
|
|
|
+ 2375 sfx := TRUE
|
|
|
+ 2376 END
|
|
|
+ 2377 END; .) } (. astCur := astDes; .) .
|
|
|
+ 2378 (* Result suffix (ISO component after a function call): `F()^`,
|
|
|
+ 2379 `F()[i]`, `F().field`. The call result is in t/q with sfx FALSE
|
|
|
+ 2380 (a value, or a descriptor address for aggregates); each component
|
|
|
+ 2381 descends one level exactly like the Design components. *)
|
|
|
+ 2382 ResultComp<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal;
|
|
|
+ 2383 VAR sfx: BOOLEAN; VAR node: AST.Node> (. VAR it, eT, bt: SymTab.TypeIndex;
|
|
|
+ 2384 iq, ql, qlo, qhi, qe, qb:
|
|
|
+ 2385 QbeGen.QVal;
|
|
|
+ 2386 lo, hi, fo: INTEGER;
|
|
|
+ 2387 isOpen: BOOLEAN;
|
|
|
+ 2388 fname: SymTab.Name;
|
|
|
+ 2389 astWrap, astSel: AST.Node; .)
|
|
|
+ 2390 = "[" Expr<it, iq>
|
|
|
+ 2391 (. IF AST.Kind(node) # AST.NkDesignator THEN
|
|
|
+ 2392 astWrap := AST.MakeNode(
|
|
|
+ 2393 AST.NkDesignator);
|
|
|
+ 2394 AST.SetChild(astWrap, 0, node);
|
|
|
+ 2395 node := astWrap
|
|
|
+ 2396 END;
|
|
|
+ 2397 AST.SetChild(node, AST.NChild(node),
|
|
|
+ 2398 AST.MakeUn(AST.NkSelector,
|
|
|
+ 2399 AST.SelIndex, astCur)); IF t = SymTab.InvalidType THEN
|
|
|
+ 2400 ELSIF SymTab.ClassOf(t) #
|
|
|
+ 2401 SymTab.ClArray THEN
|
|
|
+ 2402 SemError(217);
|
|
|
+ 2403 t := SymTab.InvalidType
|
|
|
+ 2404 ELSIF NOT SymTab.IsIntFamily(it)
|
|
|
+ 2405 AND (SymTab.ClassOf(it) # SymTab.ClChar)
|
|
|
+ 2406 AND (SymTab.ClassOf(it) # SymTab.ClEnum) THEN
|
|
|
+ 2407 SemError(218);
|
|
|
+ 2408 t := SymTab.InvalidType
|
|
|
+ 2409 ELSE
|
|
|
+ 2410 QbeGen.WidenIndex(iq, ql);
|
|
|
+ 2411 isOpen :=
|
|
|
+ 2412 SymTab.IsOpenArray(t);
|
|
|
+ 2413 IF isOpen THEN
|
|
|
+ 2414 QbeGen.CopyOp("0", qlo);
|
|
|
+ 2415 IF SymTab.IsCharArray(t)
|
|
|
+ 2416 OR SymTab.IsUCharArray(t) THEN
|
|
|
+ 2417 QbeGen.OpenHiChar(q, qhi)
|
|
|
+ 2418 ELSE QbeGen.OpenHi(q, qhi)
|
|
|
+ 2419 END
|
|
|
+ 2420 ELSE
|
|
|
+ 2421 lo := SymTab.ArrayLo(t);
|
|
|
+ 2422 hi := SymTab.ArrayHi(t);
|
|
|
+ 2423 IF SymTab.IsCharArray(t)
|
|
|
+ 2424 OR SymTab.IsUCharArray(t) THEN
|
|
|
+ 2425 hi := hi + 1
|
|
|
+ 2426 END;
|
|
|
+ 2427 QbeGen.IntStr(lo, qlo);
|
|
|
+ 2428 QbeGen.IntStr(hi, qhi)
|
|
|
+ 2429 END;
|
|
|
+ 2430 QbeGen.CheckRange(ql, qlo,
|
|
|
+ 2431 qhi);
|
|
|
+ 2432 eT := SymTab.ArrayElem(t);
|
|
|
+ 2433 QbeGen.ElemAddr(q, ql, qlo,
|
|
|
+ 2434 t, qe);
|
|
|
+ 2435 IF SymTab.ClassOf(eT) =
|
|
|
+ 2436 SymTab.ClArray THEN
|
|
|
+ 2437 QbeGen.ElemLoad(qe, eT, q)
|
|
|
+ 2438 ELSE QbeGen.CopyOp(qe, q)
|
|
|
+ 2439 END;
|
|
|
+ 2440 t := eT; sfx := TRUE
|
|
|
+ 2441 END; .)
|
|
|
+ 2442 "]"
|
|
|
+ 2443 | "." GetIdent<fname>
|
|
|
+ 2444 (. IF AST.Kind(node) # AST.NkDesignator THEN
|
|
|
+ 2445 astWrap := AST.MakeNode(
|
|
|
+ 2446 AST.NkDesignator);
|
|
|
+ 2447 AST.SetChild(astWrap, 0, node);
|
|
|
+ 2448 node := astWrap
|
|
|
+ 2449 END;
|
|
|
+ 2450 AST.SetChild(node, AST.NChild(node),
|
|
|
+ 2451 AST.MakeUn(AST.NkSelector,
|
|
|
+ 2452 AST.SelField,
|
|
|
+ 2453 AST.MakeLeaf(AST.NkIdent,
|
|
|
+ 2454 fname))); IF t = SymTab.InvalidType THEN
|
|
|
+ 2455 ELSIF (SymTab.ClassOf(t) #
|
|
|
+ 2456 SymTab.ClRecord)
|
|
|
+ 2457 AND (SymTab.ClassOf(t) # SymTab.ClClass) THEN
|
|
|
+ 2458 SemError(215);
|
|
|
+ 2459 t := SymTab.InvalidType
|
|
|
+ 2460 ELSIF NOT SymTab.FieldExists(t,
|
|
|
+ 2461 fname) THEN
|
|
|
+ 2462 SemError(216);
|
|
|
+ 2463 t := SymTab.InvalidType
|
|
|
+ 2464 ELSE
|
|
|
+ 2465 fo := SymTab.FieldOffset(t,
|
|
|
+ 2466 fname);
|
|
|
+ 2467 t := SymTab.FieldType(t, fname);
|
|
|
+ 2468 QbeGen.FieldAddr(q, fo, qe);
|
|
|
+ 2469 QbeGen.CopyOp(qe, q);
|
|
|
+ 2470 sfx := TRUE
|
|
|
+ 2471 END; .)
|
|
|
+ 2472 | "^" (. IF AST.Kind(node) # AST.NkDesignator THEN
|
|
|
+ 2473 astWrap := AST.MakeNode(
|
|
|
+ 2474 AST.NkDesignator);
|
|
|
+ 2475 AST.SetChild(astWrap, 0, node);
|
|
|
+ 2476 node := astWrap
|
|
|
+ 2477 END;
|
|
|
+ 2478 astSel := AST.MakeNode(AST.NkSelector);
|
|
|
+ 2479 AST.SetOp(astSel, AST.SelDeref);
|
|
|
+ 2480 AST.SetChild(node,
|
|
|
+ 2481 AST.NChild(node), astSel); IF t = SymTab.InvalidType THEN
|
|
|
+ 2482 ELSIF SymTab.ClassOf(t) #
|
|
|
+ 2483 SymTab.ClPtr THEN
|
|
|
+ 2484 SemError(219);
|
|
|
+ 2485 t := SymTab.InvalidType
|
|
|
+ 2486 ELSE
|
|
|
+ 2487 bt := SymTab.PtrBase(t);
|
|
|
+ 2488 IF bt # SymTab.InvalidType THEN
|
|
|
+ 2489 IF sfx THEN
|
|
|
+ 2490 QbeGen.ElemLoad(q, t, qb);
|
|
|
+ 2491 QbeGen.CopyOp(qb, q)
|
|
|
+ 2492 END;
|
|
|
+ 2493 t := bt; sfx := TRUE
|
|
|
+ 2494 END
|
|
|
+ 2495 END; .) .
|
|
|
+ 2496 Expr<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
+ 2497 (. VAR t2: SymTab.TypeIndex;
|
|
|
+ 2498 op: INTEGER;
|
|
|
+ 2499 q2, qt, wl: QbeGen.QVal;
|
|
|
+ 2500 astA, astB: AST.Node;
|
|
|
+ 2501 astOp: INTEGER;
|
|
|
+ 2502 astMade: BOOLEAN;
|
|
|
+ 2503 isR: BOOLEAN; .)
|
|
|
+ 2504 = SimExpr<t, q> (. astA := astCur; astMade := FALSE; .)
|
|
|
+ 2505 [ Rel<op> SimExpr<t2, q2>
|
|
|
+ 2506 (. astB := astCur; astMade := TRUE;
|
|
|
+ 2507 astOp := AST.OpEq;
|
|
|
+ 2508 IF op = SymTab.OpNeq1 THEN astOp := AST.OpNe
|
|
|
+ 2509 ELSIF op = SymTab.OpNeq2 THEN astOp := AST.OpNe
|
|
|
+ 2510 ELSIF op = SymTab.OpLt THEN astOp := AST.OpLt
|
|
|
+ 2511 ELSIF op = SymTab.OpLe THEN astOp := AST.OpLe
|
|
|
+ 2512 ELSIF op = SymTab.OpGt THEN astOp := AST.OpGt
|
|
|
+ 2513 ELSIF op = SymTab.OpGe THEN astOp := AST.OpGe
|
|
|
+ 2514 ELSIF op = SymTab.OpIn THEN astOp := AST.OpIn
|
|
|
+ 2515 END;
|
|
|
+ 2516 IF op = SymTab.OpIn THEN
|
|
|
+ 2517 IF SymTab.InCheck(t, t2) THEN
|
|
|
+ 2518 IF (t = SymTab.InvalidType)
|
|
|
+ 2519 OR (t2 = SymTab.InvalidType) THEN
|
|
|
+ 2520 t := SymTab.BoolType(); QbeGen.CopyOp("0", q)
|
|
|
+ 2521 ELSE
|
|
|
+ 2522 t := SymTab.BoolType(); QbeGen.CopyOp("@", q)
|
|
|
+ 2523 END
|
|
|
+ 2524 ELSE SemError(222); t := SymTab.InvalidType;
|
|
|
+ 2525 QbeGen.CopyOp("0", q)
|
|
|
+ 2526 END
|
|
|
+ 2527 ELSIF SymTab.RelCheck(t, t2, op) THEN
|
|
|
+ 2528 IF (t = SymTab.InvalidType)
|
|
|
+ 2529 OR (t2 = SymTab.InvalidType) THEN
|
|
|
+ 2530 t := SymTab.BoolType(); QbeGen.CopyOp("0", q)
|
|
|
+ 2531 ELSIF (SymTab.ClassOf(t) = SymTab.ClPtr)
|
|
|
+ 2532 OR (SymTab.ClassOf(t2) = SymTab.ClPtr) THEN
|
|
|
+ 2533 IF SymTab.IsFwdVar(t) OR SymTab.IsFwdVar(t2) THEN
|
|
|
+ 2534 t := SymTab.BoolType(); QbeGen.CopyOp("@", q)
|
|
|
+ 2535 ELSIF (op # SymTab.OpEq) AND (op # SymTab.OpNeq1)
|
|
|
+ 2536 AND (op # SymTab.OpNeq2) THEN
|
|
|
+ 2537 SemError(213); t := SymTab.InvalidType;
|
|
|
+ 2538 QbeGen.CopyOp("0", q)
|
|
|
+ 2539 ELSE
|
|
|
+ 2540 t := SymTab.BoolType(); QbeGen.CopyOp("@", q)
|
|
|
+ 2541 END
|
|
|
+ 2542 ELSIF (SymTab.ClassOf(t) = SymTab.ClSet)
|
|
|
+ 2543 OR (SymTab.ClassOf(t2) = SymTab.ClSet) THEN
|
|
|
+ 2544 t := SymTab.BoolType(); QbeGen.CopyOp("@", q)
|
|
|
+ 2545 ELSIF SymTab.StrCompat(t, t2) THEN
|
|
|
+ 2546 QbeGen.StrEq(op, q, q2, qt);
|
|
|
+ 2547 t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
|
|
|
+ 2548 ELSIF SymTab.IsLongFamily(t)
|
|
|
+ 2549 OR SymTab.IsLongFamily(t2) THEN
|
|
|
+ 2550 t := SymTab.BoolType(); QbeGen.CopyOp("@", q)
|
|
|
+ 2551 ELSE
|
|
|
+ 2552 t := SymTab.BoolType();
|
|
|
+ 2553 QbeGen.CopyOp("@", q)
|
|
|
+ 2554 END
|
|
|
+ 2555 ELSE SemError(213); t := SymTab.InvalidType;
|
|
|
+ 2556 QbeGen.CopyOp("0", q)
|
|
|
+ 2557 END;
|
|
|
+ 2558 astCur := AST.MakeBin(AST.NkBinExpr, astOp, astA, astB); .) ]
|
|
|
+ 2559 (. IF NOT astMade THEN astCur := astA END; .) .
|
|
|
+ 2560 Rel<VAR op: INTEGER>
|
|
|
+ 2561 = "=" (. op := SymTab.OpEq; .)
|
|
|
+ 2562 | "#" (. op := SymTab.OpNeq1; .)
|
|
|
+ 2563 | "<" (. op := SymTab.OpLt; .)
|
|
|
+ 2564 | "<=" (. op := SymTab.OpLe; .)
|
|
|
+ 2565 | ">" (. op := SymTab.OpGt; .)
|
|
|
+ 2566 | ">=" (. op := SymTab.OpGe; .)
|
|
|
+ 2567 | "IN" (. op := SymTab.OpIn; .) .
|
|
|
+ 2568 SimExpr<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
+ 2569 (. VAR t2, res2, lt, rt:
|
|
|
+ 2570 SymTab.TypeIndex;
|
|
|
+ 2571 op: INTEGER;
|
|
|
+ 2572 q2, qt, wq, qf, q2a, q2b:
|
|
|
+ 2573 QbeGen.QVal;
|
|
|
+ 2574 neg, isR, isL, folded:
|
|
|
+ 2575 BOOLEAN;
|
|
|
+ 2576 fok: BOOLEAN;
|
|
|
+ 2577 lw, rw, mw: CARDINAL;
|
|
|
+ 2578 lTrue, lNext, lDone, qr, qs: QbeGen.QVal;
|
|
|
+ 2579 astA, astB: AST.Node;
|
|
|
+ 2580 astSign, astOp: INTEGER; .)
|
|
|
+ 2581 = (. neg := FALSE; astSign := 0; .)
|
|
|
+ 2582 [ "+" (. neg := TRUE; astSign := 1; .)
|
|
|
+ 2583 | "-" (. neg := TRUE; astSign := -1; .) ]
|
|
|
+ 2584 Term<t, q> (. astA := astCur;
|
|
|
+ 2585 IF neg AND QbeGen.IsImm(q) THEN
|
|
|
+ 2586 QbeGen.NegFold(q, q)
|
|
|
+ 2587 END;
|
|
|
+ 2588 IF astSign < 0 THEN
|
|
|
+ 2589 astCur := AST.MakeUn(
|
|
|
+ 2590 AST.NkUnary, AST.OpSub, astA);
|
|
|
+ 2591 astA := astCur
|
|
|
+ 2592 END; .)
|
|
|
+ 2593 { AddOp<op> (. IF op = SymTab.OpOr THEN
|
|
|
+ 2594 QbeGen.DelayBegin END; .)
|
|
|
+ 2595 Term<t2, q2> (. astB := astCur; IF op = SymTab.OpOr THEN
|
|
|
+ 2596 QbeGen.DelayEnd END; .)
|
|
|
+ 2597 (. astOp := AST.OpAdd;
|
|
|
+ 2598 IF op = SymTab.OpSub THEN astOp := AST.OpSub
|
|
|
+ 2599 ELSIF op = SymTab.OpOr THEN astOp := AST.OpOr END;
|
|
|
+ 2600 astA := AST.MakeBin(AST.NkBinExpr, astOp, astA, astB);
|
|
|
+ 2601 astCur := astA;
|
|
|
+ 2602 IF op = SymTab.OpOr THEN
|
|
|
+ 2603 (* short-circuit: if q is true the RHS is skipped *)
|
|
|
+ 2604 IF SymTab.BoolCheck(t) AND SymTab.BoolCheck(t2) THEN
|
|
|
+ 2605 t := SymTab.BoolType()
|
|
|
+ 2606 ELSE SemError(212); t := SymTab.InvalidType END;
|
|
|
+ 2607 IF t # SymTab.InvalidType THEN
|
|
|
+ 2608 QbeGen.CopyOp("@", q)
|
|
|
+ 2609 ELSE QbeGen.CopyOp("0", q)
|
|
|
+ 2610 END
|
|
|
+ 2611 ELSIF (op = SymTab.OpAdd)
|
|
|
+ 2612 AND (SymTab.UStrCompat(t, t2)
|
|
|
+ 2613 OR ((SymTab.ClassOf(t) = SymTab.ClUChar)
|
|
|
+ 2614 AND (SymTab.ClassOf(t2) = SymTab.ClUStr))
|
|
|
+ 2615 OR ((SymTab.ClassOf(t) = SymTab.ClUStr)
|
|
|
+ 2616 AND (SymTab.ClassOf(t2) = SymTab.ClUChar))
|
|
|
+ 2617 OR ((SymTab.ClassOf(t) = SymTab.ClUChar)
|
|
|
+ 2618 AND (SymTab.ClassOf(t2) = SymTab.ClUChar))) THEN
|
|
|
+ 2619 (* UString concatenation: a UCHAR operand becomes a
|
|
|
+ 2620 1-codepoint UString; the result is a descriptor in the
|
|
|
+ 2621 shim's concat buffer. Work on copies so neither
|
|
|
+ 2622 operand is clobbered. *)
|
|
|
+ 2623 t := SymTab.NewUStr();
|
|
|
+ 2624 QbeGen.CopyOp("@", q)
|
|
|
+ 2625 ELSIF (op = SymTab.OpAdd)
|
|
|
+ 2626 AND (SymTab.StrCompat(t, t2)
|
|
|
+ 2627 OR (SymTab.IsStrType(t)
|
|
|
+ 2628 AND (SymTab.ClassOf(t2) = SymTab.ClChar))
|
|
|
+ 2629 OR ((SymTab.ClassOf(t) = SymTab.ClChar)
|
|
|
+ 2630 AND SymTab.IsStrType(t2))) THEN
|
|
|
+ 2631 (* string concatenation; a CHAR operand becomes a
|
|
|
+ 2632 1-character string literal. When both operands are
|
|
|
+ 2633 constants, fold to a single string literal so a
|
|
|
+ 2634 constructor element stays compile-time. *)
|
|
|
+ 2635 QbeGen.StrFold(q, q2, SymTab.ClassOf(t), SymTab.ClassOf(t2),
|
|
|
+ 2636 qt, fok);
|
|
|
+ 2637 IF fok THEN QbeGen.CopyOp(qt, q)
|
|
|
+ 2638 ELSE QbeGen.CopyOp("@", q)
|
|
|
+ 2639 END;
|
|
|
+ 2640 t := SymTab.NewStr()
|
|
|
+ 2641 ELSIF (t # SymTab.InvalidType) AND (t2 # SymTab.InvalidType)
|
|
|
+ 2642 AND (SymTab.ClassOf(t) = SymTab.ClSet)
|
|
|
+ 2643 AND (SymTab.ClassOf(t2) = SymTab.ClSet) THEN
|
|
|
+ 2644 lw := SymTab.SetWords(t); rw := SymTab.SetWords(t2);
|
|
|
+ 2645 mw := lw;
|
|
|
+ 2646 IF rw > mw THEN mw := rw END;
|
|
|
+ 2647 t := SymTab.NewSet(
|
|
|
+ 2648 SymTab.NewSubR(0,
|
|
|
+ 2649 VAL(INTEGER, mw) * 32 - 1));
|
|
|
+ 2650 QbeGen.CopyOp("@", q)
|
|
|
+ 2651 ELSE
|
|
|
+ 2652 IF SymTab.ArithCheck(t, t2, FALSE, res2) THEN
|
|
|
+ 2653 lt := t; rt := t2; t := res2
|
|
|
+ 2654 ELSE SemError(211); t := SymTab.InvalidType END;
|
|
|
+ 2655 IF t # SymTab.InvalidType THEN
|
|
|
+ 2656 isL := SymTab.IsLongFamily(t);
|
|
|
+ 2657 isR := SymTab.ClassOf(t) = SymTab.ClReal;
|
|
|
+ 2658 folded := FALSE;
|
|
|
+ 2659 IF (NOT isL) AND (NOT isR)
|
|
|
+ 2660 AND QbeGen.IsImm(q) AND QbeGen.IsImm(q2) THEN
|
|
|
+ 2661 IF op = SymTab.OpAdd THEN
|
|
|
+ 2662 folded := QbeGen.Fold2(0, q, q2, qf)
|
|
|
+ 2663 ELSE
|
|
|
+ 2664 folded := QbeGen.Fold2(1, q, q2, qf)
|
|
|
+ 2665 END
|
|
|
+ 2666 END;
|
|
|
+ 2667 IF folded THEN QbeGen.CopyOp(qf, q)
|
|
|
+ 2668 ELSE
|
|
|
+ 2669 QbeGen.CopyOp("@", q)
|
|
|
+ 2670 END
|
|
|
+ 2671 ELSE QbeGen.CopyOp("0", q)
|
|
|
+ 2672 END
|
|
|
+ 2673 END; .) } .
|
|
|
+ 2674 AddOp<VAR op: INTEGER>
|
|
|
+ 2675 = "+" (. op := SymTab.OpAdd; .)
|
|
|
+ 2676 | "-" (. op := SymTab.OpSub; .)
|
|
|
+ 2677 | "OR" (. op := SymTab.OpOr; .) .
|
|
|
+ 2678 Term<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
+ 2679 (. VAR t2, res2, lt, rt:
|
|
|
+ 2680 SymTab.TypeIndex;
|
|
|
+ 2681 op: INTEGER;
|
|
|
+ 2682 q2, qt, wq, qf:
|
|
|
+ 2683 QbeGen.QVal;
|
|
|
+ 2684 isR, isL, folded: BOOLEAN;
|
|
|
+ 2685 lw, rw, mw: CARDINAL;
|
|
|
+ 2686 lNext, lFalse, lDone, qr, qs: QbeGen.QVal;
|
|
|
+ 2687 astA, astB: AST.Node;
|
|
|
+ 2688 astOp: INTEGER; .)
|
|
|
+ 2689 = Fact<t, q> (. astA := astCur; .) { MulOp<op>
|
|
|
+ 2690 Fact<t2, q2> (. astB := astCur; .)
|
|
|
+ 2691 (. astOp := AST.OpMul;
|
|
|
+ 2692 IF op = SymTab.OpSlash THEN astOp := AST.OpDiv
|
|
|
+ 2693 ELSIF op = SymTab.OpDiv THEN astOp := AST.OpDiv
|
|
|
+ 2694 ELSIF op = SymTab.OpMod THEN astOp := AST.OpMod
|
|
|
+ 2695 ELSIF op = SymTab.OpAnd THEN astOp := AST.OpAnd END;
|
|
|
+ 2696 astA := AST.MakeBin(AST.NkBinExpr, astOp, astA, astB);
|
|
|
+ 2697 astCur := astA;
|
|
|
+ 2698 IF op = SymTab.OpAnd THEN
|
|
|
+ 2699 (* short-circuit: if q is false the RHS is skipped *)
|
|
|
+ 2700 IF SymTab.BoolCheck(t) AND SymTab.BoolCheck(t2) THEN
|
|
|
+ 2701 t := SymTab.BoolType()
|
|
|
+ 2702 ELSE SemError(212); t := SymTab.InvalidType END;
|
|
|
+ 2703 IF t # SymTab.InvalidType THEN QbeGen.CopyOp("@", q)
|
|
|
+ 2704 ELSE QbeGen.CopyOp("0", q)
|
|
|
+ 2705 END
|
|
|
+ 2706 ELSIF (t # SymTab.InvalidType) AND (t2 # SymTab.InvalidType)
|
|
|
+ 2707 AND (SymTab.ClassOf(t) = SymTab.ClSet)
|
|
|
+ 2708 AND (SymTab.ClassOf(t2) = SymTab.ClSet) THEN
|
|
|
+ 2709 lw := SymTab.SetWords(t); rw := SymTab.SetWords(t2);
|
|
|
+ 2710 mw := lw;
|
|
|
+ 2711 IF rw > mw THEN mw := rw END;
|
|
|
+ 2712 t := SymTab.NewSet(
|
|
|
+ 2713 SymTab.NewSubR(0,
|
|
|
+ 2714 VAL(INTEGER, mw) * 32 - 1));
|
|
|
+ 2715 QbeGen.CopyOp("@", q)
|
|
|
+ 2716 ELSE
|
|
|
+ 2717 IF SymTab.ArithCheck(t, t2,
|
|
|
+ 2718 (op = SymTab.OpDiv) OR (op = SymTab.OpMod),
|
|
|
+ 2719 res2) THEN
|
|
|
+ 2720 lt := t; rt := t2; t := res2
|
|
|
+ 2721 ELSE SemError(211); t := SymTab.InvalidType END;
|
|
|
+ 2722 IF t # SymTab.InvalidType THEN
|
|
|
+ 2723 isL := SymTab.IsLongFamily(t);
|
|
|
+ 2724 isR := SymTab.ClassOf(t) = SymTab.ClReal;
|
|
|
+ 2725 folded := FALSE;
|
|
|
+ 2726 IF (NOT isL) AND (NOT isR)
|
|
|
+ 2727 AND QbeGen.IsImm(q) AND QbeGen.IsImm(q2) THEN
|
|
|
+ 2728 IF op = SymTab.OpTimes THEN
|
|
|
+ 2729 folded := QbeGen.Fold2(2, q, q2, qf)
|
|
|
+ 2730 ELSIF op = SymTab.OpDiv THEN
|
|
|
+ 2731 folded := QbeGen.Fold2(3, q, q2, qf)
|
|
|
+ 2732 ELSIF op = SymTab.OpMod THEN
|
|
|
+ 2733 folded := QbeGen.Fold2(4, q, q2, qf)
|
|
|
+ 2734 END
|
|
|
+ 2735 END;
|
|
|
+ 2736 IF folded THEN QbeGen.CopyOp(qf, q)
|
|
|
+ 2737 ELSE
|
|
|
+ 2738 QbeGen.CopyOp("@", q)
|
|
|
+ 2739 END
|
|
|
+ 2740 ELSE QbeGen.CopyOp("0", q)
|
|
|
+ 2741 END
|
|
|
+ 2742 END; .) } .
|
|
|
+ 2743 MulOp<VAR op: INTEGER>
|
|
|
+ 2744 = "*" (. op := SymTab.OpTimes; .)
|
|
|
+ 2745 | "/" (. op := SymTab.OpSlash; .)
|
|
|
+ 2746 | "DIV" (. op := SymTab.OpDiv; .)
|
|
|
+ 2747 | "MOD" (. op := SymTab.OpMod; .)
|
|
|
+ 2748 | ( "AND" | "&" ) (. op := SymTab.OpAnd; .) .
|
|
|
+ 2749 Fact<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
+ 2750 (. VAR s: ARRAY [0 .. 255] OF CHAR;
|
|
|
+ 2751 et, dt, t2, st, ct2, et2:
|
|
|
+ 2752 SymTab.TypeIndex;
|
|
|
+ 2753 dk: INTEGER;
|
|
|
+ 2754 qd, q2, sq, qa, qm0, qr, qt:
|
|
|
+ 2755 QbeGen.QVal;
|
|
|
+ 2756 qn, vn: SymTab.Name;
|
|
|
+ 2757 vt: SymTab.TypeIndex;
|
|
|
+ 2758 c1, c2: INTEGER;
|
|
|
+ 2759 lo, hi: INTEGER;
|
|
|
+ 2760 isMax: BOOLEAN;
|
|
|
+ 2761 called, isHigh, sfx, isCh,
|
|
|
+ 2762 isU, uok, isStr: BOOLEAN;
|
|
|
+ 2763 ucp: INTEGER; astIsLit: BOOLEAN;
|
|
|
+ 2764 astD: AST.Node;
|
|
|
+ 2765 astCall: BOOLEAN;
|
|
|
+ 2766 astNode, astNot: AST.Node;
|
|
|
+ 2767 j: CARDINAL;
|
|
|
+ 2768 astArg2: AST.Node;
|
|
|
+ 2769 astBrace: AST.Node;
|
|
|
+ 2770 astRes: AST.Node; .)
|
|
|
+ 2771 = (. astIsLit := FALSE; .)
|
|
|
+ 2772 ( integer (. LexString(s);
|
|
|
+ 2773 QbeGen.NormInt(s, q); IF twoPhase THEN astIsLit := TRUE; astCur := AST.MakeLeaf(AST.NkIntLit, s) END;
|
|
|
+ 2774 t := SymTab.IntType(); .)
|
|
|
+ 2775 | charConst (. LexString(s);
|
|
|
+ 2776 QbeGen.NormLit(s, q, isCh);
|
|
|
+ 2777 IF twoPhase THEN
|
|
|
+ 2778 astIsLit := TRUE;
|
|
|
+ 2779 astCur := AST.MakeLeaf(
|
|
|
+ 2780 AST.NkCharLit, s)
|
|
|
+ 2781 END;
|
|
|
+ 2782 t := SymTab.CharType(); .)
|
|
|
+ 2783 | real (. LexString(s);
|
|
|
+ 2784 QbeGen.NormReal(s, q);
|
|
|
+ 2785 IF twoPhase THEN
|
|
|
+ 2786 astIsLit := TRUE;
|
|
|
+ 2787 astCur := AST.MakeLeaf(
|
|
|
+ 2788 AST.NkRealLit, s)
|
|
|
+ 2789 END;
|
|
|
+ 2790 t := SymTab.RealType(); .)
|
|
|
+ 2791 | string (. LexString(s);
|
|
|
+ 2792 IF twoPhase THEN
|
|
|
+ 2793 astIsLit := TRUE;
|
|
|
+ 2794 astCur := AST.MakeLeaf(
|
|
|
+ 2795 AST.NkStrLit, s)
|
|
|
+ 2796 END;
|
|
|
+ 2797 IF SymTab.StrLen(s) = 3 THEN
|
|
|
+ 2798 t := SymTab.CharType();
|
|
|
+ 2799 QbeGen.IntStr(
|
|
|
+ 2800 QbeGen.CharVal(s), q)
|
|
|
+ 2801 ELSE t := SymTab.NewStr();
|
|
|
+ 2802 QbeGen.DeclStr(s, q);
|
|
|
+ 2803 (* a literal's value IS its
|
|
|
+ 2804 static descriptor address *)
|
|
|
+ 2805 END; .)
|
|
|
+ 2806 | ustring (. LexString(s);
|
|
|
+ 2807 IF twoPhase THEN
|
|
|
+ 2808 astIsLit := TRUE;
|
|
|
+ 2809 astCur := AST.MakeLeaf(
|
|
|
+ 2810 AST.NkStrLit, s)
|
|
|
+ 2811 END;
|
|
|
+ 2812 QbeGen.DeclUStr(s, q, isU, ucp,
|
|
|
+ 2813 uok);
|
|
|
+ 2814 IF NOT uok THEN
|
|
|
+ 2815 SemError(234);
|
|
|
+ 2816 t := SymTab.InvalidType
|
|
|
+ 2817 ELSIF isU THEN
|
|
|
+ 2818 t := SymTab.UCharType();
|
|
|
+ 2819 QbeGen.IntStr(ucp, q)
|
|
|
+ 2820 ELSE
|
|
|
+ 2821 t := SymTab.NewUStr();
|
|
|
+ 2822 END; .)
|
|
|
+ 2823 | Design<dt, dk, qd, qn, sfx> (. astD := astCur; astCall := FALSE; astBrace := AST.NoNode;
|
|
|
+ 2824 astNArgs := 0; called := FALSE;
|
|
|
+ 2825 t := dt;
|
|
|
+ 2826 IF dk = SymTab.KindConst THEN
|
|
|
+ 2827 QbeGen.CopyOp(qd, q)
|
|
|
+ 2828 ELSE QbeGen.CopyOp("@", q)
|
|
|
+ 2829 END; .)
|
|
|
+ 2830 [ TypedBraceLit<dt, q> (. t := dt; astCall := TRUE;
|
|
|
+ 2831 astBrace := astCur; .) ]
|
|
|
+ 2832 [ ArgList<qn, dt, qd, TRUE, FALSE, methCls, ct2, q2, called>
|
|
|
+ 2833 (. astCall := TRUE;
|
|
|
+ 2834 astNode := AstCallNode(astD);
|
|
|
+ 2835 astRes := astNode;
|
|
|
+ 2836 t := ct2;
|
|
|
+ 2837 QbeGen.CopyOp(q2, q);
|
|
|
+ 2838 sfx := FALSE; .)
|
|
|
+ 2839 { ResultComp<t, q, sfx, astRes> }
|
|
|
+ 2840 (. IF sfx THEN
|
|
|
+ 2841 IF t = SymTab.InvalidType THEN
|
|
|
+ 2842 QbeGen.CopyOp("0", q)
|
|
|
+ 2843 ELSIF (SymTab.ClassOf(t) #
|
|
|
+ 2844 SymTab.ClRecord)
|
|
|
+ 2845 AND (SymTab.ClassOf(t) # SymTab.ClSet)
|
|
|
+ 2846 AND (SymTab.ClassOf(t) # SymTab.ClArray)
|
|
|
+ 2847 AND (SymTab.ClassOf(t) # SymTab.ClClass) THEN
|
|
|
+ 2848 QbeGen.CopyOp("@", q)
|
|
|
+ 2849 END
|
|
|
+ 2850 END; .) ]
|
|
|
+ 2851 (. IF called THEN
|
|
|
+ 2852 astCur := astRes
|
|
|
+ 2853 ELSIF astCall THEN
|
|
|
+ 2854 astCur := astBrace
|
|
|
+ 2855 ELSE astCur := astD
|
|
|
+ 2856 END;
|
|
|
+ 2857 astIsLit := TRUE;
|
|
|
+ 2858 IF NOT called
|
|
|
+ 2859 AND (dk = SymTab.KindProc) THEN
|
|
|
+ 2860 (* bare zero-arg function
|
|
|
+ 2861 call (parentheses may be
|
|
|
+ 2862 omitted); a proper or
|
|
|
+ 2863 parameterised proc here
|
|
|
+ 2864 is 230 *)
|
|
|
+ 2865 IF (SymTab.ProcNPar(qn) = 0)
|
|
|
+ 2866 AND (SymTab.ProcRes(qn) # SymTab.InvalidType) THEN
|
|
|
+ 2867 t := SymTab.ProcRes(qn);
|
|
|
+ 2868 QbeGen.CopyOp("@", q);
|
|
|
+ 2869 astCur := AST.MakeNode(AST.NkCall);
|
|
|
+ 2870 AST.SetChild(astCur, 0, astD)
|
|
|
+ 2871 ELSE
|
|
|
+ 2872 t := SymTab.ProcTypeOf(qn);
|
|
|
+ 2873 QbeGen.CopyOp("@", q)
|
|
|
+ 2874 END
|
|
|
+ 2875 END; .)
|
|
|
+ 2876 | ( "HIGH" (. isHigh := TRUE; .)
|
|
|
+ 2877 | ( "LEN" | "LENGTH" ) (. isHigh := FALSE; .) )
|
|
|
+ 2878 "(" ( Design<dt, dk, qd, qn, sfx> (. isStr := FALSE;
|
|
|
+ 2879 isU := FALSE; .)
|
|
|
+ 2880 | string (. LexString(s); astCur := AST.MakeLeaf(AST.NkStrLit, s);
|
|
|
+ 2881 isStr := TRUE;
|
|
|
+ 2882 isU := FALSE;
|
|
|
+ 2883 IF SymTab.StrLen(s) = 3 THEN
|
|
|
+ 2884 dt := SymTab.CharType();
|
|
|
+ 2885 QbeGen.IntStr(QbeGen.CharVal(s),
|
|
|
+ 2886 qd)
|
|
|
+ 2887 ELSE
|
|
|
+ 2888 dt := SymTab.NewStr();
|
|
|
+ 2889 QbeGen.DeclStr(s, qd);
|
|
|
+ 2890 QbeGen.NoteAddr(qd, qd)
|
|
|
+ 2891 END;
|
|
|
+ 2892 dk := -1;
|
|
|
+ 2893 qn[0] := CHR(0); .)
|
|
|
+ 2894 | ustring (. LexString(s); astCur := AST.MakeLeaf(AST.NkStrLit, s);
|
|
|
+ 2895 QbeGen.DeclUStr(s, qd, isU, ucp,
|
|
|
+ 2896 uok);
|
|
|
+ 2897 isStr := FALSE;
|
|
|
+ 2898 IF NOT uok THEN
|
|
|
+ 2899 SemError(234);
|
|
|
+ 2900 dt := SymTab.InvalidType
|
|
|
+ 2901 ELSIF isU THEN
|
|
|
+ 2902 (* one codepoint: a UCHAR;
|
|
|
+ 2903 LEN is 1, HIGH is 0 *)
|
|
|
+ 2904 dt := SymTab.UCharType();
|
|
|
+ 2905 QbeGen.IntStr(ucp, qd)
|
|
|
+ 2906 ELSE
|
|
|
+ 2907 dt := SymTab.NewUStr();
|
|
|
+ 2908 QbeGen.NoteAddr(qd, qd)
|
|
|
+ 2909 END;
|
|
|
+ 2910 dk := -1;
|
|
|
+ 2911 qn[0] := CHR(0); .) )
|
|
|
+ 2912 ")"
|
|
|
+ 2913 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
+ 2914 IF isHigh THEN AST.SetChild(astNode, 0,
|
|
|
+ 2915 AST.MakeLeaf(AST.NkIdent, "HIGH"))
|
|
|
+ 2916 ELSE AST.SetChild(astNode, 0,
|
|
|
+ 2917 AST.MakeLeaf(AST.NkIdent, "LEN")) END;
|
|
|
+ 2918 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
+ 2919 astCur := astNode; astIsLit := TRUE;
|
|
|
+ 2920 IF (dt # SymTab.InvalidType)
|
|
|
+ 2921 AND (SymTab.ClassOf(dt) = SymTab.ClUStr) THEN
|
|
|
+ 2922 (* UString: the count is
|
|
|
+ 2923 the descriptor header *)
|
|
|
+ 2924 IF isHigh THEN
|
|
|
+ 2925 QbeGen.UStrLen(qd, qr);
|
|
|
+ 2926 QbeGen.DecQ(qr)
|
|
|
+ 2927 ELSE
|
|
|
+ 2928 QbeGen.UStrLen(qd, qr)
|
|
|
+ 2929 END;
|
|
|
+ 2930 t := SymTab.IntType();
|
|
|
+ 2931 QbeGen.CopyOp(qr, q)
|
|
|
+ 2932 ELSIF (dt # SymTab.InvalidType)
|
|
|
+ 2933 AND (SymTab.ClassOf(dt) = SymTab.ClUChar) THEN
|
|
|
+ 2934 (* single UCHAR codepoint *)
|
|
|
+ 2935 IF isHigh THEN
|
|
|
+ 2936 QbeGen.CopyOp("0", qr)
|
|
|
+ 2937 ELSE
|
|
|
+ 2938 QbeGen.CopyOp("1", qr)
|
|
|
+ 2939 END;
|
|
|
+ 2940 t := SymTab.IntType();
|
|
|
+ 2941 QbeGen.CopyOp(qr, q)
|
|
|
+ 2942 ELSIF isStr THEN
|
|
|
+ 2943 (* fold: content length at
|
|
|
+ 2944 compile time *)
|
|
|
+ 2945 IF SymTab.StrLen(s) = 3 THEN
|
|
|
+ 2946 c1 := 1
|
|
|
+ 2947 ELSE
|
|
|
+ 2948 c1 :=
|
|
|
+ 2949 SymTab.StrLen(s) - 2
|
|
|
+ 2950 END;
|
|
|
+ 2951 IF isHigh THEN
|
|
|
+ 2952 DEC(c1)
|
|
|
+ 2953 END;
|
|
|
+ 2954 QbeGen.IntStr(c1, qr);
|
|
|
+ 2955 t := SymTab.IntType();
|
|
|
+ 2956 QbeGen.CopyOp(qr, q)
|
|
|
+ 2957 ELSIF dt = SymTab.InvalidType THEN
|
|
|
+ 2958 t := SymTab.InvalidType;
|
|
|
+ 2959 QbeGen.CopyOp("0", q)
|
|
|
+ 2960 ELSIF SymTab.ClassOf(dt) #
|
|
|
+ 2961 SymTab.ClArray THEN
|
|
|
+ 2962 SemError(217);
|
|
|
+ 2963 t := SymTab.InvalidType;
|
|
|
+ 2964 QbeGen.CopyOp("0", q)
|
|
|
+ 2965 ELSE
|
|
|
+ 2966 IF SymTab.IsOpenArray(dt) THEN
|
|
|
+ 2967 t := SymTab.IntType();
|
|
|
+ 2968 QbeGen.CopyOp("@", q)
|
|
|
+ 2969 ELSE
|
|
|
+ 2970 IF isHigh THEN
|
|
|
+ 2971 QbeGen.IntStr(
|
|
|
+ 2972 SymTab.ArrayHi(dt), qr)
|
|
|
+ 2973 ELSE
|
|
|
+ 2974 QbeGen.IntStr(VAL(
|
|
|
+ 2975 INTEGER,
|
|
|
+ 2976 SymTab.ArrayLen(dt)),
|
|
|
+ 2977 qr)
|
|
|
+ 2978 END;
|
|
|
+ 2979 t := SymTab.IntType();
|
|
|
+ 2980 QbeGen.CopyOp(qr, q)
|
|
|
2981 END
|
|
|
- 2982 END; .)
|
|
|
- 2983 | ( "HIGH" (. isHigh := TRUE; .)
|
|
|
- 2984 | ( "LEN" | "LENGTH" ) (. isHigh := FALSE; .) )
|
|
|
- 2985 "(" ( Design<dt, dk, qd, qn, sfx> (. isStr := FALSE;
|
|
|
- 2986 isU := FALSE; .)
|
|
|
- 2987 | string (. LexString(s); astCur := AST.MakeLeaf(AST.NkStrLit, s);
|
|
|
- 2988 isStr := TRUE;
|
|
|
- 2989 isU := FALSE;
|
|
|
- 2990 IF SymTab.StrLen(s) = 3 THEN
|
|
|
- 2991 dt := SymTab.CharType();
|
|
|
- 2992 QbeGen.IntStr(QbeGen.CharVal(s),
|
|
|
- 2993 qd)
|
|
|
- 2994 ELSE
|
|
|
- 2995 dt := SymTab.NewStr();
|
|
|
- 2996 QbeGen.DeclStr(s, qd);
|
|
|
- 2997 QbeGen.NoteAddr(qd, qd)
|
|
|
- 2998 END;
|
|
|
- 2999 dk := -1;
|
|
|
- 3000 qn[0] := CHR(0); .)
|
|
|
- 3001 | ustring (. LexString(s); astCur := AST.MakeLeaf(AST.NkStrLit, s);
|
|
|
- 3002 QbeGen.DeclUStr(s, qd, isU, ucp,
|
|
|
- 3003 uok);
|
|
|
- 3004 isStr := FALSE;
|
|
|
- 3005 IF NOT uok THEN
|
|
|
- 3006 SemError(234);
|
|
|
- 3007 dt := SymTab.InvalidType
|
|
|
- 3008 ELSIF isU THEN
|
|
|
- 3009 (* one codepoint: a UCHAR;
|
|
|
- 3010 LEN is 1, HIGH is 0 *)
|
|
|
- 3011 dt := SymTab.UCharType();
|
|
|
- 3012 QbeGen.IntStr(ucp, qd)
|
|
|
- 3013 ELSE
|
|
|
- 3014 dt := SymTab.NewUStr();
|
|
|
- 3015 QbeGen.NoteAddr(qd, qd)
|
|
|
- 3016 END;
|
|
|
- 3017 dk := -1;
|
|
|
- 3018 qn[0] := CHR(0); .) )
|
|
|
- 3019 ")"
|
|
|
- 3020 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
- 3021 IF isHigh THEN AST.SetChild(astNode, 0,
|
|
|
- 3022 AST.MakeLeaf(AST.NkIdent, "HIGH"))
|
|
|
- 3023 ELSE AST.SetChild(astNode, 0,
|
|
|
- 3024 AST.MakeLeaf(AST.NkIdent, "LEN")) END;
|
|
|
- 3025 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
- 3026 astCur := astNode; astIsLit := TRUE;
|
|
|
- 3027 IF (dt # SymTab.InvalidType)
|
|
|
- 3028 AND (SymTab.ClassOf(dt) = SymTab.ClUStr) THEN
|
|
|
- 3029 (* UString: the count is
|
|
|
- 3030 the descriptor header *)
|
|
|
- 3031 IF isHigh THEN
|
|
|
- 3032 QbeGen.UStrLen(qd, qr);
|
|
|
- 3033 QbeGen.DecQ(qr)
|
|
|
- 3034 ELSE
|
|
|
- 3035 QbeGen.UStrLen(qd, qr)
|
|
|
- 3036 END;
|
|
|
- 3037 t := SymTab.IntType();
|
|
|
- 3038 QbeGen.CopyOp(qr, q)
|
|
|
- 3039 ELSIF (dt # SymTab.InvalidType)
|
|
|
- 3040 AND (SymTab.ClassOf(dt) = SymTab.ClUChar) THEN
|
|
|
- 3041 (* single UCHAR codepoint *)
|
|
|
- 3042 IF isHigh THEN
|
|
|
- 3043 QbeGen.CopyOp("0", qr)
|
|
|
- 3044 ELSE
|
|
|
- 3045 QbeGen.CopyOp("1", qr)
|
|
|
- 3046 END;
|
|
|
- 3047 t := SymTab.IntType();
|
|
|
- 3048 QbeGen.CopyOp(qr, q)
|
|
|
- 3049 ELSIF isStr THEN
|
|
|
- 3050 (* fold: content length at
|
|
|
- 3051 compile time *)
|
|
|
- 3052 IF SymTab.StrLen(s) = 3 THEN
|
|
|
- 3053 c1 := 1
|
|
|
- 3054 ELSE
|
|
|
- 3055 c1 :=
|
|
|
- 3056 SymTab.StrLen(s) - 2
|
|
|
- 3057 END;
|
|
|
- 3058 IF isHigh THEN
|
|
|
- 3059 DEC(c1)
|
|
|
- 3060 END;
|
|
|
- 3061 QbeGen.IntStr(c1, qr);
|
|
|
- 3062 t := SymTab.IntType();
|
|
|
- 3063 QbeGen.CopyOp(qr, q)
|
|
|
- 3064 ELSIF dt = SymTab.InvalidType THEN
|
|
|
- 3065 t := SymTab.InvalidType;
|
|
|
- 3066 QbeGen.CopyOp("0", q)
|
|
|
- 3067 ELSIF SymTab.ClassOf(dt) #
|
|
|
- 3068 SymTab.ClArray THEN
|
|
|
- 3069 SemError(217);
|
|
|
- 3070 t := SymTab.InvalidType;
|
|
|
- 3071 QbeGen.CopyOp("0", q)
|
|
|
- 3072 ELSE
|
|
|
- 3073 IF SymTab.IsOpenArray(dt) THEN
|
|
|
- 3074 t := SymTab.IntType();
|
|
|
- 3075 QbeGen.CopyOp("@", q)
|
|
|
- 3076 ELSE
|
|
|
- 3077 IF isHigh THEN
|
|
|
- 3078 QbeGen.IntStr(
|
|
|
- 3079 SymTab.ArrayHi(dt), qr)
|
|
|
- 3080 ELSE
|
|
|
- 3081 QbeGen.IntStr(VAL(
|
|
|
- 3082 INTEGER,
|
|
|
- 3083 SymTab.ArrayLen(dt)),
|
|
|
- 3084 qr)
|
|
|
- 3085 END;
|
|
|
- 3086 t := SymTab.IntType();
|
|
|
- 3087 QbeGen.CopyOp(qr, q)
|
|
|
- 3088 END
|
|
|
- 3089 END; .)
|
|
|
- 3090 | ( "SIZE" | "TSIZE" ) "(" Design<dt, dk, qd, qn, sfx> ")"
|
|
|
- 3091 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
- 3092 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "SIZE"));
|
|
|
- 3093 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
- 3094 astCur := astNode; astIsLit := TRUE; .)
|
|
|
- 3095 (. IF dt = SymTab.InvalidType THEN
|
|
|
- 3096 t := SymTab.InvalidType;
|
|
|
- 3097 QbeGen.CopyOp("0", q)
|
|
|
- 3098 ELSE
|
|
|
- 3099 QbeGen.IntStr(VAL(INTEGER,
|
|
|
- 3100 SymTab.ObjectSize(dt)), q);
|
|
|
- 3101 t := SymTab.IntType()
|
|
|
- 3102 END; .)
|
|
|
- 3103 | ( "SHIFT" (. isMax := FALSE; .)
|
|
|
- 3104 | "ROTATE" (. isMax := TRUE; .) )
|
|
|
- 3105 "(" Expr<et, q> (. astArg2 := astCur; .) "," Expr<et2, q2> ")"
|
|
|
- 3106 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
- 3107 IF isMax THEN AST.SetChild(astNode, 0,
|
|
|
- 3108 AST.MakeLeaf(AST.NkIdent, "ROTATE"))
|
|
|
- 3109 ELSE AST.SetChild(astNode, 0,
|
|
|
- 3110 AST.MakeLeaf(AST.NkIdent, "SHIFT")) END;
|
|
|
- 3111 IF astArg2 # AST.NoNode THEN AST.SetChild(astNode, 1, astArg2) END;
|
|
|
- 3112 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 2, astCur) END;
|
|
|
- 3113 astCur := astNode; astIsLit := TRUE;
|
|
|
- 3114 (* set shift/rotate: isMax
|
|
|
- 3115 doubles as "rotate" *)
|
|
|
- 3116 IF (et # SymTab.InvalidType)
|
|
|
- 3117 AND (SymTab.ClassOf(et) =
|
|
|
- 3118 SymTab.ClSet) THEN
|
|
|
- 3119 t := et;
|
|
|
- 3120 QbeGen.CopyOp("@", q)
|
|
|
- 3121 ELSE SemError(230);
|
|
|
- 3122 t := SymTab.InvalidType;
|
|
|
- 3123 QbeGen.CopyOp("0", q)
|
|
|
- 3124 END; .)
|
|
|
- 3125 | ( "MIN" (. isMax := FALSE; .)
|
|
|
- 3126 | "MAX" (. isMax := TRUE; .) )
|
|
|
- 3127 "(" Design<dt, dk, qd, qn, sfx> ")"
|
|
|
- 3128 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
- 3129 IF isMax THEN AST.SetChild(astNode, 0,
|
|
|
- 3130 AST.MakeLeaf(AST.NkIdent, "MAX"))
|
|
|
- 3131 ELSE AST.SetChild(astNode, 0,
|
|
|
- 3132 AST.MakeLeaf(AST.NkIdent, "MIN")) END;
|
|
|
- 3133 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
- 3134 astCur := astNode; astIsLit := TRUE;
|
|
|
- 3135 IF (dt # SymTab.InvalidType)
|
|
|
- 3136 AND (SymTab.ClassOf(dt) = SymTab.ClReal) THEN
|
|
|
- 3137 (* REAL/LONGREAL: the
|
|
|
- 3138 implementation bounds *)
|
|
|
- 3139 IF isMax THEN
|
|
|
- 3140 QbeGen.NormReal(
|
|
|
- 3141 "3.402823e38", q)
|
|
|
- 3142 ELSE QbeGen.NormReal(
|
|
|
- 3143 "-3.402823e38", q)
|
|
|
- 3144 END;
|
|
|
- 3145 t := SymTab.RealType()
|
|
|
- 3146 ELSIF (dt #
|
|
|
- 3147 SymTab.InvalidType)
|
|
|
- 3148 AND (SymTab.ClassOf(dt) =
|
|
|
- 3149 SymTab.ClLong) THEN
|
|
|
- 3150 IF isMax THEN
|
|
|
- 3151 QbeGen.CopyOp(
|
|
|
- 3152 "9223372036854775807", q)
|
|
|
- 3153 ELSE QbeGen.CopyOp(
|
|
|
- 3154 "-9223372036854775808", q)
|
|
|
- 3155 END;
|
|
|
- 3156 t := SymTab.LongType()
|
|
|
- 3157 ELSIF SymTab.TypeBounds(dt, lo,
|
|
|
- 3158 hi) THEN
|
|
|
- 3159 IF isMax THEN
|
|
|
- 3160 QbeGen.IntStr(hi, q)
|
|
|
- 3161 ELSE QbeGen.IntStr(lo, q)
|
|
|
- 3162 END;
|
|
|
- 3163 t := SymTab.IntType()
|
|
|
- 3164 ELSE SemError(230);
|
|
|
- 3165 t := SymTab.InvalidType;
|
|
|
- 3166 QbeGen.CopyOp("0", q)
|
|
|
- 3167 END; .)
|
|
|
- 3168 | "ADR" "(" Design<dt, dk, qd, qn, sfx> ")"
|
|
|
- 3169 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
- 3170 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "ADR"));
|
|
|
- 3171 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
- 3172 astCur := astNode; astIsLit := TRUE; .)
|
|
|
- 3173 (. IF dt = SymTab.InvalidType THEN
|
|
|
- 3174 t := SymTab.InvalidType;
|
|
|
- 3175 QbeGen.CopyOp("0", q)
|
|
|
- 3176 ELSE
|
|
|
- 3177 IF sfx
|
|
|
- 3178 OR (dk = SymTab.KindVar)
|
|
|
- 3179 OR (dk = SymTab.KindParam) THEN
|
|
|
- 3180 QbeGen.CopyOp("@", q)
|
|
|
- 3181 ELSE SemError(230);
|
|
|
- 3182 QbeGen.CopyOp("0", q)
|
|
|
- 3183 END;
|
|
|
- 3184 t := SymTab.AddrType()
|
|
|
- 3185 END; .)
|
|
|
- 3186 | "CHR" "(" Expr<et, q> ")"
|
|
|
- 3187 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
- 3188 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "CHR"));
|
|
|
- 3189 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
- 3190 astCur := astNode; astIsLit := TRUE; .)
|
|
|
- 3191 (. IF (et # SymTab.InvalidType)
|
|
|
- 3192 AND NOT SymTab.IsIntFamily(et) THEN
|
|
|
- 3193 SemError(211) END;
|
|
|
- 3194 t := SymTab.CharType(); .)
|
|
|
- 3195 | ( "ORD" | "ORDL" ) "(" Expr<et, q> ")"
|
|
|
- 3196 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
- 3197 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "ORD"));
|
|
|
- 3198 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
- 3199 astCur := astNode; astIsLit := TRUE; .)
|
|
|
- 3200 (. IF et # SymTab.InvalidType THEN
|
|
|
- 3201 IF (SymTab.ClassOf(et) #
|
|
|
- 3202 SymTab.ClChar)
|
|
|
- 3203 AND (SymTab.ClassOf(et) #
|
|
|
- 3204 SymTab.ClBool)
|
|
|
- 3205 AND (SymTab.ClassOf(et) #
|
|
|
- 3206 SymTab.ClEnum)
|
|
|
- 3207 AND NOT SymTab.IsIntFamily(et) THEN
|
|
|
- 3208 SemError(211) END
|
|
|
- 3209 END;
|
|
|
- 3210 t := SymTab.IntType(); .)
|
|
|
- 3211 | "CAP" "(" Expr<et, q> ")"
|
|
|
- 3212 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
- 3213 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "CAP"));
|
|
|
- 3214 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
- 3215 astCur := astNode; astIsLit := TRUE; .)
|
|
|
- 3216 (. QbeGen.CapQ(q, qa);
|
|
|
- 3217 QbeGen.CopyOp(qa, q);
|
|
|
- 3218 t := SymTab.CharType(); .)
|
|
|
- 3219 | "UCHR" "(" Expr<et, q> ")"
|
|
|
- 3220 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
- 3221 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "UCHR"));
|
|
|
- 3222 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
- 3223 astCur := astNode; astIsLit := TRUE; .)
|
|
|
- 3224 (. (* UCHR: the UCHAR constructor.
|
|
|
- 3225 CHAR -> UCHAR (identity);
|
|
|
- 3226 INTEGER familly -> UCHAR
|
|
|
- 3227 (codepoint value). *)
|
|
|
- 3228 IF (et # SymTab.InvalidType)
|
|
|
- 3229 AND (SymTab.ClassOf(et) # SymTab.ClChar)
|
|
|
- 3230 AND NOT SymTab.IsIntFamily(et) THEN
|
|
|
- 3231 SemError(211) END;
|
|
|
- 3232 t := SymTab.UCharType(); .)
|
|
|
- 3233 | "CHR8" "(" Expr<et, q> ")"
|
|
|
- 3234 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
- 3235 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "CHR8"));
|
|
|
- 3236 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
- 3237 astCur := astNode; astIsLit := TRUE; .)
|
|
|
- 3238 (. IF (et # SymTab.InvalidType)
|
|
|
- 3239 AND (SymTab.ClassOf(et) # SymTab.ClUChar) THEN
|
|
|
- 3240 SemError(211) END;
|
|
|
- 3241 t := SymTab.CharType(); .)
|
|
|
- 3242 | "UORD" "(" Expr<et, q> ")"
|
|
|
- 3243 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
- 3244 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "UORD"));
|
|
|
- 3245 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
- 3246 astCur := astNode; astIsLit := TRUE; .)
|
|
|
- 3247 (. (* UORD(u): the codepoint as a
|
|
|
- 3248 32-bit ordinal (INTEGER),
|
|
|
- 3249 cf. ORD for CHAR. *)
|
|
|
- 3250 IF (et # SymTab.InvalidType)
|
|
|
- 3251 AND (SymTab.ClassOf(et) # SymTab.ClUChar) THEN
|
|
|
- 3252 SemError(211) END;
|
|
|
- 3253 t := SymTab.IntType(); .)
|
|
|
- 3254 | "ABS" "(" Expr<et, q> ")"
|
|
|
- 3255 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
- 3256 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "ABS"));
|
|
|
- 3257 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
- 3258 astCur := astNode; astIsLit := TRUE; .)
|
|
|
- 3259 (. IF (et # SymTab.InvalidType)
|
|
|
- 3260 AND NOT SymTab.IsIntFamily(et)
|
|
|
- 3261 AND (SymTab.ClassOf(et) #
|
|
|
- 3262 SymTab.ClReal) THEN
|
|
|
- 3263 SemError(211)
|
|
|
- 3264 ELSE QbeGen.AbsQ(q, qa,
|
|
|
- 3265 SymTab.ClassOf(et) =
|
|
|
- 3266 SymTab.ClReal);
|
|
|
- 3267 QbeGen.CopyOp(qa, q)
|
|
|
- 3268 END;
|
|
|
- 3269 t := et; .)
|
|
|
- 3270 | "VAL" "(" GetIdent<vn> (. astArg2 := AST.MakeLeaf(AST.NkIdent, vn); .) "," Expr<et, q> ")"
|
|
|
- 3271 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
- 3272 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "VAL"));
|
|
|
- 3273 IF astArg2 # AST.NoNode THEN AST.SetChild(astNode, 1, astArg2) END;
|
|
|
- 3274 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 2, astCur) END;
|
|
|
- 3275 astCur := astNode; astIsLit := TRUE; .)
|
|
|
- 3276 (. IF NOT SymTab.Lookup(vn) THEN
|
|
|
- 3277 SemError(201);
|
|
|
- 3278 t := SymTab.InvalidType
|
|
|
- 3279 ELSE vt := SymTab.SymType(vn);
|
|
|
- 3280 IF vt = SymTab.InvalidType THEN
|
|
|
- 3281 t := SymTab.InvalidType
|
|
|
- 3282 ELSIF et =
|
|
|
- 3283 SymTab.InvalidType THEN
|
|
|
- 3284 t := vt
|
|
|
- 3285 ELSE
|
|
|
- 3286 c1 := SymTab.ClassOf(et);
|
|
|
- 3287 c2 := SymTab.ClassOf(vt);
|
|
|
- 3288 IF (c1 = SymTab.ClInt)
|
|
|
- 3289 AND (c2 = SymTab.ClLong) THEN
|
|
|
- 3290 QbeGen.WidenLong(q, qa);
|
|
|
- 3291 QbeGen.CopyOp(qa, q);
|
|
|
- 3292 t := vt
|
|
|
- 3293 ELSIF (c1 = SymTab.ClLong)
|
|
|
- 3294 AND (c2 = SymTab.ClInt) THEN
|
|
|
- 3295 QbeGen.NarrowLong(q, qa);
|
|
|
- 3296 QbeGen.CopyOp(qa, q);
|
|
|
- 3297 t := vt
|
|
|
- 3298 ELSIF (c1 = SymTab.ClInt)
|
|
|
- 3299 AND (c2 = SymTab.ClReal) THEN
|
|
|
- 3300 QbeGen.ConvIR(q, qa);
|
|
|
- 3301 QbeGen.CopyOp(qa, q);
|
|
|
- 3302 t := vt
|
|
|
- 3303 ELSIF (c1 = SymTab.ClLong)
|
|
|
- 3304 AND (c2 = SymTab.ClReal) THEN
|
|
|
- 3305 QbeGen.ConvLR(q, qa);
|
|
|
- 3306 QbeGen.CopyOp(qa, q);
|
|
|
- 3307 t := vt
|
|
|
- 3308 ELSIF (c1 = SymTab.ClReal)
|
|
|
- 3309 AND (c2 = SymTab.ClInt) THEN
|
|
|
- 3310 QbeGen.ConvRI(q, qa);
|
|
|
- 3311 QbeGen.CopyOp(qa, q);
|
|
|
- 3312 t := vt
|
|
|
- 3313 ELSIF (c1 = SymTab.ClReal)
|
|
|
- 3314 AND (c2 = SymTab.ClLong) THEN
|
|
|
- 3315 QbeGen.ConvRL(q, qa);
|
|
|
- 3316 QbeGen.CopyOp(qa, q);
|
|
|
- 3317 t := vt
|
|
|
- 3318 ELSIF ((c1 = SymTab.ClInt)
|
|
|
- 3319 OR (c1 =
|
|
|
- 3320 SymTab.ClChar)
|
|
|
- 3321 OR (c1 =
|
|
|
- 3322 SymTab.ClBool)
|
|
|
- 3323 OR (c1 =
|
|
|
- 3324 SymTab.ClEnum))
|
|
|
- 3325 AND ((c2 = SymTab.ClInt)
|
|
|
- 3326 OR (c2 =
|
|
|
- 3327 SymTab.ClChar)
|
|
|
- 3328 OR (c2 =
|
|
|
- 3329 SymTab.ClBool)
|
|
|
- 3330 OR (c2 =
|
|
|
- 3331 SymTab.ClEnum)) THEN
|
|
|
- 3332 t := vt
|
|
|
- 3333 ELSIF (c1 = SymTab.ClPtr)
|
|
|
- 3334 AND (c2 = SymTab.ClPtr) THEN
|
|
|
- 3335 t := vt
|
|
|
- 3336 ELSIF (c1 = SymTab.ClReal)
|
|
|
- 3337 AND (c2 = SymTab.ClReal) THEN
|
|
|
- 3338 t := vt
|
|
|
- 3339 ELSE SemError(230);
|
|
|
- 3340 t := SymTab.InvalidType
|
|
|
- 3341 END
|
|
|
- 3342 END
|
|
|
- 3343 END; .)
|
|
|
- 3344 | "(" Expr<et, q> ")" (. t := et; astIsLit := TRUE; .)
|
|
|
- 3345 | SetLit<st, sq> (. astIsLit := TRUE; t := st;
|
|
|
- 3346 QbeGen.CopyOp(sq, q); .)
|
|
|
- 3347 | ( "NOT" | "~" ) Fact<t2, q2> (. astNot := astCur;
|
|
|
- 3348 IF SymTab.BoolCheck(t2) THEN
|
|
|
- 3349 t := SymTab.BoolType()
|
|
|
- 3350 ELSE SemError(212);
|
|
|
- 3351 t := SymTab.InvalidType END;
|
|
|
- 3352 IF t # SymTab.InvalidType THEN
|
|
|
- 3353 QbeGen.NotQ(q2, q)
|
|
|
- 3354 ELSE QbeGen.CopyOp("0", q)
|
|
|
- 3355 END;
|
|
|
- 3356 astIsLit := TRUE;
|
|
|
- 3357 astCur := AST.MakeUn(
|
|
|
- 3358 AST.NkUnary, AST.OpNot, astNot); .)
|
|
|
- 3359 )
|
|
|
- 3360 (. IF NOT astIsLit THEN astCur := AST.NoNode END; .) .
|
|
|
- 3361 (* Set literals are SET OF [0..255] (8 words); elements validated
|
|
|
- 3362 0..255 statically when foldable (222 otherwise), runtime trap
|
|
|
- 3363 for computed elements. Ranges always lower via SetRange. *)
|
|
|
- 3364 SetLit<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
- 3365 (. VAR astNode: AST.Node; .)
|
|
|
- 3366 = "{" (. t := SymTab.NewSet(
|
|
|
- 3367 SymTab.NewSubR(0, 255));
|
|
|
- 3368 astNode := AST.MakeNode(AST.NkSetLit);
|
|
|
- 3369 QbeGen.NewSetTemp(8, q);
|
|
|
- 3370 QbeGen.SetZero(q, 8); .)
|
|
|
- 3371 [ SetElem<t, q, astNode> { "," SetElem<t, q, astNode> } ]
|
|
|
- 3372 "}" (. astCur := astNode; .) .
|
|
|
- 3373 (* Typed brace constructor: TypeName{ elems } — BITSET{0} (a set)
|
|
|
- 3374 or ArrayName{...} (an array constructor, GNU Modula-2). The
|
|
|
- 3375 declared type sets the width (set) or element type (array). *)
|
|
|
- 3376 TypedBraceLit<vt: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
- 3377 (. VAR nw: CARDINAL;
|
|
|
- 3378 astNode, astTail: AST.Node;
|
|
|
- 3379 savedCls: INTEGER; .)
|
|
|
- 3380 = "{" (. savedCls := braceCls;
|
|
|
- 3381 astNode := AST.MakeNode(AST.NkBraceLit);
|
|
|
- 3382 AST.SetTy(astNode, vt);
|
|
|
- 3383 astTail := astNode;
|
|
|
- 3384 IF vt = SymTab.InvalidType THEN
|
|
|
- 3385 braceCls := -1
|
|
|
- 3386 ELSE braceCls :=
|
|
|
- 3387 SymTab.ClassOf(vt)
|
|
|
- 3388 END;
|
|
|
- 3389 IF braceCls = SymTab.ClSet THEN
|
|
|
- 3390 IF vt = SymTab.InvalidType THEN
|
|
|
- 3391 nw := 8
|
|
|
- 3392 ELSE nw := SymTab.SetWords(vt);
|
|
|
- 3393 IF nw = 0 THEN nw := 8 END
|
|
|
- 3394 END;
|
|
|
- 3395 QbeGen.NewSetTemp(nw, q);
|
|
|
- 3396 QbeGen.SetZero(q, nw)
|
|
|
- 3397 ELSIF (braceCls =
|
|
|
- 3398 SymTab.ClArray)
|
|
|
- 3399 OR (braceCls =
|
|
|
- 3400 SymTab.ClRecord)
|
|
|
- 3401 OR (braceCls =
|
|
|
- 3402 SymTab.ClClass) THEN
|
|
|
- 3403 QbeGen.CtorBegin(vt)
|
|
|
- 3404 ELSE
|
|
|
- 3405 IF vt # SymTab.InvalidType THEN
|
|
|
- 3406 SemError(230) END;
|
|
|
- 3407 braceCls := -1
|
|
|
- 3408 END; .)
|
|
|
- 3409 [ BraceElem<vt, q, astNode, astTail>
|
|
|
- 3410 { "," BraceElem<vt, q, astNode, astTail> } ]
|
|
|
- 3411 "}" (. IF (braceCls = SymTab.ClArray)
|
|
|
- 3412 OR (braceCls =
|
|
|
- 3413 SymTab.ClRecord)
|
|
|
- 3414 OR (braceCls =
|
|
|
- 3415 SymTab.ClClass) THEN
|
|
|
- 3416 QbeGen.CtorEnd(q)
|
|
|
- 3417 ELSIF braceCls # SymTab.ClSet THEN
|
|
|
- 3418 QbeGen.CopyOp("0", q)
|
|
|
- 3419 END;
|
|
|
- 3420 braceCls := savedCls; .)
|
|
|
- 3421 (. astCur := astNode; .) .
|
|
|
- 3422 BraceElem<vt: SymTab.TypeIndex; VAR sq: QbeGen.QVal;
|
|
|
- 3423 VAR node, tail: AST.Node>
|
|
|
- 3424 (. VAR et, et2: SymTab.TypeIndex;
|
|
|
- 3425 qe, q2: QbeGen.QVal;
|
|
|
- 3426 v, v2, reps, k: INTEGER;
|
|
|
- 3427 elem: SymTab.TypeIndex;
|
|
|
- 3428 lo: INTEGER;
|
|
|
- 3429 span: CARDINAL;
|
|
|
- 3430 cl, cl2: INTEGER;
|
|
|
- 3431 hasR, hasB: BOOLEAN;
|
|
|
- 3432 astEl: AST.Node; .)
|
|
|
- 3433 = (. hasR := FALSE; hasB := FALSE;
|
|
|
- 3434 reps := 1; .)
|
|
|
- 3435 Expr<et, qe> (. astEl := astCur; .)
|
|
|
- 3436 [ ".." Expr<et2, q2> (. astEl := AST.MakeBin(
|
|
|
- 3437 AST.NkSubrange, 0, astEl, astCur);
|
|
|
- 3438 hasR := TRUE; .) ]
|
|
|
- 3439 [ "BY" Expr<et2, q2> (. hasB := TRUE; .) ]
|
|
|
- 3440 (. IF braceCls = SymTab.ClSet THEN
|
|
|
- 3441 IF hasB THEN SemError(230) END;
|
|
|
- 3442 lo := SymTab.SetBaseLo(vt);
|
|
|
- 3443 span := SymTab.SetCount(vt);
|
|
|
- 3444 IF (et = SymTab.InvalidType)
|
|
|
- 3445 OR (hasR AND (et2 =
|
|
|
- 3446 SymTab.InvalidType)) THEN
|
|
|
- 3447 ELSE cl :=
|
|
|
- 3448 SymTab.ClassOf(et);
|
|
|
- 3449 IF hasR THEN
|
|
|
- 3450 cl2 :=
|
|
|
- 3451 SymTab.ClassOf(et2)
|
|
|
- 3452 ELSE cl2 := SymTab.ClInt
|
|
|
- 3453 END;
|
|
|
- 3454 IF NOT SymTab.SetElemClassOk(cl)
|
|
|
- 3455 OR (hasR AND NOT
|
|
|
- 3456 SymTab.SetElemClassOk(cl2))
|
|
|
- 3457 THEN
|
|
|
- 3458 SemError(222)
|
|
|
- 3459 ELSIF hasR
|
|
|
- 3460 AND SymTab.ConstInt(qe, v)
|
|
|
- 3461 AND SymTab.ConstInt(q2,
|
|
|
- 3462 v2)
|
|
|
- 3463 AND ((v < lo)
|
|
|
- 3464 OR (v2 < lo)
|
|
|
- 3465 OR (v >= lo +
|
|
|
- 3466 VAL(INTEGER, span))
|
|
|
- 3467 OR (v2 >= lo +
|
|
|
- 3468 VAL(INTEGER, span))
|
|
|
- 3469 OR (v > v2)) THEN
|
|
|
- 3470 SemError(222)
|
|
|
- 3471 ELSIF hasR THEN
|
|
|
- 3472 QbeGen.SetRange(sq, qe, q2,
|
|
|
- 3473 lo, span)
|
|
|
- 3474 ELSIF SymTab.ConstInt(qe,
|
|
|
- 3475 v)
|
|
|
- 3476 AND ((v < lo)
|
|
|
- 3477 OR (v >= lo +
|
|
|
- 3478 VAL(INTEGER,
|
|
|
- 3479 span))) THEN
|
|
|
- 3480 SemError(222)
|
|
|
- 3481 ELSE QbeGen.SetBit(sq, qe,
|
|
|
- 3482 lo, span)
|
|
|
- 3483 END
|
|
|
- 3484 END
|
|
|
- 3485 ELSIF (braceCls = SymTab.ClArray)
|
|
|
- 3486 OR (braceCls =
|
|
|
- 3487 SymTab.ClRecord)
|
|
|
- 3488 OR (braceCls =
|
|
|
- 3489 SymTab.ClClass) THEN
|
|
|
- 3490 IF hasR THEN SemError(230) END;
|
|
|
- 3491 reps := 1;
|
|
|
- 3492 IF hasB THEN
|
|
|
- 3493 IF SymTab.ConstInt(q2, v2)
|
|
|
- 3494 AND (v2 >= 1) THEN
|
|
|
- 3495 reps := v2
|
|
|
- 3496 ELSE SemError(230)
|
|
|
- 3497 END
|
|
|
- 3498 END;
|
|
|
- 3499 k := 0;
|
|
|
- 3500 WHILE k < reps DO
|
|
|
- 3501 QbeGen.CtorElem(qe);
|
|
|
- 3502 INC(k)
|
|
|
- 3503 END
|
|
|
- 3504 END; .)
|
|
|
- 3505 (. (* the BY form repeats the
|
|
|
- 3506 element; keep the AST in
|
|
|
- 3507 step with CtorElem *)
|
|
|
- 3508 k := 0;
|
|
|
- 3509 WHILE k < reps DO
|
|
|
- 3510 AstAppend(AST.NkBlock,
|
|
|
- 3511 node, tail, astEl);
|
|
|
- 3512 INC(k)
|
|
|
- 3513 END; .) .
|
|
|
- 3514 SetElem<st: SymTab.TypeIndex; sq: QbeGen.QVal; node: AST.Node> (. VAR et, et2: SymTab.TypeIndex;
|
|
|
- 3515 qe, q2: QbeGen.QVal;
|
|
|
- 3516 v, v2: INTEGER;
|
|
|
- 3517 lo: INTEGER;
|
|
|
- 3518 span: CARDINAL;
|
|
|
- 3519 cl, cl2: INTEGER;
|
|
|
- 3520 hasR: BOOLEAN;
|
|
|
- 3521 astEl: AST.Node; .)
|
|
|
- 3522 = (. hasR := FALSE; .)
|
|
|
- 3523 Expr<et, qe> (. astEl := astCur; .)
|
|
|
- 3524 [ ".." Expr<et2, q2> (. astEl := AST.MakeBin(
|
|
|
- 3525 AST.NkSubrange, 0, astEl, astCur);
|
|
|
- 3526 hasR := TRUE; .) ]
|
|
|
- 3527 (. lo := SymTab.SetBaseLo(st);
|
|
|
- 3528 span := SymTab.SetCount(st);
|
|
|
- 3529 IF (et = SymTab.InvalidType)
|
|
|
- 3530 OR (hasR AND (et2 =
|
|
|
- 3531 SymTab.InvalidType)) THEN
|
|
|
- 3532 ELSE cl :=
|
|
|
- 3533 SymTab.ClassOf(et);
|
|
|
- 3534 IF hasR THEN
|
|
|
- 3535 cl2 :=
|
|
|
- 3536 SymTab.ClassOf(et2)
|
|
|
- 3537 ELSE cl2 := SymTab.ClInt
|
|
|
- 3538 END;
|
|
|
- 3539 IF NOT SymTab.SetElemClassOk(cl)
|
|
|
- 3540 OR (hasR AND NOT
|
|
|
- 3541 SymTab.SetElemClassOk(cl2))
|
|
|
- 3542 THEN
|
|
|
- 3543 SemError(222)
|
|
|
- 3544 ELSIF hasR
|
|
|
- 3545 AND SymTab.ConstInt(qe, v)
|
|
|
- 3546 AND SymTab.ConstInt(q2,
|
|
|
- 3547 v2)
|
|
|
- 3548 AND ((v < lo)
|
|
|
- 3549 OR (v2 < lo)
|
|
|
- 3550 OR (v >= lo +
|
|
|
- 3551 VAL(INTEGER, span))
|
|
|
- 3552 OR (v2 >= lo +
|
|
|
- 3553 VAL(INTEGER, span))
|
|
|
- 3554 OR (v > v2)) THEN
|
|
|
- 3555 SemError(222)
|
|
|
- 3556 ELSIF hasR THEN
|
|
|
- 3557 QbeGen.SetRange(sq, qe, q2,
|
|
|
- 3558 lo, span)
|
|
|
- 3559 ELSIF SymTab.ConstInt(qe,
|
|
|
- 3560 v)
|
|
|
- 3561 AND ((v < lo)
|
|
|
- 3562 OR (v >= lo +
|
|
|
- 3563 VAL(INTEGER,
|
|
|
- 3564 span))) THEN
|
|
|
- 3565 SemError(222)
|
|
|
- 3566 ELSE QbeGen.SetBit(sq, qe,
|
|
|
- 3567 lo, span)
|
|
|
- 3568 END
|
|
|
- 3569 END; .)
|
|
|
- 3570 (. AST.SetChild(node,
|
|
|
- 3571 AST.NChild(node), astEl); .) .
|
|
|
- 3572 GetIdent<VAR n: SymTab.Name>
|
|
|
- 3573 = ident (. LexName(n); .) .
|
|
|
- 3574
|
|
|
- 3575 END M2.
|
|
|
+ 2982 END; .)
|
|
|
+ 2983 | ( "SIZE" | "TSIZE" ) "(" Design<dt, dk, qd, qn, sfx> ")"
|
|
|
+ 2984 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
+ 2985 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "SIZE"));
|
|
|
+ 2986 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
+ 2987 astCur := astNode; astIsLit := TRUE; .)
|
|
|
+ 2988 (. IF dt = SymTab.InvalidType THEN
|
|
|
+ 2989 t := SymTab.InvalidType;
|
|
|
+ 2990 QbeGen.CopyOp("0", q)
|
|
|
+ 2991 ELSE
|
|
|
+ 2992 QbeGen.IntStr(VAL(INTEGER,
|
|
|
+ 2993 SymTab.ObjectSize(dt)), q);
|
|
|
+ 2994 t := SymTab.IntType()
|
|
|
+ 2995 END; .)
|
|
|
+ 2996 | ( "SHIFT" (. isMax := FALSE; .)
|
|
|
+ 2997 | "ROTATE" (. isMax := TRUE; .) )
|
|
|
+ 2998 "(" Expr<et, q> (. astArg2 := astCur; .) "," Expr<et2, q2> ")"
|
|
|
+ 2999 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
+ 3000 IF isMax THEN AST.SetChild(astNode, 0,
|
|
|
+ 3001 AST.MakeLeaf(AST.NkIdent, "ROTATE"))
|
|
|
+ 3002 ELSE AST.SetChild(astNode, 0,
|
|
|
+ 3003 AST.MakeLeaf(AST.NkIdent, "SHIFT")) END;
|
|
|
+ 3004 IF astArg2 # AST.NoNode THEN AST.SetChild(astNode, 1, astArg2) END;
|
|
|
+ 3005 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 2, astCur) END;
|
|
|
+ 3006 astCur := astNode; astIsLit := TRUE;
|
|
|
+ 3007 (* set shift/rotate: isMax
|
|
|
+ 3008 doubles as "rotate" *)
|
|
|
+ 3009 IF (et # SymTab.InvalidType)
|
|
|
+ 3010 AND (SymTab.ClassOf(et) =
|
|
|
+ 3011 SymTab.ClSet) THEN
|
|
|
+ 3012 t := et;
|
|
|
+ 3013 QbeGen.CopyOp("@", q)
|
|
|
+ 3014 ELSE SemError(230);
|
|
|
+ 3015 t := SymTab.InvalidType;
|
|
|
+ 3016 QbeGen.CopyOp("0", q)
|
|
|
+ 3017 END; .)
|
|
|
+ 3018 | ( "MIN" (. isMax := FALSE; .)
|
|
|
+ 3019 | "MAX" (. isMax := TRUE; .) )
|
|
|
+ 3020 "(" Design<dt, dk, qd, qn, sfx> ")"
|
|
|
+ 3021 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
+ 3022 IF isMax THEN AST.SetChild(astNode, 0,
|
|
|
+ 3023 AST.MakeLeaf(AST.NkIdent, "MAX"))
|
|
|
+ 3024 ELSE AST.SetChild(astNode, 0,
|
|
|
+ 3025 AST.MakeLeaf(AST.NkIdent, "MIN")) END;
|
|
|
+ 3026 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
+ 3027 astCur := astNode; astIsLit := TRUE;
|
|
|
+ 3028 IF (dt # SymTab.InvalidType)
|
|
|
+ 3029 AND (SymTab.ClassOf(dt) = SymTab.ClReal) THEN
|
|
|
+ 3030 (* REAL/LONGREAL: the
|
|
|
+ 3031 implementation bounds *)
|
|
|
+ 3032 IF isMax THEN
|
|
|
+ 3033 QbeGen.NormReal(
|
|
|
+ 3034 "3.402823e38", q)
|
|
|
+ 3035 ELSE QbeGen.NormReal(
|
|
|
+ 3036 "-3.402823e38", q)
|
|
|
+ 3037 END;
|
|
|
+ 3038 t := SymTab.RealType()
|
|
|
+ 3039 ELSIF (dt #
|
|
|
+ 3040 SymTab.InvalidType)
|
|
|
+ 3041 AND (SymTab.ClassOf(dt) =
|
|
|
+ 3042 SymTab.ClLong) THEN
|
|
|
+ 3043 IF isMax THEN
|
|
|
+ 3044 QbeGen.CopyOp(
|
|
|
+ 3045 "9223372036854775807", q)
|
|
|
+ 3046 ELSE QbeGen.CopyOp(
|
|
|
+ 3047 "-9223372036854775808", q)
|
|
|
+ 3048 END;
|
|
|
+ 3049 t := SymTab.LongType()
|
|
|
+ 3050 ELSIF SymTab.TypeBounds(dt, lo,
|
|
|
+ 3051 hi) THEN
|
|
|
+ 3052 IF isMax THEN
|
|
|
+ 3053 QbeGen.IntStr(hi, q)
|
|
|
+ 3054 ELSE QbeGen.IntStr(lo, q)
|
|
|
+ 3055 END;
|
|
|
+ 3056 t := SymTab.IntType()
|
|
|
+ 3057 ELSE SemError(230);
|
|
|
+ 3058 t := SymTab.InvalidType;
|
|
|
+ 3059 QbeGen.CopyOp("0", q)
|
|
|
+ 3060 END; .)
|
|
|
+ 3061 | "ADR" "(" Design<dt, dk, qd, qn, sfx> ")"
|
|
|
+ 3062 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
+ 3063 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "ADR"));
|
|
|
+ 3064 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
+ 3065 astCur := astNode; astIsLit := TRUE; .)
|
|
|
+ 3066 (. IF dt = SymTab.InvalidType THEN
|
|
|
+ 3067 t := SymTab.InvalidType;
|
|
|
+ 3068 QbeGen.CopyOp("0", q)
|
|
|
+ 3069 ELSE
|
|
|
+ 3070 IF sfx
|
|
|
+ 3071 OR (dk = SymTab.KindVar)
|
|
|
+ 3072 OR (dk = SymTab.KindParam) THEN
|
|
|
+ 3073 QbeGen.CopyOp("@", q)
|
|
|
+ 3074 ELSE SemError(230);
|
|
|
+ 3075 QbeGen.CopyOp("0", q)
|
|
|
+ 3076 END;
|
|
|
+ 3077 t := SymTab.AddrType()
|
|
|
+ 3078 END; .)
|
|
|
+ 3079 | "CHR" "(" Expr<et, q> ")"
|
|
|
+ 3080 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
+ 3081 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "CHR"));
|
|
|
+ 3082 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
+ 3083 astCur := astNode; astIsLit := TRUE; .)
|
|
|
+ 3084 (. IF (et # SymTab.InvalidType)
|
|
|
+ 3085 AND NOT SymTab.IsIntFamily(et) THEN
|
|
|
+ 3086 SemError(211) END;
|
|
|
+ 3087 t := SymTab.CharType(); .)
|
|
|
+ 3088 | ( "ORD" | "ORDL" ) "(" Expr<et, q> ")"
|
|
|
+ 3089 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
+ 3090 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "ORD"));
|
|
|
+ 3091 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
+ 3092 astCur := astNode; astIsLit := TRUE; .)
|
|
|
+ 3093 (. IF et # SymTab.InvalidType THEN
|
|
|
+ 3094 IF (SymTab.ClassOf(et) #
|
|
|
+ 3095 SymTab.ClChar)
|
|
|
+ 3096 AND (SymTab.ClassOf(et) #
|
|
|
+ 3097 SymTab.ClBool)
|
|
|
+ 3098 AND (SymTab.ClassOf(et) #
|
|
|
+ 3099 SymTab.ClEnum)
|
|
|
+ 3100 AND NOT SymTab.IsIntFamily(et) THEN
|
|
|
+ 3101 SemError(211) END
|
|
|
+ 3102 END;
|
|
|
+ 3103 t := SymTab.IntType(); .)
|
|
|
+ 3104 | "CAP" "(" Expr<et, q> ")"
|
|
|
+ 3105 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
+ 3106 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "CAP"));
|
|
|
+ 3107 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
+ 3108 astCur := astNode; astIsLit := TRUE; .)
|
|
|
+ 3109 (. QbeGen.CapQ(q, qa);
|
|
|
+ 3110 QbeGen.CopyOp(qa, q);
|
|
|
+ 3111 t := SymTab.CharType(); .)
|
|
|
+ 3112 | "UCHR" "(" Expr<et, q> ")"
|
|
|
+ 3113 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
+ 3114 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "UCHR"));
|
|
|
+ 3115 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
+ 3116 astCur := astNode; astIsLit := TRUE; .)
|
|
|
+ 3117 (. (* UCHR: the UCHAR constructor.
|
|
|
+ 3118 CHAR -> UCHAR (identity);
|
|
|
+ 3119 INTEGER familly -> UCHAR
|
|
|
+ 3120 (codepoint value). *)
|
|
|
+ 3121 IF (et # SymTab.InvalidType)
|
|
|
+ 3122 AND (SymTab.ClassOf(et) # SymTab.ClChar)
|
|
|
+ 3123 AND NOT SymTab.IsIntFamily(et) THEN
|
|
|
+ 3124 SemError(211) END;
|
|
|
+ 3125 t := SymTab.UCharType(); .)
|
|
|
+ 3126 | "CHR8" "(" Expr<et, q> ")"
|
|
|
+ 3127 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
+ 3128 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "CHR8"));
|
|
|
+ 3129 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
+ 3130 astCur := astNode; astIsLit := TRUE; .)
|
|
|
+ 3131 (. IF (et # SymTab.InvalidType)
|
|
|
+ 3132 AND (SymTab.ClassOf(et) # SymTab.ClUChar) THEN
|
|
|
+ 3133 SemError(211) END;
|
|
|
+ 3134 t := SymTab.CharType(); .)
|
|
|
+ 3135 | "UORD" "(" Expr<et, q> ")"
|
|
|
+ 3136 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
+ 3137 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "UORD"));
|
|
|
+ 3138 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
+ 3139 astCur := astNode; astIsLit := TRUE; .)
|
|
|
+ 3140 (. (* UORD(u): the codepoint as a
|
|
|
+ 3141 32-bit ordinal (INTEGER),
|
|
|
+ 3142 cf. ORD for CHAR. *)
|
|
|
+ 3143 IF (et # SymTab.InvalidType)
|
|
|
+ 3144 AND (SymTab.ClassOf(et) # SymTab.ClUChar) THEN
|
|
|
+ 3145 SemError(211) END;
|
|
|
+ 3146 t := SymTab.IntType(); .)
|
|
|
+ 3147 | "ABS" "(" Expr<et, q> ")"
|
|
|
+ 3148 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
+ 3149 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "ABS"));
|
|
|
+ 3150 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
+ 3151 astCur := astNode; astIsLit := TRUE; .)
|
|
|
+ 3152 (. IF (et # SymTab.InvalidType)
|
|
|
+ 3153 AND NOT SymTab.IsIntFamily(et)
|
|
|
+ 3154 AND (SymTab.ClassOf(et) #
|
|
|
+ 3155 SymTab.ClReal) THEN
|
|
|
+ 3156 SemError(211)
|
|
|
+ 3157 ELSE QbeGen.AbsQ(q, qa,
|
|
|
+ 3158 SymTab.ClassOf(et) =
|
|
|
+ 3159 SymTab.ClReal);
|
|
|
+ 3160 QbeGen.CopyOp(qa, q)
|
|
|
+ 3161 END;
|
|
|
+ 3162 t := et; .)
|
|
|
+ 3163 | "VAL" "(" GetIdent<vn> (. astArg2 := AST.MakeLeaf(AST.NkIdent, vn); .) "," Expr<et, q> ")"
|
|
|
+ 3164 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
+ 3165 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "VAL"));
|
|
|
+ 3166 IF astArg2 # AST.NoNode THEN AST.SetChild(astNode, 1, astArg2) END;
|
|
|
+ 3167 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 2, astCur) END;
|
|
|
+ 3168 astCur := astNode; astIsLit := TRUE; .)
|
|
|
+ 3169 (. IF NOT SymTab.Lookup(vn) THEN
|
|
|
+ 3170 SemError(201);
|
|
|
+ 3171 t := SymTab.InvalidType
|
|
|
+ 3172 ELSE vt := SymTab.SymType(vn);
|
|
|
+ 3173 IF vt = SymTab.InvalidType THEN
|
|
|
+ 3174 t := SymTab.InvalidType
|
|
|
+ 3175 ELSIF et =
|
|
|
+ 3176 SymTab.InvalidType THEN
|
|
|
+ 3177 t := vt
|
|
|
+ 3178 ELSE
|
|
|
+ 3179 c1 := SymTab.ClassOf(et);
|
|
|
+ 3180 c2 := SymTab.ClassOf(vt);
|
|
|
+ 3181 IF (c1 = SymTab.ClInt)
|
|
|
+ 3182 AND (c2 = SymTab.ClLong) THEN
|
|
|
+ 3183 QbeGen.WidenLong(q, qa);
|
|
|
+ 3184 QbeGen.CopyOp(qa, q);
|
|
|
+ 3185 t := vt
|
|
|
+ 3186 ELSIF (c1 = SymTab.ClLong)
|
|
|
+ 3187 AND (c2 = SymTab.ClInt) THEN
|
|
|
+ 3188 QbeGen.NarrowLong(q, qa);
|
|
|
+ 3189 QbeGen.CopyOp(qa, q);
|
|
|
+ 3190 t := vt
|
|
|
+ 3191 ELSIF (c1 = SymTab.ClInt)
|
|
|
+ 3192 AND (c2 = SymTab.ClReal) THEN
|
|
|
+ 3193 QbeGen.ConvIR(q, qa);
|
|
|
+ 3194 QbeGen.CopyOp(qa, q);
|
|
|
+ 3195 t := vt
|
|
|
+ 3196 ELSIF (c1 = SymTab.ClLong)
|
|
|
+ 3197 AND (c2 = SymTab.ClReal) THEN
|
|
|
+ 3198 QbeGen.ConvLR(q, qa);
|
|
|
+ 3199 QbeGen.CopyOp(qa, q);
|
|
|
+ 3200 t := vt
|
|
|
+ 3201 ELSIF (c1 = SymTab.ClReal)
|
|
|
+ 3202 AND (c2 = SymTab.ClInt) THEN
|
|
|
+ 3203 QbeGen.ConvRI(q, qa);
|
|
|
+ 3204 QbeGen.CopyOp(qa, q);
|
|
|
+ 3205 t := vt
|
|
|
+ 3206 ELSIF (c1 = SymTab.ClReal)
|
|
|
+ 3207 AND (c2 = SymTab.ClLong) THEN
|
|
|
+ 3208 QbeGen.ConvRL(q, qa);
|
|
|
+ 3209 QbeGen.CopyOp(qa, q);
|
|
|
+ 3210 t := vt
|
|
|
+ 3211 ELSIF ((c1 = SymTab.ClInt)
|
|
|
+ 3212 OR (c1 =
|
|
|
+ 3213 SymTab.ClChar)
|
|
|
+ 3214 OR (c1 =
|
|
|
+ 3215 SymTab.ClBool)
|
|
|
+ 3216 OR (c1 =
|
|
|
+ 3217 SymTab.ClEnum))
|
|
|
+ 3218 AND ((c2 = SymTab.ClInt)
|
|
|
+ 3219 OR (c2 =
|
|
|
+ 3220 SymTab.ClChar)
|
|
|
+ 3221 OR (c2 =
|
|
|
+ 3222 SymTab.ClBool)
|
|
|
+ 3223 OR (c2 =
|
|
|
+ 3224 SymTab.ClEnum)) THEN
|
|
|
+ 3225 t := vt
|
|
|
+ 3226 ELSIF (c1 = SymTab.ClPtr)
|
|
|
+ 3227 AND (c2 = SymTab.ClPtr) THEN
|
|
|
+ 3228 t := vt
|
|
|
+ 3229 ELSIF (c1 = SymTab.ClReal)
|
|
|
+ 3230 AND (c2 = SymTab.ClReal) THEN
|
|
|
+ 3231 t := vt
|
|
|
+ 3232 ELSE SemError(230);
|
|
|
+ 3233 t := SymTab.InvalidType
|
|
|
+ 3234 END
|
|
|
+ 3235 END
|
|
|
+ 3236 END; .)
|
|
|
+ 3237 | "(" Expr<et, q> ")" (. t := et; astIsLit := TRUE; .)
|
|
|
+ 3238 | SetLit<st, sq> (. astIsLit := TRUE; t := st;
|
|
|
+ 3239 QbeGen.CopyOp(sq, q); .)
|
|
|
+ 3240 | ( "NOT" | "~" ) Fact<t2, q2> (. astNot := astCur;
|
|
|
+ 3241 IF SymTab.BoolCheck(t2) THEN
|
|
|
+ 3242 t := SymTab.BoolType()
|
|
|
+ 3243 ELSE SemError(212);
|
|
|
+ 3244 t := SymTab.InvalidType END;
|
|
|
+ 3245 IF t # SymTab.InvalidType THEN
|
|
|
+ 3246 QbeGen.NotQ(q2, q)
|
|
|
+ 3247 ELSE QbeGen.CopyOp("0", q)
|
|
|
+ 3248 END;
|
|
|
+ 3249 astIsLit := TRUE;
|
|
|
+ 3250 astCur := AST.MakeUn(
|
|
|
+ 3251 AST.NkUnary, AST.OpNot, astNot); .)
|
|
|
+ 3252 )
|
|
|
+ 3253 (. IF NOT astIsLit THEN astCur := AST.NoNode END; .) .
|
|
|
+ 3254 (* Set literals are SET OF [0..255] (8 words); elements validated
|
|
|
+ 3255 0..255 statically when foldable (222 otherwise), runtime trap
|
|
|
+ 3256 for computed elements. Ranges always lower via SetRange. *)
|
|
|
+ 3257 SetLit<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
+ 3258 (. VAR astNode: AST.Node; .)
|
|
|
+ 3259 = "{" (. t := SymTab.NewSet(
|
|
|
+ 3260 SymTab.NewSubR(0, 255));
|
|
|
+ 3261 astNode := AST.MakeNode(AST.NkSetLit);
|
|
|
+ 3262 QbeGen.NewSetTemp(8, q);
|
|
|
+ 3263 QbeGen.SetZero(q, 8); .)
|
|
|
+ 3264 [ SetElem<t, q, astNode> { "," SetElem<t, q, astNode> } ]
|
|
|
+ 3265 "}" (. astCur := astNode; .) .
|
|
|
+ 3266 (* Typed brace constructor: TypeName{ elems } — BITSET{0} (a set)
|
|
|
+ 3267 or ArrayName{...} (an array constructor, GNU Modula-2). The
|
|
|
+ 3268 declared type sets the width (set) or element type (array). *)
|
|
|
+ 3269 TypedBraceLit<vt: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
+ 3270 (. VAR nw: CARDINAL;
|
|
|
+ 3271 astNode, astTail: AST.Node;
|
|
|
+ 3272 savedCls: INTEGER; .)
|
|
|
+ 3273 = "{" (. savedCls := braceCls;
|
|
|
+ 3274 astNode := AST.MakeNode(AST.NkBraceLit);
|
|
|
+ 3275 AST.SetTy(astNode, vt);
|
|
|
+ 3276 astTail := astNode;
|
|
|
+ 3277 IF vt = SymTab.InvalidType THEN
|
|
|
+ 3278 braceCls := -1
|
|
|
+ 3279 ELSE braceCls :=
|
|
|
+ 3280 SymTab.ClassOf(vt)
|
|
|
+ 3281 END;
|
|
|
+ 3282 IF braceCls = SymTab.ClSet THEN
|
|
|
+ 3283 IF vt = SymTab.InvalidType THEN
|
|
|
+ 3284 nw := 8
|
|
|
+ 3285 ELSE nw := SymTab.SetWords(vt);
|
|
|
+ 3286 IF nw = 0 THEN nw := 8 END
|
|
|
+ 3287 END;
|
|
|
+ 3288 QbeGen.NewSetTemp(nw, q);
|
|
|
+ 3289 QbeGen.SetZero(q, nw)
|
|
|
+ 3290 ELSIF (braceCls =
|
|
|
+ 3291 SymTab.ClArray)
|
|
|
+ 3292 OR (braceCls =
|
|
|
+ 3293 SymTab.ClRecord)
|
|
|
+ 3294 OR (braceCls =
|
|
|
+ 3295 SymTab.ClClass) THEN
|
|
|
+ 3296 QbeGen.CtorBegin(vt)
|
|
|
+ 3297 ELSE
|
|
|
+ 3298 IF vt # SymTab.InvalidType THEN
|
|
|
+ 3299 SemError(230) END;
|
|
|
+ 3300 braceCls := -1
|
|
|
+ 3301 END; .)
|
|
|
+ 3302 [ BraceElem<vt, q, astNode, astTail>
|
|
|
+ 3303 { "," BraceElem<vt, q, astNode, astTail> } ]
|
|
|
+ 3304 "}" (. IF (braceCls = SymTab.ClArray)
|
|
|
+ 3305 OR (braceCls =
|
|
|
+ 3306 SymTab.ClRecord)
|
|
|
+ 3307 OR (braceCls =
|
|
|
+ 3308 SymTab.ClClass) THEN
|
|
|
+ 3309 QbeGen.CtorEnd(q)
|
|
|
+ 3310 ELSIF braceCls # SymTab.ClSet THEN
|
|
|
+ 3311 QbeGen.CopyOp("0", q)
|
|
|
+ 3312 END;
|
|
|
+ 3313 braceCls := savedCls; .)
|
|
|
+ 3314 (. astCur := astNode; .) .
|
|
|
+ 3315 BraceElem<vt: SymTab.TypeIndex; VAR sq: QbeGen.QVal;
|
|
|
+ 3316 VAR node, tail: AST.Node>
|
|
|
+ 3317 (. VAR et, et2: SymTab.TypeIndex;
|
|
|
+ 3318 qe, q2: QbeGen.QVal;
|
|
|
+ 3319 v, v2, reps, k: INTEGER;
|
|
|
+ 3320 elem: SymTab.TypeIndex;
|
|
|
+ 3321 lo: INTEGER;
|
|
|
+ 3322 span: CARDINAL;
|
|
|
+ 3323 cl, cl2: INTEGER;
|
|
|
+ 3324 hasR, hasB: BOOLEAN;
|
|
|
+ 3325 astEl: AST.Node; .)
|
|
|
+ 3326 = (. hasR := FALSE; hasB := FALSE;
|
|
|
+ 3327 reps := 1; .)
|
|
|
+ 3328 Expr<et, qe> (. astEl := astCur; .)
|
|
|
+ 3329 [ ".." Expr<et2, q2> (. astEl := AST.MakeBin(
|
|
|
+ 3330 AST.NkSubrange, 0, astEl, astCur);
|
|
|
+ 3331 hasR := TRUE; .) ]
|
|
|
+ 3332 [ "BY" Expr<et2, q2> (. hasB := TRUE; .) ]
|
|
|
+ 3333 (. IF braceCls = SymTab.ClSet THEN
|
|
|
+ 3334 IF hasB THEN SemError(230) END;
|
|
|
+ 3335 lo := SymTab.SetBaseLo(vt);
|
|
|
+ 3336 span := SymTab.SetCount(vt);
|
|
|
+ 3337 IF (et = SymTab.InvalidType)
|
|
|
+ 3338 OR (hasR AND (et2 =
|
|
|
+ 3339 SymTab.InvalidType)) THEN
|
|
|
+ 3340 ELSE cl :=
|
|
|
+ 3341 SymTab.ClassOf(et);
|
|
|
+ 3342 IF hasR THEN
|
|
|
+ 3343 cl2 :=
|
|
|
+ 3344 SymTab.ClassOf(et2)
|
|
|
+ 3345 ELSE cl2 := SymTab.ClInt
|
|
|
+ 3346 END;
|
|
|
+ 3347 IF NOT SymTab.SetElemClassOk(cl)
|
|
|
+ 3348 OR (hasR AND NOT
|
|
|
+ 3349 SymTab.SetElemClassOk(cl2))
|
|
|
+ 3350 THEN
|
|
|
+ 3351 SemError(222)
|
|
|
+ 3352 ELSIF hasR
|
|
|
+ 3353 AND SymTab.ConstInt(qe, v)
|
|
|
+ 3354 AND SymTab.ConstInt(q2,
|
|
|
+ 3355 v2)
|
|
|
+ 3356 AND ((v < lo)
|
|
|
+ 3357 OR (v2 < lo)
|
|
|
+ 3358 OR (v >= lo +
|
|
|
+ 3359 VAL(INTEGER, span))
|
|
|
+ 3360 OR (v2 >= lo +
|
|
|
+ 3361 VAL(INTEGER, span))
|
|
|
+ 3362 OR (v > v2)) THEN
|
|
|
+ 3363 SemError(222)
|
|
|
+ 3364 ELSIF hasR THEN
|
|
|
+ 3365 QbeGen.SetRange(sq, qe, q2,
|
|
|
+ 3366 lo, span)
|
|
|
+ 3367 ELSIF SymTab.ConstInt(qe,
|
|
|
+ 3368 v)
|
|
|
+ 3369 AND ((v < lo)
|
|
|
+ 3370 OR (v >= lo +
|
|
|
+ 3371 VAL(INTEGER,
|
|
|
+ 3372 span))) THEN
|
|
|
+ 3373 SemError(222)
|
|
|
+ 3374 ELSE QbeGen.SetBit(sq, qe,
|
|
|
+ 3375 lo, span)
|
|
|
+ 3376 END
|
|
|
+ 3377 END
|
|
|
+ 3378 ELSIF (braceCls = SymTab.ClArray)
|
|
|
+ 3379 OR (braceCls =
|
|
|
+ 3380 SymTab.ClRecord)
|
|
|
+ 3381 OR (braceCls =
|
|
|
+ 3382 SymTab.ClClass) THEN
|
|
|
+ 3383 IF hasR THEN SemError(230) END;
|
|
|
+ 3384 reps := 1;
|
|
|
+ 3385 IF hasB THEN
|
|
|
+ 3386 IF SymTab.ConstInt(q2, v2)
|
|
|
+ 3387 AND (v2 >= 1) THEN
|
|
|
+ 3388 reps := v2
|
|
|
+ 3389 ELSE SemError(230)
|
|
|
+ 3390 END
|
|
|
+ 3391 END;
|
|
|
+ 3392 k := 0;
|
|
|
+ 3393 WHILE k < reps DO
|
|
|
+ 3394 QbeGen.CtorElem(qe);
|
|
|
+ 3395 INC(k)
|
|
|
+ 3396 END
|
|
|
+ 3397 END; .)
|
|
|
+ 3398 (. (* the BY form repeats the
|
|
|
+ 3399 element; keep the AST in
|
|
|
+ 3400 step with CtorElem *)
|
|
|
+ 3401 k := 0;
|
|
|
+ 3402 WHILE k < reps DO
|
|
|
+ 3403 AstAppend(AST.NkBlock,
|
|
|
+ 3404 node, tail, astEl);
|
|
|
+ 3405 INC(k)
|
|
|
+ 3406 END; .) .
|
|
|
+ 3407 SetElem<st: SymTab.TypeIndex; sq: QbeGen.QVal; node: AST.Node> (. VAR et, et2: SymTab.TypeIndex;
|
|
|
+ 3408 qe, q2: QbeGen.QVal;
|
|
|
+ 3409 v, v2: INTEGER;
|
|
|
+ 3410 lo: INTEGER;
|
|
|
+ 3411 span: CARDINAL;
|
|
|
+ 3412 cl, cl2: INTEGER;
|
|
|
+ 3413 hasR: BOOLEAN;
|
|
|
+ 3414 astEl: AST.Node; .)
|
|
|
+ 3415 = (. hasR := FALSE; .)
|
|
|
+ 3416 Expr<et, qe> (. astEl := astCur; .)
|
|
|
+ 3417 [ ".." Expr<et2, q2> (. astEl := AST.MakeBin(
|
|
|
+ 3418 AST.NkSubrange, 0, astEl, astCur);
|
|
|
+ 3419 hasR := TRUE; .) ]
|
|
|
+ 3420 (. lo := SymTab.SetBaseLo(st);
|
|
|
+ 3421 span := SymTab.SetCount(st);
|
|
|
+ 3422 IF (et = SymTab.InvalidType)
|
|
|
+ 3423 OR (hasR AND (et2 =
|
|
|
+ 3424 SymTab.InvalidType)) THEN
|
|
|
+ 3425 ELSE cl :=
|
|
|
+ 3426 SymTab.ClassOf(et);
|
|
|
+ 3427 IF hasR THEN
|
|
|
+ 3428 cl2 :=
|
|
|
+ 3429 SymTab.ClassOf(et2)
|
|
|
+ 3430 ELSE cl2 := SymTab.ClInt
|
|
|
+ 3431 END;
|
|
|
+ 3432 IF NOT SymTab.SetElemClassOk(cl)
|
|
|
+ 3433 OR (hasR AND NOT
|
|
|
+ 3434 SymTab.SetElemClassOk(cl2))
|
|
|
+ 3435 THEN
|
|
|
+ 3436 SemError(222)
|
|
|
+ 3437 ELSIF hasR
|
|
|
+ 3438 AND SymTab.ConstInt(qe, v)
|
|
|
+ 3439 AND SymTab.ConstInt(q2,
|
|
|
+ 3440 v2)
|
|
|
+ 3441 AND ((v < lo)
|
|
|
+ 3442 OR (v2 < lo)
|
|
|
+ 3443 OR (v >= lo +
|
|
|
+ 3444 VAL(INTEGER, span))
|
|
|
+ 3445 OR (v2 >= lo +
|
|
|
+ 3446 VAL(INTEGER, span))
|
|
|
+ 3447 OR (v > v2)) THEN
|
|
|
+ 3448 SemError(222)
|
|
|
+ 3449 ELSIF hasR THEN
|
|
|
+ 3450 QbeGen.SetRange(sq, qe, q2,
|
|
|
+ 3451 lo, span)
|
|
|
+ 3452 ELSIF SymTab.ConstInt(qe,
|
|
|
+ 3453 v)
|
|
|
+ 3454 AND ((v < lo)
|
|
|
+ 3455 OR (v >= lo +
|
|
|
+ 3456 VAL(INTEGER,
|
|
|
+ 3457 span))) THEN
|
|
|
+ 3458 SemError(222)
|
|
|
+ 3459 ELSE QbeGen.SetBit(sq, qe,
|
|
|
+ 3460 lo, span)
|
|
|
+ 3461 END
|
|
|
+ 3462 END; .)
|
|
|
+ 3463 (. AST.SetChild(node,
|
|
|
+ 3464 AST.NChild(node), astEl); .) .
|
|
|
+ 3465 GetIdent<VAR n: SymTab.Name>
|
|
|
+ 3466 = ident (. LexName(n); .) .
|
|
|
+ 3467
|
|
|
+ 3468 END M2.
|
|
|
|
|
|
0 errors
|
|
|
|