|
|
@@ -1739,7 +1739,7 @@ Listing:
|
|
|
1722 neg, isR, isL, folded:
|
|
|
1723 BOOLEAN;
|
|
|
1724 lw, rw, mw: CARDINAL;
|
|
|
- 1725 lTrue, lNext, lDone:
|
|
|
+ 1725 lTrue, lNext, lDone, qr, qs:
|
|
|
1726 QbeGen.QVal; .)
|
|
|
1727 = (. neg := FALSE; .)
|
|
|
1728 [ "+" | "-" (. neg := TRUE; .) ]
|
|
|
@@ -1763,521 +1763,529 @@ Listing:
|
|
|
1746 t := SymTab.BoolType()
|
|
|
1747 ELSE SemError(212); t := SymTab.InvalidType END;
|
|
|
1748 IF t # SymTab.InvalidType THEN
|
|
|
- 1749 QbeGen.NewLabel(lTrue);
|
|
|
- 1750 QbeGen.NewLabel(lNext);
|
|
|
- 1751 QbeGen.NewLabel(lDone);
|
|
|
- 1752 QbeGen.Jnz(q, lTrue, lNext);
|
|
|
- 1753 QbeGen.EmitLabel(lNext);
|
|
|
- 1754 QbeGen.DelayFlush;
|
|
|
- 1755 QbeGen.CopyOp(q2, q);
|
|
|
+ 1749 QbeGen.Slot4(qs);
|
|
|
+ 1750 QbeGen.NewLabel(lTrue);
|
|
|
+ 1751 QbeGen.NewLabel(lNext);
|
|
|
+ 1752 QbeGen.NewLabel(lDone);
|
|
|
+ 1753 QbeGen.Jnz(q, lTrue, lNext);
|
|
|
+ 1754 QbeGen.EmitLabel(lTrue);
|
|
|
+ 1755 QbeGen.StoreW(qs, "1");
|
|
|
1756 QbeGen.Jmp(lDone);
|
|
|
- 1757 QbeGen.EmitLabel(lTrue);
|
|
|
- 1758 QbeGen.CopyOp("1", q);
|
|
|
- 1759 QbeGen.EmitLabel(lDone)
|
|
|
- 1760 ELSE QbeGen.DelayFlush; QbeGen.CopyOp("0", q)
|
|
|
- 1761 END
|
|
|
- 1762 ELSIF (t # SymTab.InvalidType) AND (t2 # SymTab.InvalidType)
|
|
|
- 1763 AND (SymTab.ClassOf(t) = SymTab.ClSet)
|
|
|
- 1764 AND (SymTab.ClassOf(t2) = SymTab.ClSet) THEN
|
|
|
- 1765 lw := SymTab.SetWords(t); rw := SymTab.SetWords(t2);
|
|
|
- 1766 mw := lw;
|
|
|
- 1767 IF rw > mw THEN mw := rw END;
|
|
|
- 1768 IF op = SymTab.OpAdd THEN
|
|
|
- 1769 QbeGen.SetBinOp(0, q, q2, lw, rw, qt)
|
|
|
- 1770 ELSE
|
|
|
- 1771 QbeGen.SetBinOp(2, q, q2, lw, rw, qt)
|
|
|
- 1772 END;
|
|
|
- 1773 t := SymTab.NewSet(
|
|
|
- 1774 SymTab.NewSubR(0,
|
|
|
- 1775 VAL(INTEGER, mw) * 32 - 1));
|
|
|
- 1776 QbeGen.CopyOp(qt, q)
|
|
|
- 1777 ELSE
|
|
|
- 1778 IF SymTab.ArithCheck(t, t2, FALSE, res2) THEN
|
|
|
- 1779 lt := t; rt := t2; t := res2
|
|
|
- 1780 ELSE SemError(211); t := SymTab.InvalidType END;
|
|
|
- 1781 IF t # SymTab.InvalidType THEN
|
|
|
- 1782 isL := SymTab.IsLongFamily(t);
|
|
|
- 1783 isR := SymTab.ClassOf(t) = SymTab.ClReal;
|
|
|
- 1784 folded := FALSE;
|
|
|
- 1785 IF (NOT isL) AND (NOT isR)
|
|
|
- 1786 AND QbeGen.IsImm(q) AND QbeGen.IsImm(q2) THEN
|
|
|
- 1787 IF op = SymTab.OpAdd THEN
|
|
|
- 1788 folded := QbeGen.Fold2(0, q, q2, qf)
|
|
|
- 1789 ELSE
|
|
|
- 1790 folded := QbeGen.Fold2(1, q, q2, qf)
|
|
|
- 1791 END
|
|
|
- 1792 END;
|
|
|
- 1793 IF folded THEN QbeGen.CopyOp(qf, q)
|
|
|
- 1794 ELSE
|
|
|
- 1795 IF isL THEN
|
|
|
- 1796 IF SymTab.IsIntFamily(lt) THEN
|
|
|
- 1797 QbeGen.WidenLong(q, wq); QbeGen.CopyOp(wq, q)
|
|
|
- 1798 END;
|
|
|
- 1799 IF SymTab.IsIntFamily(rt) THEN
|
|
|
- 1800 QbeGen.WidenLong(q2, wq); QbeGen.CopyOp(wq, q2)
|
|
|
- 1801 END;
|
|
|
- 1802 QbeGen.NewTemp(qt);
|
|
|
- 1803 IF op = SymTab.OpAdd THEN
|
|
|
- 1804 QbeGen.Op3L("add", qt, q, q2)
|
|
|
- 1805 ELSE
|
|
|
- 1806 QbeGen.Op3L("sub", qt, q, q2)
|
|
|
- 1807 END
|
|
|
- 1808 ELSE
|
|
|
- 1809 QbeGen.NewTemp(qt);
|
|
|
- 1810 IF op = SymTab.OpAdd THEN
|
|
|
- 1811 QbeGen.Op3("add", qt, q, q2, isR)
|
|
|
- 1812 ELSE
|
|
|
- 1813 QbeGen.Op3("sub", qt, q, q2, isR)
|
|
|
- 1814 END
|
|
|
- 1815 END;
|
|
|
- 1816 QbeGen.CopyOp(qt, q)
|
|
|
- 1817 END
|
|
|
- 1818 ELSE QbeGen.CopyOp("0", q)
|
|
|
- 1819 END
|
|
|
- 1820 END; .) } .
|
|
|
- 1821 AddOp<VAR op: INTEGER>
|
|
|
- 1822 = "+" (. op := SymTab.OpAdd; .)
|
|
|
- 1823 | "-" (. op := SymTab.OpSub; .)
|
|
|
- 1824 | "OR" (. op := SymTab.OpOr; .) .
|
|
|
- 1825 Term<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
- 1826 (. VAR t2, res2, lt, rt:
|
|
|
- 1827 SymTab.TypeIndex;
|
|
|
- 1828 op: INTEGER;
|
|
|
- 1829 q2, qt, wq, qf:
|
|
|
- 1830 QbeGen.QVal;
|
|
|
- 1831 isR, isL, folded: BOOLEAN;
|
|
|
- 1832 lw, rw, mw: CARDINAL;
|
|
|
- 1833 lNext, lFalse, lDone:
|
|
|
- 1834 QbeGen.QVal; .)
|
|
|
- 1835 = Fact<t, q> { MulOp<op> (. IF op = SymTab.OpAnd THEN
|
|
|
- 1836 QbeGen.DelayBegin END; .)
|
|
|
- 1837 Fact<t2, q2> (. IF op = SymTab.OpAnd THEN
|
|
|
- 1838 QbeGen.DelayEnd END; .)
|
|
|
- 1839 (. IF op = SymTab.OpAnd THEN
|
|
|
- 1840 (* short-circuit: if q is false the RHS is skipped *)
|
|
|
- 1841 IF SymTab.BoolCheck(t) AND SymTab.BoolCheck(t2) THEN
|
|
|
- 1842 t := SymTab.BoolType()
|
|
|
- 1843 ELSE SemError(212); t := SymTab.InvalidType END;
|
|
|
- 1844 IF t # SymTab.InvalidType THEN
|
|
|
- 1845 QbeGen.NewLabel(lNext);
|
|
|
- 1846 QbeGen.NewLabel(lFalse);
|
|
|
- 1847 QbeGen.NewLabel(lDone);
|
|
|
- 1848 QbeGen.Jnz(q, lNext, lFalse);
|
|
|
- 1849 QbeGen.EmitLabel(lNext);
|
|
|
- 1850 QbeGen.DelayFlush;
|
|
|
- 1851 QbeGen.CopyOp(q2, q);
|
|
|
- 1852 QbeGen.Jmp(lDone);
|
|
|
- 1853 QbeGen.EmitLabel(lFalse);
|
|
|
- 1854 QbeGen.CopyOp("0", q);
|
|
|
- 1855 QbeGen.EmitLabel(lDone)
|
|
|
- 1856 ELSE QbeGen.DelayFlush; QbeGen.CopyOp("0", q)
|
|
|
- 1857 END
|
|
|
- 1858 ELSIF (t # SymTab.InvalidType) AND (t2 # SymTab.InvalidType)
|
|
|
- 1859 AND (SymTab.ClassOf(t) = SymTab.ClSet)
|
|
|
- 1860 AND (SymTab.ClassOf(t2) = SymTab.ClSet) THEN
|
|
|
- 1861 lw := SymTab.SetWords(t); rw := SymTab.SetWords(t2);
|
|
|
- 1862 mw := lw;
|
|
|
- 1863 IF rw > mw THEN mw := rw END;
|
|
|
- 1864 IF op = SymTab.OpTimes THEN
|
|
|
- 1865 QbeGen.SetBinOp(1, q, q2, lw, rw, qt)
|
|
|
- 1866 ELSE
|
|
|
- 1867 QbeGen.SetBinOp(3, q, q2, lw, rw, qt)
|
|
|
- 1868 END;
|
|
|
- 1869 t := SymTab.NewSet(
|
|
|
- 1870 SymTab.NewSubR(0,
|
|
|
- 1871 VAL(INTEGER, mw) * 32 - 1));
|
|
|
- 1872 QbeGen.CopyOp(qt, q)
|
|
|
- 1873 ELSE
|
|
|
- 1874 IF SymTab.ArithCheck(t, t2,
|
|
|
- 1875 (op = SymTab.OpDiv) OR (op = SymTab.OpMod),
|
|
|
- 1876 res2) THEN
|
|
|
- 1877 lt := t; rt := t2; t := res2
|
|
|
- 1878 ELSE SemError(211); t := SymTab.InvalidType END;
|
|
|
- 1879 IF t # SymTab.InvalidType THEN
|
|
|
- 1880 isL := SymTab.IsLongFamily(t);
|
|
|
- 1881 isR := SymTab.ClassOf(t) = SymTab.ClReal;
|
|
|
- 1882 folded := FALSE;
|
|
|
- 1883 IF (NOT isL) AND (NOT isR)
|
|
|
- 1884 AND QbeGen.IsImm(q) AND QbeGen.IsImm(q2) THEN
|
|
|
- 1885 IF op = SymTab.OpTimes THEN
|
|
|
- 1886 folded := QbeGen.Fold2(2, q, q2, qf)
|
|
|
- 1887 ELSIF op = SymTab.OpDiv THEN
|
|
|
- 1888 folded := QbeGen.Fold2(3, q, q2, qf)
|
|
|
- 1889 ELSIF op = SymTab.OpMod THEN
|
|
|
- 1890 folded := QbeGen.Fold2(4, q, q2, qf)
|
|
|
- 1891 END
|
|
|
- 1892 END;
|
|
|
- 1893 IF folded THEN QbeGen.CopyOp(qf, q)
|
|
|
- 1894 ELSE
|
|
|
- 1895 IF isL THEN
|
|
|
- 1896 IF SymTab.IsIntFamily(lt) THEN
|
|
|
- 1897 QbeGen.WidenLong(q, wq); QbeGen.CopyOp(wq, q)
|
|
|
- 1898 END;
|
|
|
- 1899 IF SymTab.IsIntFamily(rt) THEN
|
|
|
- 1900 QbeGen.WidenLong(q2, wq); QbeGen.CopyOp(wq, q2)
|
|
|
- 1901 END;
|
|
|
- 1902 QbeGen.NewTemp(qt);
|
|
|
- 1903 IF op = SymTab.OpTimes THEN
|
|
|
- 1904 QbeGen.Op3L("mul", qt, q, q2)
|
|
|
- 1905 ELSIF (op = SymTab.OpDiv)
|
|
|
- 1906 OR (op = SymTab.OpSlash) THEN
|
|
|
- 1907 QbeGen.Op3L("div", qt, q, q2)
|
|
|
- 1908 ELSE
|
|
|
- 1909 QbeGen.Op3L("rem", qt, q, q2)
|
|
|
- 1910 END
|
|
|
- 1911 ELSE
|
|
|
- 1912 QbeGen.NewTemp(qt);
|
|
|
- 1913 IF op = SymTab.OpTimes THEN
|
|
|
- 1914 QbeGen.Op3("mul", qt, q, q2, isR)
|
|
|
- 1915 ELSIF (op = SymTab.OpDiv)
|
|
|
- 1916 OR (op = SymTab.OpSlash) THEN
|
|
|
- 1917 QbeGen.Op3("div", qt, q, q2, isR)
|
|
|
- 1918 ELSE
|
|
|
- 1919 QbeGen.Op3("rem", qt, q, q2, isR)
|
|
|
- 1920 END
|
|
|
- 1921 END;
|
|
|
- 1922 QbeGen.CopyOp(qt, q)
|
|
|
- 1923 END
|
|
|
- 1924 ELSE QbeGen.CopyOp("0", q)
|
|
|
- 1925 END
|
|
|
- 1926 END; .) } .
|
|
|
- 1927 MulOp<VAR op: INTEGER>
|
|
|
- 1928 = "*" (. op := SymTab.OpTimes; .)
|
|
|
- 1929 | "/" (. op := SymTab.OpSlash; .)
|
|
|
- 1930 | "DIV" (. op := SymTab.OpDiv; .)
|
|
|
- 1931 | "MOD" (. op := SymTab.OpMod; .)
|
|
|
- 1932 | ( "AND" | "&" ) (. op := SymTab.OpAnd; .) .
|
|
|
- 1933 Fact<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
- 1934 (. VAR s: ARRAY [0 .. 255] OF CHAR;
|
|
|
- 1935 et, dt, t2, st, ct2:
|
|
|
- 1936 SymTab.TypeIndex;
|
|
|
- 1937 dk: INTEGER;
|
|
|
- 1938 qd, q2, sq, qa, qm0, qr:
|
|
|
- 1939 QbeGen.QVal;
|
|
|
- 1940 qn, vn: SymTab.Name;
|
|
|
- 1941 vt: SymTab.TypeIndex;
|
|
|
- 1942 c1, c2: INTEGER;
|
|
|
- 1943 called, isHigh, sfx, isCh:
|
|
|
- 1944 BOOLEAN; .)
|
|
|
- 1945 = integer (. LexString(s);
|
|
|
- 1946 QbeGen.NormInt(s, q);
|
|
|
- 1947 t := SymTab.IntType(); .)
|
|
|
- 1948 | charConst (. LexString(s);
|
|
|
- 1949 QbeGen.NormLit(s, q, isCh);
|
|
|
- 1950 t := SymTab.CharType(); .)
|
|
|
- 1951 | real (. LexString(s);
|
|
|
- 1952 QbeGen.NormReal(s, q);
|
|
|
- 1953 t := SymTab.RealType(); .)
|
|
|
- 1954 | string (. LexString(s);
|
|
|
- 1955 IF SymTab.StrLen(s) = 3 THEN
|
|
|
- 1956 t := SymTab.CharType();
|
|
|
- 1957 QbeGen.IntStr(
|
|
|
- 1958 QbeGen.CharVal(s), q)
|
|
|
- 1959 ELSE t := SymTab.NewStr();
|
|
|
- 1960 QbeGen.DeclStr(s, q);
|
|
|
- 1961 (* a literal's value IS its
|
|
|
- 1962 static descriptor address *)
|
|
|
- 1963 QbeGen.NoteAddr(q, q)
|
|
|
- 1964 END; .)
|
|
|
- 1965 | Design<dt, dk, qd, qn, sfx> (. called := FALSE;
|
|
|
- 1966 t := dt;
|
|
|
- 1967 IF sfx THEN
|
|
|
- 1968 IF dt =
|
|
|
- 1969 SymTab.InvalidType THEN
|
|
|
- 1970 QbeGen.CopyOp("0", q)
|
|
|
- 1971 ELSIF (SymTab.ClassOf(dt) =
|
|
|
- 1972 SymTab.ClRecord)
|
|
|
- 1973 OR (SymTab.ClassOf(dt) =
|
|
|
- 1974 SymTab.ClSet)
|
|
|
- 1975 OR (SymTab.ClassOf(dt) =
|
|
|
- 1976 SymTab.ClArray)
|
|
|
- 1977 OR (SymTab.ClassOf(dt) =
|
|
|
- 1978 SymTab.ClClass) THEN
|
|
|
- 1979 QbeGen.CopyOp(qd, q)
|
|
|
- 1980 ELSE QbeGen.ElemLoad(qd, dt,
|
|
|
- 1981 q)
|
|
|
- 1982 END
|
|
|
- 1983 ELSE QbeGen.CopyOp(qd, q)
|
|
|
- 1984 END;
|
|
|
- 1985 IF (dk = SymTab.KindVar)
|
|
|
- 1986 OR (dk = SymTab.KindParam)
|
|
|
- 1987 OR (dk =
|
|
|
- 1988 SymTab.KindField) THEN
|
|
|
- 1989 IF sfx THEN
|
|
|
- 1990 QbeGen.NoteAddr(q, qd)
|
|
|
- 1991 ELSE
|
|
|
- 1992 QbeGen.AddrOf(qn, qa);
|
|
|
- 1993 QbeGen.NoteAddr(q, qa)
|
|
|
- 1994 END
|
|
|
- 1995 ELSIF sfx
|
|
|
- 1996 AND (dt #
|
|
|
- 1997 SymTab.InvalidType)
|
|
|
- 1998 AND ((SymTab.ClassOf(dt) =
|
|
|
- 1999 SymTab.ClArray)
|
|
|
- 2000 OR (SymTab.ClassOf(dt) =
|
|
|
- 2001 SymTab.ClSet)
|
|
|
- 2002 OR (SymTab.ClassOf(dt) =
|
|
|
- 2003 SymTab.ClRecord)) THEN
|
|
|
- 2004 QbeGen.NoteAddr(qd, qd)
|
|
|
- 2005 END; .)
|
|
|
- 2006 [ TypedSetLit<dt, q> (. t := dt; .) ]
|
|
|
- 2007 [ ArgList<qn, dt, qd, TRUE, ct2, q2, called>
|
|
|
- 2008 (. t := ct2;
|
|
|
- 2009 QbeGen.CopyOp(q2, q); .) ]
|
|
|
- 2010 (. IF NOT called
|
|
|
- 2011 AND (dk = SymTab.KindProc) THEN
|
|
|
- 2012 (* bare zero-arg function
|
|
|
- 2013 call (parentheses may be
|
|
|
- 2014 omitted); a proper or
|
|
|
- 2015 parameterised proc here
|
|
|
- 2016 is 230 *)
|
|
|
- 2017 IF (SymTab.ProcNPar(qn) = 0)
|
|
|
- 2018 AND (SymTab.ProcRes(qn) #
|
|
|
- 2019 SymTab.InvalidType) THEN
|
|
|
- 2020 QbeGen.Mangled(qn,
|
|
|
- 2021 SymTab.ProcUid(qn), qm0);
|
|
|
- 2022 QbeGen.CallBegin(qm0,
|
|
|
- 2023 SymTab.ProcRes(qn),
|
|
|
- 2024 SymTab.ProcDepthOf(qn),
|
|
|
- 2025 SymTab.IsExternal(qn));
|
|
|
- 2026 QbeGen.CallEnd(TRUE, q);
|
|
|
- 2027 t := SymTab.ProcRes(qn)
|
|
|
- 2028 ELSE
|
|
|
- 2029 (* procedure used as a
|
|
|
- 2030 value (assign to a
|
|
|
- 2031 procedure variable):
|
|
|
- 2032 its code address *)
|
|
|
- 2033 t := SymTab.ProcTypeOf(qn);
|
|
|
- 2034 QbeGen.Mangled(qn,
|
|
|
- 2035 SymTab.ProcUid(qn), qm0);
|
|
|
- 2036 QbeGen.ProcAddr(qm0, q)
|
|
|
- 2037 END
|
|
|
- 2038 END; .)
|
|
|
- 2039 | ( "HIGH" (. isHigh := TRUE; .)
|
|
|
- 2040 | ( "LEN" | "LENGTH" ) (. isHigh := FALSE; .) )
|
|
|
- 2041 "(" Design<dt, dk, qd, qn, sfx> ")"
|
|
|
- 2042 (. IF dt = SymTab.InvalidType THEN
|
|
|
- 2043 ELSIF SymTab.ClassOf(dt) #
|
|
|
- 2044 SymTab.ClArray THEN
|
|
|
- 2045 SemError(217);
|
|
|
- 2046 t := SymTab.InvalidType;
|
|
|
- 2047 QbeGen.CopyOp("0", q)
|
|
|
- 2048 ELSE
|
|
|
- 2049 IF isHigh THEN
|
|
|
- 2050 IF SymTab.IsOpenArray(dt) THEN
|
|
|
- 2051 QbeGen.OpenHi(qd, qr)
|
|
|
- 2052 ELSE
|
|
|
- 2053 QbeGen.IntStr(
|
|
|
- 2054 SymTab.ArrayHi(dt), qr)
|
|
|
- 2055 END
|
|
|
- 2056 ELSE
|
|
|
- 2057 IF SymTab.IsOpenArray(dt) THEN
|
|
|
- 2058 QbeGen.LoadCount(qd, qr)
|
|
|
- 2059 ELSE
|
|
|
- 2060 QbeGen.IntStr(VAL(
|
|
|
- 2061 INTEGER,
|
|
|
- 2062 SymTab.ArrayLen(dt)),
|
|
|
- 2063 qr)
|
|
|
- 2064 END
|
|
|
- 2065 END;
|
|
|
- 2066 t := SymTab.IntType();
|
|
|
- 2067 QbeGen.CopyOp(qr, q)
|
|
|
- 2068 END; .)
|
|
|
- 2069 | ( "SIZE" | "TSIZE" ) "(" Design<dt, dk, qd, qn, sfx> ")"
|
|
|
- 2070 (. IF dt = SymTab.InvalidType THEN
|
|
|
- 2071 t := SymTab.InvalidType;
|
|
|
- 2072 QbeGen.CopyOp("0", q)
|
|
|
- 2073 ELSE
|
|
|
- 2074 QbeGen.IntStr(VAL(INTEGER,
|
|
|
- 2075 SymTab.ObjectSize(dt)), q);
|
|
|
- 2076 t := SymTab.IntType()
|
|
|
- 2077 END; .)
|
|
|
- 2078 | "ADR" "(" Design<dt, dk, qd, qn, sfx> ")"
|
|
|
- 2079 (. IF dt = SymTab.InvalidType THEN
|
|
|
- 2080 t := SymTab.InvalidType;
|
|
|
- 2081 QbeGen.CopyOp("0", q)
|
|
|
- 2082 ELSE
|
|
|
- 2083 IF sfx THEN
|
|
|
- 2084 QbeGen.CopyOp(qd, q)
|
|
|
- 2085 ELSIF (dk = SymTab.KindVar)
|
|
|
- 2086 OR (dk = SymTab.KindParam) THEN
|
|
|
- 2087 QbeGen.AddrOf(qn, q)
|
|
|
- 2088 ELSE SemError(230);
|
|
|
- 2089 QbeGen.CopyOp("0", q)
|
|
|
- 2090 END;
|
|
|
- 2091 t := SymTab.AddrType()
|
|
|
- 2092 END; .)
|
|
|
- 2093 | "CHR" "(" Expr<et, q> ")"
|
|
|
- 2094 (. IF (et # SymTab.InvalidType)
|
|
|
- 2095 AND NOT SymTab.IsIntFamily(et) THEN
|
|
|
- 2096 SemError(211) END;
|
|
|
- 2097 t := SymTab.CharType(); .)
|
|
|
- 2098 | ( "ORD" | "ORDL" ) "(" Expr<et, q> ")"
|
|
|
- 2099 (. IF et # SymTab.InvalidType THEN
|
|
|
- 2100 IF (SymTab.ClassOf(et) #
|
|
|
- 2101 SymTab.ClChar)
|
|
|
- 2102 AND (SymTab.ClassOf(et) #
|
|
|
- 2103 SymTab.ClBool)
|
|
|
- 2104 AND (SymTab.ClassOf(et) #
|
|
|
- 2105 SymTab.ClEnum)
|
|
|
- 2106 AND NOT SymTab.IsIntFamily(et) THEN
|
|
|
- 2107 SemError(211) END
|
|
|
- 2108 END;
|
|
|
- 2109 t := SymTab.IntType(); .)
|
|
|
- 2110 | "CAP" "(" Expr<et, q> ")"
|
|
|
- 2111 (. QbeGen.CapQ(q, qa);
|
|
|
- 2112 QbeGen.CopyOp(qa, q);
|
|
|
- 2113 t := SymTab.CharType(); .)
|
|
|
- 2114 | "ABS" "(" Expr<et, q> ")"
|
|
|
- 2115 (. IF (et # SymTab.InvalidType)
|
|
|
- 2116 AND NOT SymTab.IsIntFamily(et)
|
|
|
- 2117 AND (SymTab.ClassOf(et) #
|
|
|
- 2118 SymTab.ClReal) THEN
|
|
|
- 2119 SemError(211)
|
|
|
- 2120 ELSE QbeGen.AbsQ(q, qa,
|
|
|
- 2121 SymTab.ClassOf(et) =
|
|
|
- 2122 SymTab.ClReal);
|
|
|
- 2123 QbeGen.CopyOp(qa, q)
|
|
|
- 2124 END;
|
|
|
- 2125 t := et; .)
|
|
|
- 2126 | "VAL" "(" GetIdent<vn> "," Expr<et, q> ")"
|
|
|
- 2127 (. IF NOT SymTab.Lookup(vn) THEN
|
|
|
- 2128 SemError(201);
|
|
|
- 2129 t := SymTab.InvalidType
|
|
|
- 2130 ELSE vt := SymTab.SymType(vn);
|
|
|
- 2131 IF vt = SymTab.InvalidType THEN
|
|
|
- 2132 t := SymTab.InvalidType
|
|
|
- 2133 ELSIF et =
|
|
|
- 2134 SymTab.InvalidType THEN
|
|
|
- 2135 t := vt
|
|
|
- 2136 ELSE
|
|
|
- 2137 c1 := SymTab.ClassOf(et);
|
|
|
- 2138 c2 := SymTab.ClassOf(vt);
|
|
|
- 2139 IF ((c1 = SymTab.ClInt)
|
|
|
- 2140 OR (c1 =
|
|
|
- 2141 SymTab.ClChar)
|
|
|
- 2142 OR (c1 =
|
|
|
- 2143 SymTab.ClBool)
|
|
|
- 2144 OR (c1 =
|
|
|
- 2145 SymTab.ClEnum))
|
|
|
- 2146 AND ((c2 = SymTab.ClInt)
|
|
|
- 2147 OR (c2 =
|
|
|
- 2148 SymTab.ClChar)
|
|
|
- 2149 OR (c2 =
|
|
|
- 2150 SymTab.ClBool)
|
|
|
- 2151 OR (c2 =
|
|
|
- 2152 SymTab.ClEnum)) THEN
|
|
|
- 2153 t := vt
|
|
|
- 2154 ELSIF (c1 = SymTab.ClPtr)
|
|
|
- 2155 AND (c2 = SymTab.ClPtr) THEN
|
|
|
- 2156 t := vt
|
|
|
- 2157 ELSIF (c1 = SymTab.ClReal)
|
|
|
- 2158 AND (c2 = SymTab.ClReal) THEN
|
|
|
- 2159 t := vt
|
|
|
- 2160 ELSE SemError(230);
|
|
|
- 2161 t := SymTab.InvalidType
|
|
|
- 2162 END
|
|
|
- 2163 END
|
|
|
- 2164 END; .)
|
|
|
- 2165 | "(" Expr<et, q> ")" (. t := et; .)
|
|
|
- 2166 | SetLit<st, sq> (. t := st;
|
|
|
- 2167 QbeGen.CopyOp(sq, q); .)
|
|
|
- 2168 | ( "NOT" | "~" ) Fact<t2, q2> (. IF SymTab.BoolCheck(t2) THEN
|
|
|
- 2169 t := SymTab.BoolType()
|
|
|
- 2170 ELSE SemError(212);
|
|
|
- 2171 t := SymTab.InvalidType END;
|
|
|
- 2172 IF t # SymTab.InvalidType THEN
|
|
|
- 2173 QbeGen.NotQ(q2, q)
|
|
|
- 2174 ELSE QbeGen.CopyOp("0", q)
|
|
|
- 2175 END; .) .
|
|
|
- 2176 (* Set literals are SET OF [0..255] (8 words); elements validated
|
|
|
- 2177 0..255 statically when foldable (222 otherwise), runtime trap
|
|
|
- 2178 for computed elements. Ranges always lower via SetRange. *)
|
|
|
- 2179 SetLit<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
- 2180 = "{" (. t := SymTab.NewSet(
|
|
|
- 2181 SymTab.NewSubR(0, 255));
|
|
|
- 2182 QbeGen.NewSetTemp(8, q);
|
|
|
- 2183 QbeGen.SetZero(q, 8); .)
|
|
|
- 2184 [ SetElem<t, q> { "," SetElem<t, q> } ]
|
|
|
- 2185 "}" .
|
|
|
- 2186 (* Typed set constructor: TypeName{ elems } — e.g. BITSET{0},
|
|
|
- 2187 BITSET{}. The declared type (not SET OF [0..255]) sets the
|
|
|
- 2188 width and element span. *)
|
|
|
- 2189 TypedSetLit<vt: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
- 2190 (. VAR nw: CARDINAL; .)
|
|
|
- 2191 = "{" (. IF SymTab.ClassOf(vt) #
|
|
|
- 2192 SymTab.ClSet THEN
|
|
|
- 2193 SemError(230); nw := 8
|
|
|
- 2194 ELSE nw := SymTab.SetWords(vt);
|
|
|
- 2195 IF nw = 0 THEN nw := 8 END
|
|
|
- 2196 END;
|
|
|
- 2197 QbeGen.NewSetTemp(nw, q);
|
|
|
- 2198 QbeGen.SetZero(q, nw); .)
|
|
|
- 2199 [ SetElem<vt, q> { "," SetElem<vt, q> } ]
|
|
|
- 2200 "}" .
|
|
|
- 2201 SetElem<st: SymTab.TypeIndex; sq: QbeGen.QVal> (. VAR et, et2: SymTab.TypeIndex;
|
|
|
- 2202 qe, q2: QbeGen.QVal;
|
|
|
- 2203 v, v2: INTEGER;
|
|
|
- 2204 lo: INTEGER;
|
|
|
- 2205 span: CARDINAL;
|
|
|
- 2206 cl, cl2: INTEGER;
|
|
|
- 2207 hasR: BOOLEAN; .)
|
|
|
- 2208 = (. hasR := FALSE; .)
|
|
|
- 2209 Expr<et, qe>
|
|
|
- 2210 [ ".." Expr<et2, q2> (. hasR := TRUE; .) ]
|
|
|
- 2211 (. lo := SymTab.SetBaseLo(st);
|
|
|
- 2212 span := SymTab.SetCount(st);
|
|
|
- 2213 IF (et = SymTab.InvalidType)
|
|
|
- 2214 OR (hasR AND (et2 =
|
|
|
- 2215 SymTab.InvalidType)) THEN
|
|
|
- 2216 ELSE cl :=
|
|
|
- 2217 SymTab.ClassOf(et);
|
|
|
- 2218 IF hasR THEN
|
|
|
- 2219 cl2 :=
|
|
|
- 2220 SymTab.ClassOf(et2)
|
|
|
- 2221 ELSE cl2 := SymTab.ClInt
|
|
|
- 2222 END;
|
|
|
- 2223 IF ((cl # SymTab.ClInt)
|
|
|
- 2224 AND (cl # SymTab.ClChar)
|
|
|
- 2225 AND (cl # SymTab.ClBool))
|
|
|
- 2226 OR (hasR AND
|
|
|
- 2227 ((cl2
|
|
|
- 2228 # SymTab.ClInt)
|
|
|
- 2229 AND (cl2
|
|
|
- 2230 # SymTab.ClChar)
|
|
|
- 2231 AND (cl2
|
|
|
- 2232 # SymTab.ClBool))) THEN
|
|
|
- 2233 SemError(222)
|
|
|
- 2234 ELSIF hasR
|
|
|
- 2235 AND SymTab.ConstInt(qe, v)
|
|
|
- 2236 AND SymTab.ConstInt(q2,
|
|
|
- 2237 v2)
|
|
|
- 2238 AND ((v < lo)
|
|
|
- 2239 OR (v2 < lo)
|
|
|
- 2240 OR (v >= lo +
|
|
|
- 2241 VAL(INTEGER, span))
|
|
|
- 2242 OR (v2 >= lo +
|
|
|
- 2243 VAL(INTEGER, span))
|
|
|
- 2244 OR (v > v2)) THEN
|
|
|
- 2245 SemError(222)
|
|
|
- 2246 ELSIF hasR THEN
|
|
|
- 2247 QbeGen.SetRange(sq, qe, q2,
|
|
|
- 2248 lo, span)
|
|
|
- 2249 ELSIF SymTab.ConstInt(qe,
|
|
|
- 2250 v)
|
|
|
- 2251 AND ((v < lo)
|
|
|
- 2252 OR (v >= lo +
|
|
|
- 2253 VAL(INTEGER,
|
|
|
- 2254 span))) THEN
|
|
|
- 2255 SemError(222)
|
|
|
- 2256 ELSE QbeGen.SetBit(sq, qe,
|
|
|
- 2257 lo, span)
|
|
|
- 2258 END
|
|
|
- 2259 END; .) .
|
|
|
- 2260 GetIdent<VAR n: SymTab.Name>
|
|
|
- 2261 = ident (. LexName(n); .) .
|
|
|
- 2262
|
|
|
- 2263 END M2.
|
|
|
+ 1757 QbeGen.EmitLabel(lNext);
|
|
|
+ 1758 QbeGen.DelayFlush;
|
|
|
+ 1759 QbeGen.StoreW(qs, q2);
|
|
|
+ 1760 QbeGen.Jmp(lDone);
|
|
|
+ 1761 QbeGen.EmitLabel(lDone);
|
|
|
+ 1762 QbeGen.LoadW(qs, qr);
|
|
|
+ 1763 QbeGen.CopyOp(qr, q)
|
|
|
+ 1764 ELSE QbeGen.DelayFlush; QbeGen.CopyOp("0", q)
|
|
|
+ 1765 END
|
|
|
+ 1766 ELSIF (t # SymTab.InvalidType) AND (t2 # SymTab.InvalidType)
|
|
|
+ 1767 AND (SymTab.ClassOf(t) = SymTab.ClSet)
|
|
|
+ 1768 AND (SymTab.ClassOf(t2) = SymTab.ClSet) THEN
|
|
|
+ 1769 lw := SymTab.SetWords(t); rw := SymTab.SetWords(t2);
|
|
|
+ 1770 mw := lw;
|
|
|
+ 1771 IF rw > mw THEN mw := rw END;
|
|
|
+ 1772 IF op = SymTab.OpAdd THEN
|
|
|
+ 1773 QbeGen.SetBinOp(0, q, q2, lw, rw, qt)
|
|
|
+ 1774 ELSE
|
|
|
+ 1775 QbeGen.SetBinOp(2, q, q2, lw, rw, qt)
|
|
|
+ 1776 END;
|
|
|
+ 1777 t := SymTab.NewSet(
|
|
|
+ 1778 SymTab.NewSubR(0,
|
|
|
+ 1779 VAL(INTEGER, mw) * 32 - 1));
|
|
|
+ 1780 QbeGen.CopyOp(qt, q)
|
|
|
+ 1781 ELSE
|
|
|
+ 1782 IF SymTab.ArithCheck(t, t2, FALSE, res2) THEN
|
|
|
+ 1783 lt := t; rt := t2; t := res2
|
|
|
+ 1784 ELSE SemError(211); t := SymTab.InvalidType END;
|
|
|
+ 1785 IF t # SymTab.InvalidType THEN
|
|
|
+ 1786 isL := SymTab.IsLongFamily(t);
|
|
|
+ 1787 isR := SymTab.ClassOf(t) = SymTab.ClReal;
|
|
|
+ 1788 folded := FALSE;
|
|
|
+ 1789 IF (NOT isL) AND (NOT isR)
|
|
|
+ 1790 AND QbeGen.IsImm(q) AND QbeGen.IsImm(q2) THEN
|
|
|
+ 1791 IF op = SymTab.OpAdd THEN
|
|
|
+ 1792 folded := QbeGen.Fold2(0, q, q2, qf)
|
|
|
+ 1793 ELSE
|
|
|
+ 1794 folded := QbeGen.Fold2(1, q, q2, qf)
|
|
|
+ 1795 END
|
|
|
+ 1796 END;
|
|
|
+ 1797 IF folded THEN QbeGen.CopyOp(qf, q)
|
|
|
+ 1798 ELSE
|
|
|
+ 1799 IF isL THEN
|
|
|
+ 1800 IF SymTab.IsIntFamily(lt) THEN
|
|
|
+ 1801 QbeGen.WidenLong(q, wq); QbeGen.CopyOp(wq, q)
|
|
|
+ 1802 END;
|
|
|
+ 1803 IF SymTab.IsIntFamily(rt) THEN
|
|
|
+ 1804 QbeGen.WidenLong(q2, wq); QbeGen.CopyOp(wq, q2)
|
|
|
+ 1805 END;
|
|
|
+ 1806 QbeGen.NewTemp(qt);
|
|
|
+ 1807 IF op = SymTab.OpAdd THEN
|
|
|
+ 1808 QbeGen.Op3L("add", qt, q, q2)
|
|
|
+ 1809 ELSE
|
|
|
+ 1810 QbeGen.Op3L("sub", qt, q, q2)
|
|
|
+ 1811 END
|
|
|
+ 1812 ELSE
|
|
|
+ 1813 QbeGen.NewTemp(qt);
|
|
|
+ 1814 IF op = SymTab.OpAdd THEN
|
|
|
+ 1815 QbeGen.Op3("add", qt, q, q2, isR)
|
|
|
+ 1816 ELSE
|
|
|
+ 1817 QbeGen.Op3("sub", qt, q, q2, isR)
|
|
|
+ 1818 END
|
|
|
+ 1819 END;
|
|
|
+ 1820 QbeGen.CopyOp(qt, q)
|
|
|
+ 1821 END
|
|
|
+ 1822 ELSE QbeGen.CopyOp("0", q)
|
|
|
+ 1823 END
|
|
|
+ 1824 END; .) } .
|
|
|
+ 1825 AddOp<VAR op: INTEGER>
|
|
|
+ 1826 = "+" (. op := SymTab.OpAdd; .)
|
|
|
+ 1827 | "-" (. op := SymTab.OpSub; .)
|
|
|
+ 1828 | "OR" (. op := SymTab.OpOr; .) .
|
|
|
+ 1829 Term<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
+ 1830 (. VAR t2, res2, lt, rt:
|
|
|
+ 1831 SymTab.TypeIndex;
|
|
|
+ 1832 op: INTEGER;
|
|
|
+ 1833 q2, qt, wq, qf:
|
|
|
+ 1834 QbeGen.QVal;
|
|
|
+ 1835 isR, isL, folded: BOOLEAN;
|
|
|
+ 1836 lw, rw, mw: CARDINAL;
|
|
|
+ 1837 lNext, lFalse, lDone, qr, qs:
|
|
|
+ 1838 QbeGen.QVal; .)
|
|
|
+ 1839 = Fact<t, q> { MulOp<op> (. IF op = SymTab.OpAnd THEN
|
|
|
+ 1840 QbeGen.DelayBegin END; .)
|
|
|
+ 1841 Fact<t2, q2> (. IF op = SymTab.OpAnd THEN
|
|
|
+ 1842 QbeGen.DelayEnd END; .)
|
|
|
+ 1843 (. IF op = SymTab.OpAnd THEN
|
|
|
+ 1844 (* short-circuit: if q is false the RHS is skipped *)
|
|
|
+ 1845 IF SymTab.BoolCheck(t) AND SymTab.BoolCheck(t2) THEN
|
|
|
+ 1846 t := SymTab.BoolType()
|
|
|
+ 1847 ELSE SemError(212); t := SymTab.InvalidType END;
|
|
|
+ 1848 IF t # SymTab.InvalidType THEN
|
|
|
+ 1849 QbeGen.Slot4(qs);
|
|
|
+ 1850 QbeGen.NewLabel(lNext);
|
|
|
+ 1851 QbeGen.NewLabel(lFalse);
|
|
|
+ 1852 QbeGen.NewLabel(lDone);
|
|
|
+ 1853 QbeGen.Jnz(q, lNext, lFalse);
|
|
|
+ 1854 QbeGen.EmitLabel(lNext);
|
|
|
+ 1855 QbeGen.DelayFlush;
|
|
|
+ 1856 QbeGen.StoreW(qs, q2);
|
|
|
+ 1857 QbeGen.Jmp(lDone);
|
|
|
+ 1858 QbeGen.EmitLabel(lFalse);
|
|
|
+ 1859 QbeGen.StoreW(qs, "0");
|
|
|
+ 1860 QbeGen.Jmp(lDone);
|
|
|
+ 1861 QbeGen.EmitLabel(lDone);
|
|
|
+ 1862 QbeGen.LoadW(qs, qr);
|
|
|
+ 1863 QbeGen.CopyOp(qr, q)
|
|
|
+ 1864 ELSE QbeGen.DelayFlush; QbeGen.CopyOp("0", q)
|
|
|
+ 1865 END
|
|
|
+ 1866 ELSIF (t # SymTab.InvalidType) AND (t2 # SymTab.InvalidType)
|
|
|
+ 1867 AND (SymTab.ClassOf(t) = SymTab.ClSet)
|
|
|
+ 1868 AND (SymTab.ClassOf(t2) = SymTab.ClSet) THEN
|
|
|
+ 1869 lw := SymTab.SetWords(t); rw := SymTab.SetWords(t2);
|
|
|
+ 1870 mw := lw;
|
|
|
+ 1871 IF rw > mw THEN mw := rw END;
|
|
|
+ 1872 IF op = SymTab.OpTimes THEN
|
|
|
+ 1873 QbeGen.SetBinOp(1, q, q2, lw, rw, qt)
|
|
|
+ 1874 ELSE
|
|
|
+ 1875 QbeGen.SetBinOp(3, q, q2, lw, rw, qt)
|
|
|
+ 1876 END;
|
|
|
+ 1877 t := SymTab.NewSet(
|
|
|
+ 1878 SymTab.NewSubR(0,
|
|
|
+ 1879 VAL(INTEGER, mw) * 32 - 1));
|
|
|
+ 1880 QbeGen.CopyOp(qt, q)
|
|
|
+ 1881 ELSE
|
|
|
+ 1882 IF SymTab.ArithCheck(t, t2,
|
|
|
+ 1883 (op = SymTab.OpDiv) OR (op = SymTab.OpMod),
|
|
|
+ 1884 res2) THEN
|
|
|
+ 1885 lt := t; rt := t2; t := res2
|
|
|
+ 1886 ELSE SemError(211); t := SymTab.InvalidType END;
|
|
|
+ 1887 IF t # SymTab.InvalidType THEN
|
|
|
+ 1888 isL := SymTab.IsLongFamily(t);
|
|
|
+ 1889 isR := SymTab.ClassOf(t) = SymTab.ClReal;
|
|
|
+ 1890 folded := FALSE;
|
|
|
+ 1891 IF (NOT isL) AND (NOT isR)
|
|
|
+ 1892 AND QbeGen.IsImm(q) AND QbeGen.IsImm(q2) THEN
|
|
|
+ 1893 IF op = SymTab.OpTimes THEN
|
|
|
+ 1894 folded := QbeGen.Fold2(2, q, q2, qf)
|
|
|
+ 1895 ELSIF op = SymTab.OpDiv THEN
|
|
|
+ 1896 folded := QbeGen.Fold2(3, q, q2, qf)
|
|
|
+ 1897 ELSIF op = SymTab.OpMod THEN
|
|
|
+ 1898 folded := QbeGen.Fold2(4, q, q2, qf)
|
|
|
+ 1899 END
|
|
|
+ 1900 END;
|
|
|
+ 1901 IF folded THEN QbeGen.CopyOp(qf, q)
|
|
|
+ 1902 ELSE
|
|
|
+ 1903 IF isL THEN
|
|
|
+ 1904 IF SymTab.IsIntFamily(lt) THEN
|
|
|
+ 1905 QbeGen.WidenLong(q, wq); QbeGen.CopyOp(wq, q)
|
|
|
+ 1906 END;
|
|
|
+ 1907 IF SymTab.IsIntFamily(rt) THEN
|
|
|
+ 1908 QbeGen.WidenLong(q2, wq); QbeGen.CopyOp(wq, q2)
|
|
|
+ 1909 END;
|
|
|
+ 1910 QbeGen.NewTemp(qt);
|
|
|
+ 1911 IF op = SymTab.OpTimes THEN
|
|
|
+ 1912 QbeGen.Op3L("mul", qt, q, q2)
|
|
|
+ 1913 ELSIF (op = SymTab.OpDiv)
|
|
|
+ 1914 OR (op = SymTab.OpSlash) THEN
|
|
|
+ 1915 QbeGen.Op3L("div", qt, q, q2)
|
|
|
+ 1916 ELSE
|
|
|
+ 1917 QbeGen.Op3L("rem", qt, q, q2)
|
|
|
+ 1918 END
|
|
|
+ 1919 ELSE
|
|
|
+ 1920 QbeGen.NewTemp(qt);
|
|
|
+ 1921 IF op = SymTab.OpTimes THEN
|
|
|
+ 1922 QbeGen.Op3("mul", qt, q, q2, isR)
|
|
|
+ 1923 ELSIF (op = SymTab.OpDiv)
|
|
|
+ 1924 OR (op = SymTab.OpSlash) THEN
|
|
|
+ 1925 QbeGen.Op3("div", qt, q, q2, isR)
|
|
|
+ 1926 ELSE
|
|
|
+ 1927 QbeGen.Op3("rem", qt, q, q2, isR)
|
|
|
+ 1928 END
|
|
|
+ 1929 END;
|
|
|
+ 1930 QbeGen.CopyOp(qt, q)
|
|
|
+ 1931 END
|
|
|
+ 1932 ELSE QbeGen.CopyOp("0", q)
|
|
|
+ 1933 END
|
|
|
+ 1934 END; .) } .
|
|
|
+ 1935 MulOp<VAR op: INTEGER>
|
|
|
+ 1936 = "*" (. op := SymTab.OpTimes; .)
|
|
|
+ 1937 | "/" (. op := SymTab.OpSlash; .)
|
|
|
+ 1938 | "DIV" (. op := SymTab.OpDiv; .)
|
|
|
+ 1939 | "MOD" (. op := SymTab.OpMod; .)
|
|
|
+ 1940 | ( "AND" | "&" ) (. op := SymTab.OpAnd; .) .
|
|
|
+ 1941 Fact<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
+ 1942 (. VAR s: ARRAY [0 .. 255] OF CHAR;
|
|
|
+ 1943 et, dt, t2, st, ct2:
|
|
|
+ 1944 SymTab.TypeIndex;
|
|
|
+ 1945 dk: INTEGER;
|
|
|
+ 1946 qd, q2, sq, qa, qm0, qr:
|
|
|
+ 1947 QbeGen.QVal;
|
|
|
+ 1948 qn, vn: SymTab.Name;
|
|
|
+ 1949 vt: SymTab.TypeIndex;
|
|
|
+ 1950 c1, c2: INTEGER;
|
|
|
+ 1951 called, isHigh, sfx, isCh:
|
|
|
+ 1952 BOOLEAN; .)
|
|
|
+ 1953 = integer (. LexString(s);
|
|
|
+ 1954 QbeGen.NormInt(s, q);
|
|
|
+ 1955 t := SymTab.IntType(); .)
|
|
|
+ 1956 | charConst (. LexString(s);
|
|
|
+ 1957 QbeGen.NormLit(s, q, isCh);
|
|
|
+ 1958 t := SymTab.CharType(); .)
|
|
|
+ 1959 | real (. LexString(s);
|
|
|
+ 1960 QbeGen.NormReal(s, q);
|
|
|
+ 1961 t := SymTab.RealType(); .)
|
|
|
+ 1962 | string (. LexString(s);
|
|
|
+ 1963 IF SymTab.StrLen(s) = 3 THEN
|
|
|
+ 1964 t := SymTab.CharType();
|
|
|
+ 1965 QbeGen.IntStr(
|
|
|
+ 1966 QbeGen.CharVal(s), q)
|
|
|
+ 1967 ELSE t := SymTab.NewStr();
|
|
|
+ 1968 QbeGen.DeclStr(s, q);
|
|
|
+ 1969 (* a literal's value IS its
|
|
|
+ 1970 static descriptor address *)
|
|
|
+ 1971 QbeGen.NoteAddr(q, q)
|
|
|
+ 1972 END; .)
|
|
|
+ 1973 | Design<dt, dk, qd, qn, sfx> (. called := FALSE;
|
|
|
+ 1974 t := dt;
|
|
|
+ 1975 IF sfx THEN
|
|
|
+ 1976 IF dt =
|
|
|
+ 1977 SymTab.InvalidType THEN
|
|
|
+ 1978 QbeGen.CopyOp("0", q)
|
|
|
+ 1979 ELSIF (SymTab.ClassOf(dt) =
|
|
|
+ 1980 SymTab.ClRecord)
|
|
|
+ 1981 OR (SymTab.ClassOf(dt) =
|
|
|
+ 1982 SymTab.ClSet)
|
|
|
+ 1983 OR (SymTab.ClassOf(dt) =
|
|
|
+ 1984 SymTab.ClArray)
|
|
|
+ 1985 OR (SymTab.ClassOf(dt) =
|
|
|
+ 1986 SymTab.ClClass) THEN
|
|
|
+ 1987 QbeGen.CopyOp(qd, q)
|
|
|
+ 1988 ELSE QbeGen.ElemLoad(qd, dt,
|
|
|
+ 1989 q)
|
|
|
+ 1990 END
|
|
|
+ 1991 ELSE QbeGen.CopyOp(qd, q)
|
|
|
+ 1992 END;
|
|
|
+ 1993 IF (dk = SymTab.KindVar)
|
|
|
+ 1994 OR (dk = SymTab.KindParam)
|
|
|
+ 1995 OR (dk =
|
|
|
+ 1996 SymTab.KindField) THEN
|
|
|
+ 1997 IF sfx THEN
|
|
|
+ 1998 QbeGen.NoteAddr(q, qd)
|
|
|
+ 1999 ELSE
|
|
|
+ 2000 QbeGen.AddrOf(qn, qa);
|
|
|
+ 2001 QbeGen.NoteAddr(q, qa)
|
|
|
+ 2002 END
|
|
|
+ 2003 ELSIF sfx
|
|
|
+ 2004 AND (dt #
|
|
|
+ 2005 SymTab.InvalidType)
|
|
|
+ 2006 AND ((SymTab.ClassOf(dt) =
|
|
|
+ 2007 SymTab.ClArray)
|
|
|
+ 2008 OR (SymTab.ClassOf(dt) =
|
|
|
+ 2009 SymTab.ClSet)
|
|
|
+ 2010 OR (SymTab.ClassOf(dt) =
|
|
|
+ 2011 SymTab.ClRecord)) THEN
|
|
|
+ 2012 QbeGen.NoteAddr(qd, qd)
|
|
|
+ 2013 END; .)
|
|
|
+ 2014 [ TypedSetLit<dt, q> (. t := dt; .) ]
|
|
|
+ 2015 [ ArgList<qn, dt, qd, TRUE, ct2, q2, called>
|
|
|
+ 2016 (. t := ct2;
|
|
|
+ 2017 QbeGen.CopyOp(q2, q); .) ]
|
|
|
+ 2018 (. IF NOT called
|
|
|
+ 2019 AND (dk = SymTab.KindProc) THEN
|
|
|
+ 2020 (* bare zero-arg function
|
|
|
+ 2021 call (parentheses may be
|
|
|
+ 2022 omitted); a proper or
|
|
|
+ 2023 parameterised proc here
|
|
|
+ 2024 is 230 *)
|
|
|
+ 2025 IF (SymTab.ProcNPar(qn) = 0)
|
|
|
+ 2026 AND (SymTab.ProcRes(qn) #
|
|
|
+ 2027 SymTab.InvalidType) THEN
|
|
|
+ 2028 QbeGen.Mangled(qn,
|
|
|
+ 2029 SymTab.ProcUid(qn), qm0);
|
|
|
+ 2030 QbeGen.CallBegin(qm0,
|
|
|
+ 2031 SymTab.ProcRes(qn),
|
|
|
+ 2032 SymTab.ProcDepthOf(qn),
|
|
|
+ 2033 SymTab.IsExternal(qn));
|
|
|
+ 2034 QbeGen.CallEnd(TRUE, q);
|
|
|
+ 2035 t := SymTab.ProcRes(qn)
|
|
|
+ 2036 ELSE
|
|
|
+ 2037 (* procedure used as a
|
|
|
+ 2038 value (assign to a
|
|
|
+ 2039 procedure variable):
|
|
|
+ 2040 its code address *)
|
|
|
+ 2041 t := SymTab.ProcTypeOf(qn);
|
|
|
+ 2042 QbeGen.Mangled(qn,
|
|
|
+ 2043 SymTab.ProcUid(qn), qm0);
|
|
|
+ 2044 QbeGen.ProcAddr(qm0, q)
|
|
|
+ 2045 END
|
|
|
+ 2046 END; .)
|
|
|
+ 2047 | ( "HIGH" (. isHigh := TRUE; .)
|
|
|
+ 2048 | ( "LEN" | "LENGTH" ) (. isHigh := FALSE; .) )
|
|
|
+ 2049 "(" Design<dt, dk, qd, qn, sfx> ")"
|
|
|
+ 2050 (. IF dt = SymTab.InvalidType THEN
|
|
|
+ 2051 ELSIF SymTab.ClassOf(dt) #
|
|
|
+ 2052 SymTab.ClArray THEN
|
|
|
+ 2053 SemError(217);
|
|
|
+ 2054 t := SymTab.InvalidType;
|
|
|
+ 2055 QbeGen.CopyOp("0", q)
|
|
|
+ 2056 ELSE
|
|
|
+ 2057 IF isHigh THEN
|
|
|
+ 2058 IF SymTab.IsOpenArray(dt) THEN
|
|
|
+ 2059 QbeGen.OpenHi(qd, qr)
|
|
|
+ 2060 ELSE
|
|
|
+ 2061 QbeGen.IntStr(
|
|
|
+ 2062 SymTab.ArrayHi(dt), qr)
|
|
|
+ 2063 END
|
|
|
+ 2064 ELSE
|
|
|
+ 2065 IF SymTab.IsOpenArray(dt) THEN
|
|
|
+ 2066 QbeGen.LoadCount(qd, qr)
|
|
|
+ 2067 ELSE
|
|
|
+ 2068 QbeGen.IntStr(VAL(
|
|
|
+ 2069 INTEGER,
|
|
|
+ 2070 SymTab.ArrayLen(dt)),
|
|
|
+ 2071 qr)
|
|
|
+ 2072 END
|
|
|
+ 2073 END;
|
|
|
+ 2074 t := SymTab.IntType();
|
|
|
+ 2075 QbeGen.CopyOp(qr, q)
|
|
|
+ 2076 END; .)
|
|
|
+ 2077 | ( "SIZE" | "TSIZE" ) "(" Design<dt, dk, qd, qn, sfx> ")"
|
|
|
+ 2078 (. IF dt = SymTab.InvalidType THEN
|
|
|
+ 2079 t := SymTab.InvalidType;
|
|
|
+ 2080 QbeGen.CopyOp("0", q)
|
|
|
+ 2081 ELSE
|
|
|
+ 2082 QbeGen.IntStr(VAL(INTEGER,
|
|
|
+ 2083 SymTab.ObjectSize(dt)), q);
|
|
|
+ 2084 t := SymTab.IntType()
|
|
|
+ 2085 END; .)
|
|
|
+ 2086 | "ADR" "(" Design<dt, dk, qd, qn, sfx> ")"
|
|
|
+ 2087 (. IF dt = SymTab.InvalidType THEN
|
|
|
+ 2088 t := SymTab.InvalidType;
|
|
|
+ 2089 QbeGen.CopyOp("0", q)
|
|
|
+ 2090 ELSE
|
|
|
+ 2091 IF sfx THEN
|
|
|
+ 2092 QbeGen.CopyOp(qd, q)
|
|
|
+ 2093 ELSIF (dk = SymTab.KindVar)
|
|
|
+ 2094 OR (dk = SymTab.KindParam) THEN
|
|
|
+ 2095 QbeGen.AddrOf(qn, q)
|
|
|
+ 2096 ELSE SemError(230);
|
|
|
+ 2097 QbeGen.CopyOp("0", q)
|
|
|
+ 2098 END;
|
|
|
+ 2099 t := SymTab.AddrType()
|
|
|
+ 2100 END; .)
|
|
|
+ 2101 | "CHR" "(" Expr<et, q> ")"
|
|
|
+ 2102 (. IF (et # SymTab.InvalidType)
|
|
|
+ 2103 AND NOT SymTab.IsIntFamily(et) THEN
|
|
|
+ 2104 SemError(211) END;
|
|
|
+ 2105 t := SymTab.CharType(); .)
|
|
|
+ 2106 | ( "ORD" | "ORDL" ) "(" Expr<et, q> ")"
|
|
|
+ 2107 (. IF et # SymTab.InvalidType THEN
|
|
|
+ 2108 IF (SymTab.ClassOf(et) #
|
|
|
+ 2109 SymTab.ClChar)
|
|
|
+ 2110 AND (SymTab.ClassOf(et) #
|
|
|
+ 2111 SymTab.ClBool)
|
|
|
+ 2112 AND (SymTab.ClassOf(et) #
|
|
|
+ 2113 SymTab.ClEnum)
|
|
|
+ 2114 AND NOT SymTab.IsIntFamily(et) THEN
|
|
|
+ 2115 SemError(211) END
|
|
|
+ 2116 END;
|
|
|
+ 2117 t := SymTab.IntType(); .)
|
|
|
+ 2118 | "CAP" "(" Expr<et, q> ")"
|
|
|
+ 2119 (. QbeGen.CapQ(q, qa);
|
|
|
+ 2120 QbeGen.CopyOp(qa, q);
|
|
|
+ 2121 t := SymTab.CharType(); .)
|
|
|
+ 2122 | "ABS" "(" Expr<et, q> ")"
|
|
|
+ 2123 (. IF (et # SymTab.InvalidType)
|
|
|
+ 2124 AND NOT SymTab.IsIntFamily(et)
|
|
|
+ 2125 AND (SymTab.ClassOf(et) #
|
|
|
+ 2126 SymTab.ClReal) THEN
|
|
|
+ 2127 SemError(211)
|
|
|
+ 2128 ELSE QbeGen.AbsQ(q, qa,
|
|
|
+ 2129 SymTab.ClassOf(et) =
|
|
|
+ 2130 SymTab.ClReal);
|
|
|
+ 2131 QbeGen.CopyOp(qa, q)
|
|
|
+ 2132 END;
|
|
|
+ 2133 t := et; .)
|
|
|
+ 2134 | "VAL" "(" GetIdent<vn> "," Expr<et, q> ")"
|
|
|
+ 2135 (. IF NOT SymTab.Lookup(vn) THEN
|
|
|
+ 2136 SemError(201);
|
|
|
+ 2137 t := SymTab.InvalidType
|
|
|
+ 2138 ELSE vt := SymTab.SymType(vn);
|
|
|
+ 2139 IF vt = SymTab.InvalidType THEN
|
|
|
+ 2140 t := SymTab.InvalidType
|
|
|
+ 2141 ELSIF et =
|
|
|
+ 2142 SymTab.InvalidType THEN
|
|
|
+ 2143 t := vt
|
|
|
+ 2144 ELSE
|
|
|
+ 2145 c1 := SymTab.ClassOf(et);
|
|
|
+ 2146 c2 := SymTab.ClassOf(vt);
|
|
|
+ 2147 IF ((c1 = SymTab.ClInt)
|
|
|
+ 2148 OR (c1 =
|
|
|
+ 2149 SymTab.ClChar)
|
|
|
+ 2150 OR (c1 =
|
|
|
+ 2151 SymTab.ClBool)
|
|
|
+ 2152 OR (c1 =
|
|
|
+ 2153 SymTab.ClEnum))
|
|
|
+ 2154 AND ((c2 = SymTab.ClInt)
|
|
|
+ 2155 OR (c2 =
|
|
|
+ 2156 SymTab.ClChar)
|
|
|
+ 2157 OR (c2 =
|
|
|
+ 2158 SymTab.ClBool)
|
|
|
+ 2159 OR (c2 =
|
|
|
+ 2160 SymTab.ClEnum)) THEN
|
|
|
+ 2161 t := vt
|
|
|
+ 2162 ELSIF (c1 = SymTab.ClPtr)
|
|
|
+ 2163 AND (c2 = SymTab.ClPtr) THEN
|
|
|
+ 2164 t := vt
|
|
|
+ 2165 ELSIF (c1 = SymTab.ClReal)
|
|
|
+ 2166 AND (c2 = SymTab.ClReal) THEN
|
|
|
+ 2167 t := vt
|
|
|
+ 2168 ELSE SemError(230);
|
|
|
+ 2169 t := SymTab.InvalidType
|
|
|
+ 2170 END
|
|
|
+ 2171 END
|
|
|
+ 2172 END; .)
|
|
|
+ 2173 | "(" Expr<et, q> ")" (. t := et; .)
|
|
|
+ 2174 | SetLit<st, sq> (. t := st;
|
|
|
+ 2175 QbeGen.CopyOp(sq, q); .)
|
|
|
+ 2176 | ( "NOT" | "~" ) Fact<t2, q2> (. IF SymTab.BoolCheck(t2) THEN
|
|
|
+ 2177 t := SymTab.BoolType()
|
|
|
+ 2178 ELSE SemError(212);
|
|
|
+ 2179 t := SymTab.InvalidType END;
|
|
|
+ 2180 IF t # SymTab.InvalidType THEN
|
|
|
+ 2181 QbeGen.NotQ(q2, q)
|
|
|
+ 2182 ELSE QbeGen.CopyOp("0", q)
|
|
|
+ 2183 END; .) .
|
|
|
+ 2184 (* Set literals are SET OF [0..255] (8 words); elements validated
|
|
|
+ 2185 0..255 statically when foldable (222 otherwise), runtime trap
|
|
|
+ 2186 for computed elements. Ranges always lower via SetRange. *)
|
|
|
+ 2187 SetLit<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
+ 2188 = "{" (. t := SymTab.NewSet(
|
|
|
+ 2189 SymTab.NewSubR(0, 255));
|
|
|
+ 2190 QbeGen.NewSetTemp(8, q);
|
|
|
+ 2191 QbeGen.SetZero(q, 8); .)
|
|
|
+ 2192 [ SetElem<t, q> { "," SetElem<t, q> } ]
|
|
|
+ 2193 "}" .
|
|
|
+ 2194 (* Typed set constructor: TypeName{ elems } — e.g. BITSET{0},
|
|
|
+ 2195 BITSET{}. The declared type (not SET OF [0..255]) sets the
|
|
|
+ 2196 width and element span. *)
|
|
|
+ 2197 TypedSetLit<vt: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
+ 2198 (. VAR nw: CARDINAL; .)
|
|
|
+ 2199 = "{" (. IF SymTab.ClassOf(vt) #
|
|
|
+ 2200 SymTab.ClSet THEN
|
|
|
+ 2201 SemError(230); nw := 8
|
|
|
+ 2202 ELSE nw := SymTab.SetWords(vt);
|
|
|
+ 2203 IF nw = 0 THEN nw := 8 END
|
|
|
+ 2204 END;
|
|
|
+ 2205 QbeGen.NewSetTemp(nw, q);
|
|
|
+ 2206 QbeGen.SetZero(q, nw); .)
|
|
|
+ 2207 [ SetElem<vt, q> { "," SetElem<vt, q> } ]
|
|
|
+ 2208 "}" .
|
|
|
+ 2209 SetElem<st: SymTab.TypeIndex; sq: QbeGen.QVal> (. VAR et, et2: SymTab.TypeIndex;
|
|
|
+ 2210 qe, q2: QbeGen.QVal;
|
|
|
+ 2211 v, v2: INTEGER;
|
|
|
+ 2212 lo: INTEGER;
|
|
|
+ 2213 span: CARDINAL;
|
|
|
+ 2214 cl, cl2: INTEGER;
|
|
|
+ 2215 hasR: BOOLEAN; .)
|
|
|
+ 2216 = (. hasR := FALSE; .)
|
|
|
+ 2217 Expr<et, qe>
|
|
|
+ 2218 [ ".." Expr<et2, q2> (. hasR := TRUE; .) ]
|
|
|
+ 2219 (. lo := SymTab.SetBaseLo(st);
|
|
|
+ 2220 span := SymTab.SetCount(st);
|
|
|
+ 2221 IF (et = SymTab.InvalidType)
|
|
|
+ 2222 OR (hasR AND (et2 =
|
|
|
+ 2223 SymTab.InvalidType)) THEN
|
|
|
+ 2224 ELSE cl :=
|
|
|
+ 2225 SymTab.ClassOf(et);
|
|
|
+ 2226 IF hasR THEN
|
|
|
+ 2227 cl2 :=
|
|
|
+ 2228 SymTab.ClassOf(et2)
|
|
|
+ 2229 ELSE cl2 := SymTab.ClInt
|
|
|
+ 2230 END;
|
|
|
+ 2231 IF ((cl # SymTab.ClInt)
|
|
|
+ 2232 AND (cl # SymTab.ClChar)
|
|
|
+ 2233 AND (cl # SymTab.ClBool))
|
|
|
+ 2234 OR (hasR AND
|
|
|
+ 2235 ((cl2
|
|
|
+ 2236 # SymTab.ClInt)
|
|
|
+ 2237 AND (cl2
|
|
|
+ 2238 # SymTab.ClChar)
|
|
|
+ 2239 AND (cl2
|
|
|
+ 2240 # SymTab.ClBool))) THEN
|
|
|
+ 2241 SemError(222)
|
|
|
+ 2242 ELSIF hasR
|
|
|
+ 2243 AND SymTab.ConstInt(qe, v)
|
|
|
+ 2244 AND SymTab.ConstInt(q2,
|
|
|
+ 2245 v2)
|
|
|
+ 2246 AND ((v < lo)
|
|
|
+ 2247 OR (v2 < lo)
|
|
|
+ 2248 OR (v >= lo +
|
|
|
+ 2249 VAL(INTEGER, span))
|
|
|
+ 2250 OR (v2 >= lo +
|
|
|
+ 2251 VAL(INTEGER, span))
|
|
|
+ 2252 OR (v > v2)) THEN
|
|
|
+ 2253 SemError(222)
|
|
|
+ 2254 ELSIF hasR THEN
|
|
|
+ 2255 QbeGen.SetRange(sq, qe, q2,
|
|
|
+ 2256 lo, span)
|
|
|
+ 2257 ELSIF SymTab.ConstInt(qe,
|
|
|
+ 2258 v)
|
|
|
+ 2259 AND ((v < lo)
|
|
|
+ 2260 OR (v >= lo +
|
|
|
+ 2261 VAL(INTEGER,
|
|
|
+ 2262 span))) THEN
|
|
|
+ 2263 SemError(222)
|
|
|
+ 2264 ELSE QbeGen.SetBit(sq, qe,
|
|
|
+ 2265 lo, span)
|
|
|
+ 2266 END
|
|
|
+ 2267 END; .) .
|
|
|
+ 2268 GetIdent<VAR n: SymTab.Name>
|
|
|
+ 2269 = ident (. LexName(n); .) .
|
|
|
+ 2270
|
|
|
+ 2271 END M2.
|
|
|
|
|
|
0 errors
|
|
|
|