|
|
@@ -1621,628 +1621,627 @@ Listing:
|
|
|
1604 fn);
|
|
|
1605 t := SymTab.FieldType(t, fn);
|
|
|
1606 QbeGen.FieldAddr(q, fo, qe);
|
|
|
- 1607 IF SymTab.ClassOf(t) =
|
|
|
- 1608 SymTab.ClArray THEN
|
|
|
- 1609 QbeGen.ElemLoad(qe, t, q)
|
|
|
- 1610 ELSE QbeGen.CopyOp(qe, q)
|
|
|
- 1611 END;
|
|
|
- 1612 sfx := TRUE
|
|
|
- 1613 END; .)
|
|
|
- 1614 | "^"
|
|
|
- 1615 (. IF t = SymTab.InvalidType THEN
|
|
|
- 1616 ELSIF SymTab.ClassOf(t) #
|
|
|
- 1617 SymTab.ClPtr THEN
|
|
|
- 1618 SemError(219);
|
|
|
- 1619 t := SymTab.InvalidType
|
|
|
- 1620 ELSE
|
|
|
- 1621 bt := SymTab.PtrBase(t);
|
|
|
- 1622 IF bt = SymTab.InvalidType THEN
|
|
|
- 1623 ELSE
|
|
|
- 1624 IF sfx THEN
|
|
|
- 1625 QbeGen.ElemLoad(q, t,
|
|
|
- 1626 qb);
|
|
|
- 1627 QbeGen.CopyOp(qb, q)
|
|
|
- 1628 END;
|
|
|
- 1629 t := bt;
|
|
|
- 1630 IF (SymTab.ClassOf(bt) =
|
|
|
- 1631 SymTab.ClInt)
|
|
|
- 1632 OR (SymTab.ClassOf(bt) =
|
|
|
- 1633 SymTab.ClBool)
|
|
|
- 1634 OR (SymTab.ClassOf(bt) =
|
|
|
- 1635 SymTab.ClChar)
|
|
|
- 1636 OR (SymTab.ClassOf(bt) =
|
|
|
- 1637 SymTab.ClReal) THEN
|
|
|
- 1638 sfx := TRUE
|
|
|
- 1639 ELSE sfx := FALSE
|
|
|
- 1640 END
|
|
|
- 1641 END
|
|
|
- 1642 END; .) } .
|
|
|
- 1643 Expr<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
- 1644 (. VAR t2: SymTab.TypeIndex;
|
|
|
- 1645 op: INTEGER;
|
|
|
- 1646 q2, qt, wl: QbeGen.QVal;
|
|
|
- 1647 isR: BOOLEAN; .)
|
|
|
- 1648 = SimExpr<t, q>
|
|
|
- 1649 [ Rel<op> SimExpr<t2, q2>
|
|
|
- 1650 (. IF op = SymTab.OpIn THEN
|
|
|
- 1651 IF SymTab.InCheck(t, t2) THEN
|
|
|
- 1652 IF (t = SymTab.InvalidType)
|
|
|
- 1653 OR (t2 = SymTab.InvalidType) THEN
|
|
|
- 1654 t := SymTab.BoolType(); QbeGen.CopyOp("0", q)
|
|
|
- 1655 ELSE
|
|
|
- 1656 QbeGen.InSet(q, q2, SymTab.SetBaseLo(t2),
|
|
|
- 1657 SymTab.SetCount(t2), qt);
|
|
|
- 1658 t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
|
|
|
- 1659 END
|
|
|
- 1660 ELSE SemError(222); t := SymTab.InvalidType;
|
|
|
- 1661 QbeGen.CopyOp("0", q)
|
|
|
- 1662 END
|
|
|
- 1663 ELSIF SymTab.RelCheck(t, t2, op) THEN
|
|
|
- 1664 IF (t = SymTab.InvalidType)
|
|
|
- 1665 OR (t2 = SymTab.InvalidType) THEN
|
|
|
- 1666 t := SymTab.BoolType(); QbeGen.CopyOp("0", q)
|
|
|
- 1667 ELSIF (SymTab.ClassOf(t) = SymTab.ClPtr)
|
|
|
- 1668 OR (SymTab.ClassOf(t2) = SymTab.ClPtr) THEN
|
|
|
- 1669 IF (op # SymTab.OpEq) AND (op # SymTab.OpNeq1)
|
|
|
- 1670 AND (op # SymTab.OpNeq2) THEN
|
|
|
- 1671 SemError(213); t := SymTab.InvalidType;
|
|
|
- 1672 QbeGen.CopyOp("0", q)
|
|
|
- 1673 ELSE
|
|
|
- 1674 QbeGen.CmpL(op, q, q2, qt);
|
|
|
- 1675 t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
|
|
|
- 1676 END
|
|
|
- 1677 ELSIF (SymTab.ClassOf(t) = SymTab.ClSet)
|
|
|
- 1678 OR (SymTab.ClassOf(t2) = SymTab.ClSet) THEN
|
|
|
- 1679 QbeGen.CmpSet(op, q, q2,
|
|
|
- 1680 SymTab.SetWords(t), SymTab.SetWords(t2), qt);
|
|
|
- 1681 t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
|
|
|
- 1682 ELSIF SymTab.IsLongFamily(t)
|
|
|
- 1683 OR SymTab.IsLongFamily(t2) THEN
|
|
|
- 1684 IF SymTab.IsIntFamily(t) THEN
|
|
|
- 1685 QbeGen.WidenLong(q, wl); QbeGen.CopyOp(wl, q)
|
|
|
- 1686 END;
|
|
|
- 1687 IF SymTab.IsIntFamily(t2) THEN
|
|
|
- 1688 QbeGen.WidenLong(q2, wl); QbeGen.CopyOp(wl, q2)
|
|
|
- 1689 END;
|
|
|
- 1690 QbeGen.CmpLong(op, q, q2, qt);
|
|
|
- 1691 t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
|
|
|
- 1692 ELSE
|
|
|
- 1693 isR := SymTab.ClassOf(t) = SymTab.ClReal;
|
|
|
- 1694 t := SymTab.BoolType();
|
|
|
- 1695 QbeGen.Cmp(op, q, q2, qt, isR);
|
|
|
- 1696 QbeGen.CopyOp(qt, q)
|
|
|
- 1697 END
|
|
|
- 1698 ELSE SemError(213); t := SymTab.InvalidType;
|
|
|
- 1699 QbeGen.CopyOp("0", q)
|
|
|
- 1700 END; .) ] .
|
|
|
- 1701 Rel<VAR op: INTEGER>
|
|
|
- 1702 = "=" (. op := SymTab.OpEq; .)
|
|
|
- 1703 | "#" (. op := SymTab.OpNeq1; .)
|
|
|
- 1704 | "<" (. op := SymTab.OpLt; .)
|
|
|
- 1705 | "<=" (. op := SymTab.OpLe; .)
|
|
|
- 1706 | ">" (. op := SymTab.OpGt; .)
|
|
|
- 1707 | ">=" (. op := SymTab.OpGe; .)
|
|
|
- 1708 | "IN" (. op := SymTab.OpIn; .) .
|
|
|
- 1709 SimExpr<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
- 1710 (. VAR t2, res2, lt, rt:
|
|
|
- 1711 SymTab.TypeIndex;
|
|
|
- 1712 op: INTEGER;
|
|
|
- 1713 q2, qt, wq, qf:
|
|
|
- 1714 QbeGen.QVal;
|
|
|
- 1715 neg, isR, isL, folded:
|
|
|
- 1716 BOOLEAN;
|
|
|
- 1717 lw, rw, mw: CARDINAL; .)
|
|
|
- 1718 = (. neg := FALSE; .)
|
|
|
- 1719 [ "+" | "-" (. neg := TRUE; .) ]
|
|
|
- 1720 Term<t, q> (. IF neg THEN
|
|
|
- 1721 IF QbeGen.IsImm(q) THEN
|
|
|
- 1722 QbeGen.NegFold(q, q)
|
|
|
- 1723 ELSE QbeGen.NewTemp(qt);
|
|
|
- 1724 QbeGen.NegQ(q, qt,
|
|
|
- 1725 SymTab.ClassOf(t)
|
|
|
- 1726 = SymTab.ClReal);
|
|
|
- 1727 QbeGen.CopyOp(qt, q)
|
|
|
- 1728 END
|
|
|
- 1729 END; .)
|
|
|
- 1730 { AddOp<op> Term<t2, q2>
|
|
|
- 1731 (. IF op = SymTab.OpOr THEN
|
|
|
- 1732 IF SymTab.BoolCheck(t) AND SymTab.BoolCheck(t2) THEN
|
|
|
- 1733 t := SymTab.BoolType()
|
|
|
- 1734 ELSE SemError(212); t := SymTab.InvalidType END;
|
|
|
- 1735 IF t # SymTab.InvalidType THEN
|
|
|
- 1736 QbeGen.NewTemp(qt);
|
|
|
- 1737 QbeGen.Op3("or", qt, q, q2, FALSE);
|
|
|
- 1738 QbeGen.CopyOp(qt, q)
|
|
|
- 1739 ELSE QbeGen.CopyOp("0", q)
|
|
|
- 1740 END
|
|
|
- 1741 ELSIF (t # SymTab.InvalidType) AND (t2 # SymTab.InvalidType)
|
|
|
- 1742 AND (SymTab.ClassOf(t) = SymTab.ClSet)
|
|
|
- 1743 AND (SymTab.ClassOf(t2) = SymTab.ClSet) THEN
|
|
|
- 1744 lw := SymTab.SetWords(t); rw := SymTab.SetWords(t2);
|
|
|
- 1745 mw := lw;
|
|
|
- 1746 IF rw > mw THEN mw := rw END;
|
|
|
- 1747 IF op = SymTab.OpAdd THEN
|
|
|
- 1748 QbeGen.SetBinOp(0, q, q2, lw, rw, qt)
|
|
|
- 1749 ELSE
|
|
|
- 1750 QbeGen.SetBinOp(2, q, q2, lw, rw, qt)
|
|
|
- 1751 END;
|
|
|
- 1752 t := SymTab.NewSet(
|
|
|
- 1753 SymTab.NewSubR(0,
|
|
|
- 1754 VAL(INTEGER, mw) * 32 - 1));
|
|
|
- 1755 QbeGen.CopyOp(qt, q)
|
|
|
- 1756 ELSE
|
|
|
- 1757 IF SymTab.ArithCheck(t, t2, FALSE, res2) THEN
|
|
|
- 1758 lt := t; rt := t2; t := res2
|
|
|
- 1759 ELSE SemError(211); t := SymTab.InvalidType END;
|
|
|
- 1760 IF t # SymTab.InvalidType THEN
|
|
|
- 1761 isL := SymTab.IsLongFamily(t);
|
|
|
- 1762 isR := SymTab.ClassOf(t) = SymTab.ClReal;
|
|
|
- 1763 folded := FALSE;
|
|
|
- 1764 IF (NOT isL) AND (NOT isR)
|
|
|
- 1765 AND QbeGen.IsImm(q) AND QbeGen.IsImm(q2) THEN
|
|
|
- 1766 IF op = SymTab.OpAdd THEN
|
|
|
- 1767 folded := QbeGen.Fold2(0, q, q2, qf)
|
|
|
- 1768 ELSE
|
|
|
- 1769 folded := QbeGen.Fold2(1, q, q2, qf)
|
|
|
- 1770 END
|
|
|
- 1771 END;
|
|
|
- 1772 IF folded THEN QbeGen.CopyOp(qf, q)
|
|
|
- 1773 ELSE
|
|
|
- 1774 IF isL THEN
|
|
|
- 1775 IF SymTab.IsIntFamily(lt) THEN
|
|
|
- 1776 QbeGen.WidenLong(q, wq); QbeGen.CopyOp(wq, q)
|
|
|
- 1777 END;
|
|
|
- 1778 IF SymTab.IsIntFamily(rt) THEN
|
|
|
- 1779 QbeGen.WidenLong(q2, wq); QbeGen.CopyOp(wq, q2)
|
|
|
- 1780 END;
|
|
|
- 1781 QbeGen.NewTemp(qt);
|
|
|
- 1782 IF op = SymTab.OpAdd THEN
|
|
|
- 1783 QbeGen.Op3L("add", qt, q, q2)
|
|
|
- 1784 ELSE
|
|
|
- 1785 QbeGen.Op3L("sub", qt, q, q2)
|
|
|
- 1786 END
|
|
|
- 1787 ELSE
|
|
|
- 1788 QbeGen.NewTemp(qt);
|
|
|
- 1789 IF op = SymTab.OpAdd THEN
|
|
|
- 1790 QbeGen.Op3("add", qt, q, q2, isR)
|
|
|
- 1791 ELSE
|
|
|
- 1792 QbeGen.Op3("sub", qt, q, q2, isR)
|
|
|
- 1793 END
|
|
|
- 1794 END;
|
|
|
- 1795 QbeGen.CopyOp(qt, q)
|
|
|
- 1796 END
|
|
|
- 1797 ELSE QbeGen.CopyOp("0", q)
|
|
|
- 1798 END
|
|
|
- 1799 END; .) } .
|
|
|
- 1800 AddOp<VAR op: INTEGER>
|
|
|
- 1801 = "+" (. op := SymTab.OpAdd; .)
|
|
|
- 1802 | "-" (. op := SymTab.OpSub; .)
|
|
|
- 1803 | "OR" (. op := SymTab.OpOr; .) .
|
|
|
- 1804 Term<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
- 1805 (. VAR t2, res2, lt, rt:
|
|
|
- 1806 SymTab.TypeIndex;
|
|
|
- 1807 op: INTEGER;
|
|
|
- 1808 q2, qt, wq, qf:
|
|
|
- 1809 QbeGen.QVal;
|
|
|
- 1810 isR, isL, folded: BOOLEAN;
|
|
|
- 1811 lw, rw, mw: CARDINAL; .)
|
|
|
- 1812 = Fact<t, q> { MulOp<op> Fact<t2, q2>
|
|
|
- 1813 (. IF op = SymTab.OpAnd THEN
|
|
|
- 1814 IF SymTab.BoolCheck(t) AND SymTab.BoolCheck(t2) THEN
|
|
|
- 1815 t := SymTab.BoolType()
|
|
|
- 1816 ELSE SemError(212); t := SymTab.InvalidType END;
|
|
|
- 1817 IF t # SymTab.InvalidType THEN
|
|
|
- 1818 QbeGen.NewTemp(qt);
|
|
|
- 1819 QbeGen.Op3("and", qt, q, q2, FALSE);
|
|
|
- 1820 QbeGen.CopyOp(qt, q)
|
|
|
- 1821 ELSE QbeGen.CopyOp("0", q)
|
|
|
- 1822 END
|
|
|
- 1823 ELSIF (t # SymTab.InvalidType) AND (t2 # SymTab.InvalidType)
|
|
|
- 1824 AND (SymTab.ClassOf(t) = SymTab.ClSet)
|
|
|
- 1825 AND (SymTab.ClassOf(t2) = SymTab.ClSet) THEN
|
|
|
- 1826 lw := SymTab.SetWords(t); rw := SymTab.SetWords(t2);
|
|
|
- 1827 mw := lw;
|
|
|
- 1828 IF rw > mw THEN mw := rw END;
|
|
|
- 1829 IF op = SymTab.OpTimes THEN
|
|
|
- 1830 QbeGen.SetBinOp(1, q, q2, lw, rw, qt)
|
|
|
- 1831 ELSE
|
|
|
- 1832 QbeGen.SetBinOp(3, q, q2, lw, rw, qt)
|
|
|
- 1833 END;
|
|
|
- 1834 t := SymTab.NewSet(
|
|
|
- 1835 SymTab.NewSubR(0,
|
|
|
- 1836 VAL(INTEGER, mw) * 32 - 1));
|
|
|
- 1837 QbeGen.CopyOp(qt, q)
|
|
|
- 1838 ELSE
|
|
|
- 1839 IF SymTab.ArithCheck(t, t2,
|
|
|
- 1840 (op = SymTab.OpDiv) OR (op = SymTab.OpMod),
|
|
|
- 1841 res2) THEN
|
|
|
- 1842 lt := t; rt := t2; t := res2
|
|
|
- 1843 ELSE SemError(211); t := SymTab.InvalidType END;
|
|
|
- 1844 IF t # SymTab.InvalidType THEN
|
|
|
- 1845 isL := SymTab.IsLongFamily(t);
|
|
|
- 1846 isR := SymTab.ClassOf(t) = SymTab.ClReal;
|
|
|
- 1847 folded := FALSE;
|
|
|
- 1848 IF (NOT isL) AND (NOT isR)
|
|
|
- 1849 AND QbeGen.IsImm(q) AND QbeGen.IsImm(q2) THEN
|
|
|
- 1850 IF op = SymTab.OpTimes THEN
|
|
|
- 1851 folded := QbeGen.Fold2(2, q, q2, qf)
|
|
|
- 1852 ELSIF op = SymTab.OpDiv THEN
|
|
|
- 1853 folded := QbeGen.Fold2(3, q, q2, qf)
|
|
|
- 1854 ELSIF op = SymTab.OpMod THEN
|
|
|
- 1855 folded := QbeGen.Fold2(4, q, q2, qf)
|
|
|
- 1856 END
|
|
|
- 1857 END;
|
|
|
- 1858 IF folded THEN QbeGen.CopyOp(qf, q)
|
|
|
- 1859 ELSE
|
|
|
- 1860 IF isL THEN
|
|
|
- 1861 IF SymTab.IsIntFamily(lt) THEN
|
|
|
- 1862 QbeGen.WidenLong(q, wq); QbeGen.CopyOp(wq, q)
|
|
|
- 1863 END;
|
|
|
- 1864 IF SymTab.IsIntFamily(rt) THEN
|
|
|
- 1865 QbeGen.WidenLong(q2, wq); QbeGen.CopyOp(wq, q2)
|
|
|
- 1866 END;
|
|
|
- 1867 QbeGen.NewTemp(qt);
|
|
|
- 1868 IF op = SymTab.OpTimes THEN
|
|
|
- 1869 QbeGen.Op3L("mul", qt, q, q2)
|
|
|
- 1870 ELSIF (op = SymTab.OpDiv)
|
|
|
- 1871 OR (op = SymTab.OpSlash) THEN
|
|
|
- 1872 QbeGen.Op3L("div", qt, q, q2)
|
|
|
- 1873 ELSE
|
|
|
- 1874 QbeGen.Op3L("rem", qt, q, q2)
|
|
|
- 1875 END
|
|
|
- 1876 ELSE
|
|
|
- 1877 QbeGen.NewTemp(qt);
|
|
|
- 1878 IF op = SymTab.OpTimes THEN
|
|
|
- 1879 QbeGen.Op3("mul", qt, q, q2, isR)
|
|
|
- 1880 ELSIF (op = SymTab.OpDiv)
|
|
|
- 1881 OR (op = SymTab.OpSlash) THEN
|
|
|
- 1882 QbeGen.Op3("div", qt, q, q2, isR)
|
|
|
- 1883 ELSE
|
|
|
- 1884 QbeGen.Op3("rem", qt, q, q2, isR)
|
|
|
- 1885 END
|
|
|
- 1886 END;
|
|
|
- 1887 QbeGen.CopyOp(qt, q)
|
|
|
- 1888 END
|
|
|
- 1889 ELSE QbeGen.CopyOp("0", q)
|
|
|
- 1890 END
|
|
|
- 1891 END; .) } .
|
|
|
- 1892 MulOp<VAR op: INTEGER>
|
|
|
- 1893 = "*" (. op := SymTab.OpTimes; .)
|
|
|
- 1894 | "/" (. op := SymTab.OpSlash; .)
|
|
|
- 1895 | "DIV" (. op := SymTab.OpDiv; .)
|
|
|
- 1896 | "MOD" (. op := SymTab.OpMod; .)
|
|
|
- 1897 | ( "AND" | "&" ) (. op := SymTab.OpAnd; .) .
|
|
|
- 1898 Fact<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
- 1899 (. VAR s: ARRAY [0 .. 255] OF CHAR;
|
|
|
- 1900 et, dt, t2, st, ct2:
|
|
|
- 1901 SymTab.TypeIndex;
|
|
|
- 1902 dk: INTEGER;
|
|
|
- 1903 qd, q2, sq, qa, qm0, qr:
|
|
|
- 1904 QbeGen.QVal;
|
|
|
- 1905 qn, vn: SymTab.Name;
|
|
|
- 1906 vt: SymTab.TypeIndex;
|
|
|
- 1907 c1, c2: INTEGER;
|
|
|
- 1908 called, isHigh, sfx, isCh:
|
|
|
- 1909 BOOLEAN; .)
|
|
|
- 1910 = integer (. LexString(s);
|
|
|
- 1911 QbeGen.NormInt(s, q);
|
|
|
- 1912 t := SymTab.IntType(); .)
|
|
|
- 1913 | charConst (. LexString(s);
|
|
|
- 1914 QbeGen.NormLit(s, q, isCh);
|
|
|
- 1915 t := SymTab.CharType(); .)
|
|
|
- 1916 | real (. LexString(s);
|
|
|
- 1917 QbeGen.NormReal(s, q);
|
|
|
- 1918 t := SymTab.RealType(); .)
|
|
|
- 1919 | string (. LexString(s);
|
|
|
- 1920 IF SymTab.StrLen(s) = 3 THEN
|
|
|
- 1921 t := SymTab.CharType();
|
|
|
- 1922 QbeGen.IntStr(
|
|
|
- 1923 QbeGen.CharVal(s), q)
|
|
|
- 1924 ELSE t := SymTab.NewStr();
|
|
|
- 1925 QbeGen.DeclStr(s, q);
|
|
|
- 1926 (* a literal's value IS its
|
|
|
- 1927 static descriptor address *)
|
|
|
- 1928 QbeGen.NoteAddr(q, q)
|
|
|
- 1929 END; .)
|
|
|
- 1930 | Design<dt, dk, qd, qn, sfx> (. called := FALSE;
|
|
|
- 1931 t := dt;
|
|
|
- 1932 IF sfx THEN
|
|
|
- 1933 IF dt =
|
|
|
- 1934 SymTab.InvalidType THEN
|
|
|
- 1935 QbeGen.CopyOp("0", q)
|
|
|
- 1936 ELSIF (SymTab.ClassOf(dt) =
|
|
|
- 1937 SymTab.ClRecord)
|
|
|
- 1938 OR (SymTab.ClassOf(dt) =
|
|
|
- 1939 SymTab.ClSet)
|
|
|
- 1940 OR (SymTab.ClassOf(dt) =
|
|
|
- 1941 SymTab.ClArray)
|
|
|
- 1942 OR (SymTab.ClassOf(dt) =
|
|
|
- 1943 SymTab.ClClass) THEN
|
|
|
- 1944 QbeGen.CopyOp(qd, q)
|
|
|
- 1945 ELSE QbeGen.ElemLoad(qd, dt,
|
|
|
- 1946 q)
|
|
|
- 1947 END
|
|
|
- 1948 ELSE QbeGen.CopyOp(qd, q)
|
|
|
- 1949 END;
|
|
|
- 1950 IF (dk = SymTab.KindVar)
|
|
|
- 1951 OR (dk = SymTab.KindParam)
|
|
|
- 1952 OR (dk =
|
|
|
- 1953 SymTab.KindField) THEN
|
|
|
- 1954 IF sfx THEN
|
|
|
- 1955 QbeGen.NoteAddr(q, qd)
|
|
|
- 1956 ELSE
|
|
|
- 1957 QbeGen.AddrOf(qn, qa);
|
|
|
- 1958 QbeGen.NoteAddr(q, qa)
|
|
|
- 1959 END
|
|
|
- 1960 ELSIF sfx
|
|
|
- 1961 AND (dt #
|
|
|
- 1962 SymTab.InvalidType)
|
|
|
- 1963 AND ((SymTab.ClassOf(dt) =
|
|
|
- 1964 SymTab.ClArray)
|
|
|
- 1965 OR (SymTab.ClassOf(dt) =
|
|
|
- 1966 SymTab.ClSet)
|
|
|
- 1967 OR (SymTab.ClassOf(dt) =
|
|
|
- 1968 SymTab.ClRecord)) THEN
|
|
|
- 1969 QbeGen.NoteAddr(qd, qd)
|
|
|
- 1970 END; .)
|
|
|
- 1971 [ TypedSetLit<dt, q> (. t := dt; .) ]
|
|
|
- 1972 [ ArgList<qn, dt, qd, TRUE, ct2, q2, called>
|
|
|
- 1973 (. t := ct2;
|
|
|
- 1974 QbeGen.CopyOp(q2, q); .) ]
|
|
|
- 1975 (. IF NOT called
|
|
|
- 1976 AND (dk = SymTab.KindProc) THEN
|
|
|
- 1977 (* bare zero-arg function
|
|
|
- 1978 call (parentheses may be
|
|
|
- 1979 omitted); a proper or
|
|
|
- 1980 parameterised proc here
|
|
|
- 1981 is 230 *)
|
|
|
- 1982 IF (SymTab.ProcNPar(qn) = 0)
|
|
|
- 1983 AND (SymTab.ProcRes(qn) #
|
|
|
- 1984 SymTab.InvalidType) THEN
|
|
|
- 1985 QbeGen.Mangled(qn,
|
|
|
- 1986 SymTab.ProcUid(qn), qm0);
|
|
|
- 1987 QbeGen.CallBegin(qm0,
|
|
|
- 1988 SymTab.ProcRes(qn),
|
|
|
- 1989 SymTab.ProcDepthOf(qn),
|
|
|
- 1990 SymTab.IsExternal(qn));
|
|
|
- 1991 QbeGen.CallEnd(TRUE, q);
|
|
|
- 1992 t := SymTab.ProcRes(qn)
|
|
|
- 1993 ELSE
|
|
|
- 1994 (* procedure used as a
|
|
|
- 1995 value (assign to a
|
|
|
- 1996 procedure variable):
|
|
|
- 1997 its code address *)
|
|
|
- 1998 t := SymTab.ProcTypeOf(qn);
|
|
|
- 1999 QbeGen.Mangled(qn,
|
|
|
- 2000 SymTab.ProcUid(qn), qm0);
|
|
|
- 2001 QbeGen.ProcAddr(qm0, q)
|
|
|
- 2002 END
|
|
|
- 2003 END; .)
|
|
|
- 2004 | ( "HIGH" (. isHigh := TRUE; .)
|
|
|
- 2005 | ( "LEN" | "LENGTH" ) (. isHigh := FALSE; .) )
|
|
|
- 2006 "(" Design<dt, dk, qd, qn, sfx> ")"
|
|
|
- 2007 (. IF dt = SymTab.InvalidType THEN
|
|
|
- 2008 ELSIF SymTab.ClassOf(dt) #
|
|
|
- 2009 SymTab.ClArray THEN
|
|
|
- 2010 SemError(217);
|
|
|
- 2011 t := SymTab.InvalidType;
|
|
|
- 2012 QbeGen.CopyOp("0", q)
|
|
|
- 2013 ELSE
|
|
|
- 2014 IF isHigh THEN
|
|
|
- 2015 IF SymTab.IsOpenArray(dt) THEN
|
|
|
- 2016 QbeGen.OpenHi(qd, qr)
|
|
|
- 2017 ELSE
|
|
|
- 2018 QbeGen.IntStr(
|
|
|
- 2019 SymTab.ArrayHi(dt), qr)
|
|
|
- 2020 END
|
|
|
- 2021 ELSE
|
|
|
- 2022 IF SymTab.IsOpenArray(dt) THEN
|
|
|
- 2023 QbeGen.LoadCount(qd, qr)
|
|
|
- 2024 ELSE
|
|
|
- 2025 QbeGen.IntStr(VAL(
|
|
|
- 2026 INTEGER,
|
|
|
- 2027 SymTab.ArrayLen(dt)),
|
|
|
- 2028 qr)
|
|
|
- 2029 END
|
|
|
- 2030 END;
|
|
|
- 2031 t := SymTab.IntType();
|
|
|
- 2032 QbeGen.CopyOp(qr, q)
|
|
|
- 2033 END; .)
|
|
|
- 2034 | ( "SIZE" | "TSIZE" ) "(" Design<dt, dk, qd, qn, sfx> ")"
|
|
|
- 2035 (. IF dt = SymTab.InvalidType THEN
|
|
|
- 2036 t := SymTab.InvalidType;
|
|
|
- 2037 QbeGen.CopyOp("0", q)
|
|
|
- 2038 ELSE
|
|
|
- 2039 QbeGen.IntStr(VAL(INTEGER,
|
|
|
- 2040 SymTab.ObjectSize(dt)), q);
|
|
|
- 2041 t := SymTab.IntType()
|
|
|
- 2042 END; .)
|
|
|
- 2043 | "ADR" "(" Design<dt, dk, qd, qn, sfx> ")"
|
|
|
- 2044 (. IF dt = SymTab.InvalidType THEN
|
|
|
- 2045 t := SymTab.InvalidType;
|
|
|
- 2046 QbeGen.CopyOp("0", q)
|
|
|
- 2047 ELSE
|
|
|
- 2048 IF sfx THEN
|
|
|
- 2049 QbeGen.CopyOp(qd, q)
|
|
|
- 2050 ELSIF (dk = SymTab.KindVar)
|
|
|
- 2051 OR (dk = SymTab.KindParam) THEN
|
|
|
- 2052 QbeGen.AddrOf(qn, q)
|
|
|
- 2053 ELSE SemError(230);
|
|
|
- 2054 QbeGen.CopyOp("0", q)
|
|
|
- 2055 END;
|
|
|
- 2056 t := SymTab.AddrType()
|
|
|
- 2057 END; .)
|
|
|
- 2058 | "CHR" "(" Expr<et, q> ")"
|
|
|
- 2059 (. IF (et # SymTab.InvalidType)
|
|
|
- 2060 AND NOT SymTab.IsIntFamily(et) THEN
|
|
|
- 2061 SemError(211) END;
|
|
|
- 2062 t := SymTab.CharType(); .)
|
|
|
- 2063 | ( "ORD" | "ORDL" ) "(" Expr<et, q> ")"
|
|
|
- 2064 (. IF et # SymTab.InvalidType THEN
|
|
|
- 2065 IF (SymTab.ClassOf(et) #
|
|
|
- 2066 SymTab.ClChar)
|
|
|
- 2067 AND (SymTab.ClassOf(et) #
|
|
|
- 2068 SymTab.ClBool)
|
|
|
- 2069 AND (SymTab.ClassOf(et) #
|
|
|
- 2070 SymTab.ClEnum)
|
|
|
- 2071 AND NOT SymTab.IsIntFamily(et) THEN
|
|
|
- 2072 SemError(211) END
|
|
|
- 2073 END;
|
|
|
- 2074 t := SymTab.IntType(); .)
|
|
|
- 2075 | "CAP" "(" Expr<et, q> ")"
|
|
|
- 2076 (. QbeGen.CapQ(q, qa);
|
|
|
- 2077 QbeGen.CopyOp(qa, q);
|
|
|
- 2078 t := SymTab.CharType(); .)
|
|
|
- 2079 | "ABS" "(" Expr<et, q> ")"
|
|
|
- 2080 (. IF (et # SymTab.InvalidType)
|
|
|
- 2081 AND NOT SymTab.IsIntFamily(et)
|
|
|
- 2082 AND (SymTab.ClassOf(et) #
|
|
|
- 2083 SymTab.ClReal) THEN
|
|
|
- 2084 SemError(211)
|
|
|
- 2085 ELSE QbeGen.AbsQ(q, qa,
|
|
|
- 2086 SymTab.ClassOf(et) =
|
|
|
- 2087 SymTab.ClReal);
|
|
|
- 2088 QbeGen.CopyOp(qa, q)
|
|
|
- 2089 END;
|
|
|
- 2090 t := et; .)
|
|
|
- 2091 | "VAL" "(" GetIdent<vn> "," Expr<et, q> ")"
|
|
|
- 2092 (. IF NOT SymTab.Lookup(vn) THEN
|
|
|
- 2093 SemError(201);
|
|
|
- 2094 t := SymTab.InvalidType
|
|
|
- 2095 ELSE vt := SymTab.SymType(vn);
|
|
|
- 2096 IF vt = SymTab.InvalidType THEN
|
|
|
- 2097 t := SymTab.InvalidType
|
|
|
- 2098 ELSIF et =
|
|
|
- 2099 SymTab.InvalidType THEN
|
|
|
- 2100 t := vt
|
|
|
- 2101 ELSE
|
|
|
- 2102 c1 := SymTab.ClassOf(et);
|
|
|
- 2103 c2 := SymTab.ClassOf(vt);
|
|
|
- 2104 IF ((c1 = SymTab.ClInt)
|
|
|
- 2105 OR (c1 =
|
|
|
- 2106 SymTab.ClChar)
|
|
|
- 2107 OR (c1 =
|
|
|
- 2108 SymTab.ClBool)
|
|
|
- 2109 OR (c1 =
|
|
|
- 2110 SymTab.ClEnum))
|
|
|
- 2111 AND ((c2 = SymTab.ClInt)
|
|
|
- 2112 OR (c2 =
|
|
|
- 2113 SymTab.ClChar)
|
|
|
- 2114 OR (c2 =
|
|
|
- 2115 SymTab.ClBool)
|
|
|
- 2116 OR (c2 =
|
|
|
- 2117 SymTab.ClEnum)) THEN
|
|
|
- 2118 t := vt
|
|
|
- 2119 ELSIF (c1 = SymTab.ClPtr)
|
|
|
- 2120 AND (c2 = SymTab.ClPtr) THEN
|
|
|
- 2121 t := vt
|
|
|
- 2122 ELSIF (c1 = SymTab.ClReal)
|
|
|
- 2123 AND (c2 = SymTab.ClReal) THEN
|
|
|
- 2124 t := vt
|
|
|
- 2125 ELSE SemError(230);
|
|
|
- 2126 t := SymTab.InvalidType
|
|
|
- 2127 END
|
|
|
- 2128 END
|
|
|
- 2129 END; .)
|
|
|
- 2130 | "(" Expr<et, q> ")" (. t := et; .)
|
|
|
- 2131 | SetLit<st, sq> (. t := st;
|
|
|
- 2132 QbeGen.CopyOp(sq, q); .)
|
|
|
- 2133 | ( "NOT" | "~" ) Fact<t2, q2> (. IF SymTab.BoolCheck(t2) THEN
|
|
|
- 2134 t := SymTab.BoolType()
|
|
|
- 2135 ELSE SemError(212);
|
|
|
- 2136 t := SymTab.InvalidType END;
|
|
|
- 2137 IF t # SymTab.InvalidType THEN
|
|
|
- 2138 QbeGen.NotQ(q2, q)
|
|
|
- 2139 ELSE QbeGen.CopyOp("0", q)
|
|
|
- 2140 END; .) .
|
|
|
- 2141 (* Set literals are SET OF [0..255] (8 words); elements validated
|
|
|
- 2142 0..255 statically when foldable (222 otherwise), runtime trap
|
|
|
- 2143 for computed elements. Ranges always lower via SetRange. *)
|
|
|
- 2144 SetLit<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
- 2145 = "{" (. t := SymTab.NewSet(
|
|
|
- 2146 SymTab.NewSubR(0, 255));
|
|
|
- 2147 QbeGen.NewSetTemp(8, q);
|
|
|
- 2148 QbeGen.SetZero(q, 8); .)
|
|
|
- 2149 [ SetElem<t, q> { "," SetElem<t, q> } ]
|
|
|
- 2150 "}" .
|
|
|
- 2151 (* Typed set constructor: TypeName{ elems } — e.g. BITSET{0},
|
|
|
- 2152 BITSET{}. The declared type (not SET OF [0..255]) sets the
|
|
|
- 2153 width and element span. *)
|
|
|
- 2154 TypedSetLit<vt: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
- 2155 (. VAR nw: CARDINAL; .)
|
|
|
- 2156 = "{" (. IF SymTab.ClassOf(vt) #
|
|
|
- 2157 SymTab.ClSet THEN
|
|
|
- 2158 SemError(230); nw := 8
|
|
|
- 2159 ELSE nw := SymTab.SetWords(vt);
|
|
|
- 2160 IF nw = 0 THEN nw := 8 END
|
|
|
- 2161 END;
|
|
|
- 2162 QbeGen.NewSetTemp(nw, q);
|
|
|
- 2163 QbeGen.SetZero(q, nw); .)
|
|
|
- 2164 [ SetElem<vt, q> { "," SetElem<vt, q> } ]
|
|
|
- 2165 "}" .
|
|
|
- 2166 SetElem<st: SymTab.TypeIndex; sq: QbeGen.QVal> (. VAR et, et2: SymTab.TypeIndex;
|
|
|
- 2167 qe, q2: QbeGen.QVal;
|
|
|
- 2168 v, v2: INTEGER;
|
|
|
- 2169 lo: INTEGER;
|
|
|
- 2170 span: CARDINAL;
|
|
|
- 2171 cl, cl2: INTEGER;
|
|
|
- 2172 hasR: BOOLEAN; .)
|
|
|
- 2173 = (. hasR := FALSE; .)
|
|
|
- 2174 Expr<et, qe>
|
|
|
- 2175 [ ".." Expr<et2, q2> (. hasR := TRUE; .) ]
|
|
|
- 2176 (. lo := SymTab.SetBaseLo(st);
|
|
|
- 2177 span := SymTab.SetCount(st);
|
|
|
- 2178 IF (et = SymTab.InvalidType)
|
|
|
- 2179 OR (hasR AND (et2 =
|
|
|
- 2180 SymTab.InvalidType)) THEN
|
|
|
- 2181 ELSE cl :=
|
|
|
- 2182 SymTab.ClassOf(et);
|
|
|
- 2183 IF hasR THEN
|
|
|
- 2184 cl2 :=
|
|
|
- 2185 SymTab.ClassOf(et2)
|
|
|
- 2186 ELSE cl2 := SymTab.ClInt
|
|
|
- 2187 END;
|
|
|
- 2188 IF ((cl # SymTab.ClInt)
|
|
|
- 2189 AND (cl # SymTab.ClChar)
|
|
|
- 2190 AND (cl # SymTab.ClBool))
|
|
|
- 2191 OR (hasR AND
|
|
|
- 2192 ((cl2
|
|
|
- 2193 # SymTab.ClInt)
|
|
|
- 2194 AND (cl2
|
|
|
- 2195 # SymTab.ClChar)
|
|
|
- 2196 AND (cl2
|
|
|
- 2197 # SymTab.ClBool))) THEN
|
|
|
- 2198 SemError(222)
|
|
|
- 2199 ELSIF hasR
|
|
|
- 2200 AND SymTab.ConstInt(qe, v)
|
|
|
- 2201 AND SymTab.ConstInt(q2,
|
|
|
- 2202 v2)
|
|
|
- 2203 AND ((v < lo)
|
|
|
- 2204 OR (v2 < lo)
|
|
|
- 2205 OR (v >= lo +
|
|
|
- 2206 VAL(INTEGER, span))
|
|
|
- 2207 OR (v2 >= lo +
|
|
|
- 2208 VAL(INTEGER, span))
|
|
|
- 2209 OR (v > v2)) THEN
|
|
|
- 2210 SemError(222)
|
|
|
- 2211 ELSIF hasR THEN
|
|
|
- 2212 QbeGen.SetRange(sq, qe, q2,
|
|
|
- 2213 lo, span)
|
|
|
- 2214 ELSIF SymTab.ConstInt(qe,
|
|
|
- 2215 v)
|
|
|
- 2216 AND ((v < lo)
|
|
|
- 2217 OR (v >= lo +
|
|
|
- 2218 VAL(INTEGER,
|
|
|
- 2219 span))) THEN
|
|
|
- 2220 SemError(222)
|
|
|
- 2221 ELSE QbeGen.SetBit(sq, qe,
|
|
|
- 2222 lo, span)
|
|
|
- 2223 END
|
|
|
- 2224 END; .) .
|
|
|
- 2225 GetIdent<VAR n: SymTab.Name>
|
|
|
- 2226 = ident (. LexName(n); .) .
|
|
|
- 2227
|
|
|
- 2228 END M2.
|
|
|
+ 1607 (* array fields are inline:
|
|
|
+ 1608 the field address is the
|
|
|
+ 1609 descriptor, like records *)
|
|
|
+ 1610 QbeGen.CopyOp(qe, q);
|
|
|
+ 1611 sfx := TRUE
|
|
|
+ 1612 END; .)
|
|
|
+ 1613 | "^"
|
|
|
+ 1614 (. IF t = SymTab.InvalidType THEN
|
|
|
+ 1615 ELSIF SymTab.ClassOf(t) #
|
|
|
+ 1616 SymTab.ClPtr THEN
|
|
|
+ 1617 SemError(219);
|
|
|
+ 1618 t := SymTab.InvalidType
|
|
|
+ 1619 ELSE
|
|
|
+ 1620 bt := SymTab.PtrBase(t);
|
|
|
+ 1621 IF bt = SymTab.InvalidType THEN
|
|
|
+ 1622 ELSE
|
|
|
+ 1623 IF sfx THEN
|
|
|
+ 1624 QbeGen.ElemLoad(q, t,
|
|
|
+ 1625 qb);
|
|
|
+ 1626 QbeGen.CopyOp(qb, q)
|
|
|
+ 1627 END;
|
|
|
+ 1628 t := bt;
|
|
|
+ 1629 IF (SymTab.ClassOf(bt) =
|
|
|
+ 1630 SymTab.ClInt)
|
|
|
+ 1631 OR (SymTab.ClassOf(bt) =
|
|
|
+ 1632 SymTab.ClBool)
|
|
|
+ 1633 OR (SymTab.ClassOf(bt) =
|
|
|
+ 1634 SymTab.ClChar)
|
|
|
+ 1635 OR (SymTab.ClassOf(bt) =
|
|
|
+ 1636 SymTab.ClReal) THEN
|
|
|
+ 1637 sfx := TRUE
|
|
|
+ 1638 ELSE sfx := FALSE
|
|
|
+ 1639 END
|
|
|
+ 1640 END
|
|
|
+ 1641 END; .) } .
|
|
|
+ 1642 Expr<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
+ 1643 (. VAR t2: SymTab.TypeIndex;
|
|
|
+ 1644 op: INTEGER;
|
|
|
+ 1645 q2, qt, wl: QbeGen.QVal;
|
|
|
+ 1646 isR: BOOLEAN; .)
|
|
|
+ 1647 = SimExpr<t, q>
|
|
|
+ 1648 [ Rel<op> SimExpr<t2, q2>
|
|
|
+ 1649 (. IF op = SymTab.OpIn THEN
|
|
|
+ 1650 IF SymTab.InCheck(t, t2) THEN
|
|
|
+ 1651 IF (t = SymTab.InvalidType)
|
|
|
+ 1652 OR (t2 = SymTab.InvalidType) THEN
|
|
|
+ 1653 t := SymTab.BoolType(); QbeGen.CopyOp("0", q)
|
|
|
+ 1654 ELSE
|
|
|
+ 1655 QbeGen.InSet(q, q2, SymTab.SetBaseLo(t2),
|
|
|
+ 1656 SymTab.SetCount(t2), qt);
|
|
|
+ 1657 t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
|
|
|
+ 1658 END
|
|
|
+ 1659 ELSE SemError(222); t := SymTab.InvalidType;
|
|
|
+ 1660 QbeGen.CopyOp("0", q)
|
|
|
+ 1661 END
|
|
|
+ 1662 ELSIF SymTab.RelCheck(t, t2, op) THEN
|
|
|
+ 1663 IF (t = SymTab.InvalidType)
|
|
|
+ 1664 OR (t2 = SymTab.InvalidType) THEN
|
|
|
+ 1665 t := SymTab.BoolType(); QbeGen.CopyOp("0", q)
|
|
|
+ 1666 ELSIF (SymTab.ClassOf(t) = SymTab.ClPtr)
|
|
|
+ 1667 OR (SymTab.ClassOf(t2) = SymTab.ClPtr) THEN
|
|
|
+ 1668 IF (op # SymTab.OpEq) AND (op # SymTab.OpNeq1)
|
|
|
+ 1669 AND (op # SymTab.OpNeq2) THEN
|
|
|
+ 1670 SemError(213); t := SymTab.InvalidType;
|
|
|
+ 1671 QbeGen.CopyOp("0", q)
|
|
|
+ 1672 ELSE
|
|
|
+ 1673 QbeGen.CmpL(op, q, q2, qt);
|
|
|
+ 1674 t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
|
|
|
+ 1675 END
|
|
|
+ 1676 ELSIF (SymTab.ClassOf(t) = SymTab.ClSet)
|
|
|
+ 1677 OR (SymTab.ClassOf(t2) = SymTab.ClSet) THEN
|
|
|
+ 1678 QbeGen.CmpSet(op, q, q2,
|
|
|
+ 1679 SymTab.SetWords(t), SymTab.SetWords(t2), qt);
|
|
|
+ 1680 t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
|
|
|
+ 1681 ELSIF SymTab.IsLongFamily(t)
|
|
|
+ 1682 OR SymTab.IsLongFamily(t2) THEN
|
|
|
+ 1683 IF SymTab.IsIntFamily(t) THEN
|
|
|
+ 1684 QbeGen.WidenLong(q, wl); QbeGen.CopyOp(wl, q)
|
|
|
+ 1685 END;
|
|
|
+ 1686 IF SymTab.IsIntFamily(t2) THEN
|
|
|
+ 1687 QbeGen.WidenLong(q2, wl); QbeGen.CopyOp(wl, q2)
|
|
|
+ 1688 END;
|
|
|
+ 1689 QbeGen.CmpLong(op, q, q2, qt);
|
|
|
+ 1690 t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
|
|
|
+ 1691 ELSE
|
|
|
+ 1692 isR := SymTab.ClassOf(t) = SymTab.ClReal;
|
|
|
+ 1693 t := SymTab.BoolType();
|
|
|
+ 1694 QbeGen.Cmp(op, q, q2, qt, isR);
|
|
|
+ 1695 QbeGen.CopyOp(qt, q)
|
|
|
+ 1696 END
|
|
|
+ 1697 ELSE SemError(213); t := SymTab.InvalidType;
|
|
|
+ 1698 QbeGen.CopyOp("0", q)
|
|
|
+ 1699 END; .) ] .
|
|
|
+ 1700 Rel<VAR op: INTEGER>
|
|
|
+ 1701 = "=" (. op := SymTab.OpEq; .)
|
|
|
+ 1702 | "#" (. op := SymTab.OpNeq1; .)
|
|
|
+ 1703 | "<" (. op := SymTab.OpLt; .)
|
|
|
+ 1704 | "<=" (. op := SymTab.OpLe; .)
|
|
|
+ 1705 | ">" (. op := SymTab.OpGt; .)
|
|
|
+ 1706 | ">=" (. op := SymTab.OpGe; .)
|
|
|
+ 1707 | "IN" (. op := SymTab.OpIn; .) .
|
|
|
+ 1708 SimExpr<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
+ 1709 (. VAR t2, res2, lt, rt:
|
|
|
+ 1710 SymTab.TypeIndex;
|
|
|
+ 1711 op: INTEGER;
|
|
|
+ 1712 q2, qt, wq, qf:
|
|
|
+ 1713 QbeGen.QVal;
|
|
|
+ 1714 neg, isR, isL, folded:
|
|
|
+ 1715 BOOLEAN;
|
|
|
+ 1716 lw, rw, mw: CARDINAL; .)
|
|
|
+ 1717 = (. neg := FALSE; .)
|
|
|
+ 1718 [ "+" | "-" (. neg := TRUE; .) ]
|
|
|
+ 1719 Term<t, q> (. IF neg THEN
|
|
|
+ 1720 IF QbeGen.IsImm(q) THEN
|
|
|
+ 1721 QbeGen.NegFold(q, q)
|
|
|
+ 1722 ELSE QbeGen.NewTemp(qt);
|
|
|
+ 1723 QbeGen.NegQ(q, qt,
|
|
|
+ 1724 SymTab.ClassOf(t)
|
|
|
+ 1725 = SymTab.ClReal);
|
|
|
+ 1726 QbeGen.CopyOp(qt, q)
|
|
|
+ 1727 END
|
|
|
+ 1728 END; .)
|
|
|
+ 1729 { AddOp<op> Term<t2, q2>
|
|
|
+ 1730 (. IF op = SymTab.OpOr THEN
|
|
|
+ 1731 IF SymTab.BoolCheck(t) AND SymTab.BoolCheck(t2) THEN
|
|
|
+ 1732 t := SymTab.BoolType()
|
|
|
+ 1733 ELSE SemError(212); t := SymTab.InvalidType END;
|
|
|
+ 1734 IF t # SymTab.InvalidType THEN
|
|
|
+ 1735 QbeGen.NewTemp(qt);
|
|
|
+ 1736 QbeGen.Op3("or", qt, q, q2, FALSE);
|
|
|
+ 1737 QbeGen.CopyOp(qt, q)
|
|
|
+ 1738 ELSE QbeGen.CopyOp("0", q)
|
|
|
+ 1739 END
|
|
|
+ 1740 ELSIF (t # SymTab.InvalidType) AND (t2 # SymTab.InvalidType)
|
|
|
+ 1741 AND (SymTab.ClassOf(t) = SymTab.ClSet)
|
|
|
+ 1742 AND (SymTab.ClassOf(t2) = SymTab.ClSet) THEN
|
|
|
+ 1743 lw := SymTab.SetWords(t); rw := SymTab.SetWords(t2);
|
|
|
+ 1744 mw := lw;
|
|
|
+ 1745 IF rw > mw THEN mw := rw END;
|
|
|
+ 1746 IF op = SymTab.OpAdd THEN
|
|
|
+ 1747 QbeGen.SetBinOp(0, q, q2, lw, rw, qt)
|
|
|
+ 1748 ELSE
|
|
|
+ 1749 QbeGen.SetBinOp(2, q, q2, lw, rw, qt)
|
|
|
+ 1750 END;
|
|
|
+ 1751 t := SymTab.NewSet(
|
|
|
+ 1752 SymTab.NewSubR(0,
|
|
|
+ 1753 VAL(INTEGER, mw) * 32 - 1));
|
|
|
+ 1754 QbeGen.CopyOp(qt, q)
|
|
|
+ 1755 ELSE
|
|
|
+ 1756 IF SymTab.ArithCheck(t, t2, FALSE, res2) THEN
|
|
|
+ 1757 lt := t; rt := t2; t := res2
|
|
|
+ 1758 ELSE SemError(211); t := SymTab.InvalidType END;
|
|
|
+ 1759 IF t # SymTab.InvalidType THEN
|
|
|
+ 1760 isL := SymTab.IsLongFamily(t);
|
|
|
+ 1761 isR := SymTab.ClassOf(t) = SymTab.ClReal;
|
|
|
+ 1762 folded := FALSE;
|
|
|
+ 1763 IF (NOT isL) AND (NOT isR)
|
|
|
+ 1764 AND QbeGen.IsImm(q) AND QbeGen.IsImm(q2) THEN
|
|
|
+ 1765 IF op = SymTab.OpAdd THEN
|
|
|
+ 1766 folded := QbeGen.Fold2(0, q, q2, qf)
|
|
|
+ 1767 ELSE
|
|
|
+ 1768 folded := QbeGen.Fold2(1, q, q2, qf)
|
|
|
+ 1769 END
|
|
|
+ 1770 END;
|
|
|
+ 1771 IF folded THEN QbeGen.CopyOp(qf, q)
|
|
|
+ 1772 ELSE
|
|
|
+ 1773 IF isL THEN
|
|
|
+ 1774 IF SymTab.IsIntFamily(lt) THEN
|
|
|
+ 1775 QbeGen.WidenLong(q, wq); QbeGen.CopyOp(wq, q)
|
|
|
+ 1776 END;
|
|
|
+ 1777 IF SymTab.IsIntFamily(rt) THEN
|
|
|
+ 1778 QbeGen.WidenLong(q2, wq); QbeGen.CopyOp(wq, q2)
|
|
|
+ 1779 END;
|
|
|
+ 1780 QbeGen.NewTemp(qt);
|
|
|
+ 1781 IF op = SymTab.OpAdd THEN
|
|
|
+ 1782 QbeGen.Op3L("add", qt, q, q2)
|
|
|
+ 1783 ELSE
|
|
|
+ 1784 QbeGen.Op3L("sub", qt, q, q2)
|
|
|
+ 1785 END
|
|
|
+ 1786 ELSE
|
|
|
+ 1787 QbeGen.NewTemp(qt);
|
|
|
+ 1788 IF op = SymTab.OpAdd THEN
|
|
|
+ 1789 QbeGen.Op3("add", qt, q, q2, isR)
|
|
|
+ 1790 ELSE
|
|
|
+ 1791 QbeGen.Op3("sub", qt, q, q2, isR)
|
|
|
+ 1792 END
|
|
|
+ 1793 END;
|
|
|
+ 1794 QbeGen.CopyOp(qt, q)
|
|
|
+ 1795 END
|
|
|
+ 1796 ELSE QbeGen.CopyOp("0", q)
|
|
|
+ 1797 END
|
|
|
+ 1798 END; .) } .
|
|
|
+ 1799 AddOp<VAR op: INTEGER>
|
|
|
+ 1800 = "+" (. op := SymTab.OpAdd; .)
|
|
|
+ 1801 | "-" (. op := SymTab.OpSub; .)
|
|
|
+ 1802 | "OR" (. op := SymTab.OpOr; .) .
|
|
|
+ 1803 Term<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
+ 1804 (. VAR t2, res2, lt, rt:
|
|
|
+ 1805 SymTab.TypeIndex;
|
|
|
+ 1806 op: INTEGER;
|
|
|
+ 1807 q2, qt, wq, qf:
|
|
|
+ 1808 QbeGen.QVal;
|
|
|
+ 1809 isR, isL, folded: BOOLEAN;
|
|
|
+ 1810 lw, rw, mw: CARDINAL; .)
|
|
|
+ 1811 = Fact<t, q> { MulOp<op> Fact<t2, q2>
|
|
|
+ 1812 (. IF op = SymTab.OpAnd THEN
|
|
|
+ 1813 IF SymTab.BoolCheck(t) AND SymTab.BoolCheck(t2) THEN
|
|
|
+ 1814 t := SymTab.BoolType()
|
|
|
+ 1815 ELSE SemError(212); t := SymTab.InvalidType END;
|
|
|
+ 1816 IF t # SymTab.InvalidType THEN
|
|
|
+ 1817 QbeGen.NewTemp(qt);
|
|
|
+ 1818 QbeGen.Op3("and", qt, q, q2, FALSE);
|
|
|
+ 1819 QbeGen.CopyOp(qt, q)
|
|
|
+ 1820 ELSE QbeGen.CopyOp("0", q)
|
|
|
+ 1821 END
|
|
|
+ 1822 ELSIF (t # SymTab.InvalidType) AND (t2 # SymTab.InvalidType)
|
|
|
+ 1823 AND (SymTab.ClassOf(t) = SymTab.ClSet)
|
|
|
+ 1824 AND (SymTab.ClassOf(t2) = SymTab.ClSet) THEN
|
|
|
+ 1825 lw := SymTab.SetWords(t); rw := SymTab.SetWords(t2);
|
|
|
+ 1826 mw := lw;
|
|
|
+ 1827 IF rw > mw THEN mw := rw END;
|
|
|
+ 1828 IF op = SymTab.OpTimes THEN
|
|
|
+ 1829 QbeGen.SetBinOp(1, q, q2, lw, rw, qt)
|
|
|
+ 1830 ELSE
|
|
|
+ 1831 QbeGen.SetBinOp(3, q, q2, lw, rw, qt)
|
|
|
+ 1832 END;
|
|
|
+ 1833 t := SymTab.NewSet(
|
|
|
+ 1834 SymTab.NewSubR(0,
|
|
|
+ 1835 VAL(INTEGER, mw) * 32 - 1));
|
|
|
+ 1836 QbeGen.CopyOp(qt, q)
|
|
|
+ 1837 ELSE
|
|
|
+ 1838 IF SymTab.ArithCheck(t, t2,
|
|
|
+ 1839 (op = SymTab.OpDiv) OR (op = SymTab.OpMod),
|
|
|
+ 1840 res2) THEN
|
|
|
+ 1841 lt := t; rt := t2; t := res2
|
|
|
+ 1842 ELSE SemError(211); t := SymTab.InvalidType END;
|
|
|
+ 1843 IF t # SymTab.InvalidType THEN
|
|
|
+ 1844 isL := SymTab.IsLongFamily(t);
|
|
|
+ 1845 isR := SymTab.ClassOf(t) = SymTab.ClReal;
|
|
|
+ 1846 folded := FALSE;
|
|
|
+ 1847 IF (NOT isL) AND (NOT isR)
|
|
|
+ 1848 AND QbeGen.IsImm(q) AND QbeGen.IsImm(q2) THEN
|
|
|
+ 1849 IF op = SymTab.OpTimes THEN
|
|
|
+ 1850 folded := QbeGen.Fold2(2, q, q2, qf)
|
|
|
+ 1851 ELSIF op = SymTab.OpDiv THEN
|
|
|
+ 1852 folded := QbeGen.Fold2(3, q, q2, qf)
|
|
|
+ 1853 ELSIF op = SymTab.OpMod THEN
|
|
|
+ 1854 folded := QbeGen.Fold2(4, q, q2, qf)
|
|
|
+ 1855 END
|
|
|
+ 1856 END;
|
|
|
+ 1857 IF folded THEN QbeGen.CopyOp(qf, q)
|
|
|
+ 1858 ELSE
|
|
|
+ 1859 IF isL THEN
|
|
|
+ 1860 IF SymTab.IsIntFamily(lt) THEN
|
|
|
+ 1861 QbeGen.WidenLong(q, wq); QbeGen.CopyOp(wq, q)
|
|
|
+ 1862 END;
|
|
|
+ 1863 IF SymTab.IsIntFamily(rt) THEN
|
|
|
+ 1864 QbeGen.WidenLong(q2, wq); QbeGen.CopyOp(wq, q2)
|
|
|
+ 1865 END;
|
|
|
+ 1866 QbeGen.NewTemp(qt);
|
|
|
+ 1867 IF op = SymTab.OpTimes THEN
|
|
|
+ 1868 QbeGen.Op3L("mul", qt, q, q2)
|
|
|
+ 1869 ELSIF (op = SymTab.OpDiv)
|
|
|
+ 1870 OR (op = SymTab.OpSlash) THEN
|
|
|
+ 1871 QbeGen.Op3L("div", qt, q, q2)
|
|
|
+ 1872 ELSE
|
|
|
+ 1873 QbeGen.Op3L("rem", qt, q, q2)
|
|
|
+ 1874 END
|
|
|
+ 1875 ELSE
|
|
|
+ 1876 QbeGen.NewTemp(qt);
|
|
|
+ 1877 IF op = SymTab.OpTimes THEN
|
|
|
+ 1878 QbeGen.Op3("mul", qt, q, q2, isR)
|
|
|
+ 1879 ELSIF (op = SymTab.OpDiv)
|
|
|
+ 1880 OR (op = SymTab.OpSlash) THEN
|
|
|
+ 1881 QbeGen.Op3("div", qt, q, q2, isR)
|
|
|
+ 1882 ELSE
|
|
|
+ 1883 QbeGen.Op3("rem", qt, q, q2, isR)
|
|
|
+ 1884 END
|
|
|
+ 1885 END;
|
|
|
+ 1886 QbeGen.CopyOp(qt, q)
|
|
|
+ 1887 END
|
|
|
+ 1888 ELSE QbeGen.CopyOp("0", q)
|
|
|
+ 1889 END
|
|
|
+ 1890 END; .) } .
|
|
|
+ 1891 MulOp<VAR op: INTEGER>
|
|
|
+ 1892 = "*" (. op := SymTab.OpTimes; .)
|
|
|
+ 1893 | "/" (. op := SymTab.OpSlash; .)
|
|
|
+ 1894 | "DIV" (. op := SymTab.OpDiv; .)
|
|
|
+ 1895 | "MOD" (. op := SymTab.OpMod; .)
|
|
|
+ 1896 | ( "AND" | "&" ) (. op := SymTab.OpAnd; .) .
|
|
|
+ 1897 Fact<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
+ 1898 (. VAR s: ARRAY [0 .. 255] OF CHAR;
|
|
|
+ 1899 et, dt, t2, st, ct2:
|
|
|
+ 1900 SymTab.TypeIndex;
|
|
|
+ 1901 dk: INTEGER;
|
|
|
+ 1902 qd, q2, sq, qa, qm0, qr:
|
|
|
+ 1903 QbeGen.QVal;
|
|
|
+ 1904 qn, vn: SymTab.Name;
|
|
|
+ 1905 vt: SymTab.TypeIndex;
|
|
|
+ 1906 c1, c2: INTEGER;
|
|
|
+ 1907 called, isHigh, sfx, isCh:
|
|
|
+ 1908 BOOLEAN; .)
|
|
|
+ 1909 = integer (. LexString(s);
|
|
|
+ 1910 QbeGen.NormInt(s, q);
|
|
|
+ 1911 t := SymTab.IntType(); .)
|
|
|
+ 1912 | charConst (. LexString(s);
|
|
|
+ 1913 QbeGen.NormLit(s, q, isCh);
|
|
|
+ 1914 t := SymTab.CharType(); .)
|
|
|
+ 1915 | real (. LexString(s);
|
|
|
+ 1916 QbeGen.NormReal(s, q);
|
|
|
+ 1917 t := SymTab.RealType(); .)
|
|
|
+ 1918 | string (. LexString(s);
|
|
|
+ 1919 IF SymTab.StrLen(s) = 3 THEN
|
|
|
+ 1920 t := SymTab.CharType();
|
|
|
+ 1921 QbeGen.IntStr(
|
|
|
+ 1922 QbeGen.CharVal(s), q)
|
|
|
+ 1923 ELSE t := SymTab.NewStr();
|
|
|
+ 1924 QbeGen.DeclStr(s, q);
|
|
|
+ 1925 (* a literal's value IS its
|
|
|
+ 1926 static descriptor address *)
|
|
|
+ 1927 QbeGen.NoteAddr(q, q)
|
|
|
+ 1928 END; .)
|
|
|
+ 1929 | Design<dt, dk, qd, qn, sfx> (. called := FALSE;
|
|
|
+ 1930 t := dt;
|
|
|
+ 1931 IF sfx THEN
|
|
|
+ 1932 IF dt =
|
|
|
+ 1933 SymTab.InvalidType THEN
|
|
|
+ 1934 QbeGen.CopyOp("0", q)
|
|
|
+ 1935 ELSIF (SymTab.ClassOf(dt) =
|
|
|
+ 1936 SymTab.ClRecord)
|
|
|
+ 1937 OR (SymTab.ClassOf(dt) =
|
|
|
+ 1938 SymTab.ClSet)
|
|
|
+ 1939 OR (SymTab.ClassOf(dt) =
|
|
|
+ 1940 SymTab.ClArray)
|
|
|
+ 1941 OR (SymTab.ClassOf(dt) =
|
|
|
+ 1942 SymTab.ClClass) THEN
|
|
|
+ 1943 QbeGen.CopyOp(qd, q)
|
|
|
+ 1944 ELSE QbeGen.ElemLoad(qd, dt,
|
|
|
+ 1945 q)
|
|
|
+ 1946 END
|
|
|
+ 1947 ELSE QbeGen.CopyOp(qd, q)
|
|
|
+ 1948 END;
|
|
|
+ 1949 IF (dk = SymTab.KindVar)
|
|
|
+ 1950 OR (dk = SymTab.KindParam)
|
|
|
+ 1951 OR (dk =
|
|
|
+ 1952 SymTab.KindField) THEN
|
|
|
+ 1953 IF sfx THEN
|
|
|
+ 1954 QbeGen.NoteAddr(q, qd)
|
|
|
+ 1955 ELSE
|
|
|
+ 1956 QbeGen.AddrOf(qn, qa);
|
|
|
+ 1957 QbeGen.NoteAddr(q, qa)
|
|
|
+ 1958 END
|
|
|
+ 1959 ELSIF sfx
|
|
|
+ 1960 AND (dt #
|
|
|
+ 1961 SymTab.InvalidType)
|
|
|
+ 1962 AND ((SymTab.ClassOf(dt) =
|
|
|
+ 1963 SymTab.ClArray)
|
|
|
+ 1964 OR (SymTab.ClassOf(dt) =
|
|
|
+ 1965 SymTab.ClSet)
|
|
|
+ 1966 OR (SymTab.ClassOf(dt) =
|
|
|
+ 1967 SymTab.ClRecord)) THEN
|
|
|
+ 1968 QbeGen.NoteAddr(qd, qd)
|
|
|
+ 1969 END; .)
|
|
|
+ 1970 [ TypedSetLit<dt, q> (. t := dt; .) ]
|
|
|
+ 1971 [ ArgList<qn, dt, qd, TRUE, ct2, q2, called>
|
|
|
+ 1972 (. t := ct2;
|
|
|
+ 1973 QbeGen.CopyOp(q2, q); .) ]
|
|
|
+ 1974 (. IF NOT called
|
|
|
+ 1975 AND (dk = SymTab.KindProc) THEN
|
|
|
+ 1976 (* bare zero-arg function
|
|
|
+ 1977 call (parentheses may be
|
|
|
+ 1978 omitted); a proper or
|
|
|
+ 1979 parameterised proc here
|
|
|
+ 1980 is 230 *)
|
|
|
+ 1981 IF (SymTab.ProcNPar(qn) = 0)
|
|
|
+ 1982 AND (SymTab.ProcRes(qn) #
|
|
|
+ 1983 SymTab.InvalidType) THEN
|
|
|
+ 1984 QbeGen.Mangled(qn,
|
|
|
+ 1985 SymTab.ProcUid(qn), qm0);
|
|
|
+ 1986 QbeGen.CallBegin(qm0,
|
|
|
+ 1987 SymTab.ProcRes(qn),
|
|
|
+ 1988 SymTab.ProcDepthOf(qn),
|
|
|
+ 1989 SymTab.IsExternal(qn));
|
|
|
+ 1990 QbeGen.CallEnd(TRUE, q);
|
|
|
+ 1991 t := SymTab.ProcRes(qn)
|
|
|
+ 1992 ELSE
|
|
|
+ 1993 (* procedure used as a
|
|
|
+ 1994 value (assign to a
|
|
|
+ 1995 procedure variable):
|
|
|
+ 1996 its code address *)
|
|
|
+ 1997 t := SymTab.ProcTypeOf(qn);
|
|
|
+ 1998 QbeGen.Mangled(qn,
|
|
|
+ 1999 SymTab.ProcUid(qn), qm0);
|
|
|
+ 2000 QbeGen.ProcAddr(qm0, q)
|
|
|
+ 2001 END
|
|
|
+ 2002 END; .)
|
|
|
+ 2003 | ( "HIGH" (. isHigh := TRUE; .)
|
|
|
+ 2004 | ( "LEN" | "LENGTH" ) (. isHigh := FALSE; .) )
|
|
|
+ 2005 "(" Design<dt, dk, qd, qn, sfx> ")"
|
|
|
+ 2006 (. IF dt = SymTab.InvalidType THEN
|
|
|
+ 2007 ELSIF SymTab.ClassOf(dt) #
|
|
|
+ 2008 SymTab.ClArray THEN
|
|
|
+ 2009 SemError(217);
|
|
|
+ 2010 t := SymTab.InvalidType;
|
|
|
+ 2011 QbeGen.CopyOp("0", q)
|
|
|
+ 2012 ELSE
|
|
|
+ 2013 IF isHigh THEN
|
|
|
+ 2014 IF SymTab.IsOpenArray(dt) THEN
|
|
|
+ 2015 QbeGen.OpenHi(qd, qr)
|
|
|
+ 2016 ELSE
|
|
|
+ 2017 QbeGen.IntStr(
|
|
|
+ 2018 SymTab.ArrayHi(dt), qr)
|
|
|
+ 2019 END
|
|
|
+ 2020 ELSE
|
|
|
+ 2021 IF SymTab.IsOpenArray(dt) THEN
|
|
|
+ 2022 QbeGen.LoadCount(qd, qr)
|
|
|
+ 2023 ELSE
|
|
|
+ 2024 QbeGen.IntStr(VAL(
|
|
|
+ 2025 INTEGER,
|
|
|
+ 2026 SymTab.ArrayLen(dt)),
|
|
|
+ 2027 qr)
|
|
|
+ 2028 END
|
|
|
+ 2029 END;
|
|
|
+ 2030 t := SymTab.IntType();
|
|
|
+ 2031 QbeGen.CopyOp(qr, q)
|
|
|
+ 2032 END; .)
|
|
|
+ 2033 | ( "SIZE" | "TSIZE" ) "(" Design<dt, dk, qd, qn, sfx> ")"
|
|
|
+ 2034 (. IF dt = SymTab.InvalidType THEN
|
|
|
+ 2035 t := SymTab.InvalidType;
|
|
|
+ 2036 QbeGen.CopyOp("0", q)
|
|
|
+ 2037 ELSE
|
|
|
+ 2038 QbeGen.IntStr(VAL(INTEGER,
|
|
|
+ 2039 SymTab.ObjectSize(dt)), q);
|
|
|
+ 2040 t := SymTab.IntType()
|
|
|
+ 2041 END; .)
|
|
|
+ 2042 | "ADR" "(" Design<dt, dk, qd, qn, sfx> ")"
|
|
|
+ 2043 (. IF dt = SymTab.InvalidType THEN
|
|
|
+ 2044 t := SymTab.InvalidType;
|
|
|
+ 2045 QbeGen.CopyOp("0", q)
|
|
|
+ 2046 ELSE
|
|
|
+ 2047 IF sfx THEN
|
|
|
+ 2048 QbeGen.CopyOp(qd, q)
|
|
|
+ 2049 ELSIF (dk = SymTab.KindVar)
|
|
|
+ 2050 OR (dk = SymTab.KindParam) THEN
|
|
|
+ 2051 QbeGen.AddrOf(qn, q)
|
|
|
+ 2052 ELSE SemError(230);
|
|
|
+ 2053 QbeGen.CopyOp("0", q)
|
|
|
+ 2054 END;
|
|
|
+ 2055 t := SymTab.AddrType()
|
|
|
+ 2056 END; .)
|
|
|
+ 2057 | "CHR" "(" Expr<et, q> ")"
|
|
|
+ 2058 (. IF (et # SymTab.InvalidType)
|
|
|
+ 2059 AND NOT SymTab.IsIntFamily(et) THEN
|
|
|
+ 2060 SemError(211) END;
|
|
|
+ 2061 t := SymTab.CharType(); .)
|
|
|
+ 2062 | ( "ORD" | "ORDL" ) "(" Expr<et, q> ")"
|
|
|
+ 2063 (. IF et # SymTab.InvalidType THEN
|
|
|
+ 2064 IF (SymTab.ClassOf(et) #
|
|
|
+ 2065 SymTab.ClChar)
|
|
|
+ 2066 AND (SymTab.ClassOf(et) #
|
|
|
+ 2067 SymTab.ClBool)
|
|
|
+ 2068 AND (SymTab.ClassOf(et) #
|
|
|
+ 2069 SymTab.ClEnum)
|
|
|
+ 2070 AND NOT SymTab.IsIntFamily(et) THEN
|
|
|
+ 2071 SemError(211) END
|
|
|
+ 2072 END;
|
|
|
+ 2073 t := SymTab.IntType(); .)
|
|
|
+ 2074 | "CAP" "(" Expr<et, q> ")"
|
|
|
+ 2075 (. QbeGen.CapQ(q, qa);
|
|
|
+ 2076 QbeGen.CopyOp(qa, q);
|
|
|
+ 2077 t := SymTab.CharType(); .)
|
|
|
+ 2078 | "ABS" "(" Expr<et, q> ")"
|
|
|
+ 2079 (. IF (et # SymTab.InvalidType)
|
|
|
+ 2080 AND NOT SymTab.IsIntFamily(et)
|
|
|
+ 2081 AND (SymTab.ClassOf(et) #
|
|
|
+ 2082 SymTab.ClReal) THEN
|
|
|
+ 2083 SemError(211)
|
|
|
+ 2084 ELSE QbeGen.AbsQ(q, qa,
|
|
|
+ 2085 SymTab.ClassOf(et) =
|
|
|
+ 2086 SymTab.ClReal);
|
|
|
+ 2087 QbeGen.CopyOp(qa, q)
|
|
|
+ 2088 END;
|
|
|
+ 2089 t := et; .)
|
|
|
+ 2090 | "VAL" "(" GetIdent<vn> "," Expr<et, q> ")"
|
|
|
+ 2091 (. IF NOT SymTab.Lookup(vn) THEN
|
|
|
+ 2092 SemError(201);
|
|
|
+ 2093 t := SymTab.InvalidType
|
|
|
+ 2094 ELSE vt := SymTab.SymType(vn);
|
|
|
+ 2095 IF vt = SymTab.InvalidType THEN
|
|
|
+ 2096 t := SymTab.InvalidType
|
|
|
+ 2097 ELSIF et =
|
|
|
+ 2098 SymTab.InvalidType THEN
|
|
|
+ 2099 t := vt
|
|
|
+ 2100 ELSE
|
|
|
+ 2101 c1 := SymTab.ClassOf(et);
|
|
|
+ 2102 c2 := SymTab.ClassOf(vt);
|
|
|
+ 2103 IF ((c1 = SymTab.ClInt)
|
|
|
+ 2104 OR (c1 =
|
|
|
+ 2105 SymTab.ClChar)
|
|
|
+ 2106 OR (c1 =
|
|
|
+ 2107 SymTab.ClBool)
|
|
|
+ 2108 OR (c1 =
|
|
|
+ 2109 SymTab.ClEnum))
|
|
|
+ 2110 AND ((c2 = SymTab.ClInt)
|
|
|
+ 2111 OR (c2 =
|
|
|
+ 2112 SymTab.ClChar)
|
|
|
+ 2113 OR (c2 =
|
|
|
+ 2114 SymTab.ClBool)
|
|
|
+ 2115 OR (c2 =
|
|
|
+ 2116 SymTab.ClEnum)) THEN
|
|
|
+ 2117 t := vt
|
|
|
+ 2118 ELSIF (c1 = SymTab.ClPtr)
|
|
|
+ 2119 AND (c2 = SymTab.ClPtr) THEN
|
|
|
+ 2120 t := vt
|
|
|
+ 2121 ELSIF (c1 = SymTab.ClReal)
|
|
|
+ 2122 AND (c2 = SymTab.ClReal) THEN
|
|
|
+ 2123 t := vt
|
|
|
+ 2124 ELSE SemError(230);
|
|
|
+ 2125 t := SymTab.InvalidType
|
|
|
+ 2126 END
|
|
|
+ 2127 END
|
|
|
+ 2128 END; .)
|
|
|
+ 2129 | "(" Expr<et, q> ")" (. t := et; .)
|
|
|
+ 2130 | SetLit<st, sq> (. t := st;
|
|
|
+ 2131 QbeGen.CopyOp(sq, q); .)
|
|
|
+ 2132 | ( "NOT" | "~" ) Fact<t2, q2> (. IF SymTab.BoolCheck(t2) THEN
|
|
|
+ 2133 t := SymTab.BoolType()
|
|
|
+ 2134 ELSE SemError(212);
|
|
|
+ 2135 t := SymTab.InvalidType END;
|
|
|
+ 2136 IF t # SymTab.InvalidType THEN
|
|
|
+ 2137 QbeGen.NotQ(q2, q)
|
|
|
+ 2138 ELSE QbeGen.CopyOp("0", q)
|
|
|
+ 2139 END; .) .
|
|
|
+ 2140 (* Set literals are SET OF [0..255] (8 words); elements validated
|
|
|
+ 2141 0..255 statically when foldable (222 otherwise), runtime trap
|
|
|
+ 2142 for computed elements. Ranges always lower via SetRange. *)
|
|
|
+ 2143 SetLit<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
+ 2144 = "{" (. t := SymTab.NewSet(
|
|
|
+ 2145 SymTab.NewSubR(0, 255));
|
|
|
+ 2146 QbeGen.NewSetTemp(8, q);
|
|
|
+ 2147 QbeGen.SetZero(q, 8); .)
|
|
|
+ 2148 [ SetElem<t, q> { "," SetElem<t, q> } ]
|
|
|
+ 2149 "}" .
|
|
|
+ 2150 (* Typed set constructor: TypeName{ elems } — e.g. BITSET{0},
|
|
|
+ 2151 BITSET{}. The declared type (not SET OF [0..255]) sets the
|
|
|
+ 2152 width and element span. *)
|
|
|
+ 2153 TypedSetLit<vt: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
+ 2154 (. VAR nw: CARDINAL; .)
|
|
|
+ 2155 = "{" (. IF SymTab.ClassOf(vt) #
|
|
|
+ 2156 SymTab.ClSet THEN
|
|
|
+ 2157 SemError(230); nw := 8
|
|
|
+ 2158 ELSE nw := SymTab.SetWords(vt);
|
|
|
+ 2159 IF nw = 0 THEN nw := 8 END
|
|
|
+ 2160 END;
|
|
|
+ 2161 QbeGen.NewSetTemp(nw, q);
|
|
|
+ 2162 QbeGen.SetZero(q, nw); .)
|
|
|
+ 2163 [ SetElem<vt, q> { "," SetElem<vt, q> } ]
|
|
|
+ 2164 "}" .
|
|
|
+ 2165 SetElem<st: SymTab.TypeIndex; sq: QbeGen.QVal> (. VAR et, et2: SymTab.TypeIndex;
|
|
|
+ 2166 qe, q2: QbeGen.QVal;
|
|
|
+ 2167 v, v2: INTEGER;
|
|
|
+ 2168 lo: INTEGER;
|
|
|
+ 2169 span: CARDINAL;
|
|
|
+ 2170 cl, cl2: INTEGER;
|
|
|
+ 2171 hasR: BOOLEAN; .)
|
|
|
+ 2172 = (. hasR := FALSE; .)
|
|
|
+ 2173 Expr<et, qe>
|
|
|
+ 2174 [ ".." Expr<et2, q2> (. hasR := TRUE; .) ]
|
|
|
+ 2175 (. lo := SymTab.SetBaseLo(st);
|
|
|
+ 2176 span := SymTab.SetCount(st);
|
|
|
+ 2177 IF (et = SymTab.InvalidType)
|
|
|
+ 2178 OR (hasR AND (et2 =
|
|
|
+ 2179 SymTab.InvalidType)) THEN
|
|
|
+ 2180 ELSE cl :=
|
|
|
+ 2181 SymTab.ClassOf(et);
|
|
|
+ 2182 IF hasR THEN
|
|
|
+ 2183 cl2 :=
|
|
|
+ 2184 SymTab.ClassOf(et2)
|
|
|
+ 2185 ELSE cl2 := SymTab.ClInt
|
|
|
+ 2186 END;
|
|
|
+ 2187 IF ((cl # SymTab.ClInt)
|
|
|
+ 2188 AND (cl # SymTab.ClChar)
|
|
|
+ 2189 AND (cl # SymTab.ClBool))
|
|
|
+ 2190 OR (hasR AND
|
|
|
+ 2191 ((cl2
|
|
|
+ 2192 # SymTab.ClInt)
|
|
|
+ 2193 AND (cl2
|
|
|
+ 2194 # SymTab.ClChar)
|
|
|
+ 2195 AND (cl2
|
|
|
+ 2196 # SymTab.ClBool))) THEN
|
|
|
+ 2197 SemError(222)
|
|
|
+ 2198 ELSIF hasR
|
|
|
+ 2199 AND SymTab.ConstInt(qe, v)
|
|
|
+ 2200 AND SymTab.ConstInt(q2,
|
|
|
+ 2201 v2)
|
|
|
+ 2202 AND ((v < lo)
|
|
|
+ 2203 OR (v2 < lo)
|
|
|
+ 2204 OR (v >= lo +
|
|
|
+ 2205 VAL(INTEGER, span))
|
|
|
+ 2206 OR (v2 >= lo +
|
|
|
+ 2207 VAL(INTEGER, span))
|
|
|
+ 2208 OR (v > v2)) THEN
|
|
|
+ 2209 SemError(222)
|
|
|
+ 2210 ELSIF hasR THEN
|
|
|
+ 2211 QbeGen.SetRange(sq, qe, q2,
|
|
|
+ 2212 lo, span)
|
|
|
+ 2213 ELSIF SymTab.ConstInt(qe,
|
|
|
+ 2214 v)
|
|
|
+ 2215 AND ((v < lo)
|
|
|
+ 2216 OR (v >= lo +
|
|
|
+ 2217 VAL(INTEGER,
|
|
|
+ 2218 span))) THEN
|
|
|
+ 2219 SemError(222)
|
|
|
+ 2220 ELSE QbeGen.SetBit(sq, qe,
|
|
|
+ 2221 lo, span)
|
|
|
+ 2222 END
|
|
|
+ 2223 END; .) .
|
|
|
+ 2224 GetIdent<VAR n: SymTab.Name>
|
|
|
+ 2225 = ident (. LexName(n); .) .
|
|
|
+ 2226
|
|
|
+ 2227 END M2.
|
|
|
|
|
|
0 errors
|
|
|
|