Przeglądaj źródła

fix VAR actual of a dereferenced pointer (p^/a[i]^): ^ yields the pointee address, so sfx:=TRUE and the VAR-actual note is q itself; scanner Reset now correct (111/111)

Eric Streit 2 tygodni temu
rodzic
commit
0a776e3b18
2 zmienionych plików z 599 dodań i 607 usunięć
  1. 7 11
      compiler/src/M2.atg
  2. 592 596
      compiler/src/M2.lst

+ 7 - 11
compiler/src/M2.atg

@@ -1638,17 +1638,13 @@ PRODUCTIONS
                                                  QbeGen.CopyOp(qb, q)
                                                END;
                                                t := bt;
-                                               IF (SymTab.ClassOf(bt) =
-                                                  SymTab.ClInt)
-                                                  OR (SymTab.ClassOf(bt) =
-                                                      SymTab.ClBool)
-                                                  OR (SymTab.ClassOf(bt) =
-                                                      SymTab.ClChar)
-                                                  OR (SymTab.ClassOf(bt) =
-                                                      SymTab.ClReal) THEN
-                                                 sfx := TRUE
-                                               ELSE sfx := FALSE
-                                               END
+                                               (* q holds the pointee
+                                                  address: Fact loads
+                                                  scalars/pointers and uses
+                                                  the address for
+                                                  aggregates; the VAR-actual
+                                                  note is q itself. *)
+                                               sfx := TRUE
                                              END
                                            END; .) } .
   Expr<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>

+ 592 - 596
compiler/src/M2.lst

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