|
|
@@ -2076,1796 +2076,1800 @@ Listing:
|
|
|
2058 QbeGen.EmitLabel(lEnd); .) .
|
|
|
2059 CaseStat (. VAR tsel: SymTab.TypeIndex;
|
|
|
2060 qsel, lEnd: QbeGen.QVal;
|
|
|
- 2061 arm, astNode: AST.Node; .)
|
|
|
- 2062 = "CASE" Expr<tsel, qsel> (. astNode := AST.MakeNode(AST.NkCase);
|
|
|
- 2063 AST.SetChild(astNode, 0, astCur);
|
|
|
- 2064 QbeGen.NewLabel(lEnd); .)
|
|
|
- 2065 "OF" CaseAlt<tsel, qsel, lEnd, astNode>
|
|
|
- 2066 { "|" CaseAlt<tsel, qsel, lEnd, astNode> }
|
|
|
- 2067 [ "ELSE" (. astStmt := AST.NoNode; .)
|
|
|
- 2068 [ StatSeq ] (. arm := AST.MakeNode(AST.NkCaseArm);
|
|
|
- 2069 AST.SetOp(arm, 1);
|
|
|
- 2070 AST.SetChild(arm, 0, astStmt);
|
|
|
- 2071 AST.SetChild(astNode,
|
|
|
- 2072 AST.NChild(astNode), arm); .) ]
|
|
|
- 2073 "END" (. astStmt := astNode;
|
|
|
- 2074 QbeGen.EmitLabel(lEnd); .) .
|
|
|
- 2075 (* Compare-chain lowering: each alternative ends its match-tests
|
|
|
- 2076 with "jmp lAfter", so the no-match fallthrough skips the body:
|
|
|
- 2077 "cmp; jnz(lBody,lF); lF: ... ; jmp lAfter; lBody: S; jmp lEnd;
|
|
|
- 2078 lAfter:". Falls into the next alternative, ELSE, or END. *)
|
|
|
- 2079 CaseAlt<tsel: SymTab.TypeIndex; qsel: QbeGen.QVal;
|
|
|
- 2080 lEnd: QbeGen.QVal; cnode: AST.Node>
|
|
|
- 2081 (. VAR lBody, lAfter: QbeGen.QVal;
|
|
|
- 2082 arm: AST.Node; .)
|
|
|
- 2083 = (. arm := AST.MakeNode(AST.NkCaseArm);
|
|
|
- 2084 QbeGen.NewLabel(lBody);
|
|
|
- 2085 QbeGen.NewLabel(lAfter); .)
|
|
|
- 2086 CaseLabel<tsel, qsel, lBody, arm>
|
|
|
- 2087 { "," CaseLabel<tsel, qsel, lBody, arm> }
|
|
|
- 2088 ":" (. astStmt := AST.NoNode;
|
|
|
- 2089 QbeGen.Jmp(lAfter);
|
|
|
- 2090 QbeGen.EmitLabel(lBody); .)
|
|
|
- 2091 [ StatSeq ] (. AST.SetChild(arm, AST.NChild(arm),
|
|
|
- 2092 astStmt);
|
|
|
- 2093 AST.SetChild(cnode,
|
|
|
- 2094 AST.NChild(cnode), arm);
|
|
|
- 2095 QbeGen.Jmp(lEnd);
|
|
|
- 2096 QbeGen.EmitLabel(lAfter); .) .
|
|
|
- 2097 CaseLabel<tsel: SymTab.TypeIndex; qsel: QbeGen.QVal;
|
|
|
- 2098 lBody: QbeGen.QVal; arm: AST.Node>
|
|
|
- 2099 (. VAR t2, t3: SymTab.TypeIndex;
|
|
|
- 2100 q2, q3, qc, qd, qe:
|
|
|
- 2101 QbeGen.QVal;
|
|
|
- 2102 astLab: AST.Node;
|
|
|
- 2103 lNext: QbeGen.QVal; .)
|
|
|
- 2104 = Expr<t2, q2> (. astLab := astCur;
|
|
|
- 2105 IF (t2 #
|
|
|
- 2106 SymTab.InvalidType)
|
|
|
- 2107 AND (tsel #
|
|
|
- 2108 SymTab.InvalidType)
|
|
|
- 2109 AND ((SymTab.ClassOf(t2) =
|
|
|
- 2110 SymTab.ClSet)
|
|
|
- 2111 OR (SymTab.ClassOf(tsel) =
|
|
|
- 2112 SymTab.ClSet)) THEN
|
|
|
- 2113 SemError(230)
|
|
|
- 2114 ELSIF (t2 #
|
|
|
- 2115 SymTab.InvalidType)
|
|
|
- 2116 AND (tsel #
|
|
|
- 2117 SymTab.InvalidType)
|
|
|
- 2118 AND NOT SymTab.EqCheck(t2,
|
|
|
- 2119 tsel) THEN
|
|
|
- 2120 SemError(213) END;
|
|
|
- 2121 IF NOT QbeGen.IsImm(q2) THEN
|
|
|
- 2122 SemError(230);
|
|
|
- 2123 QbeGen.CopyOp("0", q2)
|
|
|
- 2124 END;
|
|
|
- 2125 QbeGen.NewLabel(lNext);
|
|
|
- 2126 QbeGen.Cmp(SymTab.OpEq,
|
|
|
- 2127 qsel, q2, qc, FALSE);
|
|
|
- 2128 QbeGen.Jnz(qc, lBody, lNext);
|
|
|
- 2129 QbeGen.EmitLabel(lNext); .)
|
|
|
- 2130 [ ".." Expr<t3, q3> (. astLab := AST.MakeBin(
|
|
|
- 2131 AST.NkSubrange, 0, astLab, astCur);
|
|
|
- 2132 IF (t3 #
|
|
|
- 2133 SymTab.InvalidType)
|
|
|
- 2134 AND (tsel #
|
|
|
- 2135 SymTab.InvalidType)
|
|
|
- 2136 AND NOT SymTab.EqCheck(t3,
|
|
|
- 2137 tsel) THEN
|
|
|
- 2138 SemError(213) END;
|
|
|
- 2139 IF NOT QbeGen.IsImm(q3) THEN
|
|
|
- 2140 SemError(230);
|
|
|
- 2141 QbeGen.CopyOp("0", q3)
|
|
|
- 2142 END;
|
|
|
- 2143 QbeGen.Cmp(SymTab.OpGe,
|
|
|
- 2144 qsel, q2, qc, FALSE);
|
|
|
- 2145 QbeGen.Cmp(SymTab.OpLe,
|
|
|
- 2146 qsel, q3, qd, FALSE);
|
|
|
- 2147 QbeGen.NewTemp(qe);
|
|
|
- 2148 QbeGen.Op3("and", qe, qc, qd,
|
|
|
- 2149 FALSE);
|
|
|
- 2150 QbeGen.NewLabel(lNext);
|
|
|
- 2151 QbeGen.Jnz(qe, lBody, lNext);
|
|
|
- 2152 QbeGen.EmitLabel(lNext); .) ]
|
|
|
- 2153 (. AST.SetChild(arm,
|
|
|
- 2154 AST.NChild(arm), astLab); .) .
|
|
|
- 2155 ReturnStat (. VAR t: SymTab.TypeIndex;
|
|
|
- 2156 q, qt: QbeGen.QVal;
|
|
|
- 2157 res: SymTab.TypeIndex;
|
|
|
- 2158 hadE, conv: BOOLEAN;
|
|
|
- 2159 astVal, astNode: AST.Node; .)
|
|
|
- 2160 = "RETURN" (. hadE := FALSE; astStmt := AST.NoNode; .)
|
|
|
- 2161 [ Expr<t, q> (. hadE := TRUE; astVal := astCur; .) ]
|
|
|
- 2162 (. astNode := AST.MakeNode(AST.NkReturn);
|
|
|
- 2163 IF hadE THEN
|
|
|
- 2164 AST.SetChild(astNode, 0, astVal)
|
|
|
- 2165 END;
|
|
|
- 2166 astStmt := astNode;
|
|
|
- 2167 conv := FALSE;
|
|
|
- 2168 IF NOT SymTab.InProc() THEN
|
|
|
- 2169 SemError(232)
|
|
|
- 2170 ELSE res := SymTab.CurRes();
|
|
|
- 2171 IF NOT hadE THEN
|
|
|
- 2172 IF res #
|
|
|
- 2173 SymTab.InvalidType THEN
|
|
|
- 2174 SemError(232)
|
|
|
- 2175 ELSE QbeGen.EmitRet(q,
|
|
|
- 2176 FALSE)
|
|
|
- 2177 END
|
|
|
- 2178 ELSIF (res =
|
|
|
- 2179 SymTab.InvalidType)
|
|
|
- 2180 OR (t #
|
|
|
- 2181 SymTab.InvalidType)
|
|
|
- 2182 AND NOT SymTab.Assignable(t,
|
|
|
- 2183 res) THEN
|
|
|
- 2184 SemError(232)
|
|
|
- 2185 ELSE
|
|
|
- 2186 conv := (SymTab.ClassOf(
|
|
|
- 2187 res) = SymTab.ClReal)
|
|
|
- 2188 AND SymTab.IsIntFamily(t);
|
|
|
- 2189 IF conv THEN
|
|
|
- 2190 QbeGen.ConvIR(q, qt);
|
|
|
- 2191 QbeGen.EmitRet(qt, TRUE)
|
|
|
- 2192 ELSE QbeGen.EmitRet(q, TRUE)
|
|
|
- 2193 END
|
|
|
- 2194 END
|
|
|
- 2195 END; .) .
|
|
|
- 2196 HaltStat (. VAR t: SymTab.TypeIndex;
|
|
|
- 2197 q: QbeGen.QVal;
|
|
|
- 2198 astVal, astNode: AST.Node; .)
|
|
|
- 2199 = "HALT" (. astVal := AST.NoNode; .)
|
|
|
- 2200 [ "(" Expr<t, q> (. astVal := astCur; .) ")" ]
|
|
|
- 2201 (. astNode := AST.MakeNode(AST.NkHalt);
|
|
|
- 2202 IF astVal # AST.NoNode THEN
|
|
|
- 2203 AST.SetChild(astNode, 0, astVal)
|
|
|
- 2204 END;
|
|
|
- 2205 astStmt := astNode;
|
|
|
- 2206 QbeGen.HaltQ; .) .
|
|
|
- 2207 (* Designator: scalar loads, array addresses, and index suffixes.
|
|
|
- 2208 Each index descends one level (bounds-checked, trap on breach);
|
|
|
- 2209 nested levels reload the inner descriptor address. q ends as the
|
|
|
- 2210 value (scalars), the descriptor address (plain arrays), or the
|
|
|
- 2211 element address (indexed); sfx marks the indexed form. *)
|
|
|
- 2212 Design<VAR t: SymTab.TypeIndex; VAR k: INTEGER;
|
|
|
- 2213 VAR q: QbeGen.QVal; VAR qn: SymTab.Name; VAR sfx: BOOLEAN>
|
|
|
- 2214 (. VAR n, fn, mal: SymTab.Name;
|
|
|
- 2215 cls: INTEGER;
|
|
|
- 2216 ic: SymTab.TypeIndex;
|
|
|
- 2217 curT, it, eT, bt:
|
|
|
- 2218 SymTab.TypeIndex;
|
|
|
- 2219 iq, ql, qlo, qhi, qe:
|
|
|
- 2220 QbeGen.QVal;
|
|
|
- 2221 lo, hi: INTEGER;
|
|
|
- 2222 fo: INTEGER;
|
|
|
- 2223 isOpen: BOOLEAN;
|
|
|
- 2224 qb, cv: QbeGen.QVal;
|
|
|
- 2225 fid, fref, slot: INTEGER;
|
|
|
- 2226 r: BOOLEAN;
|
|
|
- 2227 astDes, astSel: AST.Node; .)
|
|
|
- 2228 = GetIdent<n> (. methCls := SymTab.InvalidType;
|
|
|
- 2229 QbeGen.CopyOp(n, qn);
|
|
|
- 2230 sfx := FALSE;
|
|
|
- 2231 fid := 0; fref := 0; slot := 0;
|
|
|
- 2232 IF NOT SymTab.Lookup(n) THEN
|
|
|
- 2233 (* a bare method name inside
|
|
|
- 2234 a CLASS IMPLEMENTATION
|
|
|
- 2235 is a sibling call on
|
|
|
- 2236 THIS *)
|
|
|
- 2237 ic := SymTab.CurImplClass();
|
|
|
- 2238 IF (ic #
|
|
|
- 2239 SymTab.InvalidType)
|
|
|
- 2240 AND SymTab.MethodExists(ic, n) THEN
|
|
|
- 2241 sfx := FALSE;
|
|
|
- 2242 QbeGen.ThisBase(q);
|
|
|
- 2243 QbeGen.ArmRecv(q);
|
|
|
- 2244 methCls := ic;
|
|
|
- 2245 k := SymTab.KindProc;
|
|
|
- 2246 t := SymTab.InvalidType
|
|
|
- 2247 ELSIF SymTab.InProc() THEN
|
|
|
- 2248 (* not declared yet: a
|
|
|
- 2249 forward reference to a
|
|
|
- 2250 module-level variable
|
|
|
- 2251 declared further down. *)
|
|
|
- 2252 k := SymTab.KindVar;
|
|
|
- 2253 r := SymTab.FwdVarRef(n, k,
|
|
|
- 2254 fref, t);
|
|
|
- 2255 slot := QbeGen.FwdDesignator();
|
|
|
- 2256 FwdVarNote(fref, slot);
|
|
|
- 2257 fid := slot;
|
|
|
- 2258 QbeGen.FwdAddrOper(fid, q);
|
|
|
- 2259 sfx := TRUE
|
|
|
- 2260 ELSE
|
|
|
- 2261 SemError(201);
|
|
|
- 2262 t :=
|
|
|
- 2263 SymTab.InvalidType;
|
|
|
- 2264 k := -1;
|
|
|
- 2265 QbeGen.CopyOp("0", q)
|
|
|
- 2266 END
|
|
|
- 2267 ELSE
|
|
|
- 2268 t := SymTab.SymType(n);
|
|
|
- 2269 k := SymTab.SymKind(n);
|
|
|
- 2270 IF k = SymTab.KindConst THEN
|
|
|
- 2271 IF SymTab.Equal(n,
|
|
|
- 2272 "TRUE") THEN
|
|
|
- 2273 t := SymTab.BoolType();
|
|
|
- 2274 QbeGen.CopyOp("1", q)
|
|
|
- 2275 ELSIF SymTab.Equal(n,
|
|
|
- 2276 "FALSE") THEN
|
|
|
+ 2061 arm, astNode, astArms,
|
|
|
+ 2062 astArmsTail: AST.Node; .)
|
|
|
+ 2063 = "CASE" Expr<tsel, qsel> (. astNode := AST.MakeNode(AST.NkCase);
|
|
|
+ 2064 AST.SetChild(astNode, 0, astCur);
|
|
|
+ 2065 astArms := AST.NoNode;
|
|
|
+ 2066 astArmsTail := AST.NoNode;
|
|
|
+ 2067 QbeGen.NewLabel(lEnd); .)
|
|
|
+ 2068 "OF" CaseAlt<tsel, qsel, lEnd, astArms, astArmsTail>
|
|
|
+ 2069 { "|" CaseAlt<tsel, qsel, lEnd, astArms, astArmsTail> }
|
|
|
+ 2070 [ "ELSE" (. astStmt := AST.NoNode; .)
|
|
|
+ 2071 [ StatSeq ] (. arm := AST.MakeNode(AST.NkCaseArm);
|
|
|
+ 2072 AST.SetOp(arm, 1);
|
|
|
+ 2073 AST.SetChild(arm, 0, astStmt);
|
|
|
+ 2074 AstAppend(AST.NkBlock,
|
|
|
+ 2075 astArms, astArmsTail, arm); .) ]
|
|
|
+ 2076 "END" (. AST.SetChild(astNode, 1, astArms);
|
|
|
+ 2077 astStmt := astNode;
|
|
|
+ 2078 QbeGen.EmitLabel(lEnd); .) .
|
|
|
+ 2079 (* Compare-chain lowering: each alternative ends its match-tests
|
|
|
+ 2080 with "jmp lAfter", so the no-match fallthrough skips the body:
|
|
|
+ 2081 "cmp; jnz(lBody,lF); lF: ... ; jmp lAfter; lBody: S; jmp lEnd;
|
|
|
+ 2082 lAfter:". Falls into the next alternative, ELSE, or END. *)
|
|
|
+ 2083 CaseAlt<tsel: SymTab.TypeIndex; qsel: QbeGen.QVal;
|
|
|
+ 2084 lEnd: QbeGen.QVal; VAR arms, armsTail: AST.Node>
|
|
|
+ 2085 (. VAR lBody, lAfter: QbeGen.QVal;
|
|
|
+ 2086 arm: AST.Node; .)
|
|
|
+ 2087 = (. arm := AST.MakeNode(AST.NkCaseArm);
|
|
|
+ 2088 QbeGen.NewLabel(lBody);
|
|
|
+ 2089 QbeGen.NewLabel(lAfter); .)
|
|
|
+ 2090 CaseLabel<tsel, qsel, lBody, arm>
|
|
|
+ 2091 { "," CaseLabel<tsel, qsel, lBody, arm> }
|
|
|
+ 2092 ":" (. astStmt := AST.NoNode;
|
|
|
+ 2093 QbeGen.Jmp(lAfter);
|
|
|
+ 2094 QbeGen.EmitLabel(lBody); .)
|
|
|
+ 2095 [ StatSeq ] (. AST.SetChild(arm, AST.NChild(arm),
|
|
|
+ 2096 astStmt);
|
|
|
+ 2097 AstAppend(AST.NkBlock,
|
|
|
+ 2098 arms, armsTail, arm);
|
|
|
+ 2099 QbeGen.Jmp(lEnd);
|
|
|
+ 2100 QbeGen.EmitLabel(lAfter); .) .
|
|
|
+ 2101 CaseLabel<tsel: SymTab.TypeIndex; qsel: QbeGen.QVal;
|
|
|
+ 2102 lBody: QbeGen.QVal; arm: AST.Node>
|
|
|
+ 2103 (. VAR t2, t3: SymTab.TypeIndex;
|
|
|
+ 2104 q2, q3, qc, qd, qe:
|
|
|
+ 2105 QbeGen.QVal;
|
|
|
+ 2106 astLab: AST.Node;
|
|
|
+ 2107 lNext: QbeGen.QVal; .)
|
|
|
+ 2108 = Expr<t2, q2> (. astLab := astCur;
|
|
|
+ 2109 IF (t2 #
|
|
|
+ 2110 SymTab.InvalidType)
|
|
|
+ 2111 AND (tsel #
|
|
|
+ 2112 SymTab.InvalidType)
|
|
|
+ 2113 AND ((SymTab.ClassOf(t2) =
|
|
|
+ 2114 SymTab.ClSet)
|
|
|
+ 2115 OR (SymTab.ClassOf(tsel) =
|
|
|
+ 2116 SymTab.ClSet)) THEN
|
|
|
+ 2117 SemError(230)
|
|
|
+ 2118 ELSIF (t2 #
|
|
|
+ 2119 SymTab.InvalidType)
|
|
|
+ 2120 AND (tsel #
|
|
|
+ 2121 SymTab.InvalidType)
|
|
|
+ 2122 AND NOT SymTab.EqCheck(t2,
|
|
|
+ 2123 tsel) THEN
|
|
|
+ 2124 SemError(213) END;
|
|
|
+ 2125 IF NOT QbeGen.IsImm(q2) THEN
|
|
|
+ 2126 SemError(230);
|
|
|
+ 2127 QbeGen.CopyOp("0", q2)
|
|
|
+ 2128 END;
|
|
|
+ 2129 QbeGen.NewLabel(lNext);
|
|
|
+ 2130 QbeGen.Cmp(SymTab.OpEq,
|
|
|
+ 2131 qsel, q2, qc, FALSE);
|
|
|
+ 2132 QbeGen.Jnz(qc, lBody, lNext);
|
|
|
+ 2133 QbeGen.EmitLabel(lNext); .)
|
|
|
+ 2134 [ ".." Expr<t3, q3> (. astLab := AST.MakeBin(
|
|
|
+ 2135 AST.NkSubrange, 0, astLab, astCur);
|
|
|
+ 2136 IF (t3 #
|
|
|
+ 2137 SymTab.InvalidType)
|
|
|
+ 2138 AND (tsel #
|
|
|
+ 2139 SymTab.InvalidType)
|
|
|
+ 2140 AND NOT SymTab.EqCheck(t3,
|
|
|
+ 2141 tsel) THEN
|
|
|
+ 2142 SemError(213) END;
|
|
|
+ 2143 IF NOT QbeGen.IsImm(q3) THEN
|
|
|
+ 2144 SemError(230);
|
|
|
+ 2145 QbeGen.CopyOp("0", q3)
|
|
|
+ 2146 END;
|
|
|
+ 2147 QbeGen.Cmp(SymTab.OpGe,
|
|
|
+ 2148 qsel, q2, qc, FALSE);
|
|
|
+ 2149 QbeGen.Cmp(SymTab.OpLe,
|
|
|
+ 2150 qsel, q3, qd, FALSE);
|
|
|
+ 2151 QbeGen.NewTemp(qe);
|
|
|
+ 2152 QbeGen.Op3("and", qe, qc, qd,
|
|
|
+ 2153 FALSE);
|
|
|
+ 2154 QbeGen.NewLabel(lNext);
|
|
|
+ 2155 QbeGen.Jnz(qe, lBody, lNext);
|
|
|
+ 2156 QbeGen.EmitLabel(lNext); .) ]
|
|
|
+ 2157 (. AST.SetChild(arm,
|
|
|
+ 2158 AST.NChild(arm), astLab); .) .
|
|
|
+ 2159 ReturnStat (. VAR t: SymTab.TypeIndex;
|
|
|
+ 2160 q, qt: QbeGen.QVal;
|
|
|
+ 2161 res: SymTab.TypeIndex;
|
|
|
+ 2162 hadE, conv: BOOLEAN;
|
|
|
+ 2163 astVal, astNode: AST.Node; .)
|
|
|
+ 2164 = "RETURN" (. hadE := FALSE; astStmt := AST.NoNode; .)
|
|
|
+ 2165 [ Expr<t, q> (. hadE := TRUE; astVal := astCur; .) ]
|
|
|
+ 2166 (. astNode := AST.MakeNode(AST.NkReturn);
|
|
|
+ 2167 IF hadE THEN
|
|
|
+ 2168 AST.SetChild(astNode, 0, astVal)
|
|
|
+ 2169 END;
|
|
|
+ 2170 astStmt := astNode;
|
|
|
+ 2171 conv := FALSE;
|
|
|
+ 2172 IF NOT SymTab.InProc() THEN
|
|
|
+ 2173 SemError(232)
|
|
|
+ 2174 ELSE res := SymTab.CurRes();
|
|
|
+ 2175 IF NOT hadE THEN
|
|
|
+ 2176 IF res #
|
|
|
+ 2177 SymTab.InvalidType THEN
|
|
|
+ 2178 SemError(232)
|
|
|
+ 2179 ELSE QbeGen.EmitRet(q,
|
|
|
+ 2180 FALSE)
|
|
|
+ 2181 END
|
|
|
+ 2182 ELSIF (res =
|
|
|
+ 2183 SymTab.InvalidType)
|
|
|
+ 2184 OR (t #
|
|
|
+ 2185 SymTab.InvalidType)
|
|
|
+ 2186 AND NOT SymTab.Assignable(t,
|
|
|
+ 2187 res) THEN
|
|
|
+ 2188 SemError(232)
|
|
|
+ 2189 ELSE
|
|
|
+ 2190 conv := (SymTab.ClassOf(
|
|
|
+ 2191 res) = SymTab.ClReal)
|
|
|
+ 2192 AND SymTab.IsIntFamily(t);
|
|
|
+ 2193 IF conv THEN
|
|
|
+ 2194 QbeGen.ConvIR(q, qt);
|
|
|
+ 2195 QbeGen.EmitRet(qt, TRUE)
|
|
|
+ 2196 ELSE QbeGen.EmitRet(q, TRUE)
|
|
|
+ 2197 END
|
|
|
+ 2198 END
|
|
|
+ 2199 END; .) .
|
|
|
+ 2200 HaltStat (. VAR t: SymTab.TypeIndex;
|
|
|
+ 2201 q: QbeGen.QVal;
|
|
|
+ 2202 astVal, astNode: AST.Node; .)
|
|
|
+ 2203 = "HALT" (. astVal := AST.NoNode; .)
|
|
|
+ 2204 [ "(" Expr<t, q> (. astVal := astCur; .) ")" ]
|
|
|
+ 2205 (. astNode := AST.MakeNode(AST.NkHalt);
|
|
|
+ 2206 IF astVal # AST.NoNode THEN
|
|
|
+ 2207 AST.SetChild(astNode, 0, astVal)
|
|
|
+ 2208 END;
|
|
|
+ 2209 astStmt := astNode;
|
|
|
+ 2210 QbeGen.HaltQ; .) .
|
|
|
+ 2211 (* Designator: scalar loads, array addresses, and index suffixes.
|
|
|
+ 2212 Each index descends one level (bounds-checked, trap on breach);
|
|
|
+ 2213 nested levels reload the inner descriptor address. q ends as the
|
|
|
+ 2214 value (scalars), the descriptor address (plain arrays), or the
|
|
|
+ 2215 element address (indexed); sfx marks the indexed form. *)
|
|
|
+ 2216 Design<VAR t: SymTab.TypeIndex; VAR k: INTEGER;
|
|
|
+ 2217 VAR q: QbeGen.QVal; VAR qn: SymTab.Name; VAR sfx: BOOLEAN>
|
|
|
+ 2218 (. VAR n, fn, mal: SymTab.Name;
|
|
|
+ 2219 cls: INTEGER;
|
|
|
+ 2220 ic: SymTab.TypeIndex;
|
|
|
+ 2221 curT, it, eT, bt:
|
|
|
+ 2222 SymTab.TypeIndex;
|
|
|
+ 2223 iq, ql, qlo, qhi, qe:
|
|
|
+ 2224 QbeGen.QVal;
|
|
|
+ 2225 lo, hi: INTEGER;
|
|
|
+ 2226 fo: INTEGER;
|
|
|
+ 2227 isOpen: BOOLEAN;
|
|
|
+ 2228 qb, cv: QbeGen.QVal;
|
|
|
+ 2229 fid, fref, slot: INTEGER;
|
|
|
+ 2230 r: BOOLEAN;
|
|
|
+ 2231 astDes, astSel: AST.Node; .)
|
|
|
+ 2232 = GetIdent<n> (. methCls := SymTab.InvalidType;
|
|
|
+ 2233 QbeGen.CopyOp(n, qn);
|
|
|
+ 2234 sfx := FALSE;
|
|
|
+ 2235 fid := 0; fref := 0; slot := 0;
|
|
|
+ 2236 IF NOT SymTab.Lookup(n) THEN
|
|
|
+ 2237 (* a bare method name inside
|
|
|
+ 2238 a CLASS IMPLEMENTATION
|
|
|
+ 2239 is a sibling call on
|
|
|
+ 2240 THIS *)
|
|
|
+ 2241 ic := SymTab.CurImplClass();
|
|
|
+ 2242 IF (ic #
|
|
|
+ 2243 SymTab.InvalidType)
|
|
|
+ 2244 AND SymTab.MethodExists(ic, n) THEN
|
|
|
+ 2245 sfx := FALSE;
|
|
|
+ 2246 QbeGen.ThisBase(q);
|
|
|
+ 2247 QbeGen.ArmRecv(q);
|
|
|
+ 2248 methCls := ic;
|
|
|
+ 2249 k := SymTab.KindProc;
|
|
|
+ 2250 t := SymTab.InvalidType
|
|
|
+ 2251 ELSIF SymTab.InProc() THEN
|
|
|
+ 2252 (* not declared yet: a
|
|
|
+ 2253 forward reference to a
|
|
|
+ 2254 module-level variable
|
|
|
+ 2255 declared further down. *)
|
|
|
+ 2256 k := SymTab.KindVar;
|
|
|
+ 2257 r := SymTab.FwdVarRef(n, k,
|
|
|
+ 2258 fref, t);
|
|
|
+ 2259 slot := QbeGen.FwdDesignator();
|
|
|
+ 2260 FwdVarNote(fref, slot);
|
|
|
+ 2261 fid := slot;
|
|
|
+ 2262 QbeGen.FwdAddrOper(fid, q);
|
|
|
+ 2263 sfx := TRUE
|
|
|
+ 2264 ELSE
|
|
|
+ 2265 SemError(201);
|
|
|
+ 2266 t :=
|
|
|
+ 2267 SymTab.InvalidType;
|
|
|
+ 2268 k := -1;
|
|
|
+ 2269 QbeGen.CopyOp("0", q)
|
|
|
+ 2270 END
|
|
|
+ 2271 ELSE
|
|
|
+ 2272 t := SymTab.SymType(n);
|
|
|
+ 2273 k := SymTab.SymKind(n);
|
|
|
+ 2274 IF k = SymTab.KindConst THEN
|
|
|
+ 2275 IF SymTab.Equal(n,
|
|
|
+ 2276 "TRUE") THEN
|
|
|
2277 t := SymTab.BoolType();
|
|
|
- 2278 QbeGen.CopyOp("0", q)
|
|
|
+ 2278 QbeGen.CopyOp("1", q)
|
|
|
2279 ELSIF SymTab.Equal(n,
|
|
|
- 2280 "NIL") THEN
|
|
|
- 2281 QbeGen.CopyOp("0", q)
|
|
|
- 2282 ELSE
|
|
|
- 2283 cls :=
|
|
|
- 2284 SymTab.ClassOf(t);
|
|
|
- 2285 IF (t #
|
|
|
- 2286 SymTab.InvalidType)
|
|
|
- 2287 AND ((cls = SymTab.ClInt)
|
|
|
- 2288 OR (cls
|
|
|
- 2289 = SymTab.ClChar)
|
|
|
- 2290 OR (cls
|
|
|
- 2291 = SymTab.ClEnum)
|
|
|
+ 2280 "FALSE") THEN
|
|
|
+ 2281 t := SymTab.BoolType();
|
|
|
+ 2282 QbeGen.CopyOp("0", q)
|
|
|
+ 2283 ELSIF SymTab.Equal(n,
|
|
|
+ 2284 "NIL") THEN
|
|
|
+ 2285 QbeGen.CopyOp("0", q)
|
|
|
+ 2286 ELSE
|
|
|
+ 2287 cls :=
|
|
|
+ 2288 SymTab.ClassOf(t);
|
|
|
+ 2289 IF (t #
|
|
|
+ 2290 SymTab.InvalidType)
|
|
|
+ 2291 AND ((cls = SymTab.ClInt)
|
|
|
2292 OR (cls
|
|
|
- 2293 = SymTab.ClReal)
|
|
|
+ 2293 = SymTab.ClChar)
|
|
|
2294 OR (cls
|
|
|
- 2295 = SymTab.ClLong)
|
|
|
+ 2295 = SymTab.ClEnum)
|
|
|
2296 OR (cls
|
|
|
- 2297 = SymTab.ClNil)) THEN
|
|
|
- 2298 IF cls = SymTab.ClNil THEN
|
|
|
- 2299 QbeGen.CopyOp("0", q)
|
|
|
- 2300 ELSIF ((cls
|
|
|
- 2301 = SymTab.ClInt)
|
|
|
- 2302 OR (cls
|
|
|
- 2303 = SymTab.ClChar)
|
|
|
- 2304 OR (cls
|
|
|
- 2305 = SymTab.ClEnum)
|
|
|
+ 2297 = SymTab.ClReal)
|
|
|
+ 2298 OR (cls
|
|
|
+ 2299 = SymTab.ClLong)
|
|
|
+ 2300 OR (cls
|
|
|
+ 2301 = SymTab.ClNil)) THEN
|
|
|
+ 2302 IF cls = SymTab.ClNil THEN
|
|
|
+ 2303 QbeGen.CopyOp("0", q)
|
|
|
+ 2304 ELSIF ((cls
|
|
|
+ 2305 = SymTab.ClInt)
|
|
|
2306 OR (cls
|
|
|
- 2307 = SymTab.ClLong))
|
|
|
- 2308 AND SymTab.GetSymVal(n, cv)
|
|
|
- 2309 AND QbeGen.IsImm(cv) THEN
|
|
|
- 2310 QbeGen.CopyOp(cv, q)
|
|
|
- 2311 ELSE
|
|
|
- 2312 QbeGen.LoadVar(n,
|
|
|
- 2313 cls = SymTab.ClReal,
|
|
|
- 2314 q)
|
|
|
- 2315 END
|
|
|
- 2316 ELSIF (cls = SymTab.ClArray)
|
|
|
- 2317 OR (cls = SymTab.ClRecord)
|
|
|
- 2318 OR (cls = SymTab.ClClass)
|
|
|
- 2319 OR (cls = SymTab.ClStr)
|
|
|
- 2320 OR (cls = SymTab.ClUStr) THEN
|
|
|
- 2321 (* aggregate constant:
|
|
|
- 2322 its value IS the
|
|
|
- 2323 descriptor address *)
|
|
|
- 2324 IF SymTab.GetSymVal(n, cv) THEN
|
|
|
- 2325 QbeGen.CopyOp(cv, q)
|
|
|
- 2326 ELSE
|
|
|
- 2327 QbeGen.CopyOp("0", q)
|
|
|
- 2328 END
|
|
|
- 2329 ELSE
|
|
|
- 2330 IF t #
|
|
|
- 2331 SymTab.InvalidType THEN
|
|
|
- 2332 SemError(230)
|
|
|
- 2333 END;
|
|
|
- 2334 QbeGen.CopyOp("0", q)
|
|
|
- 2335 END
|
|
|
- 2336 END
|
|
|
- 2337 ELSIF (k = SymTab.KindVar)
|
|
|
- 2338 OR (k = SymTab.KindParam) THEN
|
|
|
- 2339 cls :=
|
|
|
- 2340 SymTab.ClassOf(t);
|
|
|
- 2341 IF (cls = SymTab.ClInt)
|
|
|
- 2342 OR (cls = SymTab.ClBool)
|
|
|
- 2343 OR (cls = SymTab.ClChar)
|
|
|
- 2344 OR (cls = SymTab.ClUChar)
|
|
|
- 2345 OR (cls = SymTab.ClEnum)
|
|
|
- 2346 OR (cls
|
|
|
- 2347 = SymTab.ClReal) THEN
|
|
|
- 2348 QbeGen.LoadVar(n,
|
|
|
- 2349 cls = SymTab.ClReal, q)
|
|
|
- 2350 ELSIF (cls = SymTab.ClPtr)
|
|
|
- 2351 OR (cls = SymTab.ClProc) THEN
|
|
|
- 2352 QbeGen.LoadPtr(n, q)
|
|
|
- 2353 ELSIF cls = SymTab.ClLong THEN
|
|
|
- 2354 QbeGen.LoadLong(n, q)
|
|
|
- 2355 ELSIF (cls
|
|
|
- 2356 = SymTab.ClArray)
|
|
|
- 2357 OR (cls
|
|
|
- 2358 = SymTab.ClSet)
|
|
|
- 2359 OR (cls
|
|
|
- 2360 = SymTab.ClRecord)
|
|
|
+ 2307 = SymTab.ClChar)
|
|
|
+ 2308 OR (cls
|
|
|
+ 2309 = SymTab.ClEnum)
|
|
|
+ 2310 OR (cls
|
|
|
+ 2311 = SymTab.ClLong))
|
|
|
+ 2312 AND SymTab.GetSymVal(n, cv)
|
|
|
+ 2313 AND QbeGen.IsImm(cv) THEN
|
|
|
+ 2314 QbeGen.CopyOp(cv, q)
|
|
|
+ 2315 ELSE
|
|
|
+ 2316 QbeGen.LoadVar(n,
|
|
|
+ 2317 cls = SymTab.ClReal,
|
|
|
+ 2318 q)
|
|
|
+ 2319 END
|
|
|
+ 2320 ELSIF (cls = SymTab.ClArray)
|
|
|
+ 2321 OR (cls = SymTab.ClRecord)
|
|
|
+ 2322 OR (cls = SymTab.ClClass)
|
|
|
+ 2323 OR (cls = SymTab.ClStr)
|
|
|
+ 2324 OR (cls = SymTab.ClUStr) THEN
|
|
|
+ 2325 (* aggregate constant:
|
|
|
+ 2326 its value IS the
|
|
|
+ 2327 descriptor address *)
|
|
|
+ 2328 IF SymTab.GetSymVal(n, cv) THEN
|
|
|
+ 2329 QbeGen.CopyOp(cv, q)
|
|
|
+ 2330 ELSE
|
|
|
+ 2331 QbeGen.CopyOp("0", q)
|
|
|
+ 2332 END
|
|
|
+ 2333 ELSE
|
|
|
+ 2334 IF t #
|
|
|
+ 2335 SymTab.InvalidType THEN
|
|
|
+ 2336 SemError(230)
|
|
|
+ 2337 END;
|
|
|
+ 2338 QbeGen.CopyOp("0", q)
|
|
|
+ 2339 END
|
|
|
+ 2340 END
|
|
|
+ 2341 ELSIF (k = SymTab.KindVar)
|
|
|
+ 2342 OR (k = SymTab.KindParam) THEN
|
|
|
+ 2343 cls :=
|
|
|
+ 2344 SymTab.ClassOf(t);
|
|
|
+ 2345 IF (cls = SymTab.ClInt)
|
|
|
+ 2346 OR (cls = SymTab.ClBool)
|
|
|
+ 2347 OR (cls = SymTab.ClChar)
|
|
|
+ 2348 OR (cls = SymTab.ClUChar)
|
|
|
+ 2349 OR (cls = SymTab.ClEnum)
|
|
|
+ 2350 OR (cls
|
|
|
+ 2351 = SymTab.ClReal) THEN
|
|
|
+ 2352 QbeGen.LoadVar(n,
|
|
|
+ 2353 cls = SymTab.ClReal, q)
|
|
|
+ 2354 ELSIF (cls = SymTab.ClPtr)
|
|
|
+ 2355 OR (cls = SymTab.ClProc) THEN
|
|
|
+ 2356 QbeGen.LoadPtr(n, q)
|
|
|
+ 2357 ELSIF cls = SymTab.ClLong THEN
|
|
|
+ 2358 QbeGen.LoadLong(n, q)
|
|
|
+ 2359 ELSIF (cls
|
|
|
+ 2360 = SymTab.ClArray)
|
|
|
2361 OR (cls
|
|
|
- 2362 = SymTab.ClUStr)
|
|
|
+ 2362 = SymTab.ClSet)
|
|
|
2363 OR (cls
|
|
|
- 2364 = SymTab.ClClass) THEN
|
|
|
- 2365 QbeGen.AddrOf(n, q)
|
|
|
- 2366 ELSE SemError(230);
|
|
|
- 2367 QbeGen.CopyOp("0", q)
|
|
|
- 2368 END
|
|
|
- 2369 ELSE QbeGen.CopyOp("0", q);
|
|
|
- 2370 IF k = SymTab.KindImport THEN
|
|
|
- 2371 SemError(230)
|
|
|
- 2372 ELSIF k =
|
|
|
- 2373 SymTab.KindProc THEN
|
|
|
- 2374 (* bare procedure name:
|
|
|
- 2375 a following ArgList
|
|
|
- 2376 makes it a call;
|
|
|
- 2377 otherwise Fact
|
|
|
- 2378 reports 230 *)
|
|
|
- 2379 ELSE
|
|
|
- 2380 IF k = SymTab.KindField THEN
|
|
|
- 2381 IF QbeGen.TopWith(qb) THEN
|
|
|
- 2382 fo :=
|
|
|
- 2383 SymTab.FieldOffset(
|
|
|
- 2384 SymTab.FieldOwner(n),
|
|
|
- 2385 n);
|
|
|
- 2386 QbeGen.FieldAddr(qb,
|
|
|
- 2387 fo, q);
|
|
|
- 2388 sfx := TRUE
|
|
|
- 2389 ELSE SemError(230);
|
|
|
- 2390 QbeGen.CopyOp("0", q)
|
|
|
- 2391 END
|
|
|
- 2392 END
|
|
|
- 2393 END
|
|
|
- 2394 END
|
|
|
- 2395 END; .)
|
|
|
- 2396 (. astDes := AST.MakeNode(AST.NkDesignator);
|
|
|
- 2397 AST.SetChild(astDes, AST.NChild(astDes), AST.MakeLeaf(AST.NkIdent, n)); .)
|
|
|
- 2398 { "[" Expr<it, iq>
|
|
|
- 2399 (. AST.SetChild(astDes, AST.NChild(astDes),
|
|
|
- 2400 AST.MakeUn(AST.NkSelector, AST.SelIndex, astCur)); IF t = SymTab.InvalidType THEN
|
|
|
- 2401 ELSIF SymTab.ClassOf(t) #
|
|
|
- 2402 SymTab.ClArray THEN
|
|
|
- 2403 SemError(217);
|
|
|
- 2404 t := SymTab.InvalidType
|
|
|
- 2405 ELSIF NOT SymTab.IsIntFamily(it)
|
|
|
- 2406 AND (SymTab.ClassOf(it) #
|
|
|
- 2407 SymTab.ClChar)
|
|
|
- 2408 AND (SymTab.ClassOf(it) #
|
|
|
- 2409 SymTab.ClEnum) THEN
|
|
|
- 2410 SemError(218);
|
|
|
- 2411 t := SymTab.InvalidType
|
|
|
- 2412 ELSE
|
|
|
- 2413 QbeGen.WidenIndex(iq, ql);
|
|
|
- 2414 isOpen :=
|
|
|
- 2415 SymTab.IsOpenArray(t);
|
|
|
- 2416 IF isOpen THEN
|
|
|
- 2417 QbeGen.CopyOp("0", qlo);
|
|
|
- 2418 IF SymTab.IsCharArray(t)
|
|
|
- 2419 OR SymTab.IsUCharArray(t) THEN
|
|
|
- 2420 QbeGen.OpenHiChar(q, qhi)
|
|
|
- 2421 ELSE QbeGen.OpenHi(q, qhi)
|
|
|
- 2422 END
|
|
|
- 2423 ELSE
|
|
|
- 2424 lo := SymTab.ArrayLo(t);
|
|
|
- 2425 hi := SymTab.ArrayHi(t);
|
|
|
- 2426 IF SymTab.IsCharArray(t)
|
|
|
- 2427 OR SymTab.IsUCharArray(t) THEN
|
|
|
- 2428 hi := hi + 1
|
|
|
- 2429 END;
|
|
|
- 2430 QbeGen.IntStr(lo, qlo);
|
|
|
- 2431 QbeGen.IntStr(hi, qhi)
|
|
|
- 2432 END;
|
|
|
- 2433 QbeGen.CheckRange(ql, qlo,
|
|
|
- 2434 qhi);
|
|
|
- 2435 eT := SymTab.ArrayElem(t);
|
|
|
- 2436 QbeGen.ElemAddr(q, ql, qlo,
|
|
|
- 2437 t, qe);
|
|
|
- 2438 IF SymTab.ClassOf(eT) =
|
|
|
- 2439 SymTab.ClArray THEN
|
|
|
- 2440 QbeGen.ElemLoad(qe, eT, q)
|
|
|
- 2441 ELSE QbeGen.CopyOp(qe, q)
|
|
|
- 2442 END;
|
|
|
- 2443 t := eT; sfx := TRUE
|
|
|
- 2444 END; .)
|
|
|
- 2445 { "," Expr<it, iq>
|
|
|
- 2446 (. AST.SetChild(astDes, AST.NChild(astDes),
|
|
|
- 2447 AST.MakeUn(AST.NkSelector, AST.SelIndex, astCur)); IF t = SymTab.InvalidType THEN
|
|
|
- 2448 ELSIF SymTab.ClassOf(t) #
|
|
|
- 2449 SymTab.ClArray THEN
|
|
|
- 2450 SemError(217);
|
|
|
- 2451 t := SymTab.InvalidType
|
|
|
- 2452 ELSIF NOT SymTab.IsIntFamily(it)
|
|
|
- 2453 AND (SymTab.ClassOf(it) #
|
|
|
- 2454 SymTab.ClChar)
|
|
|
- 2455 AND (SymTab.ClassOf(it) #
|
|
|
- 2456 SymTab.ClEnum) THEN
|
|
|
- 2457 SemError(218);
|
|
|
- 2458 t := SymTab.InvalidType
|
|
|
- 2459 ELSE
|
|
|
- 2460 QbeGen.WidenIndex(iq, ql);
|
|
|
- 2461 isOpen :=
|
|
|
- 2462 SymTab.IsOpenArray(t);
|
|
|
- 2463 IF isOpen THEN
|
|
|
- 2464 QbeGen.CopyOp("0", qlo);
|
|
|
- 2465 IF SymTab.IsCharArray(t)
|
|
|
- 2466 OR SymTab.IsUCharArray(t) THEN
|
|
|
- 2467 QbeGen.OpenHiChar(q, qhi)
|
|
|
- 2468 ELSE QbeGen.OpenHi(q, qhi)
|
|
|
- 2469 END
|
|
|
- 2470 ELSE
|
|
|
- 2471 lo := SymTab.ArrayLo(t);
|
|
|
- 2472 hi := SymTab.ArrayHi(t);
|
|
|
- 2473 IF SymTab.IsCharArray(t)
|
|
|
- 2474 OR SymTab.IsUCharArray(t) THEN
|
|
|
- 2475 hi := hi + 1
|
|
|
- 2476 END;
|
|
|
- 2477 QbeGen.IntStr(lo, qlo);
|
|
|
- 2478 QbeGen.IntStr(hi, qhi)
|
|
|
- 2479 END;
|
|
|
- 2480 QbeGen.CheckRange(ql, qlo,
|
|
|
- 2481 qhi);
|
|
|
- 2482 eT := SymTab.ArrayElem(t);
|
|
|
- 2483 QbeGen.ElemAddr(q, ql, qlo,
|
|
|
- 2484 t, qe);
|
|
|
- 2485 IF SymTab.ClassOf(eT) =
|
|
|
- 2486 SymTab.ClArray THEN
|
|
|
- 2487 QbeGen.ElemLoad(qe, eT, q)
|
|
|
- 2488 ELSE QbeGen.CopyOp(qe, q)
|
|
|
- 2489 END;
|
|
|
- 2490 t := eT; sfx := TRUE
|
|
|
- 2491 END; .) }
|
|
|
- 2492 "]"
|
|
|
- 2493 | "." GetIdent<fn>
|
|
|
- 2494 (. astSel := AST.MakeNode(AST.NkSelector);
|
|
|
- 2495 AST.SetOp(astSel, AST.SelField);
|
|
|
- 2496 AST.SetChild(astSel, 0, AST.MakeLeaf(AST.NkIdent, fn));
|
|
|
- 2497 AST.SetChild(astDes, AST.NChild(astDes), astSel); IF k = SymTab.KindModule THEN
|
|
|
- 2498 (* qualified L.x: materialize
|
|
|
- 2499 the export, then load it *)
|
|
|
- 2500 IF NOT SymTab.MaterializeAlias(n,
|
|
|
- 2501 fn, mal) THEN
|
|
|
- 2502 SemError(201);
|
|
|
- 2503 t := SymTab.InvalidType;
|
|
|
- 2504 QbeGen.CopyOp("0", q)
|
|
|
- 2505 ELSE
|
|
|
- 2506 QbeGen.CopyOp(mal, qn);
|
|
|
- 2507 t := SymTab.SymType(mal);
|
|
|
- 2508 k := SymTab.SymKind(mal);
|
|
|
- 2509 sfx := FALSE;
|
|
|
- 2510 IF k = SymTab.KindProc THEN
|
|
|
- 2511 (* call: ArgList supplies
|
|
|
- 2512 the value *)
|
|
|
- 2513 QbeGen.CopyOp("0", q)
|
|
|
- 2514 ELSIF NOT QbeGen.LoadDesignator(
|
|
|
- 2515 mal, t, k, q) THEN
|
|
|
- 2516 SemError(230);
|
|
|
+ 2364 = SymTab.ClRecord)
|
|
|
+ 2365 OR (cls
|
|
|
+ 2366 = SymTab.ClUStr)
|
|
|
+ 2367 OR (cls
|
|
|
+ 2368 = SymTab.ClClass) THEN
|
|
|
+ 2369 QbeGen.AddrOf(n, q)
|
|
|
+ 2370 ELSE SemError(230);
|
|
|
+ 2371 QbeGen.CopyOp("0", q)
|
|
|
+ 2372 END
|
|
|
+ 2373 ELSE QbeGen.CopyOp("0", q);
|
|
|
+ 2374 IF k = SymTab.KindImport THEN
|
|
|
+ 2375 SemError(230)
|
|
|
+ 2376 ELSIF k =
|
|
|
+ 2377 SymTab.KindProc THEN
|
|
|
+ 2378 (* bare procedure name:
|
|
|
+ 2379 a following ArgList
|
|
|
+ 2380 makes it a call;
|
|
|
+ 2381 otherwise Fact
|
|
|
+ 2382 reports 230 *)
|
|
|
+ 2383 ELSE
|
|
|
+ 2384 IF k = SymTab.KindField THEN
|
|
|
+ 2385 IF QbeGen.TopWith(qb) THEN
|
|
|
+ 2386 fo :=
|
|
|
+ 2387 SymTab.FieldOffset(
|
|
|
+ 2388 SymTab.FieldOwner(n),
|
|
|
+ 2389 n);
|
|
|
+ 2390 QbeGen.FieldAddr(qb,
|
|
|
+ 2391 fo, q);
|
|
|
+ 2392 sfx := TRUE
|
|
|
+ 2393 ELSE SemError(230);
|
|
|
+ 2394 QbeGen.CopyOp("0", q)
|
|
|
+ 2395 END
|
|
|
+ 2396 END
|
|
|
+ 2397 END
|
|
|
+ 2398 END
|
|
|
+ 2399 END; .)
|
|
|
+ 2400 (. astDes := AST.MakeNode(AST.NkDesignator);
|
|
|
+ 2401 AST.SetChild(astDes, AST.NChild(astDes), AST.MakeLeaf(AST.NkIdent, n)); .)
|
|
|
+ 2402 { "[" Expr<it, iq>
|
|
|
+ 2403 (. AST.SetChild(astDes, AST.NChild(astDes),
|
|
|
+ 2404 AST.MakeUn(AST.NkSelector, AST.SelIndex, astCur)); IF t = SymTab.InvalidType THEN
|
|
|
+ 2405 ELSIF SymTab.ClassOf(t) #
|
|
|
+ 2406 SymTab.ClArray THEN
|
|
|
+ 2407 SemError(217);
|
|
|
+ 2408 t := SymTab.InvalidType
|
|
|
+ 2409 ELSIF NOT SymTab.IsIntFamily(it)
|
|
|
+ 2410 AND (SymTab.ClassOf(it) #
|
|
|
+ 2411 SymTab.ClChar)
|
|
|
+ 2412 AND (SymTab.ClassOf(it) #
|
|
|
+ 2413 SymTab.ClEnum) THEN
|
|
|
+ 2414 SemError(218);
|
|
|
+ 2415 t := SymTab.InvalidType
|
|
|
+ 2416 ELSE
|
|
|
+ 2417 QbeGen.WidenIndex(iq, ql);
|
|
|
+ 2418 isOpen :=
|
|
|
+ 2419 SymTab.IsOpenArray(t);
|
|
|
+ 2420 IF isOpen THEN
|
|
|
+ 2421 QbeGen.CopyOp("0", qlo);
|
|
|
+ 2422 IF SymTab.IsCharArray(t)
|
|
|
+ 2423 OR SymTab.IsUCharArray(t) THEN
|
|
|
+ 2424 QbeGen.OpenHiChar(q, qhi)
|
|
|
+ 2425 ELSE QbeGen.OpenHi(q, qhi)
|
|
|
+ 2426 END
|
|
|
+ 2427 ELSE
|
|
|
+ 2428 lo := SymTab.ArrayLo(t);
|
|
|
+ 2429 hi := SymTab.ArrayHi(t);
|
|
|
+ 2430 IF SymTab.IsCharArray(t)
|
|
|
+ 2431 OR SymTab.IsUCharArray(t) THEN
|
|
|
+ 2432 hi := hi + 1
|
|
|
+ 2433 END;
|
|
|
+ 2434 QbeGen.IntStr(lo, qlo);
|
|
|
+ 2435 QbeGen.IntStr(hi, qhi)
|
|
|
+ 2436 END;
|
|
|
+ 2437 QbeGen.CheckRange(ql, qlo,
|
|
|
+ 2438 qhi);
|
|
|
+ 2439 eT := SymTab.ArrayElem(t);
|
|
|
+ 2440 QbeGen.ElemAddr(q, ql, qlo,
|
|
|
+ 2441 t, qe);
|
|
|
+ 2442 IF SymTab.ClassOf(eT) =
|
|
|
+ 2443 SymTab.ClArray THEN
|
|
|
+ 2444 QbeGen.ElemLoad(qe, eT, q)
|
|
|
+ 2445 ELSE QbeGen.CopyOp(qe, q)
|
|
|
+ 2446 END;
|
|
|
+ 2447 t := eT; sfx := TRUE
|
|
|
+ 2448 END; .)
|
|
|
+ 2449 { "," Expr<it, iq>
|
|
|
+ 2450 (. AST.SetChild(astDes, AST.NChild(astDes),
|
|
|
+ 2451 AST.MakeUn(AST.NkSelector, AST.SelIndex, astCur)); IF t = SymTab.InvalidType THEN
|
|
|
+ 2452 ELSIF SymTab.ClassOf(t) #
|
|
|
+ 2453 SymTab.ClArray THEN
|
|
|
+ 2454 SemError(217);
|
|
|
+ 2455 t := SymTab.InvalidType
|
|
|
+ 2456 ELSIF NOT SymTab.IsIntFamily(it)
|
|
|
+ 2457 AND (SymTab.ClassOf(it) #
|
|
|
+ 2458 SymTab.ClChar)
|
|
|
+ 2459 AND (SymTab.ClassOf(it) #
|
|
|
+ 2460 SymTab.ClEnum) THEN
|
|
|
+ 2461 SemError(218);
|
|
|
+ 2462 t := SymTab.InvalidType
|
|
|
+ 2463 ELSE
|
|
|
+ 2464 QbeGen.WidenIndex(iq, ql);
|
|
|
+ 2465 isOpen :=
|
|
|
+ 2466 SymTab.IsOpenArray(t);
|
|
|
+ 2467 IF isOpen THEN
|
|
|
+ 2468 QbeGen.CopyOp("0", qlo);
|
|
|
+ 2469 IF SymTab.IsCharArray(t)
|
|
|
+ 2470 OR SymTab.IsUCharArray(t) THEN
|
|
|
+ 2471 QbeGen.OpenHiChar(q, qhi)
|
|
|
+ 2472 ELSE QbeGen.OpenHi(q, qhi)
|
|
|
+ 2473 END
|
|
|
+ 2474 ELSE
|
|
|
+ 2475 lo := SymTab.ArrayLo(t);
|
|
|
+ 2476 hi := SymTab.ArrayHi(t);
|
|
|
+ 2477 IF SymTab.IsCharArray(t)
|
|
|
+ 2478 OR SymTab.IsUCharArray(t) THEN
|
|
|
+ 2479 hi := hi + 1
|
|
|
+ 2480 END;
|
|
|
+ 2481 QbeGen.IntStr(lo, qlo);
|
|
|
+ 2482 QbeGen.IntStr(hi, qhi)
|
|
|
+ 2483 END;
|
|
|
+ 2484 QbeGen.CheckRange(ql, qlo,
|
|
|
+ 2485 qhi);
|
|
|
+ 2486 eT := SymTab.ArrayElem(t);
|
|
|
+ 2487 QbeGen.ElemAddr(q, ql, qlo,
|
|
|
+ 2488 t, qe);
|
|
|
+ 2489 IF SymTab.ClassOf(eT) =
|
|
|
+ 2490 SymTab.ClArray THEN
|
|
|
+ 2491 QbeGen.ElemLoad(qe, eT, q)
|
|
|
+ 2492 ELSE QbeGen.CopyOp(qe, q)
|
|
|
+ 2493 END;
|
|
|
+ 2494 t := eT; sfx := TRUE
|
|
|
+ 2495 END; .) }
|
|
|
+ 2496 "]"
|
|
|
+ 2497 | "." GetIdent<fn>
|
|
|
+ 2498 (. astSel := AST.MakeNode(AST.NkSelector);
|
|
|
+ 2499 AST.SetOp(astSel, AST.SelField);
|
|
|
+ 2500 AST.SetChild(astSel, 0, AST.MakeLeaf(AST.NkIdent, fn));
|
|
|
+ 2501 AST.SetChild(astDes, AST.NChild(astDes), astSel); IF k = SymTab.KindModule THEN
|
|
|
+ 2502 (* qualified L.x: materialize
|
|
|
+ 2503 the export, then load it *)
|
|
|
+ 2504 IF NOT SymTab.MaterializeAlias(n,
|
|
|
+ 2505 fn, mal) THEN
|
|
|
+ 2506 SemError(201);
|
|
|
+ 2507 t := SymTab.InvalidType;
|
|
|
+ 2508 QbeGen.CopyOp("0", q)
|
|
|
+ 2509 ELSE
|
|
|
+ 2510 QbeGen.CopyOp(mal, qn);
|
|
|
+ 2511 t := SymTab.SymType(mal);
|
|
|
+ 2512 k := SymTab.SymKind(mal);
|
|
|
+ 2513 sfx := FALSE;
|
|
|
+ 2514 IF k = SymTab.KindProc THEN
|
|
|
+ 2515 (* call: ArgList supplies
|
|
|
+ 2516 the value *)
|
|
|
2517 QbeGen.CopyOp("0", q)
|
|
|
- 2518 END
|
|
|
- 2519 END
|
|
|
- 2520 ELSIF t = SymTab.InvalidType THEN
|
|
|
- 2521 ELSIF (SymTab.ClassOf(t) #
|
|
|
- 2522 SymTab.ClRecord)
|
|
|
- 2523 AND (SymTab.ClassOf(t) #
|
|
|
- 2524 SymTab.ClClass) THEN
|
|
|
- 2525 SemError(215);
|
|
|
- 2526 t := SymTab.InvalidType
|
|
|
- 2527 ELSIF (SymTab.ClassOf(t) =
|
|
|
- 2528 SymTab.ClClass)
|
|
|
- 2529 AND SymTab.MethodExists(t, fn) THEN
|
|
|
- 2530 (* obj.Method: bind the
|
|
|
- 2531 method and pass obj as
|
|
|
- 2532 the hidden receiver; q
|
|
|
- 2533 already holds the
|
|
|
- 2534 object's address *)
|
|
|
- 2535 QbeGen.ArmRecv(q);
|
|
|
- 2536 QbeGen.CopyOp(fn, n);
|
|
|
- 2537 QbeGen.CopyOp(fn, qn);
|
|
|
- 2538 methCls := t;
|
|
|
- 2539 k := SymTab.KindProc;
|
|
|
- 2540 t := SymTab.InvalidType
|
|
|
- 2541 ELSIF NOT SymTab.FieldExists(t,
|
|
|
- 2542 fn) THEN
|
|
|
- 2543 SemError(216);
|
|
|
+ 2518 ELSIF NOT QbeGen.LoadDesignator(
|
|
|
+ 2519 mal, t, k, q) THEN
|
|
|
+ 2520 SemError(230);
|
|
|
+ 2521 QbeGen.CopyOp("0", q)
|
|
|
+ 2522 END
|
|
|
+ 2523 END
|
|
|
+ 2524 ELSIF t = SymTab.InvalidType THEN
|
|
|
+ 2525 ELSIF (SymTab.ClassOf(t) #
|
|
|
+ 2526 SymTab.ClRecord)
|
|
|
+ 2527 AND (SymTab.ClassOf(t) #
|
|
|
+ 2528 SymTab.ClClass) THEN
|
|
|
+ 2529 SemError(215);
|
|
|
+ 2530 t := SymTab.InvalidType
|
|
|
+ 2531 ELSIF (SymTab.ClassOf(t) =
|
|
|
+ 2532 SymTab.ClClass)
|
|
|
+ 2533 AND SymTab.MethodExists(t, fn) THEN
|
|
|
+ 2534 (* obj.Method: bind the
|
|
|
+ 2535 method and pass obj as
|
|
|
+ 2536 the hidden receiver; q
|
|
|
+ 2537 already holds the
|
|
|
+ 2538 object's address *)
|
|
|
+ 2539 QbeGen.ArmRecv(q);
|
|
|
+ 2540 QbeGen.CopyOp(fn, n);
|
|
|
+ 2541 QbeGen.CopyOp(fn, qn);
|
|
|
+ 2542 methCls := t;
|
|
|
+ 2543 k := SymTab.KindProc;
|
|
|
2544 t := SymTab.InvalidType
|
|
|
- 2545 ELSE
|
|
|
- 2546 fo := SymTab.FieldOffset(t,
|
|
|
- 2547 fn);
|
|
|
- 2548 t := SymTab.FieldType(t, fn);
|
|
|
- 2549 QbeGen.FieldAddr(q, fo, qe);
|
|
|
- 2550 (* array fields are inline:
|
|
|
- 2551 the field address is the
|
|
|
- 2552 descriptor, like records *)
|
|
|
- 2553 QbeGen.CopyOp(qe, q);
|
|
|
- 2554 sfx := TRUE
|
|
|
- 2555 END; .)
|
|
|
- 2556 | "^"
|
|
|
- 2557 (. astSel := AST.MakeNode(AST.NkSelector);
|
|
|
- 2558 AST.SetOp(astSel, AST.SelDeref);
|
|
|
- 2559 AST.SetChild(astDes, AST.NChild(astDes), astSel); IF t = SymTab.InvalidType THEN
|
|
|
- 2560 ELSIF SymTab.ClassOf(t) #
|
|
|
- 2561 SymTab.ClPtr THEN
|
|
|
- 2562 SemError(219);
|
|
|
- 2563 t := SymTab.InvalidType
|
|
|
- 2564 ELSE
|
|
|
- 2565 bt := SymTab.PtrBase(t);
|
|
|
- 2566 IF bt = SymTab.InvalidType THEN
|
|
|
- 2567 ELSE
|
|
|
- 2568 IF sfx THEN
|
|
|
- 2569 QbeGen.ElemLoad(q, t,
|
|
|
- 2570 qb);
|
|
|
- 2571 QbeGen.CopyOp(qb, q)
|
|
|
- 2572 END;
|
|
|
- 2573 t := bt;
|
|
|
- 2574 (* q holds the pointee
|
|
|
- 2575 address: Fact loads
|
|
|
- 2576 scalars/pointers and uses
|
|
|
- 2577 the address for
|
|
|
- 2578 aggregates; the VAR-actual
|
|
|
- 2579 note is q itself. *)
|
|
|
- 2580 sfx := TRUE
|
|
|
- 2581 END
|
|
|
- 2582 END; .) } (. astCur := astDes; .) .
|
|
|
- 2583 (* Result suffix (ISO component after a function call): `F()^`,
|
|
|
- 2584 `F()[i]`, `F().field`. The call result is in t/q with sfx FALSE
|
|
|
- 2585 (a value, or a descriptor address for aggregates); each component
|
|
|
- 2586 descends one level exactly like the Design components. *)
|
|
|
- 2587 ResultComp<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal;
|
|
|
- 2588 VAR sfx: BOOLEAN; VAR node: AST.Node> (. VAR it, eT, bt: SymTab.TypeIndex;
|
|
|
- 2589 iq, ql, qlo, qhi, qe, qb:
|
|
|
- 2590 QbeGen.QVal;
|
|
|
- 2591 lo, hi, fo: INTEGER;
|
|
|
- 2592 isOpen: BOOLEAN;
|
|
|
- 2593 fname: SymTab.Name;
|
|
|
- 2594 astWrap, astSel: AST.Node; .)
|
|
|
- 2595 = "[" Expr<it, iq>
|
|
|
- 2596 (. IF AST.Kind(node) # AST.NkDesignator THEN
|
|
|
- 2597 astWrap := AST.MakeNode(
|
|
|
- 2598 AST.NkDesignator);
|
|
|
- 2599 AST.SetChild(astWrap, 0, node);
|
|
|
- 2600 node := astWrap
|
|
|
- 2601 END;
|
|
|
- 2602 AST.SetChild(node, AST.NChild(node),
|
|
|
- 2603 AST.MakeUn(AST.NkSelector,
|
|
|
- 2604 AST.SelIndex, astCur)); IF t = SymTab.InvalidType THEN
|
|
|
- 2605 ELSIF SymTab.ClassOf(t) #
|
|
|
- 2606 SymTab.ClArray THEN
|
|
|
- 2607 SemError(217);
|
|
|
- 2608 t := SymTab.InvalidType
|
|
|
- 2609 ELSIF NOT SymTab.IsIntFamily(it)
|
|
|
- 2610 AND (SymTab.ClassOf(it) # SymTab.ClChar)
|
|
|
- 2611 AND (SymTab.ClassOf(it) # SymTab.ClEnum) THEN
|
|
|
- 2612 SemError(218);
|
|
|
- 2613 t := SymTab.InvalidType
|
|
|
- 2614 ELSE
|
|
|
- 2615 QbeGen.WidenIndex(iq, ql);
|
|
|
- 2616 isOpen :=
|
|
|
- 2617 SymTab.IsOpenArray(t);
|
|
|
- 2618 IF isOpen THEN
|
|
|
- 2619 QbeGen.CopyOp("0", qlo);
|
|
|
- 2620 IF SymTab.IsCharArray(t)
|
|
|
- 2621 OR SymTab.IsUCharArray(t) THEN
|
|
|
- 2622 QbeGen.OpenHiChar(q, qhi)
|
|
|
- 2623 ELSE QbeGen.OpenHi(q, qhi)
|
|
|
- 2624 END
|
|
|
- 2625 ELSE
|
|
|
- 2626 lo := SymTab.ArrayLo(t);
|
|
|
- 2627 hi := SymTab.ArrayHi(t);
|
|
|
- 2628 IF SymTab.IsCharArray(t)
|
|
|
- 2629 OR SymTab.IsUCharArray(t) THEN
|
|
|
- 2630 hi := hi + 1
|
|
|
- 2631 END;
|
|
|
- 2632 QbeGen.IntStr(lo, qlo);
|
|
|
- 2633 QbeGen.IntStr(hi, qhi)
|
|
|
- 2634 END;
|
|
|
- 2635 QbeGen.CheckRange(ql, qlo,
|
|
|
- 2636 qhi);
|
|
|
- 2637 eT := SymTab.ArrayElem(t);
|
|
|
- 2638 QbeGen.ElemAddr(q, ql, qlo,
|
|
|
- 2639 t, qe);
|
|
|
- 2640 IF SymTab.ClassOf(eT) =
|
|
|
- 2641 SymTab.ClArray THEN
|
|
|
- 2642 QbeGen.ElemLoad(qe, eT, q)
|
|
|
- 2643 ELSE QbeGen.CopyOp(qe, q)
|
|
|
- 2644 END;
|
|
|
- 2645 t := eT; sfx := TRUE
|
|
|
- 2646 END; .)
|
|
|
- 2647 "]"
|
|
|
- 2648 | "." GetIdent<fname>
|
|
|
- 2649 (. IF AST.Kind(node) # AST.NkDesignator THEN
|
|
|
- 2650 astWrap := AST.MakeNode(
|
|
|
- 2651 AST.NkDesignator);
|
|
|
- 2652 AST.SetChild(astWrap, 0, node);
|
|
|
- 2653 node := astWrap
|
|
|
- 2654 END;
|
|
|
- 2655 AST.SetChild(node, AST.NChild(node),
|
|
|
- 2656 AST.MakeUn(AST.NkSelector,
|
|
|
- 2657 AST.SelField,
|
|
|
- 2658 AST.MakeLeaf(AST.NkIdent,
|
|
|
- 2659 fname))); IF t = SymTab.InvalidType THEN
|
|
|
- 2660 ELSIF (SymTab.ClassOf(t) #
|
|
|
- 2661 SymTab.ClRecord)
|
|
|
- 2662 AND (SymTab.ClassOf(t) # SymTab.ClClass) THEN
|
|
|
- 2663 SemError(215);
|
|
|
- 2664 t := SymTab.InvalidType
|
|
|
- 2665 ELSIF NOT SymTab.FieldExists(t,
|
|
|
- 2666 fname) THEN
|
|
|
- 2667 SemError(216);
|
|
|
+ 2545 ELSIF NOT SymTab.FieldExists(t,
|
|
|
+ 2546 fn) THEN
|
|
|
+ 2547 SemError(216);
|
|
|
+ 2548 t := SymTab.InvalidType
|
|
|
+ 2549 ELSE
|
|
|
+ 2550 fo := SymTab.FieldOffset(t,
|
|
|
+ 2551 fn);
|
|
|
+ 2552 t := SymTab.FieldType(t, fn);
|
|
|
+ 2553 QbeGen.FieldAddr(q, fo, qe);
|
|
|
+ 2554 (* array fields are inline:
|
|
|
+ 2555 the field address is the
|
|
|
+ 2556 descriptor, like records *)
|
|
|
+ 2557 QbeGen.CopyOp(qe, q);
|
|
|
+ 2558 sfx := TRUE
|
|
|
+ 2559 END; .)
|
|
|
+ 2560 | "^"
|
|
|
+ 2561 (. astSel := AST.MakeNode(AST.NkSelector);
|
|
|
+ 2562 AST.SetOp(astSel, AST.SelDeref);
|
|
|
+ 2563 AST.SetChild(astDes, AST.NChild(astDes), astSel); IF t = SymTab.InvalidType THEN
|
|
|
+ 2564 ELSIF SymTab.ClassOf(t) #
|
|
|
+ 2565 SymTab.ClPtr THEN
|
|
|
+ 2566 SemError(219);
|
|
|
+ 2567 t := SymTab.InvalidType
|
|
|
+ 2568 ELSE
|
|
|
+ 2569 bt := SymTab.PtrBase(t);
|
|
|
+ 2570 IF bt = SymTab.InvalidType THEN
|
|
|
+ 2571 ELSE
|
|
|
+ 2572 IF sfx THEN
|
|
|
+ 2573 QbeGen.ElemLoad(q, t,
|
|
|
+ 2574 qb);
|
|
|
+ 2575 QbeGen.CopyOp(qb, q)
|
|
|
+ 2576 END;
|
|
|
+ 2577 t := bt;
|
|
|
+ 2578 (* q holds the pointee
|
|
|
+ 2579 address: Fact loads
|
|
|
+ 2580 scalars/pointers and uses
|
|
|
+ 2581 the address for
|
|
|
+ 2582 aggregates; the VAR-actual
|
|
|
+ 2583 note is q itself. *)
|
|
|
+ 2584 sfx := TRUE
|
|
|
+ 2585 END
|
|
|
+ 2586 END; .) } (. astCur := astDes; .) .
|
|
|
+ 2587 (* Result suffix (ISO component after a function call): `F()^`,
|
|
|
+ 2588 `F()[i]`, `F().field`. The call result is in t/q with sfx FALSE
|
|
|
+ 2589 (a value, or a descriptor address for aggregates); each component
|
|
|
+ 2590 descends one level exactly like the Design components. *)
|
|
|
+ 2591 ResultComp<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal;
|
|
|
+ 2592 VAR sfx: BOOLEAN; VAR node: AST.Node> (. VAR it, eT, bt: SymTab.TypeIndex;
|
|
|
+ 2593 iq, ql, qlo, qhi, qe, qb:
|
|
|
+ 2594 QbeGen.QVal;
|
|
|
+ 2595 lo, hi, fo: INTEGER;
|
|
|
+ 2596 isOpen: BOOLEAN;
|
|
|
+ 2597 fname: SymTab.Name;
|
|
|
+ 2598 astWrap, astSel: AST.Node; .)
|
|
|
+ 2599 = "[" Expr<it, iq>
|
|
|
+ 2600 (. IF AST.Kind(node) # AST.NkDesignator THEN
|
|
|
+ 2601 astWrap := AST.MakeNode(
|
|
|
+ 2602 AST.NkDesignator);
|
|
|
+ 2603 AST.SetChild(astWrap, 0, node);
|
|
|
+ 2604 node := astWrap
|
|
|
+ 2605 END;
|
|
|
+ 2606 AST.SetChild(node, AST.NChild(node),
|
|
|
+ 2607 AST.MakeUn(AST.NkSelector,
|
|
|
+ 2608 AST.SelIndex, astCur)); IF t = SymTab.InvalidType THEN
|
|
|
+ 2609 ELSIF SymTab.ClassOf(t) #
|
|
|
+ 2610 SymTab.ClArray THEN
|
|
|
+ 2611 SemError(217);
|
|
|
+ 2612 t := SymTab.InvalidType
|
|
|
+ 2613 ELSIF NOT SymTab.IsIntFamily(it)
|
|
|
+ 2614 AND (SymTab.ClassOf(it) # SymTab.ClChar)
|
|
|
+ 2615 AND (SymTab.ClassOf(it) # SymTab.ClEnum) THEN
|
|
|
+ 2616 SemError(218);
|
|
|
+ 2617 t := SymTab.InvalidType
|
|
|
+ 2618 ELSE
|
|
|
+ 2619 QbeGen.WidenIndex(iq, ql);
|
|
|
+ 2620 isOpen :=
|
|
|
+ 2621 SymTab.IsOpenArray(t);
|
|
|
+ 2622 IF isOpen THEN
|
|
|
+ 2623 QbeGen.CopyOp("0", qlo);
|
|
|
+ 2624 IF SymTab.IsCharArray(t)
|
|
|
+ 2625 OR SymTab.IsUCharArray(t) THEN
|
|
|
+ 2626 QbeGen.OpenHiChar(q, qhi)
|
|
|
+ 2627 ELSE QbeGen.OpenHi(q, qhi)
|
|
|
+ 2628 END
|
|
|
+ 2629 ELSE
|
|
|
+ 2630 lo := SymTab.ArrayLo(t);
|
|
|
+ 2631 hi := SymTab.ArrayHi(t);
|
|
|
+ 2632 IF SymTab.IsCharArray(t)
|
|
|
+ 2633 OR SymTab.IsUCharArray(t) THEN
|
|
|
+ 2634 hi := hi + 1
|
|
|
+ 2635 END;
|
|
|
+ 2636 QbeGen.IntStr(lo, qlo);
|
|
|
+ 2637 QbeGen.IntStr(hi, qhi)
|
|
|
+ 2638 END;
|
|
|
+ 2639 QbeGen.CheckRange(ql, qlo,
|
|
|
+ 2640 qhi);
|
|
|
+ 2641 eT := SymTab.ArrayElem(t);
|
|
|
+ 2642 QbeGen.ElemAddr(q, ql, qlo,
|
|
|
+ 2643 t, qe);
|
|
|
+ 2644 IF SymTab.ClassOf(eT) =
|
|
|
+ 2645 SymTab.ClArray THEN
|
|
|
+ 2646 QbeGen.ElemLoad(qe, eT, q)
|
|
|
+ 2647 ELSE QbeGen.CopyOp(qe, q)
|
|
|
+ 2648 END;
|
|
|
+ 2649 t := eT; sfx := TRUE
|
|
|
+ 2650 END; .)
|
|
|
+ 2651 "]"
|
|
|
+ 2652 | "." GetIdent<fname>
|
|
|
+ 2653 (. IF AST.Kind(node) # AST.NkDesignator THEN
|
|
|
+ 2654 astWrap := AST.MakeNode(
|
|
|
+ 2655 AST.NkDesignator);
|
|
|
+ 2656 AST.SetChild(astWrap, 0, node);
|
|
|
+ 2657 node := astWrap
|
|
|
+ 2658 END;
|
|
|
+ 2659 AST.SetChild(node, AST.NChild(node),
|
|
|
+ 2660 AST.MakeUn(AST.NkSelector,
|
|
|
+ 2661 AST.SelField,
|
|
|
+ 2662 AST.MakeLeaf(AST.NkIdent,
|
|
|
+ 2663 fname))); IF t = SymTab.InvalidType THEN
|
|
|
+ 2664 ELSIF (SymTab.ClassOf(t) #
|
|
|
+ 2665 SymTab.ClRecord)
|
|
|
+ 2666 AND (SymTab.ClassOf(t) # SymTab.ClClass) THEN
|
|
|
+ 2667 SemError(215);
|
|
|
2668 t := SymTab.InvalidType
|
|
|
- 2669 ELSE
|
|
|
- 2670 fo := SymTab.FieldOffset(t,
|
|
|
- 2671 fname);
|
|
|
- 2672 t := SymTab.FieldType(t, fname);
|
|
|
- 2673 QbeGen.FieldAddr(q, fo, qe);
|
|
|
- 2674 QbeGen.CopyOp(qe, q);
|
|
|
- 2675 sfx := TRUE
|
|
|
- 2676 END; .)
|
|
|
- 2677 | "^" (. IF AST.Kind(node) # AST.NkDesignator THEN
|
|
|
- 2678 astWrap := AST.MakeNode(
|
|
|
- 2679 AST.NkDesignator);
|
|
|
- 2680 AST.SetChild(astWrap, 0, node);
|
|
|
- 2681 node := astWrap
|
|
|
- 2682 END;
|
|
|
- 2683 astSel := AST.MakeNode(AST.NkSelector);
|
|
|
- 2684 AST.SetOp(astSel, AST.SelDeref);
|
|
|
- 2685 AST.SetChild(node,
|
|
|
- 2686 AST.NChild(node), astSel); IF t = SymTab.InvalidType THEN
|
|
|
- 2687 ELSIF SymTab.ClassOf(t) #
|
|
|
- 2688 SymTab.ClPtr THEN
|
|
|
- 2689 SemError(219);
|
|
|
- 2690 t := SymTab.InvalidType
|
|
|
- 2691 ELSE
|
|
|
- 2692 bt := SymTab.PtrBase(t);
|
|
|
- 2693 IF bt # SymTab.InvalidType THEN
|
|
|
- 2694 IF sfx THEN
|
|
|
- 2695 QbeGen.ElemLoad(q, t, qb);
|
|
|
- 2696 QbeGen.CopyOp(qb, q)
|
|
|
- 2697 END;
|
|
|
- 2698 t := bt; sfx := TRUE
|
|
|
- 2699 END
|
|
|
- 2700 END; .) .
|
|
|
- 2701 Expr<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
- 2702 (. VAR t2: SymTab.TypeIndex;
|
|
|
- 2703 op: INTEGER;
|
|
|
- 2704 q2, qt, wl: QbeGen.QVal;
|
|
|
- 2705 astA, astB: AST.Node;
|
|
|
- 2706 astOp: INTEGER;
|
|
|
- 2707 astMade: BOOLEAN;
|
|
|
- 2708 isR: BOOLEAN; .)
|
|
|
- 2709 = SimExpr<t, q> (. astA := astCur; astMade := FALSE; .)
|
|
|
- 2710 [ Rel<op> SimExpr<t2, q2>
|
|
|
- 2711 (. astB := astCur; astMade := TRUE;
|
|
|
- 2712 astOp := AST.OpEq;
|
|
|
- 2713 IF op = SymTab.OpNeq1 THEN astOp := AST.OpNe
|
|
|
- 2714 ELSIF op = SymTab.OpNeq2 THEN astOp := AST.OpNe
|
|
|
- 2715 ELSIF op = SymTab.OpLt THEN astOp := AST.OpLt
|
|
|
- 2716 ELSIF op = SymTab.OpLe THEN astOp := AST.OpLe
|
|
|
- 2717 ELSIF op = SymTab.OpGt THEN astOp := AST.OpGt
|
|
|
- 2718 ELSIF op = SymTab.OpGe THEN astOp := AST.OpGe
|
|
|
- 2719 ELSIF op = SymTab.OpIn THEN astOp := AST.OpIn
|
|
|
- 2720 END;
|
|
|
- 2721 IF op = SymTab.OpIn THEN
|
|
|
- 2722 IF SymTab.InCheck(t, t2) THEN
|
|
|
- 2723 IF (t = SymTab.InvalidType)
|
|
|
- 2724 OR (t2 = SymTab.InvalidType) THEN
|
|
|
- 2725 t := SymTab.BoolType(); QbeGen.CopyOp("0", q)
|
|
|
- 2726 ELSE
|
|
|
- 2727 QbeGen.InSet(q, q2, SymTab.SetBaseLo(t2),
|
|
|
- 2728 SymTab.SetCount(t2), qt);
|
|
|
- 2729 t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
|
|
|
- 2730 END
|
|
|
- 2731 ELSE SemError(222); t := SymTab.InvalidType;
|
|
|
- 2732 QbeGen.CopyOp("0", q)
|
|
|
- 2733 END
|
|
|
- 2734 ELSIF SymTab.RelCheck(t, t2, op) THEN
|
|
|
- 2735 IF (t = SymTab.InvalidType)
|
|
|
- 2736 OR (t2 = SymTab.InvalidType) THEN
|
|
|
- 2737 t := SymTab.BoolType(); QbeGen.CopyOp("0", q)
|
|
|
- 2738 ELSIF (SymTab.ClassOf(t) = SymTab.ClPtr)
|
|
|
- 2739 OR (SymTab.ClassOf(t2) = SymTab.ClPtr) THEN
|
|
|
- 2740 IF SymTab.IsFwdVar(t) OR SymTab.IsFwdVar(t2) THEN
|
|
|
- 2741 QbeGen.Cmp(op, q, q2, qt, FALSE);
|
|
|
- 2742 t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
|
|
|
- 2743 ELSIF (op # SymTab.OpEq) AND (op # SymTab.OpNeq1)
|
|
|
- 2744 AND (op # SymTab.OpNeq2) THEN
|
|
|
- 2745 SemError(213); t := SymTab.InvalidType;
|
|
|
- 2746 QbeGen.CopyOp("0", q)
|
|
|
- 2747 ELSE
|
|
|
- 2748 QbeGen.CmpL(op, q, q2, qt);
|
|
|
- 2749 t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
|
|
|
- 2750 END
|
|
|
- 2751 ELSIF (SymTab.ClassOf(t) = SymTab.ClSet)
|
|
|
- 2752 OR (SymTab.ClassOf(t2) = SymTab.ClSet) THEN
|
|
|
- 2753 QbeGen.CmpSet(op, q, q2,
|
|
|
- 2754 SymTab.SetWords(t), SymTab.SetWords(t2), qt);
|
|
|
- 2755 t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
|
|
|
- 2756 ELSIF SymTab.StrCompat(t, t2) THEN
|
|
|
- 2757 QbeGen.StrEq(op, q, q2, qt);
|
|
|
- 2758 t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
|
|
|
- 2759 ELSIF SymTab.IsLongFamily(t)
|
|
|
- 2760 OR SymTab.IsLongFamily(t2) THEN
|
|
|
- 2761 IF SymTab.IsIntFamily(t) THEN
|
|
|
- 2762 QbeGen.WidenLong(q, wl); QbeGen.CopyOp(wl, q)
|
|
|
- 2763 END;
|
|
|
- 2764 IF SymTab.IsIntFamily(t2) THEN
|
|
|
- 2765 QbeGen.WidenLong(q2, wl); QbeGen.CopyOp(wl, q2)
|
|
|
- 2766 END;
|
|
|
- 2767 QbeGen.CmpLong(op, q, q2, qt);
|
|
|
- 2768 t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
|
|
|
- 2769 ELSE
|
|
|
- 2770 isR := SymTab.ClassOf(t) = SymTab.ClReal;
|
|
|
- 2771 t := SymTab.BoolType();
|
|
|
- 2772 QbeGen.Cmp(op, q, q2, qt, isR);
|
|
|
- 2773 QbeGen.CopyOp(qt, q)
|
|
|
- 2774 END
|
|
|
- 2775 ELSE SemError(213); t := SymTab.InvalidType;
|
|
|
- 2776 QbeGen.CopyOp("0", q)
|
|
|
- 2777 END;
|
|
|
- 2778 astCur := AST.MakeBin(AST.NkBinExpr, astOp, astA, astB); .) ]
|
|
|
- 2779 (. IF NOT astMade THEN astCur := astA END; .) .
|
|
|
- 2780 Rel<VAR op: INTEGER>
|
|
|
- 2781 = "=" (. op := SymTab.OpEq; .)
|
|
|
- 2782 | "#" (. op := SymTab.OpNeq1; .)
|
|
|
- 2783 | "<" (. op := SymTab.OpLt; .)
|
|
|
- 2784 | "<=" (. op := SymTab.OpLe; .)
|
|
|
- 2785 | ">" (. op := SymTab.OpGt; .)
|
|
|
- 2786 | ">=" (. op := SymTab.OpGe; .)
|
|
|
- 2787 | "IN" (. op := SymTab.OpIn; .) .
|
|
|
- 2788 SimExpr<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
- 2789 (. VAR t2, res2, lt, rt:
|
|
|
- 2790 SymTab.TypeIndex;
|
|
|
- 2791 op: INTEGER;
|
|
|
- 2792 q2, qt, wq, qf, q2a, q2b:
|
|
|
- 2793 QbeGen.QVal;
|
|
|
- 2794 neg, isR, isL, folded:
|
|
|
- 2795 BOOLEAN;
|
|
|
- 2796 fok: BOOLEAN;
|
|
|
- 2797 lw, rw, mw: CARDINAL;
|
|
|
- 2798 lTrue, lNext, lDone, qr, qs: QbeGen.QVal;
|
|
|
- 2799 astA, astB: AST.Node;
|
|
|
- 2800 astSign, astOp: INTEGER; .)
|
|
|
- 2801 = (. neg := FALSE; astSign := 0; .)
|
|
|
- 2802 [ "+" (. neg := TRUE; astSign := 1; .)
|
|
|
- 2803 | "-" (. neg := TRUE; astSign := -1; .) ]
|
|
|
- 2804 Term<t, q> (. astA := astCur; IF neg THEN
|
|
|
- 2805 IF QbeGen.IsImm(q) THEN
|
|
|
- 2806 QbeGen.NegFold(q, q)
|
|
|
- 2807 ELSE QbeGen.NewTemp(qt);
|
|
|
- 2808 QbeGen.NegQ(q, qt,
|
|
|
- 2809 SymTab.ClassOf(t)
|
|
|
- 2810 = SymTab.ClReal);
|
|
|
- 2811 QbeGen.CopyOp(qt, q)
|
|
|
- 2812 END
|
|
|
- 2813 END;
|
|
|
- 2814 IF astSign < 0 THEN
|
|
|
- 2815 astCur := AST.MakeUn(
|
|
|
- 2816 AST.NkUnary, AST.OpSub, astA);
|
|
|
- 2817 astA := astCur
|
|
|
- 2818 END; .)
|
|
|
- 2819 { AddOp<op> (. IF op = SymTab.OpOr THEN
|
|
|
- 2820 QbeGen.DelayBegin END; .)
|
|
|
- 2821 Term<t2, q2> (. astB := astCur; IF op = SymTab.OpOr THEN
|
|
|
- 2822 QbeGen.DelayEnd END; .)
|
|
|
- 2823 (. astOp := AST.OpAdd;
|
|
|
- 2824 IF op = SymTab.OpSub THEN astOp := AST.OpSub
|
|
|
- 2825 ELSIF op = SymTab.OpOr THEN astOp := AST.OpOr END;
|
|
|
- 2826 astA := AST.MakeBin(AST.NkBinExpr, astOp, astA, astB);
|
|
|
- 2827 astCur := astA;
|
|
|
- 2828 IF op = SymTab.OpOr THEN
|
|
|
- 2829 (* short-circuit: if q is true the RHS is skipped *)
|
|
|
- 2830 IF SymTab.BoolCheck(t) AND SymTab.BoolCheck(t2) THEN
|
|
|
- 2831 t := SymTab.BoolType()
|
|
|
- 2832 ELSE SemError(212); t := SymTab.InvalidType END;
|
|
|
- 2833 IF t # SymTab.InvalidType THEN
|
|
|
- 2834 QbeGen.Slot4(qs);
|
|
|
- 2835 QbeGen.NewLabel(lTrue);
|
|
|
- 2836 QbeGen.NewLabel(lNext);
|
|
|
- 2837 QbeGen.NewLabel(lDone);
|
|
|
- 2838 QbeGen.Jnz(q, lTrue, lNext);
|
|
|
- 2839 QbeGen.EmitLabel(lTrue);
|
|
|
- 2840 QbeGen.StoreW(qs, "1");
|
|
|
- 2841 QbeGen.Jmp(lDone);
|
|
|
- 2842 QbeGen.EmitLabel(lNext);
|
|
|
- 2843 QbeGen.DelayFlush;
|
|
|
- 2844 QbeGen.StoreW(qs, q2);
|
|
|
+ 2669 ELSIF NOT SymTab.FieldExists(t,
|
|
|
+ 2670 fname) THEN
|
|
|
+ 2671 SemError(216);
|
|
|
+ 2672 t := SymTab.InvalidType
|
|
|
+ 2673 ELSE
|
|
|
+ 2674 fo := SymTab.FieldOffset(t,
|
|
|
+ 2675 fname);
|
|
|
+ 2676 t := SymTab.FieldType(t, fname);
|
|
|
+ 2677 QbeGen.FieldAddr(q, fo, qe);
|
|
|
+ 2678 QbeGen.CopyOp(qe, q);
|
|
|
+ 2679 sfx := TRUE
|
|
|
+ 2680 END; .)
|
|
|
+ 2681 | "^" (. IF AST.Kind(node) # AST.NkDesignator THEN
|
|
|
+ 2682 astWrap := AST.MakeNode(
|
|
|
+ 2683 AST.NkDesignator);
|
|
|
+ 2684 AST.SetChild(astWrap, 0, node);
|
|
|
+ 2685 node := astWrap
|
|
|
+ 2686 END;
|
|
|
+ 2687 astSel := AST.MakeNode(AST.NkSelector);
|
|
|
+ 2688 AST.SetOp(astSel, AST.SelDeref);
|
|
|
+ 2689 AST.SetChild(node,
|
|
|
+ 2690 AST.NChild(node), astSel); IF t = SymTab.InvalidType THEN
|
|
|
+ 2691 ELSIF SymTab.ClassOf(t) #
|
|
|
+ 2692 SymTab.ClPtr THEN
|
|
|
+ 2693 SemError(219);
|
|
|
+ 2694 t := SymTab.InvalidType
|
|
|
+ 2695 ELSE
|
|
|
+ 2696 bt := SymTab.PtrBase(t);
|
|
|
+ 2697 IF bt # SymTab.InvalidType THEN
|
|
|
+ 2698 IF sfx THEN
|
|
|
+ 2699 QbeGen.ElemLoad(q, t, qb);
|
|
|
+ 2700 QbeGen.CopyOp(qb, q)
|
|
|
+ 2701 END;
|
|
|
+ 2702 t := bt; sfx := TRUE
|
|
|
+ 2703 END
|
|
|
+ 2704 END; .) .
|
|
|
+ 2705 Expr<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
+ 2706 (. VAR t2: SymTab.TypeIndex;
|
|
|
+ 2707 op: INTEGER;
|
|
|
+ 2708 q2, qt, wl: QbeGen.QVal;
|
|
|
+ 2709 astA, astB: AST.Node;
|
|
|
+ 2710 astOp: INTEGER;
|
|
|
+ 2711 astMade: BOOLEAN;
|
|
|
+ 2712 isR: BOOLEAN; .)
|
|
|
+ 2713 = SimExpr<t, q> (. astA := astCur; astMade := FALSE; .)
|
|
|
+ 2714 [ Rel<op> SimExpr<t2, q2>
|
|
|
+ 2715 (. astB := astCur; astMade := TRUE;
|
|
|
+ 2716 astOp := AST.OpEq;
|
|
|
+ 2717 IF op = SymTab.OpNeq1 THEN astOp := AST.OpNe
|
|
|
+ 2718 ELSIF op = SymTab.OpNeq2 THEN astOp := AST.OpNe
|
|
|
+ 2719 ELSIF op = SymTab.OpLt THEN astOp := AST.OpLt
|
|
|
+ 2720 ELSIF op = SymTab.OpLe THEN astOp := AST.OpLe
|
|
|
+ 2721 ELSIF op = SymTab.OpGt THEN astOp := AST.OpGt
|
|
|
+ 2722 ELSIF op = SymTab.OpGe THEN astOp := AST.OpGe
|
|
|
+ 2723 ELSIF op = SymTab.OpIn THEN astOp := AST.OpIn
|
|
|
+ 2724 END;
|
|
|
+ 2725 IF op = SymTab.OpIn THEN
|
|
|
+ 2726 IF SymTab.InCheck(t, t2) THEN
|
|
|
+ 2727 IF (t = SymTab.InvalidType)
|
|
|
+ 2728 OR (t2 = SymTab.InvalidType) THEN
|
|
|
+ 2729 t := SymTab.BoolType(); QbeGen.CopyOp("0", q)
|
|
|
+ 2730 ELSE
|
|
|
+ 2731 QbeGen.InSet(q, q2, SymTab.SetBaseLo(t2),
|
|
|
+ 2732 SymTab.SetCount(t2), qt);
|
|
|
+ 2733 t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
|
|
|
+ 2734 END
|
|
|
+ 2735 ELSE SemError(222); t := SymTab.InvalidType;
|
|
|
+ 2736 QbeGen.CopyOp("0", q)
|
|
|
+ 2737 END
|
|
|
+ 2738 ELSIF SymTab.RelCheck(t, t2, op) THEN
|
|
|
+ 2739 IF (t = SymTab.InvalidType)
|
|
|
+ 2740 OR (t2 = SymTab.InvalidType) THEN
|
|
|
+ 2741 t := SymTab.BoolType(); QbeGen.CopyOp("0", q)
|
|
|
+ 2742 ELSIF (SymTab.ClassOf(t) = SymTab.ClPtr)
|
|
|
+ 2743 OR (SymTab.ClassOf(t2) = SymTab.ClPtr) THEN
|
|
|
+ 2744 IF SymTab.IsFwdVar(t) OR SymTab.IsFwdVar(t2) THEN
|
|
|
+ 2745 QbeGen.Cmp(op, q, q2, qt, FALSE);
|
|
|
+ 2746 t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
|
|
|
+ 2747 ELSIF (op # SymTab.OpEq) AND (op # SymTab.OpNeq1)
|
|
|
+ 2748 AND (op # SymTab.OpNeq2) THEN
|
|
|
+ 2749 SemError(213); t := SymTab.InvalidType;
|
|
|
+ 2750 QbeGen.CopyOp("0", q)
|
|
|
+ 2751 ELSE
|
|
|
+ 2752 QbeGen.CmpL(op, q, q2, qt);
|
|
|
+ 2753 t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
|
|
|
+ 2754 END
|
|
|
+ 2755 ELSIF (SymTab.ClassOf(t) = SymTab.ClSet)
|
|
|
+ 2756 OR (SymTab.ClassOf(t2) = SymTab.ClSet) THEN
|
|
|
+ 2757 QbeGen.CmpSet(op, q, q2,
|
|
|
+ 2758 SymTab.SetWords(t), SymTab.SetWords(t2), qt);
|
|
|
+ 2759 t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
|
|
|
+ 2760 ELSIF SymTab.StrCompat(t, t2) THEN
|
|
|
+ 2761 QbeGen.StrEq(op, q, q2, qt);
|
|
|
+ 2762 t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
|
|
|
+ 2763 ELSIF SymTab.IsLongFamily(t)
|
|
|
+ 2764 OR SymTab.IsLongFamily(t2) THEN
|
|
|
+ 2765 IF SymTab.IsIntFamily(t) THEN
|
|
|
+ 2766 QbeGen.WidenLong(q, wl); QbeGen.CopyOp(wl, q)
|
|
|
+ 2767 END;
|
|
|
+ 2768 IF SymTab.IsIntFamily(t2) THEN
|
|
|
+ 2769 QbeGen.WidenLong(q2, wl); QbeGen.CopyOp(wl, q2)
|
|
|
+ 2770 END;
|
|
|
+ 2771 QbeGen.CmpLong(op, q, q2, qt);
|
|
|
+ 2772 t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
|
|
|
+ 2773 ELSE
|
|
|
+ 2774 isR := SymTab.ClassOf(t) = SymTab.ClReal;
|
|
|
+ 2775 t := SymTab.BoolType();
|
|
|
+ 2776 QbeGen.Cmp(op, q, q2, qt, isR);
|
|
|
+ 2777 QbeGen.CopyOp(qt, q)
|
|
|
+ 2778 END
|
|
|
+ 2779 ELSE SemError(213); t := SymTab.InvalidType;
|
|
|
+ 2780 QbeGen.CopyOp("0", q)
|
|
|
+ 2781 END;
|
|
|
+ 2782 astCur := AST.MakeBin(AST.NkBinExpr, astOp, astA, astB); .) ]
|
|
|
+ 2783 (. IF NOT astMade THEN astCur := astA END; .) .
|
|
|
+ 2784 Rel<VAR op: INTEGER>
|
|
|
+ 2785 = "=" (. op := SymTab.OpEq; .)
|
|
|
+ 2786 | "#" (. op := SymTab.OpNeq1; .)
|
|
|
+ 2787 | "<" (. op := SymTab.OpLt; .)
|
|
|
+ 2788 | "<=" (. op := SymTab.OpLe; .)
|
|
|
+ 2789 | ">" (. op := SymTab.OpGt; .)
|
|
|
+ 2790 | ">=" (. op := SymTab.OpGe; .)
|
|
|
+ 2791 | "IN" (. op := SymTab.OpIn; .) .
|
|
|
+ 2792 SimExpr<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
+ 2793 (. VAR t2, res2, lt, rt:
|
|
|
+ 2794 SymTab.TypeIndex;
|
|
|
+ 2795 op: INTEGER;
|
|
|
+ 2796 q2, qt, wq, qf, q2a, q2b:
|
|
|
+ 2797 QbeGen.QVal;
|
|
|
+ 2798 neg, isR, isL, folded:
|
|
|
+ 2799 BOOLEAN;
|
|
|
+ 2800 fok: BOOLEAN;
|
|
|
+ 2801 lw, rw, mw: CARDINAL;
|
|
|
+ 2802 lTrue, lNext, lDone, qr, qs: QbeGen.QVal;
|
|
|
+ 2803 astA, astB: AST.Node;
|
|
|
+ 2804 astSign, astOp: INTEGER; .)
|
|
|
+ 2805 = (. neg := FALSE; astSign := 0; .)
|
|
|
+ 2806 [ "+" (. neg := TRUE; astSign := 1; .)
|
|
|
+ 2807 | "-" (. neg := TRUE; astSign := -1; .) ]
|
|
|
+ 2808 Term<t, q> (. astA := astCur; IF neg THEN
|
|
|
+ 2809 IF QbeGen.IsImm(q) THEN
|
|
|
+ 2810 QbeGen.NegFold(q, q)
|
|
|
+ 2811 ELSE QbeGen.NewTemp(qt);
|
|
|
+ 2812 QbeGen.NegQ(q, qt,
|
|
|
+ 2813 SymTab.ClassOf(t)
|
|
|
+ 2814 = SymTab.ClReal);
|
|
|
+ 2815 QbeGen.CopyOp(qt, q)
|
|
|
+ 2816 END
|
|
|
+ 2817 END;
|
|
|
+ 2818 IF astSign < 0 THEN
|
|
|
+ 2819 astCur := AST.MakeUn(
|
|
|
+ 2820 AST.NkUnary, AST.OpSub, astA);
|
|
|
+ 2821 astA := astCur
|
|
|
+ 2822 END; .)
|
|
|
+ 2823 { AddOp<op> (. IF op = SymTab.OpOr THEN
|
|
|
+ 2824 QbeGen.DelayBegin END; .)
|
|
|
+ 2825 Term<t2, q2> (. astB := astCur; IF op = SymTab.OpOr THEN
|
|
|
+ 2826 QbeGen.DelayEnd END; .)
|
|
|
+ 2827 (. astOp := AST.OpAdd;
|
|
|
+ 2828 IF op = SymTab.OpSub THEN astOp := AST.OpSub
|
|
|
+ 2829 ELSIF op = SymTab.OpOr THEN astOp := AST.OpOr END;
|
|
|
+ 2830 astA := AST.MakeBin(AST.NkBinExpr, astOp, astA, astB);
|
|
|
+ 2831 astCur := astA;
|
|
|
+ 2832 IF op = SymTab.OpOr THEN
|
|
|
+ 2833 (* short-circuit: if q is true the RHS is skipped *)
|
|
|
+ 2834 IF SymTab.BoolCheck(t) AND SymTab.BoolCheck(t2) THEN
|
|
|
+ 2835 t := SymTab.BoolType()
|
|
|
+ 2836 ELSE SemError(212); t := SymTab.InvalidType END;
|
|
|
+ 2837 IF t # SymTab.InvalidType THEN
|
|
|
+ 2838 QbeGen.Slot4(qs);
|
|
|
+ 2839 QbeGen.NewLabel(lTrue);
|
|
|
+ 2840 QbeGen.NewLabel(lNext);
|
|
|
+ 2841 QbeGen.NewLabel(lDone);
|
|
|
+ 2842 QbeGen.Jnz(q, lTrue, lNext);
|
|
|
+ 2843 QbeGen.EmitLabel(lTrue);
|
|
|
+ 2844 QbeGen.StoreW(qs, "1");
|
|
|
2845 QbeGen.Jmp(lDone);
|
|
|
- 2846 QbeGen.EmitLabel(lDone);
|
|
|
- 2847 QbeGen.LoadW(qs, qr);
|
|
|
- 2848 QbeGen.CopyOp(qr, q)
|
|
|
- 2849 ELSE QbeGen.DelayFlush; QbeGen.CopyOp("0", q)
|
|
|
- 2850 END
|
|
|
- 2851 ELSIF (op = SymTab.OpAdd)
|
|
|
- 2852 AND (SymTab.UStrCompat(t, t2)
|
|
|
- 2853 OR ((SymTab.ClassOf(t) = SymTab.ClUChar)
|
|
|
- 2854 AND (SymTab.ClassOf(t2) = SymTab.ClUStr))
|
|
|
- 2855 OR ((SymTab.ClassOf(t) = SymTab.ClUStr)
|
|
|
- 2856 AND (SymTab.ClassOf(t2) = SymTab.ClUChar))
|
|
|
+ 2846 QbeGen.EmitLabel(lNext);
|
|
|
+ 2847 QbeGen.DelayFlush;
|
|
|
+ 2848 QbeGen.StoreW(qs, q2);
|
|
|
+ 2849 QbeGen.Jmp(lDone);
|
|
|
+ 2850 QbeGen.EmitLabel(lDone);
|
|
|
+ 2851 QbeGen.LoadW(qs, qr);
|
|
|
+ 2852 QbeGen.CopyOp(qr, q)
|
|
|
+ 2853 ELSE QbeGen.DelayFlush; QbeGen.CopyOp("0", q)
|
|
|
+ 2854 END
|
|
|
+ 2855 ELSIF (op = SymTab.OpAdd)
|
|
|
+ 2856 AND (SymTab.UStrCompat(t, t2)
|
|
|
2857 OR ((SymTab.ClassOf(t) = SymTab.ClUChar)
|
|
|
- 2858 AND (SymTab.ClassOf(t2) = SymTab.ClUChar))) THEN
|
|
|
- 2859 (* UString concatenation: a UCHAR operand becomes a
|
|
|
- 2860 1-codepoint UString; the result is a descriptor in the
|
|
|
- 2861 shim's concat buffer. Work on copies so neither
|
|
|
- 2862 operand is clobbered. *)
|
|
|
- 2863 IF SymTab.ClassOf(t) = SymTab.ClUStr THEN
|
|
|
- 2864 QbeGen.CopyOp(q, q2a)
|
|
|
- 2865 ELSE
|
|
|
- 2866 QbeGen.UStrFrom(q, q2a)
|
|
|
- 2867 END;
|
|
|
- 2868 IF SymTab.ClassOf(t2) = SymTab.ClUStr THEN
|
|
|
- 2869 QbeGen.UStrCat(q2a, q2, qt)
|
|
|
- 2870 ELSE
|
|
|
- 2871 QbeGen.UStrFrom(q2, q2b);
|
|
|
- 2872 QbeGen.UStrCat(q2a, q2b, qt)
|
|
|
- 2873 END;
|
|
|
- 2874 t := SymTab.NewUStr();
|
|
|
- 2875 QbeGen.CopyOp(qt, q)
|
|
|
- 2876 ELSIF (op = SymTab.OpAdd)
|
|
|
- 2877 AND (SymTab.StrCompat(t, t2)
|
|
|
- 2878 OR (SymTab.IsStrType(t)
|
|
|
- 2879 AND (SymTab.ClassOf(t2) = SymTab.ClChar))
|
|
|
- 2880 OR ((SymTab.ClassOf(t) = SymTab.ClChar)
|
|
|
- 2881 AND SymTab.IsStrType(t2))) THEN
|
|
|
- 2882 (* string concatenation; a CHAR operand becomes a
|
|
|
- 2883 1-character string literal. When both operands are
|
|
|
- 2884 constants, fold to a single string literal so a
|
|
|
- 2885 constructor element stays compile-time. *)
|
|
|
- 2886 QbeGen.StrFold(q, q2, SymTab.ClassOf(t), SymTab.ClassOf(t2),
|
|
|
- 2887 qt, fok);
|
|
|
- 2888 IF NOT fok THEN
|
|
|
- 2889 IF SymTab.StrCompat(t, t2) THEN
|
|
|
- 2890 QbeGen.StrCat(q, q2, qt)
|
|
|
- 2891 ELSIF SymTab.IsStrType(t) THEN
|
|
|
- 2892 QbeGen.DeclCharStr(q2, qs);
|
|
|
- 2893 QbeGen.StrCat(q, qs, qt)
|
|
|
- 2894 ELSE
|
|
|
- 2895 QbeGen.DeclCharStr(q, qs);
|
|
|
- 2896 QbeGen.StrCat(qs, q2, qt)
|
|
|
- 2897 END
|
|
|
- 2898 END;
|
|
|
- 2899 t := SymTab.NewStr();
|
|
|
- 2900 QbeGen.CopyOp(qt, q)
|
|
|
- 2901 ELSIF (t # SymTab.InvalidType) AND (t2 # SymTab.InvalidType)
|
|
|
- 2902 AND (SymTab.ClassOf(t) = SymTab.ClSet)
|
|
|
- 2903 AND (SymTab.ClassOf(t2) = SymTab.ClSet) THEN
|
|
|
- 2904 lw := SymTab.SetWords(t); rw := SymTab.SetWords(t2);
|
|
|
- 2905 mw := lw;
|
|
|
- 2906 IF rw > mw THEN mw := rw END;
|
|
|
- 2907 IF op = SymTab.OpAdd THEN
|
|
|
- 2908 QbeGen.SetBinOp(0, q, q2, lw, rw, qt)
|
|
|
- 2909 ELSE
|
|
|
- 2910 QbeGen.SetBinOp(2, q, q2, lw, rw, qt)
|
|
|
- 2911 END;
|
|
|
- 2912 t := SymTab.NewSet(
|
|
|
- 2913 SymTab.NewSubR(0,
|
|
|
- 2914 VAL(INTEGER, mw) * 32 - 1));
|
|
|
- 2915 QbeGen.CopyOp(qt, q)
|
|
|
- 2916 ELSE
|
|
|
- 2917 IF SymTab.ArithCheck(t, t2, FALSE, res2) THEN
|
|
|
- 2918 lt := t; rt := t2; t := res2
|
|
|
- 2919 ELSE SemError(211); t := SymTab.InvalidType END;
|
|
|
- 2920 IF t # SymTab.InvalidType THEN
|
|
|
- 2921 isL := SymTab.IsLongFamily(t);
|
|
|
- 2922 isR := SymTab.ClassOf(t) = SymTab.ClReal;
|
|
|
- 2923 folded := FALSE;
|
|
|
- 2924 IF (NOT isL) AND (NOT isR)
|
|
|
- 2925 AND QbeGen.IsImm(q) AND QbeGen.IsImm(q2) THEN
|
|
|
- 2926 IF op = SymTab.OpAdd THEN
|
|
|
- 2927 folded := QbeGen.Fold2(0, q, q2, qf)
|
|
|
- 2928 ELSE
|
|
|
- 2929 folded := QbeGen.Fold2(1, q, q2, qf)
|
|
|
- 2930 END
|
|
|
- 2931 END;
|
|
|
- 2932 IF folded THEN QbeGen.CopyOp(qf, q)
|
|
|
- 2933 ELSE
|
|
|
- 2934 IF isL THEN
|
|
|
- 2935 IF SymTab.IsIntFamily(lt) THEN
|
|
|
- 2936 QbeGen.WidenLong(q, wq); QbeGen.CopyOp(wq, q)
|
|
|
- 2937 END;
|
|
|
- 2938 IF SymTab.IsIntFamily(rt) THEN
|
|
|
- 2939 QbeGen.WidenLong(q2, wq); QbeGen.CopyOp(wq, q2)
|
|
|
- 2940 END;
|
|
|
- 2941 QbeGen.NewTemp(qt);
|
|
|
- 2942 IF op = SymTab.OpAdd THEN
|
|
|
- 2943 QbeGen.Op3L("add", qt, q, q2)
|
|
|
- 2944 ELSE
|
|
|
- 2945 QbeGen.Op3L("sub", qt, q, q2)
|
|
|
- 2946 END
|
|
|
- 2947 ELSE
|
|
|
- 2948 QbeGen.NewTemp(qt);
|
|
|
- 2949 IF op = SymTab.OpAdd THEN
|
|
|
- 2950 QbeGen.Op3("add", qt, q, q2, isR)
|
|
|
- 2951 ELSE
|
|
|
- 2952 QbeGen.Op3("sub", qt, q, q2, isR)
|
|
|
- 2953 END
|
|
|
- 2954 END;
|
|
|
- 2955 QbeGen.CopyOp(qt, q)
|
|
|
- 2956 END
|
|
|
- 2957 ELSE QbeGen.CopyOp("0", q)
|
|
|
- 2958 END
|
|
|
- 2959 END; .) } .
|
|
|
- 2960 AddOp<VAR op: INTEGER>
|
|
|
- 2961 = "+" (. op := SymTab.OpAdd; .)
|
|
|
- 2962 | "-" (. op := SymTab.OpSub; .)
|
|
|
- 2963 | "OR" (. op := SymTab.OpOr; .) .
|
|
|
- 2964 Term<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
- 2965 (. VAR t2, res2, lt, rt:
|
|
|
- 2966 SymTab.TypeIndex;
|
|
|
- 2967 op: INTEGER;
|
|
|
- 2968 q2, qt, wq, qf:
|
|
|
- 2969 QbeGen.QVal;
|
|
|
- 2970 isR, isL, folded: BOOLEAN;
|
|
|
- 2971 lw, rw, mw: CARDINAL;
|
|
|
- 2972 lNext, lFalse, lDone, qr, qs: QbeGen.QVal;
|
|
|
- 2973 astA, astB: AST.Node;
|
|
|
- 2974 astOp: INTEGER; .)
|
|
|
- 2975 = Fact<t, q> (. astA := astCur; .) { MulOp<op> (. IF op = SymTab.OpAnd THEN
|
|
|
- 2976 QbeGen.DelayBegin END; .)
|
|
|
- 2977 Fact<t2, q2> (. astB := astCur; IF op = SymTab.OpAnd THEN
|
|
|
- 2978 QbeGen.DelayEnd END; .)
|
|
|
- 2979 (. astOp := AST.OpMul;
|
|
|
- 2980 IF op = SymTab.OpSlash THEN astOp := AST.OpDiv
|
|
|
- 2981 ELSIF op = SymTab.OpDiv THEN astOp := AST.OpDiv
|
|
|
- 2982 ELSIF op = SymTab.OpMod THEN astOp := AST.OpMod
|
|
|
- 2983 ELSIF op = SymTab.OpAnd THEN astOp := AST.OpAnd END;
|
|
|
- 2984 astA := AST.MakeBin(AST.NkBinExpr, astOp, astA, astB);
|
|
|
- 2985 astCur := astA;
|
|
|
- 2986 IF op = SymTab.OpAnd THEN
|
|
|
- 2987 (* short-circuit: if q is false the RHS is skipped *)
|
|
|
- 2988 IF SymTab.BoolCheck(t) AND SymTab.BoolCheck(t2) THEN
|
|
|
- 2989 t := SymTab.BoolType()
|
|
|
- 2990 ELSE SemError(212); t := SymTab.InvalidType END;
|
|
|
- 2991 IF t # SymTab.InvalidType THEN
|
|
|
- 2992 QbeGen.Slot4(qs);
|
|
|
- 2993 QbeGen.NewLabel(lNext);
|
|
|
- 2994 QbeGen.NewLabel(lFalse);
|
|
|
- 2995 QbeGen.NewLabel(lDone);
|
|
|
- 2996 QbeGen.Jnz(q, lNext, lFalse);
|
|
|
- 2997 QbeGen.EmitLabel(lNext);
|
|
|
- 2998 QbeGen.DelayFlush;
|
|
|
- 2999 QbeGen.StoreW(qs, q2);
|
|
|
- 3000 QbeGen.Jmp(lDone);
|
|
|
- 3001 QbeGen.EmitLabel(lFalse);
|
|
|
- 3002 QbeGen.StoreW(qs, "0");
|
|
|
- 3003 QbeGen.Jmp(lDone);
|
|
|
- 3004 QbeGen.EmitLabel(lDone);
|
|
|
- 3005 QbeGen.LoadW(qs, qr);
|
|
|
- 3006 QbeGen.CopyOp(qr, q)
|
|
|
- 3007 ELSE QbeGen.DelayFlush; QbeGen.CopyOp("0", q)
|
|
|
- 3008 END
|
|
|
- 3009 ELSIF (t # SymTab.InvalidType) AND (t2 # SymTab.InvalidType)
|
|
|
- 3010 AND (SymTab.ClassOf(t) = SymTab.ClSet)
|
|
|
- 3011 AND (SymTab.ClassOf(t2) = SymTab.ClSet) THEN
|
|
|
- 3012 lw := SymTab.SetWords(t); rw := SymTab.SetWords(t2);
|
|
|
- 3013 mw := lw;
|
|
|
- 3014 IF rw > mw THEN mw := rw END;
|
|
|
- 3015 IF op = SymTab.OpTimes THEN
|
|
|
- 3016 QbeGen.SetBinOp(1, q, q2, lw, rw, qt)
|
|
|
- 3017 ELSE
|
|
|
- 3018 QbeGen.SetBinOp(3, q, q2, lw, rw, qt)
|
|
|
- 3019 END;
|
|
|
- 3020 t := SymTab.NewSet(
|
|
|
- 3021 SymTab.NewSubR(0,
|
|
|
- 3022 VAL(INTEGER, mw) * 32 - 1));
|
|
|
- 3023 QbeGen.CopyOp(qt, q)
|
|
|
- 3024 ELSE
|
|
|
- 3025 IF SymTab.ArithCheck(t, t2,
|
|
|
- 3026 (op = SymTab.OpDiv) OR (op = SymTab.OpMod),
|
|
|
- 3027 res2) THEN
|
|
|
- 3028 lt := t; rt := t2; t := res2
|
|
|
- 3029 ELSE SemError(211); t := SymTab.InvalidType END;
|
|
|
- 3030 IF t # SymTab.InvalidType THEN
|
|
|
- 3031 isL := SymTab.IsLongFamily(t);
|
|
|
- 3032 isR := SymTab.ClassOf(t) = SymTab.ClReal;
|
|
|
- 3033 folded := FALSE;
|
|
|
- 3034 IF (NOT isL) AND (NOT isR)
|
|
|
- 3035 AND QbeGen.IsImm(q) AND QbeGen.IsImm(q2) THEN
|
|
|
- 3036 IF op = SymTab.OpTimes THEN
|
|
|
- 3037 folded := QbeGen.Fold2(2, q, q2, qf)
|
|
|
- 3038 ELSIF op = SymTab.OpDiv THEN
|
|
|
- 3039 folded := QbeGen.Fold2(3, q, q2, qf)
|
|
|
- 3040 ELSIF op = SymTab.OpMod THEN
|
|
|
- 3041 folded := QbeGen.Fold2(4, q, q2, qf)
|
|
|
- 3042 END
|
|
|
- 3043 END;
|
|
|
- 3044 IF folded THEN QbeGen.CopyOp(qf, q)
|
|
|
- 3045 ELSE
|
|
|
- 3046 IF isL THEN
|
|
|
- 3047 IF SymTab.IsIntFamily(lt) THEN
|
|
|
- 3048 QbeGen.WidenLong(q, wq); QbeGen.CopyOp(wq, q)
|
|
|
- 3049 END;
|
|
|
- 3050 IF SymTab.IsIntFamily(rt) THEN
|
|
|
- 3051 QbeGen.WidenLong(q2, wq); QbeGen.CopyOp(wq, q2)
|
|
|
- 3052 END;
|
|
|
- 3053 QbeGen.NewTemp(qt);
|
|
|
- 3054 IF op = SymTab.OpTimes THEN
|
|
|
- 3055 QbeGen.Op3L("mul", qt, q, q2)
|
|
|
- 3056 ELSIF (op = SymTab.OpDiv)
|
|
|
- 3057 OR (op = SymTab.OpSlash) THEN
|
|
|
- 3058 QbeGen.Op3L("div", qt, q, q2)
|
|
|
- 3059 ELSE
|
|
|
- 3060 QbeGen.Op3L("rem", qt, q, q2)
|
|
|
- 3061 END
|
|
|
- 3062 ELSE
|
|
|
- 3063 QbeGen.NewTemp(qt);
|
|
|
- 3064 IF op = SymTab.OpTimes THEN
|
|
|
- 3065 QbeGen.Op3("mul", qt, q, q2, isR)
|
|
|
- 3066 ELSIF (op = SymTab.OpDiv)
|
|
|
- 3067 OR (op = SymTab.OpSlash) THEN
|
|
|
- 3068 QbeGen.Op3("div", qt, q, q2, isR)
|
|
|
- 3069 ELSE
|
|
|
- 3070 QbeGen.Op3("rem", qt, q, q2, isR)
|
|
|
- 3071 END
|
|
|
- 3072 END;
|
|
|
- 3073 QbeGen.CopyOp(qt, q)
|
|
|
- 3074 END
|
|
|
- 3075 ELSE QbeGen.CopyOp("0", q)
|
|
|
- 3076 END
|
|
|
- 3077 END; .) } .
|
|
|
- 3078 MulOp<VAR op: INTEGER>
|
|
|
- 3079 = "*" (. op := SymTab.OpTimes; .)
|
|
|
- 3080 | "/" (. op := SymTab.OpSlash; .)
|
|
|
- 3081 | "DIV" (. op := SymTab.OpDiv; .)
|
|
|
- 3082 | "MOD" (. op := SymTab.OpMod; .)
|
|
|
- 3083 | ( "AND" | "&" ) (. op := SymTab.OpAnd; .) .
|
|
|
- 3084 Fact<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
- 3085 (. VAR s: ARRAY [0 .. 255] OF CHAR;
|
|
|
- 3086 et, dt, t2, st, ct2, et2:
|
|
|
- 3087 SymTab.TypeIndex;
|
|
|
- 3088 dk: INTEGER;
|
|
|
- 3089 qd, q2, sq, qa, qm0, qr, qt:
|
|
|
- 3090 QbeGen.QVal;
|
|
|
- 3091 qn, vn: SymTab.Name;
|
|
|
- 3092 vt: SymTab.TypeIndex;
|
|
|
- 3093 c1, c2: INTEGER;
|
|
|
- 3094 lo, hi: INTEGER;
|
|
|
- 3095 isMax: BOOLEAN;
|
|
|
- 3096 called, isHigh, sfx, isCh,
|
|
|
- 3097 isU, uok, isStr: BOOLEAN;
|
|
|
- 3098 ucp: INTEGER; astIsLit: BOOLEAN;
|
|
|
- 3099 astD: AST.Node;
|
|
|
- 3100 astCall: BOOLEAN;
|
|
|
- 3101 astNode, astNot: AST.Node;
|
|
|
- 3102 j: CARDINAL;
|
|
|
- 3103 astArg2: AST.Node;
|
|
|
- 3104 astBrace: AST.Node;
|
|
|
- 3105 astRes: AST.Node; .)
|
|
|
- 3106 = (. astIsLit := FALSE; .)
|
|
|
- 3107 ( integer (. LexString(s);
|
|
|
- 3108 QbeGen.NormInt(s, q); IF twoPhase THEN astIsLit := TRUE; astCur := AST.MakeLeaf(AST.NkIntLit, s) END;
|
|
|
- 3109 t := SymTab.IntType(); .)
|
|
|
- 3110 | charConst (. LexString(s);
|
|
|
- 3111 QbeGen.NormLit(s, q, isCh);
|
|
|
- 3112 IF twoPhase THEN
|
|
|
- 3113 astIsLit := TRUE;
|
|
|
- 3114 astCur := AST.MakeLeaf(
|
|
|
- 3115 AST.NkCharLit, s)
|
|
|
- 3116 END;
|
|
|
- 3117 t := SymTab.CharType(); .)
|
|
|
- 3118 | real (. LexString(s);
|
|
|
- 3119 QbeGen.NormReal(s, q);
|
|
|
- 3120 IF twoPhase THEN
|
|
|
- 3121 astIsLit := TRUE;
|
|
|
- 3122 astCur := AST.MakeLeaf(
|
|
|
- 3123 AST.NkRealLit, s)
|
|
|
- 3124 END;
|
|
|
- 3125 t := SymTab.RealType(); .)
|
|
|
- 3126 | string (. LexString(s);
|
|
|
- 3127 IF twoPhase THEN
|
|
|
- 3128 astIsLit := TRUE;
|
|
|
- 3129 astCur := AST.MakeLeaf(
|
|
|
- 3130 AST.NkStrLit, s)
|
|
|
- 3131 END;
|
|
|
- 3132 IF SymTab.StrLen(s) = 3 THEN
|
|
|
- 3133 t := SymTab.CharType();
|
|
|
- 3134 QbeGen.IntStr(
|
|
|
- 3135 QbeGen.CharVal(s), q)
|
|
|
- 3136 ELSE t := SymTab.NewStr();
|
|
|
- 3137 QbeGen.DeclStr(s, q);
|
|
|
- 3138 (* a literal's value IS its
|
|
|
- 3139 static descriptor address *)
|
|
|
- 3140 QbeGen.NoteAddr(q, q)
|
|
|
- 3141 END; .)
|
|
|
- 3142 | ustring (. LexString(s);
|
|
|
- 3143 IF twoPhase THEN
|
|
|
- 3144 astIsLit := TRUE;
|
|
|
- 3145 astCur := AST.MakeLeaf(
|
|
|
- 3146 AST.NkStrLit, s)
|
|
|
- 3147 END;
|
|
|
- 3148 QbeGen.DeclUStr(s, q, isU, ucp,
|
|
|
- 3149 uok);
|
|
|
- 3150 IF NOT uok THEN
|
|
|
- 3151 SemError(234);
|
|
|
- 3152 t := SymTab.InvalidType
|
|
|
- 3153 ELSIF isU THEN
|
|
|
- 3154 t := SymTab.UCharType();
|
|
|
- 3155 QbeGen.IntStr(ucp, q)
|
|
|
- 3156 ELSE
|
|
|
- 3157 t := SymTab.NewUStr();
|
|
|
- 3158 QbeGen.NoteAddr(q, q)
|
|
|
- 3159 END; .)
|
|
|
- 3160 | Design<dt, dk, qd, qn, sfx> (. astD := astCur; astCall := FALSE; astBrace := AST.NoNode;
|
|
|
- 3161 astNArgs := 0; called := FALSE;
|
|
|
- 3162 t := dt;
|
|
|
- 3163 IF sfx THEN
|
|
|
- 3164 IF dt =
|
|
|
- 3165 SymTab.InvalidType THEN
|
|
|
- 3166 QbeGen.CopyOp("0", q)
|
|
|
- 3167 ELSIF (SymTab.ClassOf(dt) =
|
|
|
- 3168 SymTab.ClRecord)
|
|
|
- 3169 OR (SymTab.ClassOf(dt) =
|
|
|
- 3170 SymTab.ClSet)
|
|
|
- 3171 OR (SymTab.ClassOf(dt) =
|
|
|
- 3172 SymTab.ClArray)
|
|
|
+ 2858 AND (SymTab.ClassOf(t2) = SymTab.ClUStr))
|
|
|
+ 2859 OR ((SymTab.ClassOf(t) = SymTab.ClUStr)
|
|
|
+ 2860 AND (SymTab.ClassOf(t2) = SymTab.ClUChar))
|
|
|
+ 2861 OR ((SymTab.ClassOf(t) = SymTab.ClUChar)
|
|
|
+ 2862 AND (SymTab.ClassOf(t2) = SymTab.ClUChar))) THEN
|
|
|
+ 2863 (* UString concatenation: a UCHAR operand becomes a
|
|
|
+ 2864 1-codepoint UString; the result is a descriptor in the
|
|
|
+ 2865 shim's concat buffer. Work on copies so neither
|
|
|
+ 2866 operand is clobbered. *)
|
|
|
+ 2867 IF SymTab.ClassOf(t) = SymTab.ClUStr THEN
|
|
|
+ 2868 QbeGen.CopyOp(q, q2a)
|
|
|
+ 2869 ELSE
|
|
|
+ 2870 QbeGen.UStrFrom(q, q2a)
|
|
|
+ 2871 END;
|
|
|
+ 2872 IF SymTab.ClassOf(t2) = SymTab.ClUStr THEN
|
|
|
+ 2873 QbeGen.UStrCat(q2a, q2, qt)
|
|
|
+ 2874 ELSE
|
|
|
+ 2875 QbeGen.UStrFrom(q2, q2b);
|
|
|
+ 2876 QbeGen.UStrCat(q2a, q2b, qt)
|
|
|
+ 2877 END;
|
|
|
+ 2878 t := SymTab.NewUStr();
|
|
|
+ 2879 QbeGen.CopyOp(qt, q)
|
|
|
+ 2880 ELSIF (op = SymTab.OpAdd)
|
|
|
+ 2881 AND (SymTab.StrCompat(t, t2)
|
|
|
+ 2882 OR (SymTab.IsStrType(t)
|
|
|
+ 2883 AND (SymTab.ClassOf(t2) = SymTab.ClChar))
|
|
|
+ 2884 OR ((SymTab.ClassOf(t) = SymTab.ClChar)
|
|
|
+ 2885 AND SymTab.IsStrType(t2))) THEN
|
|
|
+ 2886 (* string concatenation; a CHAR operand becomes a
|
|
|
+ 2887 1-character string literal. When both operands are
|
|
|
+ 2888 constants, fold to a single string literal so a
|
|
|
+ 2889 constructor element stays compile-time. *)
|
|
|
+ 2890 QbeGen.StrFold(q, q2, SymTab.ClassOf(t), SymTab.ClassOf(t2),
|
|
|
+ 2891 qt, fok);
|
|
|
+ 2892 IF NOT fok THEN
|
|
|
+ 2893 IF SymTab.StrCompat(t, t2) THEN
|
|
|
+ 2894 QbeGen.StrCat(q, q2, qt)
|
|
|
+ 2895 ELSIF SymTab.IsStrType(t) THEN
|
|
|
+ 2896 QbeGen.DeclCharStr(q2, qs);
|
|
|
+ 2897 QbeGen.StrCat(q, qs, qt)
|
|
|
+ 2898 ELSE
|
|
|
+ 2899 QbeGen.DeclCharStr(q, qs);
|
|
|
+ 2900 QbeGen.StrCat(qs, q2, qt)
|
|
|
+ 2901 END
|
|
|
+ 2902 END;
|
|
|
+ 2903 t := SymTab.NewStr();
|
|
|
+ 2904 QbeGen.CopyOp(qt, q)
|
|
|
+ 2905 ELSIF (t # SymTab.InvalidType) AND (t2 # SymTab.InvalidType)
|
|
|
+ 2906 AND (SymTab.ClassOf(t) = SymTab.ClSet)
|
|
|
+ 2907 AND (SymTab.ClassOf(t2) = SymTab.ClSet) THEN
|
|
|
+ 2908 lw := SymTab.SetWords(t); rw := SymTab.SetWords(t2);
|
|
|
+ 2909 mw := lw;
|
|
|
+ 2910 IF rw > mw THEN mw := rw END;
|
|
|
+ 2911 IF op = SymTab.OpAdd THEN
|
|
|
+ 2912 QbeGen.SetBinOp(0, q, q2, lw, rw, qt)
|
|
|
+ 2913 ELSE
|
|
|
+ 2914 QbeGen.SetBinOp(2, q, q2, lw, rw, qt)
|
|
|
+ 2915 END;
|
|
|
+ 2916 t := SymTab.NewSet(
|
|
|
+ 2917 SymTab.NewSubR(0,
|
|
|
+ 2918 VAL(INTEGER, mw) * 32 - 1));
|
|
|
+ 2919 QbeGen.CopyOp(qt, q)
|
|
|
+ 2920 ELSE
|
|
|
+ 2921 IF SymTab.ArithCheck(t, t2, FALSE, res2) THEN
|
|
|
+ 2922 lt := t; rt := t2; t := res2
|
|
|
+ 2923 ELSE SemError(211); t := SymTab.InvalidType END;
|
|
|
+ 2924 IF t # SymTab.InvalidType THEN
|
|
|
+ 2925 isL := SymTab.IsLongFamily(t);
|
|
|
+ 2926 isR := SymTab.ClassOf(t) = SymTab.ClReal;
|
|
|
+ 2927 folded := FALSE;
|
|
|
+ 2928 IF (NOT isL) AND (NOT isR)
|
|
|
+ 2929 AND QbeGen.IsImm(q) AND QbeGen.IsImm(q2) THEN
|
|
|
+ 2930 IF op = SymTab.OpAdd THEN
|
|
|
+ 2931 folded := QbeGen.Fold2(0, q, q2, qf)
|
|
|
+ 2932 ELSE
|
|
|
+ 2933 folded := QbeGen.Fold2(1, q, q2, qf)
|
|
|
+ 2934 END
|
|
|
+ 2935 END;
|
|
|
+ 2936 IF folded THEN QbeGen.CopyOp(qf, q)
|
|
|
+ 2937 ELSE
|
|
|
+ 2938 IF isL THEN
|
|
|
+ 2939 IF SymTab.IsIntFamily(lt) THEN
|
|
|
+ 2940 QbeGen.WidenLong(q, wq); QbeGen.CopyOp(wq, q)
|
|
|
+ 2941 END;
|
|
|
+ 2942 IF SymTab.IsIntFamily(rt) THEN
|
|
|
+ 2943 QbeGen.WidenLong(q2, wq); QbeGen.CopyOp(wq, q2)
|
|
|
+ 2944 END;
|
|
|
+ 2945 QbeGen.NewTemp(qt);
|
|
|
+ 2946 IF op = SymTab.OpAdd THEN
|
|
|
+ 2947 QbeGen.Op3L("add", qt, q, q2)
|
|
|
+ 2948 ELSE
|
|
|
+ 2949 QbeGen.Op3L("sub", qt, q, q2)
|
|
|
+ 2950 END
|
|
|
+ 2951 ELSE
|
|
|
+ 2952 QbeGen.NewTemp(qt);
|
|
|
+ 2953 IF op = SymTab.OpAdd THEN
|
|
|
+ 2954 QbeGen.Op3("add", qt, q, q2, isR)
|
|
|
+ 2955 ELSE
|
|
|
+ 2956 QbeGen.Op3("sub", qt, q, q2, isR)
|
|
|
+ 2957 END
|
|
|
+ 2958 END;
|
|
|
+ 2959 QbeGen.CopyOp(qt, q)
|
|
|
+ 2960 END
|
|
|
+ 2961 ELSE QbeGen.CopyOp("0", q)
|
|
|
+ 2962 END
|
|
|
+ 2963 END; .) } .
|
|
|
+ 2964 AddOp<VAR op: INTEGER>
|
|
|
+ 2965 = "+" (. op := SymTab.OpAdd; .)
|
|
|
+ 2966 | "-" (. op := SymTab.OpSub; .)
|
|
|
+ 2967 | "OR" (. op := SymTab.OpOr; .) .
|
|
|
+ 2968 Term<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
+ 2969 (. VAR t2, res2, lt, rt:
|
|
|
+ 2970 SymTab.TypeIndex;
|
|
|
+ 2971 op: INTEGER;
|
|
|
+ 2972 q2, qt, wq, qf:
|
|
|
+ 2973 QbeGen.QVal;
|
|
|
+ 2974 isR, isL, folded: BOOLEAN;
|
|
|
+ 2975 lw, rw, mw: CARDINAL;
|
|
|
+ 2976 lNext, lFalse, lDone, qr, qs: QbeGen.QVal;
|
|
|
+ 2977 astA, astB: AST.Node;
|
|
|
+ 2978 astOp: INTEGER; .)
|
|
|
+ 2979 = Fact<t, q> (. astA := astCur; .) { MulOp<op> (. IF op = SymTab.OpAnd THEN
|
|
|
+ 2980 QbeGen.DelayBegin END; .)
|
|
|
+ 2981 Fact<t2, q2> (. astB := astCur; IF op = SymTab.OpAnd THEN
|
|
|
+ 2982 QbeGen.DelayEnd END; .)
|
|
|
+ 2983 (. astOp := AST.OpMul;
|
|
|
+ 2984 IF op = SymTab.OpSlash THEN astOp := AST.OpDiv
|
|
|
+ 2985 ELSIF op = SymTab.OpDiv THEN astOp := AST.OpDiv
|
|
|
+ 2986 ELSIF op = SymTab.OpMod THEN astOp := AST.OpMod
|
|
|
+ 2987 ELSIF op = SymTab.OpAnd THEN astOp := AST.OpAnd END;
|
|
|
+ 2988 astA := AST.MakeBin(AST.NkBinExpr, astOp, astA, astB);
|
|
|
+ 2989 astCur := astA;
|
|
|
+ 2990 IF op = SymTab.OpAnd THEN
|
|
|
+ 2991 (* short-circuit: if q is false the RHS is skipped *)
|
|
|
+ 2992 IF SymTab.BoolCheck(t) AND SymTab.BoolCheck(t2) THEN
|
|
|
+ 2993 t := SymTab.BoolType()
|
|
|
+ 2994 ELSE SemError(212); t := SymTab.InvalidType END;
|
|
|
+ 2995 IF t # SymTab.InvalidType THEN
|
|
|
+ 2996 QbeGen.Slot4(qs);
|
|
|
+ 2997 QbeGen.NewLabel(lNext);
|
|
|
+ 2998 QbeGen.NewLabel(lFalse);
|
|
|
+ 2999 QbeGen.NewLabel(lDone);
|
|
|
+ 3000 QbeGen.Jnz(q, lNext, lFalse);
|
|
|
+ 3001 QbeGen.EmitLabel(lNext);
|
|
|
+ 3002 QbeGen.DelayFlush;
|
|
|
+ 3003 QbeGen.StoreW(qs, q2);
|
|
|
+ 3004 QbeGen.Jmp(lDone);
|
|
|
+ 3005 QbeGen.EmitLabel(lFalse);
|
|
|
+ 3006 QbeGen.StoreW(qs, "0");
|
|
|
+ 3007 QbeGen.Jmp(lDone);
|
|
|
+ 3008 QbeGen.EmitLabel(lDone);
|
|
|
+ 3009 QbeGen.LoadW(qs, qr);
|
|
|
+ 3010 QbeGen.CopyOp(qr, q)
|
|
|
+ 3011 ELSE QbeGen.DelayFlush; QbeGen.CopyOp("0", q)
|
|
|
+ 3012 END
|
|
|
+ 3013 ELSIF (t # SymTab.InvalidType) AND (t2 # SymTab.InvalidType)
|
|
|
+ 3014 AND (SymTab.ClassOf(t) = SymTab.ClSet)
|
|
|
+ 3015 AND (SymTab.ClassOf(t2) = SymTab.ClSet) THEN
|
|
|
+ 3016 lw := SymTab.SetWords(t); rw := SymTab.SetWords(t2);
|
|
|
+ 3017 mw := lw;
|
|
|
+ 3018 IF rw > mw THEN mw := rw END;
|
|
|
+ 3019 IF op = SymTab.OpTimes THEN
|
|
|
+ 3020 QbeGen.SetBinOp(1, q, q2, lw, rw, qt)
|
|
|
+ 3021 ELSE
|
|
|
+ 3022 QbeGen.SetBinOp(3, q, q2, lw, rw, qt)
|
|
|
+ 3023 END;
|
|
|
+ 3024 t := SymTab.NewSet(
|
|
|
+ 3025 SymTab.NewSubR(0,
|
|
|
+ 3026 VAL(INTEGER, mw) * 32 - 1));
|
|
|
+ 3027 QbeGen.CopyOp(qt, q)
|
|
|
+ 3028 ELSE
|
|
|
+ 3029 IF SymTab.ArithCheck(t, t2,
|
|
|
+ 3030 (op = SymTab.OpDiv) OR (op = SymTab.OpMod),
|
|
|
+ 3031 res2) THEN
|
|
|
+ 3032 lt := t; rt := t2; t := res2
|
|
|
+ 3033 ELSE SemError(211); t := SymTab.InvalidType END;
|
|
|
+ 3034 IF t # SymTab.InvalidType THEN
|
|
|
+ 3035 isL := SymTab.IsLongFamily(t);
|
|
|
+ 3036 isR := SymTab.ClassOf(t) = SymTab.ClReal;
|
|
|
+ 3037 folded := FALSE;
|
|
|
+ 3038 IF (NOT isL) AND (NOT isR)
|
|
|
+ 3039 AND QbeGen.IsImm(q) AND QbeGen.IsImm(q2) THEN
|
|
|
+ 3040 IF op = SymTab.OpTimes THEN
|
|
|
+ 3041 folded := QbeGen.Fold2(2, q, q2, qf)
|
|
|
+ 3042 ELSIF op = SymTab.OpDiv THEN
|
|
|
+ 3043 folded := QbeGen.Fold2(3, q, q2, qf)
|
|
|
+ 3044 ELSIF op = SymTab.OpMod THEN
|
|
|
+ 3045 folded := QbeGen.Fold2(4, q, q2, qf)
|
|
|
+ 3046 END
|
|
|
+ 3047 END;
|
|
|
+ 3048 IF folded THEN QbeGen.CopyOp(qf, q)
|
|
|
+ 3049 ELSE
|
|
|
+ 3050 IF isL THEN
|
|
|
+ 3051 IF SymTab.IsIntFamily(lt) THEN
|
|
|
+ 3052 QbeGen.WidenLong(q, wq); QbeGen.CopyOp(wq, q)
|
|
|
+ 3053 END;
|
|
|
+ 3054 IF SymTab.IsIntFamily(rt) THEN
|
|
|
+ 3055 QbeGen.WidenLong(q2, wq); QbeGen.CopyOp(wq, q2)
|
|
|
+ 3056 END;
|
|
|
+ 3057 QbeGen.NewTemp(qt);
|
|
|
+ 3058 IF op = SymTab.OpTimes THEN
|
|
|
+ 3059 QbeGen.Op3L("mul", qt, q, q2)
|
|
|
+ 3060 ELSIF (op = SymTab.OpDiv)
|
|
|
+ 3061 OR (op = SymTab.OpSlash) THEN
|
|
|
+ 3062 QbeGen.Op3L("div", qt, q, q2)
|
|
|
+ 3063 ELSE
|
|
|
+ 3064 QbeGen.Op3L("rem", qt, q, q2)
|
|
|
+ 3065 END
|
|
|
+ 3066 ELSE
|
|
|
+ 3067 QbeGen.NewTemp(qt);
|
|
|
+ 3068 IF op = SymTab.OpTimes THEN
|
|
|
+ 3069 QbeGen.Op3("mul", qt, q, q2, isR)
|
|
|
+ 3070 ELSIF (op = SymTab.OpDiv)
|
|
|
+ 3071 OR (op = SymTab.OpSlash) THEN
|
|
|
+ 3072 QbeGen.Op3("div", qt, q, q2, isR)
|
|
|
+ 3073 ELSE
|
|
|
+ 3074 QbeGen.Op3("rem", qt, q, q2, isR)
|
|
|
+ 3075 END
|
|
|
+ 3076 END;
|
|
|
+ 3077 QbeGen.CopyOp(qt, q)
|
|
|
+ 3078 END
|
|
|
+ 3079 ELSE QbeGen.CopyOp("0", q)
|
|
|
+ 3080 END
|
|
|
+ 3081 END; .) } .
|
|
|
+ 3082 MulOp<VAR op: INTEGER>
|
|
|
+ 3083 = "*" (. op := SymTab.OpTimes; .)
|
|
|
+ 3084 | "/" (. op := SymTab.OpSlash; .)
|
|
|
+ 3085 | "DIV" (. op := SymTab.OpDiv; .)
|
|
|
+ 3086 | "MOD" (. op := SymTab.OpMod; .)
|
|
|
+ 3087 | ( "AND" | "&" ) (. op := SymTab.OpAnd; .) .
|
|
|
+ 3088 Fact<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
+ 3089 (. VAR s: ARRAY [0 .. 255] OF CHAR;
|
|
|
+ 3090 et, dt, t2, st, ct2, et2:
|
|
|
+ 3091 SymTab.TypeIndex;
|
|
|
+ 3092 dk: INTEGER;
|
|
|
+ 3093 qd, q2, sq, qa, qm0, qr, qt:
|
|
|
+ 3094 QbeGen.QVal;
|
|
|
+ 3095 qn, vn: SymTab.Name;
|
|
|
+ 3096 vt: SymTab.TypeIndex;
|
|
|
+ 3097 c1, c2: INTEGER;
|
|
|
+ 3098 lo, hi: INTEGER;
|
|
|
+ 3099 isMax: BOOLEAN;
|
|
|
+ 3100 called, isHigh, sfx, isCh,
|
|
|
+ 3101 isU, uok, isStr: BOOLEAN;
|
|
|
+ 3102 ucp: INTEGER; astIsLit: BOOLEAN;
|
|
|
+ 3103 astD: AST.Node;
|
|
|
+ 3104 astCall: BOOLEAN;
|
|
|
+ 3105 astNode, astNot: AST.Node;
|
|
|
+ 3106 j: CARDINAL;
|
|
|
+ 3107 astArg2: AST.Node;
|
|
|
+ 3108 astBrace: AST.Node;
|
|
|
+ 3109 astRes: AST.Node; .)
|
|
|
+ 3110 = (. astIsLit := FALSE; .)
|
|
|
+ 3111 ( integer (. LexString(s);
|
|
|
+ 3112 QbeGen.NormInt(s, q); IF twoPhase THEN astIsLit := TRUE; astCur := AST.MakeLeaf(AST.NkIntLit, s) END;
|
|
|
+ 3113 t := SymTab.IntType(); .)
|
|
|
+ 3114 | charConst (. LexString(s);
|
|
|
+ 3115 QbeGen.NormLit(s, q, isCh);
|
|
|
+ 3116 IF twoPhase THEN
|
|
|
+ 3117 astIsLit := TRUE;
|
|
|
+ 3118 astCur := AST.MakeLeaf(
|
|
|
+ 3119 AST.NkCharLit, s)
|
|
|
+ 3120 END;
|
|
|
+ 3121 t := SymTab.CharType(); .)
|
|
|
+ 3122 | real (. LexString(s);
|
|
|
+ 3123 QbeGen.NormReal(s, q);
|
|
|
+ 3124 IF twoPhase THEN
|
|
|
+ 3125 astIsLit := TRUE;
|
|
|
+ 3126 astCur := AST.MakeLeaf(
|
|
|
+ 3127 AST.NkRealLit, s)
|
|
|
+ 3128 END;
|
|
|
+ 3129 t := SymTab.RealType(); .)
|
|
|
+ 3130 | string (. LexString(s);
|
|
|
+ 3131 IF twoPhase THEN
|
|
|
+ 3132 astIsLit := TRUE;
|
|
|
+ 3133 astCur := AST.MakeLeaf(
|
|
|
+ 3134 AST.NkStrLit, s)
|
|
|
+ 3135 END;
|
|
|
+ 3136 IF SymTab.StrLen(s) = 3 THEN
|
|
|
+ 3137 t := SymTab.CharType();
|
|
|
+ 3138 QbeGen.IntStr(
|
|
|
+ 3139 QbeGen.CharVal(s), q)
|
|
|
+ 3140 ELSE t := SymTab.NewStr();
|
|
|
+ 3141 QbeGen.DeclStr(s, q);
|
|
|
+ 3142 (* a literal's value IS its
|
|
|
+ 3143 static descriptor address *)
|
|
|
+ 3144 QbeGen.NoteAddr(q, q)
|
|
|
+ 3145 END; .)
|
|
|
+ 3146 | ustring (. LexString(s);
|
|
|
+ 3147 IF twoPhase THEN
|
|
|
+ 3148 astIsLit := TRUE;
|
|
|
+ 3149 astCur := AST.MakeLeaf(
|
|
|
+ 3150 AST.NkStrLit, s)
|
|
|
+ 3151 END;
|
|
|
+ 3152 QbeGen.DeclUStr(s, q, isU, ucp,
|
|
|
+ 3153 uok);
|
|
|
+ 3154 IF NOT uok THEN
|
|
|
+ 3155 SemError(234);
|
|
|
+ 3156 t := SymTab.InvalidType
|
|
|
+ 3157 ELSIF isU THEN
|
|
|
+ 3158 t := SymTab.UCharType();
|
|
|
+ 3159 QbeGen.IntStr(ucp, q)
|
|
|
+ 3160 ELSE
|
|
|
+ 3161 t := SymTab.NewUStr();
|
|
|
+ 3162 QbeGen.NoteAddr(q, q)
|
|
|
+ 3163 END; .)
|
|
|
+ 3164 | Design<dt, dk, qd, qn, sfx> (. astD := astCur; astCall := FALSE; astBrace := AST.NoNode;
|
|
|
+ 3165 astNArgs := 0; called := FALSE;
|
|
|
+ 3166 t := dt;
|
|
|
+ 3167 IF sfx THEN
|
|
|
+ 3168 IF dt =
|
|
|
+ 3169 SymTab.InvalidType THEN
|
|
|
+ 3170 QbeGen.CopyOp("0", q)
|
|
|
+ 3171 ELSIF (SymTab.ClassOf(dt) =
|
|
|
+ 3172 SymTab.ClRecord)
|
|
|
3173 OR (SymTab.ClassOf(dt) =
|
|
|
- 3174 SymTab.ClClass) THEN
|
|
|
- 3175 QbeGen.CopyOp(qd, q)
|
|
|
- 3176 ELSE QbeGen.ElemLoad(qd, dt,
|
|
|
- 3177 q)
|
|
|
- 3178 END
|
|
|
- 3179 ELSE QbeGen.CopyOp(qd, q)
|
|
|
- 3180 END;
|
|
|
- 3181 IF (dk = SymTab.KindVar)
|
|
|
- 3182 OR (dk = SymTab.KindParam)
|
|
|
- 3183 OR (dk =
|
|
|
- 3184 SymTab.KindField) THEN
|
|
|
- 3185 IF sfx THEN
|
|
|
- 3186 QbeGen.NoteAddr(q, qd)
|
|
|
- 3187 ELSE
|
|
|
- 3188 QbeGen.AddrOf(qn, qa);
|
|
|
- 3189 QbeGen.NoteAddr(q, qa)
|
|
|
- 3190 END
|
|
|
- 3191 ELSIF sfx
|
|
|
- 3192 AND (dt #
|
|
|
- 3193 SymTab.InvalidType)
|
|
|
- 3194 AND ((SymTab.ClassOf(dt) =
|
|
|
- 3195 SymTab.ClArray)
|
|
|
- 3196 OR (SymTab.ClassOf(dt) =
|
|
|
- 3197 SymTab.ClSet)
|
|
|
- 3198 OR (SymTab.ClassOf(dt) =
|
|
|
- 3199 SymTab.ClRecord)) THEN
|
|
|
- 3200 QbeGen.NoteAddr(qd, qd)
|
|
|
- 3201 END; .)
|
|
|
- 3202 [ TypedBraceLit<dt, q> (. t := dt; astCall := TRUE;
|
|
|
- 3203 astBrace := astCur; .) ]
|
|
|
- 3204 [ ArgList<qn, dt, qd, TRUE, FALSE, methCls, ct2, q2, called>
|
|
|
- 3205 (. astCall := TRUE;
|
|
|
- 3206 astNode := AstCallNode(astD);
|
|
|
- 3207 astRes := astNode;
|
|
|
- 3208 t := ct2;
|
|
|
- 3209 QbeGen.CopyOp(q2, q);
|
|
|
- 3210 sfx := FALSE; .)
|
|
|
- 3211 { ResultComp<t, q, sfx, astRes> }
|
|
|
- 3212 (. IF sfx THEN
|
|
|
- 3213 IF t = SymTab.InvalidType THEN
|
|
|
- 3214 QbeGen.CopyOp("0", q)
|
|
|
- 3215 ELSIF (SymTab.ClassOf(t) #
|
|
|
- 3216 SymTab.ClRecord)
|
|
|
- 3217 AND (SymTab.ClassOf(t) # SymTab.ClSet)
|
|
|
- 3218 AND (SymTab.ClassOf(t) # SymTab.ClArray)
|
|
|
- 3219 AND (SymTab.ClassOf(t) # SymTab.ClClass) THEN
|
|
|
- 3220 QbeGen.ElemLoad(q, t, q2);
|
|
|
- 3221 QbeGen.CopyOp(q2, q)
|
|
|
- 3222 END
|
|
|
- 3223 END; .) ]
|
|
|
- 3224 (. IF called THEN
|
|
|
- 3225 astCur := astRes
|
|
|
- 3226 ELSIF astCall THEN
|
|
|
- 3227 astCur := astBrace
|
|
|
- 3228 ELSE astCur := astD
|
|
|
- 3229 END;
|
|
|
- 3230 astIsLit := TRUE;
|
|
|
- 3231 IF NOT called
|
|
|
- 3232 AND (dk = SymTab.KindProc) THEN
|
|
|
- 3233 (* bare zero-arg function
|
|
|
- 3234 call (parentheses may be
|
|
|
- 3235 omitted); a proper or
|
|
|
- 3236 parameterised proc here
|
|
|
- 3237 is 230 *)
|
|
|
- 3238 IF (SymTab.ProcNPar(qn) = 0)
|
|
|
- 3239 AND (SymTab.ProcRes(qn) #
|
|
|
- 3240 SymTab.InvalidType) THEN
|
|
|
- 3241 QbeGen.Mangled(qn,
|
|
|
- 3242 SymTab.ProcUid(qn), qm0);
|
|
|
- 3243 QbeGen.CallBegin(qm0,
|
|
|
- 3244 SymTab.ProcRes(qn),
|
|
|
- 3245 SymTab.ProcDepthOf(qn),
|
|
|
- 3246 SymTab.IsExternal(qn));
|
|
|
- 3247 QbeGen.CallEnd(TRUE, q);
|
|
|
- 3248 t := SymTab.ProcRes(qn)
|
|
|
- 3249 ELSE
|
|
|
- 3250 (* procedure used as a
|
|
|
- 3251 value (assign to a
|
|
|
- 3252 procedure variable):
|
|
|
- 3253 its code address *)
|
|
|
- 3254 t := SymTab.ProcTypeOf(qn);
|
|
|
- 3255 QbeGen.Mangled(qn,
|
|
|
- 3256 SymTab.ProcUid(qn), qm0);
|
|
|
- 3257 QbeGen.ProcAddr(qm0, q)
|
|
|
- 3258 END
|
|
|
- 3259 END; .)
|
|
|
- 3260 | ( "HIGH" (. isHigh := TRUE; .)
|
|
|
- 3261 | ( "LEN" | "LENGTH" ) (. isHigh := FALSE; .) )
|
|
|
- 3262 "(" ( Design<dt, dk, qd, qn, sfx> (. isStr := FALSE;
|
|
|
- 3263 isU := FALSE; .)
|
|
|
- 3264 | string (. LexString(s); astCur := AST.MakeLeaf(AST.NkStrLit, s);
|
|
|
- 3265 isStr := TRUE;
|
|
|
- 3266 isU := FALSE;
|
|
|
- 3267 IF SymTab.StrLen(s) = 3 THEN
|
|
|
- 3268 dt := SymTab.CharType();
|
|
|
- 3269 QbeGen.IntStr(QbeGen.CharVal(s),
|
|
|
- 3270 qd)
|
|
|
- 3271 ELSE
|
|
|
- 3272 dt := SymTab.NewStr();
|
|
|
- 3273 QbeGen.DeclStr(s, qd);
|
|
|
- 3274 QbeGen.NoteAddr(qd, qd)
|
|
|
- 3275 END;
|
|
|
- 3276 dk := -1;
|
|
|
- 3277 qn[0] := CHR(0); .)
|
|
|
- 3278 | ustring (. LexString(s); astCur := AST.MakeLeaf(AST.NkStrLit, s);
|
|
|
- 3279 QbeGen.DeclUStr(s, qd, isU, ucp,
|
|
|
- 3280 uok);
|
|
|
- 3281 isStr := FALSE;
|
|
|
- 3282 IF NOT uok THEN
|
|
|
- 3283 SemError(234);
|
|
|
- 3284 dt := SymTab.InvalidType
|
|
|
- 3285 ELSIF isU THEN
|
|
|
- 3286 (* one codepoint: a UCHAR;
|
|
|
- 3287 LEN is 1, HIGH is 0 *)
|
|
|
- 3288 dt := SymTab.UCharType();
|
|
|
- 3289 QbeGen.IntStr(ucp, qd)
|
|
|
- 3290 ELSE
|
|
|
- 3291 dt := SymTab.NewUStr();
|
|
|
- 3292 QbeGen.NoteAddr(qd, qd)
|
|
|
- 3293 END;
|
|
|
- 3294 dk := -1;
|
|
|
- 3295 qn[0] := CHR(0); .) )
|
|
|
- 3296 ")"
|
|
|
- 3297 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
- 3298 IF isHigh THEN AST.SetChild(astNode, 0,
|
|
|
- 3299 AST.MakeLeaf(AST.NkIdent, "HIGH"))
|
|
|
- 3300 ELSE AST.SetChild(astNode, 0,
|
|
|
- 3301 AST.MakeLeaf(AST.NkIdent, "LEN")) END;
|
|
|
- 3302 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
- 3303 astCur := astNode; astIsLit := TRUE;
|
|
|
- 3304 IF (dt # SymTab.InvalidType)
|
|
|
- 3305 AND (SymTab.ClassOf(dt) = SymTab.ClUStr) THEN
|
|
|
- 3306 (* UString: the count is
|
|
|
- 3307 the descriptor header *)
|
|
|
- 3308 IF isHigh THEN
|
|
|
- 3309 QbeGen.UStrLen(qd, qr);
|
|
|
- 3310 QbeGen.DecQ(qr)
|
|
|
- 3311 ELSE
|
|
|
- 3312 QbeGen.UStrLen(qd, qr)
|
|
|
- 3313 END;
|
|
|
- 3314 t := SymTab.IntType();
|
|
|
- 3315 QbeGen.CopyOp(qr, q)
|
|
|
- 3316 ELSIF (dt # SymTab.InvalidType)
|
|
|
- 3317 AND (SymTab.ClassOf(dt) = SymTab.ClUChar) THEN
|
|
|
- 3318 (* single UCHAR codepoint *)
|
|
|
- 3319 IF isHigh THEN
|
|
|
- 3320 QbeGen.CopyOp("0", qr)
|
|
|
- 3321 ELSE
|
|
|
- 3322 QbeGen.CopyOp("1", qr)
|
|
|
- 3323 END;
|
|
|
- 3324 t := SymTab.IntType();
|
|
|
- 3325 QbeGen.CopyOp(qr, q)
|
|
|
- 3326 ELSIF isStr THEN
|
|
|
- 3327 (* fold: content length at
|
|
|
- 3328 compile time *)
|
|
|
- 3329 IF SymTab.StrLen(s) = 3 THEN
|
|
|
- 3330 c1 := 1
|
|
|
- 3331 ELSE
|
|
|
- 3332 c1 :=
|
|
|
- 3333 SymTab.StrLen(s) - 2
|
|
|
- 3334 END;
|
|
|
- 3335 IF isHigh THEN
|
|
|
- 3336 DEC(c1)
|
|
|
- 3337 END;
|
|
|
- 3338 QbeGen.IntStr(c1, qr);
|
|
|
- 3339 t := SymTab.IntType();
|
|
|
- 3340 QbeGen.CopyOp(qr, q)
|
|
|
- 3341 ELSIF dt = SymTab.InvalidType THEN
|
|
|
- 3342 t := SymTab.InvalidType;
|
|
|
- 3343 QbeGen.CopyOp("0", q)
|
|
|
- 3344 ELSIF SymTab.ClassOf(dt) #
|
|
|
- 3345 SymTab.ClArray THEN
|
|
|
- 3346 SemError(217);
|
|
|
- 3347 t := SymTab.InvalidType;
|
|
|
- 3348 QbeGen.CopyOp("0", q)
|
|
|
- 3349 ELSE
|
|
|
- 3350 IF isHigh THEN
|
|
|
- 3351 IF SymTab.IsOpenArray(dt) THEN
|
|
|
- 3352 QbeGen.OpenHi(qd, qr)
|
|
|
- 3353 ELSE
|
|
|
- 3354 QbeGen.IntStr(
|
|
|
- 3355 SymTab.ArrayHi(dt), qr)
|
|
|
- 3356 END
|
|
|
- 3357 ELSE
|
|
|
- 3358 IF SymTab.IsOpenArray(dt) THEN
|
|
|
- 3359 QbeGen.LoadCount(qd, qr)
|
|
|
- 3360 ELSE
|
|
|
- 3361 QbeGen.IntStr(VAL(
|
|
|
- 3362 INTEGER,
|
|
|
- 3363 SymTab.ArrayLen(dt)),
|
|
|
- 3364 qr)
|
|
|
- 3365 END
|
|
|
- 3366 END;
|
|
|
- 3367 t := SymTab.IntType();
|
|
|
- 3368 QbeGen.CopyOp(qr, q)
|
|
|
- 3369 END; .)
|
|
|
- 3370 | ( "SIZE" | "TSIZE" ) "(" Design<dt, dk, qd, qn, sfx> ")"
|
|
|
- 3371 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
- 3372 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "SIZE"));
|
|
|
- 3373 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
- 3374 astCur := astNode; astIsLit := TRUE; .)
|
|
|
- 3375 (. IF dt = SymTab.InvalidType THEN
|
|
|
- 3376 t := SymTab.InvalidType;
|
|
|
- 3377 QbeGen.CopyOp("0", q)
|
|
|
- 3378 ELSE
|
|
|
- 3379 QbeGen.IntStr(VAL(INTEGER,
|
|
|
- 3380 SymTab.ObjectSize(dt)), q);
|
|
|
- 3381 t := SymTab.IntType()
|
|
|
- 3382 END; .)
|
|
|
- 3383 | ( "SHIFT" (. isMax := FALSE; .)
|
|
|
- 3384 | "ROTATE" (. isMax := TRUE; .) )
|
|
|
- 3385 "(" Expr<et, q> (. astArg2 := astCur; .) "," Expr<et2, q2> ")"
|
|
|
- 3386 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
- 3387 IF isMax THEN AST.SetChild(astNode, 0,
|
|
|
- 3388 AST.MakeLeaf(AST.NkIdent, "ROTATE"))
|
|
|
- 3389 ELSE AST.SetChild(astNode, 0,
|
|
|
- 3390 AST.MakeLeaf(AST.NkIdent, "SHIFT")) END;
|
|
|
- 3391 IF astArg2 # AST.NoNode THEN AST.SetChild(astNode, 1, astArg2) END;
|
|
|
- 3392 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 2, astCur) END;
|
|
|
- 3393 astCur := astNode; astIsLit := TRUE;
|
|
|
- 3394 (* set shift/rotate: isMax
|
|
|
- 3395 doubles as "rotate" *)
|
|
|
- 3396 IF (et # SymTab.InvalidType)
|
|
|
- 3397 AND (SymTab.ClassOf(et) =
|
|
|
- 3398 SymTab.ClSet) THEN
|
|
|
- 3399 QbeGen.SetShift(q, q2,
|
|
|
- 3400 SymTab.SetWords(et),
|
|
|
- 3401 SymTab.SetCount(et), isMax,
|
|
|
- 3402 qt);
|
|
|
- 3403 t := et;
|
|
|
- 3404 QbeGen.CopyOp(qt, q)
|
|
|
- 3405 ELSE SemError(230);
|
|
|
- 3406 t := SymTab.InvalidType;
|
|
|
- 3407 QbeGen.CopyOp("0", q)
|
|
|
- 3408 END; .)
|
|
|
- 3409 | ( "MIN" (. isMax := FALSE; .)
|
|
|
- 3410 | "MAX" (. isMax := TRUE; .) )
|
|
|
- 3411 "(" Design<dt, dk, qd, qn, sfx> ")"
|
|
|
- 3412 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
- 3413 IF isMax THEN AST.SetChild(astNode, 0,
|
|
|
- 3414 AST.MakeLeaf(AST.NkIdent, "MAX"))
|
|
|
- 3415 ELSE AST.SetChild(astNode, 0,
|
|
|
- 3416 AST.MakeLeaf(AST.NkIdent, "MIN")) END;
|
|
|
- 3417 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
- 3418 astCur := astNode; astIsLit := TRUE;
|
|
|
- 3419 IF (dt # SymTab.InvalidType)
|
|
|
- 3420 AND (SymTab.ClassOf(dt) = SymTab.ClReal) THEN
|
|
|
- 3421 (* REAL/LONGREAL: the
|
|
|
- 3422 implementation bounds *)
|
|
|
- 3423 IF isMax THEN
|
|
|
- 3424 QbeGen.NormReal(
|
|
|
- 3425 "3.402823e38", q)
|
|
|
- 3426 ELSE QbeGen.NormReal(
|
|
|
- 3427 "-3.402823e38", q)
|
|
|
- 3428 END;
|
|
|
- 3429 t := SymTab.RealType()
|
|
|
- 3430 ELSIF (dt #
|
|
|
- 3431 SymTab.InvalidType)
|
|
|
- 3432 AND (SymTab.ClassOf(dt) =
|
|
|
- 3433 SymTab.ClLong) THEN
|
|
|
- 3434 IF isMax THEN
|
|
|
- 3435 QbeGen.CopyOp(
|
|
|
- 3436 "9223372036854775807", q)
|
|
|
- 3437 ELSE QbeGen.CopyOp(
|
|
|
- 3438 "-9223372036854775808", q)
|
|
|
- 3439 END;
|
|
|
- 3440 t := SymTab.LongType()
|
|
|
- 3441 ELSIF SymTab.TypeBounds(dt, lo,
|
|
|
- 3442 hi) THEN
|
|
|
- 3443 IF isMax THEN
|
|
|
- 3444 QbeGen.IntStr(hi, q)
|
|
|
- 3445 ELSE QbeGen.IntStr(lo, q)
|
|
|
- 3446 END;
|
|
|
- 3447 t := SymTab.IntType()
|
|
|
- 3448 ELSE SemError(230);
|
|
|
- 3449 t := SymTab.InvalidType;
|
|
|
- 3450 QbeGen.CopyOp("0", q)
|
|
|
- 3451 END; .)
|
|
|
- 3452 | "ADR" "(" Design<dt, dk, qd, qn, sfx> ")"
|
|
|
- 3453 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
- 3454 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "ADR"));
|
|
|
- 3455 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
- 3456 astCur := astNode; astIsLit := TRUE; .)
|
|
|
- 3457 (. IF dt = SymTab.InvalidType THEN
|
|
|
- 3458 t := SymTab.InvalidType;
|
|
|
- 3459 QbeGen.CopyOp("0", q)
|
|
|
- 3460 ELSE
|
|
|
- 3461 IF sfx THEN
|
|
|
- 3462 QbeGen.CopyOp(qd, q)
|
|
|
- 3463 ELSIF (dk = SymTab.KindVar)
|
|
|
- 3464 OR (dk = SymTab.KindParam) THEN
|
|
|
- 3465 QbeGen.AddrOf(qn, q)
|
|
|
- 3466 ELSE SemError(230);
|
|
|
- 3467 QbeGen.CopyOp("0", q)
|
|
|
- 3468 END;
|
|
|
- 3469 t := SymTab.AddrType()
|
|
|
- 3470 END; .)
|
|
|
- 3471 | "CHR" "(" Expr<et, q> ")"
|
|
|
- 3472 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
- 3473 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "CHR"));
|
|
|
- 3474 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
- 3475 astCur := astNode; astIsLit := TRUE; .)
|
|
|
- 3476 (. IF (et # SymTab.InvalidType)
|
|
|
- 3477 AND NOT SymTab.IsIntFamily(et) THEN
|
|
|
- 3478 SemError(211) END;
|
|
|
- 3479 t := SymTab.CharType(); .)
|
|
|
- 3480 | ( "ORD" | "ORDL" ) "(" Expr<et, q> ")"
|
|
|
- 3481 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
- 3482 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "ORD"));
|
|
|
- 3483 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
- 3484 astCur := astNode; astIsLit := TRUE; .)
|
|
|
- 3485 (. IF et # SymTab.InvalidType THEN
|
|
|
- 3486 IF (SymTab.ClassOf(et) #
|
|
|
- 3487 SymTab.ClChar)
|
|
|
- 3488 AND (SymTab.ClassOf(et) #
|
|
|
- 3489 SymTab.ClBool)
|
|
|
- 3490 AND (SymTab.ClassOf(et) #
|
|
|
- 3491 SymTab.ClEnum)
|
|
|
- 3492 AND NOT SymTab.IsIntFamily(et) THEN
|
|
|
- 3493 SemError(211) END
|
|
|
- 3494 END;
|
|
|
- 3495 t := SymTab.IntType(); .)
|
|
|
- 3496 | "CAP" "(" Expr<et, q> ")"
|
|
|
- 3497 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
- 3498 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "CAP"));
|
|
|
- 3499 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
- 3500 astCur := astNode; astIsLit := TRUE; .)
|
|
|
- 3501 (. QbeGen.CapQ(q, qa);
|
|
|
- 3502 QbeGen.CopyOp(qa, q);
|
|
|
- 3503 t := SymTab.CharType(); .)
|
|
|
- 3504 | "UCHR" "(" Expr<et, q> ")"
|
|
|
- 3505 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
- 3506 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "UCHR"));
|
|
|
- 3507 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
- 3508 astCur := astNode; astIsLit := TRUE; .)
|
|
|
- 3509 (. (* UCHR: the UCHAR constructor.
|
|
|
- 3510 CHAR -> UCHAR (identity);
|
|
|
- 3511 INTEGER familly -> UCHAR
|
|
|
- 3512 (codepoint value). *)
|
|
|
- 3513 IF (et # SymTab.InvalidType)
|
|
|
- 3514 AND (SymTab.ClassOf(et) # SymTab.ClChar)
|
|
|
- 3515 AND NOT SymTab.IsIntFamily(et) THEN
|
|
|
- 3516 SemError(211) END;
|
|
|
- 3517 t := SymTab.UCharType(); .)
|
|
|
- 3518 | "CHR8" "(" Expr<et, q> ")"
|
|
|
- 3519 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
- 3520 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "CHR8"));
|
|
|
- 3521 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
- 3522 astCur := astNode; astIsLit := TRUE; .)
|
|
|
- 3523 (. IF (et # SymTab.InvalidType)
|
|
|
- 3524 AND (SymTab.ClassOf(et) # SymTab.ClUChar) THEN
|
|
|
- 3525 SemError(211) END;
|
|
|
- 3526 QbeGen.WidenLong(q, qa);
|
|
|
- 3527 QbeGen.CheckRange(qa, "0", "255");
|
|
|
- 3528 t := SymTab.CharType(); .)
|
|
|
- 3529 | "UORD" "(" Expr<et, q> ")"
|
|
|
- 3530 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
- 3531 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "UORD"));
|
|
|
- 3532 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
- 3533 astCur := astNode; astIsLit := TRUE; .)
|
|
|
- 3534 (. (* UORD(u): the codepoint as a
|
|
|
- 3535 32-bit ordinal (INTEGER),
|
|
|
- 3536 cf. ORD for CHAR. *)
|
|
|
- 3537 IF (et # SymTab.InvalidType)
|
|
|
- 3538 AND (SymTab.ClassOf(et) # SymTab.ClUChar) THEN
|
|
|
- 3539 SemError(211) END;
|
|
|
- 3540 t := SymTab.IntType(); .)
|
|
|
- 3541 | "ABS" "(" Expr<et, q> ")"
|
|
|
- 3542 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
- 3543 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "ABS"));
|
|
|
- 3544 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
- 3545 astCur := astNode; astIsLit := TRUE; .)
|
|
|
- 3546 (. IF (et # SymTab.InvalidType)
|
|
|
- 3547 AND NOT SymTab.IsIntFamily(et)
|
|
|
- 3548 AND (SymTab.ClassOf(et) #
|
|
|
- 3549 SymTab.ClReal) THEN
|
|
|
- 3550 SemError(211)
|
|
|
- 3551 ELSE QbeGen.AbsQ(q, qa,
|
|
|
- 3552 SymTab.ClassOf(et) =
|
|
|
- 3553 SymTab.ClReal);
|
|
|
- 3554 QbeGen.CopyOp(qa, q)
|
|
|
- 3555 END;
|
|
|
- 3556 t := et; .)
|
|
|
- 3557 | "VAL" "(" GetIdent<vn> (. astArg2 := AST.MakeLeaf(AST.NkIdent, vn); .) "," Expr<et, q> ")"
|
|
|
- 3558 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
- 3559 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "VAL"));
|
|
|
- 3560 IF astArg2 # AST.NoNode THEN AST.SetChild(astNode, 1, astArg2) END;
|
|
|
- 3561 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 2, astCur) END;
|
|
|
- 3562 astCur := astNode; astIsLit := TRUE; .)
|
|
|
- 3563 (. IF NOT SymTab.Lookup(vn) THEN
|
|
|
- 3564 SemError(201);
|
|
|
- 3565 t := SymTab.InvalidType
|
|
|
- 3566 ELSE vt := SymTab.SymType(vn);
|
|
|
- 3567 IF vt = SymTab.InvalidType THEN
|
|
|
- 3568 t := SymTab.InvalidType
|
|
|
- 3569 ELSIF et =
|
|
|
- 3570 SymTab.InvalidType THEN
|
|
|
- 3571 t := vt
|
|
|
- 3572 ELSE
|
|
|
- 3573 c1 := SymTab.ClassOf(et);
|
|
|
- 3574 c2 := SymTab.ClassOf(vt);
|
|
|
- 3575 IF (c1 = SymTab.ClInt)
|
|
|
- 3576 AND (c2 = SymTab.ClLong) THEN
|
|
|
- 3577 QbeGen.WidenLong(q, qa);
|
|
|
- 3578 QbeGen.CopyOp(qa, q);
|
|
|
- 3579 t := vt
|
|
|
- 3580 ELSIF (c1 = SymTab.ClLong)
|
|
|
- 3581 AND (c2 = SymTab.ClInt) THEN
|
|
|
- 3582 QbeGen.NarrowLong(q, qa);
|
|
|
- 3583 QbeGen.CopyOp(qa, q);
|
|
|
- 3584 t := vt
|
|
|
- 3585 ELSIF (c1 = SymTab.ClInt)
|
|
|
- 3586 AND (c2 = SymTab.ClReal) THEN
|
|
|
- 3587 QbeGen.ConvIR(q, qa);
|
|
|
- 3588 QbeGen.CopyOp(qa, q);
|
|
|
- 3589 t := vt
|
|
|
- 3590 ELSIF (c1 = SymTab.ClLong)
|
|
|
- 3591 AND (c2 = SymTab.ClReal) THEN
|
|
|
- 3592 QbeGen.ConvLR(q, qa);
|
|
|
- 3593 QbeGen.CopyOp(qa, q);
|
|
|
- 3594 t := vt
|
|
|
- 3595 ELSIF (c1 = SymTab.ClReal)
|
|
|
- 3596 AND (c2 = SymTab.ClInt) THEN
|
|
|
- 3597 QbeGen.ConvRI(q, qa);
|
|
|
- 3598 QbeGen.CopyOp(qa, q);
|
|
|
- 3599 t := vt
|
|
|
- 3600 ELSIF (c1 = SymTab.ClReal)
|
|
|
- 3601 AND (c2 = SymTab.ClLong) THEN
|
|
|
- 3602 QbeGen.ConvRL(q, qa);
|
|
|
- 3603 QbeGen.CopyOp(qa, q);
|
|
|
- 3604 t := vt
|
|
|
- 3605 ELSIF ((c1 = SymTab.ClInt)
|
|
|
- 3606 OR (c1 =
|
|
|
- 3607 SymTab.ClChar)
|
|
|
- 3608 OR (c1 =
|
|
|
- 3609 SymTab.ClBool)
|
|
|
+ 3174 SymTab.ClSet)
|
|
|
+ 3175 OR (SymTab.ClassOf(dt) =
|
|
|
+ 3176 SymTab.ClArray)
|
|
|
+ 3177 OR (SymTab.ClassOf(dt) =
|
|
|
+ 3178 SymTab.ClClass) THEN
|
|
|
+ 3179 QbeGen.CopyOp(qd, q)
|
|
|
+ 3180 ELSE QbeGen.ElemLoad(qd, dt,
|
|
|
+ 3181 q)
|
|
|
+ 3182 END
|
|
|
+ 3183 ELSE QbeGen.CopyOp(qd, q)
|
|
|
+ 3184 END;
|
|
|
+ 3185 IF (dk = SymTab.KindVar)
|
|
|
+ 3186 OR (dk = SymTab.KindParam)
|
|
|
+ 3187 OR (dk =
|
|
|
+ 3188 SymTab.KindField) THEN
|
|
|
+ 3189 IF sfx THEN
|
|
|
+ 3190 QbeGen.NoteAddr(q, qd)
|
|
|
+ 3191 ELSE
|
|
|
+ 3192 QbeGen.AddrOf(qn, qa);
|
|
|
+ 3193 QbeGen.NoteAddr(q, qa)
|
|
|
+ 3194 END
|
|
|
+ 3195 ELSIF sfx
|
|
|
+ 3196 AND (dt #
|
|
|
+ 3197 SymTab.InvalidType)
|
|
|
+ 3198 AND ((SymTab.ClassOf(dt) =
|
|
|
+ 3199 SymTab.ClArray)
|
|
|
+ 3200 OR (SymTab.ClassOf(dt) =
|
|
|
+ 3201 SymTab.ClSet)
|
|
|
+ 3202 OR (SymTab.ClassOf(dt) =
|
|
|
+ 3203 SymTab.ClRecord)) THEN
|
|
|
+ 3204 QbeGen.NoteAddr(qd, qd)
|
|
|
+ 3205 END; .)
|
|
|
+ 3206 [ TypedBraceLit<dt, q> (. t := dt; astCall := TRUE;
|
|
|
+ 3207 astBrace := astCur; .) ]
|
|
|
+ 3208 [ ArgList<qn, dt, qd, TRUE, FALSE, methCls, ct2, q2, called>
|
|
|
+ 3209 (. astCall := TRUE;
|
|
|
+ 3210 astNode := AstCallNode(astD);
|
|
|
+ 3211 astRes := astNode;
|
|
|
+ 3212 t := ct2;
|
|
|
+ 3213 QbeGen.CopyOp(q2, q);
|
|
|
+ 3214 sfx := FALSE; .)
|
|
|
+ 3215 { ResultComp<t, q, sfx, astRes> }
|
|
|
+ 3216 (. IF sfx THEN
|
|
|
+ 3217 IF t = SymTab.InvalidType THEN
|
|
|
+ 3218 QbeGen.CopyOp("0", q)
|
|
|
+ 3219 ELSIF (SymTab.ClassOf(t) #
|
|
|
+ 3220 SymTab.ClRecord)
|
|
|
+ 3221 AND (SymTab.ClassOf(t) # SymTab.ClSet)
|
|
|
+ 3222 AND (SymTab.ClassOf(t) # SymTab.ClArray)
|
|
|
+ 3223 AND (SymTab.ClassOf(t) # SymTab.ClClass) THEN
|
|
|
+ 3224 QbeGen.ElemLoad(q, t, q2);
|
|
|
+ 3225 QbeGen.CopyOp(q2, q)
|
|
|
+ 3226 END
|
|
|
+ 3227 END; .) ]
|
|
|
+ 3228 (. IF called THEN
|
|
|
+ 3229 astCur := astRes
|
|
|
+ 3230 ELSIF astCall THEN
|
|
|
+ 3231 astCur := astBrace
|
|
|
+ 3232 ELSE astCur := astD
|
|
|
+ 3233 END;
|
|
|
+ 3234 astIsLit := TRUE;
|
|
|
+ 3235 IF NOT called
|
|
|
+ 3236 AND (dk = SymTab.KindProc) THEN
|
|
|
+ 3237 (* bare zero-arg function
|
|
|
+ 3238 call (parentheses may be
|
|
|
+ 3239 omitted); a proper or
|
|
|
+ 3240 parameterised proc here
|
|
|
+ 3241 is 230 *)
|
|
|
+ 3242 IF (SymTab.ProcNPar(qn) = 0)
|
|
|
+ 3243 AND (SymTab.ProcRes(qn) #
|
|
|
+ 3244 SymTab.InvalidType) THEN
|
|
|
+ 3245 QbeGen.Mangled(qn,
|
|
|
+ 3246 SymTab.ProcUid(qn), qm0);
|
|
|
+ 3247 QbeGen.CallBegin(qm0,
|
|
|
+ 3248 SymTab.ProcRes(qn),
|
|
|
+ 3249 SymTab.ProcDepthOf(qn),
|
|
|
+ 3250 SymTab.IsExternal(qn));
|
|
|
+ 3251 QbeGen.CallEnd(TRUE, q);
|
|
|
+ 3252 t := SymTab.ProcRes(qn)
|
|
|
+ 3253 ELSE
|
|
|
+ 3254 (* procedure used as a
|
|
|
+ 3255 value (assign to a
|
|
|
+ 3256 procedure variable):
|
|
|
+ 3257 its code address *)
|
|
|
+ 3258 t := SymTab.ProcTypeOf(qn);
|
|
|
+ 3259 QbeGen.Mangled(qn,
|
|
|
+ 3260 SymTab.ProcUid(qn), qm0);
|
|
|
+ 3261 QbeGen.ProcAddr(qm0, q)
|
|
|
+ 3262 END
|
|
|
+ 3263 END; .)
|
|
|
+ 3264 | ( "HIGH" (. isHigh := TRUE; .)
|
|
|
+ 3265 | ( "LEN" | "LENGTH" ) (. isHigh := FALSE; .) )
|
|
|
+ 3266 "(" ( Design<dt, dk, qd, qn, sfx> (. isStr := FALSE;
|
|
|
+ 3267 isU := FALSE; .)
|
|
|
+ 3268 | string (. LexString(s); astCur := AST.MakeLeaf(AST.NkStrLit, s);
|
|
|
+ 3269 isStr := TRUE;
|
|
|
+ 3270 isU := FALSE;
|
|
|
+ 3271 IF SymTab.StrLen(s) = 3 THEN
|
|
|
+ 3272 dt := SymTab.CharType();
|
|
|
+ 3273 QbeGen.IntStr(QbeGen.CharVal(s),
|
|
|
+ 3274 qd)
|
|
|
+ 3275 ELSE
|
|
|
+ 3276 dt := SymTab.NewStr();
|
|
|
+ 3277 QbeGen.DeclStr(s, qd);
|
|
|
+ 3278 QbeGen.NoteAddr(qd, qd)
|
|
|
+ 3279 END;
|
|
|
+ 3280 dk := -1;
|
|
|
+ 3281 qn[0] := CHR(0); .)
|
|
|
+ 3282 | ustring (. LexString(s); astCur := AST.MakeLeaf(AST.NkStrLit, s);
|
|
|
+ 3283 QbeGen.DeclUStr(s, qd, isU, ucp,
|
|
|
+ 3284 uok);
|
|
|
+ 3285 isStr := FALSE;
|
|
|
+ 3286 IF NOT uok THEN
|
|
|
+ 3287 SemError(234);
|
|
|
+ 3288 dt := SymTab.InvalidType
|
|
|
+ 3289 ELSIF isU THEN
|
|
|
+ 3290 (* one codepoint: a UCHAR;
|
|
|
+ 3291 LEN is 1, HIGH is 0 *)
|
|
|
+ 3292 dt := SymTab.UCharType();
|
|
|
+ 3293 QbeGen.IntStr(ucp, qd)
|
|
|
+ 3294 ELSE
|
|
|
+ 3295 dt := SymTab.NewUStr();
|
|
|
+ 3296 QbeGen.NoteAddr(qd, qd)
|
|
|
+ 3297 END;
|
|
|
+ 3298 dk := -1;
|
|
|
+ 3299 qn[0] := CHR(0); .) )
|
|
|
+ 3300 ")"
|
|
|
+ 3301 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
+ 3302 IF isHigh THEN AST.SetChild(astNode, 0,
|
|
|
+ 3303 AST.MakeLeaf(AST.NkIdent, "HIGH"))
|
|
|
+ 3304 ELSE AST.SetChild(astNode, 0,
|
|
|
+ 3305 AST.MakeLeaf(AST.NkIdent, "LEN")) END;
|
|
|
+ 3306 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
+ 3307 astCur := astNode; astIsLit := TRUE;
|
|
|
+ 3308 IF (dt # SymTab.InvalidType)
|
|
|
+ 3309 AND (SymTab.ClassOf(dt) = SymTab.ClUStr) THEN
|
|
|
+ 3310 (* UString: the count is
|
|
|
+ 3311 the descriptor header *)
|
|
|
+ 3312 IF isHigh THEN
|
|
|
+ 3313 QbeGen.UStrLen(qd, qr);
|
|
|
+ 3314 QbeGen.DecQ(qr)
|
|
|
+ 3315 ELSE
|
|
|
+ 3316 QbeGen.UStrLen(qd, qr)
|
|
|
+ 3317 END;
|
|
|
+ 3318 t := SymTab.IntType();
|
|
|
+ 3319 QbeGen.CopyOp(qr, q)
|
|
|
+ 3320 ELSIF (dt # SymTab.InvalidType)
|
|
|
+ 3321 AND (SymTab.ClassOf(dt) = SymTab.ClUChar) THEN
|
|
|
+ 3322 (* single UCHAR codepoint *)
|
|
|
+ 3323 IF isHigh THEN
|
|
|
+ 3324 QbeGen.CopyOp("0", qr)
|
|
|
+ 3325 ELSE
|
|
|
+ 3326 QbeGen.CopyOp("1", qr)
|
|
|
+ 3327 END;
|
|
|
+ 3328 t := SymTab.IntType();
|
|
|
+ 3329 QbeGen.CopyOp(qr, q)
|
|
|
+ 3330 ELSIF isStr THEN
|
|
|
+ 3331 (* fold: content length at
|
|
|
+ 3332 compile time *)
|
|
|
+ 3333 IF SymTab.StrLen(s) = 3 THEN
|
|
|
+ 3334 c1 := 1
|
|
|
+ 3335 ELSE
|
|
|
+ 3336 c1 :=
|
|
|
+ 3337 SymTab.StrLen(s) - 2
|
|
|
+ 3338 END;
|
|
|
+ 3339 IF isHigh THEN
|
|
|
+ 3340 DEC(c1)
|
|
|
+ 3341 END;
|
|
|
+ 3342 QbeGen.IntStr(c1, qr);
|
|
|
+ 3343 t := SymTab.IntType();
|
|
|
+ 3344 QbeGen.CopyOp(qr, q)
|
|
|
+ 3345 ELSIF dt = SymTab.InvalidType THEN
|
|
|
+ 3346 t := SymTab.InvalidType;
|
|
|
+ 3347 QbeGen.CopyOp("0", q)
|
|
|
+ 3348 ELSIF SymTab.ClassOf(dt) #
|
|
|
+ 3349 SymTab.ClArray THEN
|
|
|
+ 3350 SemError(217);
|
|
|
+ 3351 t := SymTab.InvalidType;
|
|
|
+ 3352 QbeGen.CopyOp("0", q)
|
|
|
+ 3353 ELSE
|
|
|
+ 3354 IF isHigh THEN
|
|
|
+ 3355 IF SymTab.IsOpenArray(dt) THEN
|
|
|
+ 3356 QbeGen.OpenHi(qd, qr)
|
|
|
+ 3357 ELSE
|
|
|
+ 3358 QbeGen.IntStr(
|
|
|
+ 3359 SymTab.ArrayHi(dt), qr)
|
|
|
+ 3360 END
|
|
|
+ 3361 ELSE
|
|
|
+ 3362 IF SymTab.IsOpenArray(dt) THEN
|
|
|
+ 3363 QbeGen.LoadCount(qd, qr)
|
|
|
+ 3364 ELSE
|
|
|
+ 3365 QbeGen.IntStr(VAL(
|
|
|
+ 3366 INTEGER,
|
|
|
+ 3367 SymTab.ArrayLen(dt)),
|
|
|
+ 3368 qr)
|
|
|
+ 3369 END
|
|
|
+ 3370 END;
|
|
|
+ 3371 t := SymTab.IntType();
|
|
|
+ 3372 QbeGen.CopyOp(qr, q)
|
|
|
+ 3373 END; .)
|
|
|
+ 3374 | ( "SIZE" | "TSIZE" ) "(" Design<dt, dk, qd, qn, sfx> ")"
|
|
|
+ 3375 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
+ 3376 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "SIZE"));
|
|
|
+ 3377 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
+ 3378 astCur := astNode; astIsLit := TRUE; .)
|
|
|
+ 3379 (. IF dt = SymTab.InvalidType THEN
|
|
|
+ 3380 t := SymTab.InvalidType;
|
|
|
+ 3381 QbeGen.CopyOp("0", q)
|
|
|
+ 3382 ELSE
|
|
|
+ 3383 QbeGen.IntStr(VAL(INTEGER,
|
|
|
+ 3384 SymTab.ObjectSize(dt)), q);
|
|
|
+ 3385 t := SymTab.IntType()
|
|
|
+ 3386 END; .)
|
|
|
+ 3387 | ( "SHIFT" (. isMax := FALSE; .)
|
|
|
+ 3388 | "ROTATE" (. isMax := TRUE; .) )
|
|
|
+ 3389 "(" Expr<et, q> (. astArg2 := astCur; .) "," Expr<et2, q2> ")"
|
|
|
+ 3390 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
+ 3391 IF isMax THEN AST.SetChild(astNode, 0,
|
|
|
+ 3392 AST.MakeLeaf(AST.NkIdent, "ROTATE"))
|
|
|
+ 3393 ELSE AST.SetChild(astNode, 0,
|
|
|
+ 3394 AST.MakeLeaf(AST.NkIdent, "SHIFT")) END;
|
|
|
+ 3395 IF astArg2 # AST.NoNode THEN AST.SetChild(astNode, 1, astArg2) END;
|
|
|
+ 3396 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 2, astCur) END;
|
|
|
+ 3397 astCur := astNode; astIsLit := TRUE;
|
|
|
+ 3398 (* set shift/rotate: isMax
|
|
|
+ 3399 doubles as "rotate" *)
|
|
|
+ 3400 IF (et # SymTab.InvalidType)
|
|
|
+ 3401 AND (SymTab.ClassOf(et) =
|
|
|
+ 3402 SymTab.ClSet) THEN
|
|
|
+ 3403 QbeGen.SetShift(q, q2,
|
|
|
+ 3404 SymTab.SetWords(et),
|
|
|
+ 3405 SymTab.SetCount(et), isMax,
|
|
|
+ 3406 qt);
|
|
|
+ 3407 t := et;
|
|
|
+ 3408 QbeGen.CopyOp(qt, q)
|
|
|
+ 3409 ELSE SemError(230);
|
|
|
+ 3410 t := SymTab.InvalidType;
|
|
|
+ 3411 QbeGen.CopyOp("0", q)
|
|
|
+ 3412 END; .)
|
|
|
+ 3413 | ( "MIN" (. isMax := FALSE; .)
|
|
|
+ 3414 | "MAX" (. isMax := TRUE; .) )
|
|
|
+ 3415 "(" Design<dt, dk, qd, qn, sfx> ")"
|
|
|
+ 3416 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
+ 3417 IF isMax THEN AST.SetChild(astNode, 0,
|
|
|
+ 3418 AST.MakeLeaf(AST.NkIdent, "MAX"))
|
|
|
+ 3419 ELSE AST.SetChild(astNode, 0,
|
|
|
+ 3420 AST.MakeLeaf(AST.NkIdent, "MIN")) END;
|
|
|
+ 3421 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
+ 3422 astCur := astNode; astIsLit := TRUE;
|
|
|
+ 3423 IF (dt # SymTab.InvalidType)
|
|
|
+ 3424 AND (SymTab.ClassOf(dt) = SymTab.ClReal) THEN
|
|
|
+ 3425 (* REAL/LONGREAL: the
|
|
|
+ 3426 implementation bounds *)
|
|
|
+ 3427 IF isMax THEN
|
|
|
+ 3428 QbeGen.NormReal(
|
|
|
+ 3429 "3.402823e38", q)
|
|
|
+ 3430 ELSE QbeGen.NormReal(
|
|
|
+ 3431 "-3.402823e38", q)
|
|
|
+ 3432 END;
|
|
|
+ 3433 t := SymTab.RealType()
|
|
|
+ 3434 ELSIF (dt #
|
|
|
+ 3435 SymTab.InvalidType)
|
|
|
+ 3436 AND (SymTab.ClassOf(dt) =
|
|
|
+ 3437 SymTab.ClLong) THEN
|
|
|
+ 3438 IF isMax THEN
|
|
|
+ 3439 QbeGen.CopyOp(
|
|
|
+ 3440 "9223372036854775807", q)
|
|
|
+ 3441 ELSE QbeGen.CopyOp(
|
|
|
+ 3442 "-9223372036854775808", q)
|
|
|
+ 3443 END;
|
|
|
+ 3444 t := SymTab.LongType()
|
|
|
+ 3445 ELSIF SymTab.TypeBounds(dt, lo,
|
|
|
+ 3446 hi) THEN
|
|
|
+ 3447 IF isMax THEN
|
|
|
+ 3448 QbeGen.IntStr(hi, q)
|
|
|
+ 3449 ELSE QbeGen.IntStr(lo, q)
|
|
|
+ 3450 END;
|
|
|
+ 3451 t := SymTab.IntType()
|
|
|
+ 3452 ELSE SemError(230);
|
|
|
+ 3453 t := SymTab.InvalidType;
|
|
|
+ 3454 QbeGen.CopyOp("0", q)
|
|
|
+ 3455 END; .)
|
|
|
+ 3456 | "ADR" "(" Design<dt, dk, qd, qn, sfx> ")"
|
|
|
+ 3457 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
+ 3458 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "ADR"));
|
|
|
+ 3459 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
+ 3460 astCur := astNode; astIsLit := TRUE; .)
|
|
|
+ 3461 (. IF dt = SymTab.InvalidType THEN
|
|
|
+ 3462 t := SymTab.InvalidType;
|
|
|
+ 3463 QbeGen.CopyOp("0", q)
|
|
|
+ 3464 ELSE
|
|
|
+ 3465 IF sfx THEN
|
|
|
+ 3466 QbeGen.CopyOp(qd, q)
|
|
|
+ 3467 ELSIF (dk = SymTab.KindVar)
|
|
|
+ 3468 OR (dk = SymTab.KindParam) THEN
|
|
|
+ 3469 QbeGen.AddrOf(qn, q)
|
|
|
+ 3470 ELSE SemError(230);
|
|
|
+ 3471 QbeGen.CopyOp("0", q)
|
|
|
+ 3472 END;
|
|
|
+ 3473 t := SymTab.AddrType()
|
|
|
+ 3474 END; .)
|
|
|
+ 3475 | "CHR" "(" Expr<et, q> ")"
|
|
|
+ 3476 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
+ 3477 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "CHR"));
|
|
|
+ 3478 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
+ 3479 astCur := astNode; astIsLit := TRUE; .)
|
|
|
+ 3480 (. IF (et # SymTab.InvalidType)
|
|
|
+ 3481 AND NOT SymTab.IsIntFamily(et) THEN
|
|
|
+ 3482 SemError(211) END;
|
|
|
+ 3483 t := SymTab.CharType(); .)
|
|
|
+ 3484 | ( "ORD" | "ORDL" ) "(" Expr<et, q> ")"
|
|
|
+ 3485 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
+ 3486 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "ORD"));
|
|
|
+ 3487 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
+ 3488 astCur := astNode; astIsLit := TRUE; .)
|
|
|
+ 3489 (. IF et # SymTab.InvalidType THEN
|
|
|
+ 3490 IF (SymTab.ClassOf(et) #
|
|
|
+ 3491 SymTab.ClChar)
|
|
|
+ 3492 AND (SymTab.ClassOf(et) #
|
|
|
+ 3493 SymTab.ClBool)
|
|
|
+ 3494 AND (SymTab.ClassOf(et) #
|
|
|
+ 3495 SymTab.ClEnum)
|
|
|
+ 3496 AND NOT SymTab.IsIntFamily(et) THEN
|
|
|
+ 3497 SemError(211) END
|
|
|
+ 3498 END;
|
|
|
+ 3499 t := SymTab.IntType(); .)
|
|
|
+ 3500 | "CAP" "(" Expr<et, q> ")"
|
|
|
+ 3501 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
+ 3502 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "CAP"));
|
|
|
+ 3503 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
+ 3504 astCur := astNode; astIsLit := TRUE; .)
|
|
|
+ 3505 (. QbeGen.CapQ(q, qa);
|
|
|
+ 3506 QbeGen.CopyOp(qa, q);
|
|
|
+ 3507 t := SymTab.CharType(); .)
|
|
|
+ 3508 | "UCHR" "(" Expr<et, q> ")"
|
|
|
+ 3509 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
+ 3510 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "UCHR"));
|
|
|
+ 3511 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
+ 3512 astCur := astNode; astIsLit := TRUE; .)
|
|
|
+ 3513 (. (* UCHR: the UCHAR constructor.
|
|
|
+ 3514 CHAR -> UCHAR (identity);
|
|
|
+ 3515 INTEGER familly -> UCHAR
|
|
|
+ 3516 (codepoint value). *)
|
|
|
+ 3517 IF (et # SymTab.InvalidType)
|
|
|
+ 3518 AND (SymTab.ClassOf(et) # SymTab.ClChar)
|
|
|
+ 3519 AND NOT SymTab.IsIntFamily(et) THEN
|
|
|
+ 3520 SemError(211) END;
|
|
|
+ 3521 t := SymTab.UCharType(); .)
|
|
|
+ 3522 | "CHR8" "(" Expr<et, q> ")"
|
|
|
+ 3523 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
+ 3524 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "CHR8"));
|
|
|
+ 3525 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
+ 3526 astCur := astNode; astIsLit := TRUE; .)
|
|
|
+ 3527 (. IF (et # SymTab.InvalidType)
|
|
|
+ 3528 AND (SymTab.ClassOf(et) # SymTab.ClUChar) THEN
|
|
|
+ 3529 SemError(211) END;
|
|
|
+ 3530 QbeGen.WidenLong(q, qa);
|
|
|
+ 3531 QbeGen.CheckRange(qa, "0", "255");
|
|
|
+ 3532 t := SymTab.CharType(); .)
|
|
|
+ 3533 | "UORD" "(" Expr<et, q> ")"
|
|
|
+ 3534 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
+ 3535 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "UORD"));
|
|
|
+ 3536 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
+ 3537 astCur := astNode; astIsLit := TRUE; .)
|
|
|
+ 3538 (. (* UORD(u): the codepoint as a
|
|
|
+ 3539 32-bit ordinal (INTEGER),
|
|
|
+ 3540 cf. ORD for CHAR. *)
|
|
|
+ 3541 IF (et # SymTab.InvalidType)
|
|
|
+ 3542 AND (SymTab.ClassOf(et) # SymTab.ClUChar) THEN
|
|
|
+ 3543 SemError(211) END;
|
|
|
+ 3544 t := SymTab.IntType(); .)
|
|
|
+ 3545 | "ABS" "(" Expr<et, q> ")"
|
|
|
+ 3546 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
+ 3547 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "ABS"));
|
|
|
+ 3548 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
+ 3549 astCur := astNode; astIsLit := TRUE; .)
|
|
|
+ 3550 (. IF (et # SymTab.InvalidType)
|
|
|
+ 3551 AND NOT SymTab.IsIntFamily(et)
|
|
|
+ 3552 AND (SymTab.ClassOf(et) #
|
|
|
+ 3553 SymTab.ClReal) THEN
|
|
|
+ 3554 SemError(211)
|
|
|
+ 3555 ELSE QbeGen.AbsQ(q, qa,
|
|
|
+ 3556 SymTab.ClassOf(et) =
|
|
|
+ 3557 SymTab.ClReal);
|
|
|
+ 3558 QbeGen.CopyOp(qa, q)
|
|
|
+ 3559 END;
|
|
|
+ 3560 t := et; .)
|
|
|
+ 3561 | "VAL" "(" GetIdent<vn> (. astArg2 := AST.MakeLeaf(AST.NkIdent, vn); .) "," Expr<et, q> ")"
|
|
|
+ 3562 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
+ 3563 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "VAL"));
|
|
|
+ 3564 IF astArg2 # AST.NoNode THEN AST.SetChild(astNode, 1, astArg2) END;
|
|
|
+ 3565 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 2, astCur) END;
|
|
|
+ 3566 astCur := astNode; astIsLit := TRUE; .)
|
|
|
+ 3567 (. IF NOT SymTab.Lookup(vn) THEN
|
|
|
+ 3568 SemError(201);
|
|
|
+ 3569 t := SymTab.InvalidType
|
|
|
+ 3570 ELSE vt := SymTab.SymType(vn);
|
|
|
+ 3571 IF vt = SymTab.InvalidType THEN
|
|
|
+ 3572 t := SymTab.InvalidType
|
|
|
+ 3573 ELSIF et =
|
|
|
+ 3574 SymTab.InvalidType THEN
|
|
|
+ 3575 t := vt
|
|
|
+ 3576 ELSE
|
|
|
+ 3577 c1 := SymTab.ClassOf(et);
|
|
|
+ 3578 c2 := SymTab.ClassOf(vt);
|
|
|
+ 3579 IF (c1 = SymTab.ClInt)
|
|
|
+ 3580 AND (c2 = SymTab.ClLong) THEN
|
|
|
+ 3581 QbeGen.WidenLong(q, qa);
|
|
|
+ 3582 QbeGen.CopyOp(qa, q);
|
|
|
+ 3583 t := vt
|
|
|
+ 3584 ELSIF (c1 = SymTab.ClLong)
|
|
|
+ 3585 AND (c2 = SymTab.ClInt) THEN
|
|
|
+ 3586 QbeGen.NarrowLong(q, qa);
|
|
|
+ 3587 QbeGen.CopyOp(qa, q);
|
|
|
+ 3588 t := vt
|
|
|
+ 3589 ELSIF (c1 = SymTab.ClInt)
|
|
|
+ 3590 AND (c2 = SymTab.ClReal) THEN
|
|
|
+ 3591 QbeGen.ConvIR(q, qa);
|
|
|
+ 3592 QbeGen.CopyOp(qa, q);
|
|
|
+ 3593 t := vt
|
|
|
+ 3594 ELSIF (c1 = SymTab.ClLong)
|
|
|
+ 3595 AND (c2 = SymTab.ClReal) THEN
|
|
|
+ 3596 QbeGen.ConvLR(q, qa);
|
|
|
+ 3597 QbeGen.CopyOp(qa, q);
|
|
|
+ 3598 t := vt
|
|
|
+ 3599 ELSIF (c1 = SymTab.ClReal)
|
|
|
+ 3600 AND (c2 = SymTab.ClInt) THEN
|
|
|
+ 3601 QbeGen.ConvRI(q, qa);
|
|
|
+ 3602 QbeGen.CopyOp(qa, q);
|
|
|
+ 3603 t := vt
|
|
|
+ 3604 ELSIF (c1 = SymTab.ClReal)
|
|
|
+ 3605 AND (c2 = SymTab.ClLong) THEN
|
|
|
+ 3606 QbeGen.ConvRL(q, qa);
|
|
|
+ 3607 QbeGen.CopyOp(qa, q);
|
|
|
+ 3608 t := vt
|
|
|
+ 3609 ELSIF ((c1 = SymTab.ClInt)
|
|
|
3610 OR (c1 =
|
|
|
- 3611 SymTab.ClEnum))
|
|
|
- 3612 AND ((c2 = SymTab.ClInt)
|
|
|
- 3613 OR (c2 =
|
|
|
- 3614 SymTab.ClChar)
|
|
|
- 3615 OR (c2 =
|
|
|
- 3616 SymTab.ClBool)
|
|
|
+ 3611 SymTab.ClChar)
|
|
|
+ 3612 OR (c1 =
|
|
|
+ 3613 SymTab.ClBool)
|
|
|
+ 3614 OR (c1 =
|
|
|
+ 3615 SymTab.ClEnum))
|
|
|
+ 3616 AND ((c2 = SymTab.ClInt)
|
|
|
3617 OR (c2 =
|
|
|
- 3618 SymTab.ClEnum)) THEN
|
|
|
- 3619 t := vt
|
|
|
- 3620 ELSIF (c1 = SymTab.ClPtr)
|
|
|
- 3621 AND (c2 = SymTab.ClPtr) THEN
|
|
|
- 3622 t := vt
|
|
|
- 3623 ELSIF (c1 = SymTab.ClReal)
|
|
|
- 3624 AND (c2 = SymTab.ClReal) THEN
|
|
|
- 3625 t := vt
|
|
|
- 3626 ELSE SemError(230);
|
|
|
- 3627 t := SymTab.InvalidType
|
|
|
- 3628 END
|
|
|
- 3629 END
|
|
|
- 3630 END; .)
|
|
|
- 3631 | "(" Expr<et, q> ")" (. t := et; astIsLit := TRUE; .)
|
|
|
- 3632 | SetLit<st, sq> (. astIsLit := TRUE; t := st;
|
|
|
- 3633 QbeGen.CopyOp(sq, q); .)
|
|
|
- 3634 | ( "NOT" | "~" ) Fact<t2, q2> (. astNot := astCur;
|
|
|
- 3635 IF SymTab.BoolCheck(t2) THEN
|
|
|
- 3636 t := SymTab.BoolType()
|
|
|
- 3637 ELSE SemError(212);
|
|
|
- 3638 t := SymTab.InvalidType END;
|
|
|
- 3639 IF t # SymTab.InvalidType THEN
|
|
|
- 3640 QbeGen.NotQ(q2, q)
|
|
|
- 3641 ELSE QbeGen.CopyOp("0", q)
|
|
|
- 3642 END;
|
|
|
- 3643 astIsLit := TRUE;
|
|
|
- 3644 astCur := AST.MakeUn(
|
|
|
- 3645 AST.NkUnary, AST.OpNot, astNot); .)
|
|
|
- 3646 )
|
|
|
- 3647 (. IF NOT astIsLit THEN astCur := AST.NoNode END; .) .
|
|
|
- 3648 (* Set literals are SET OF [0..255] (8 words); elements validated
|
|
|
- 3649 0..255 statically when foldable (222 otherwise), runtime trap
|
|
|
- 3650 for computed elements. Ranges always lower via SetRange. *)
|
|
|
- 3651 SetLit<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
- 3652 (. VAR astNode: AST.Node; .)
|
|
|
- 3653 = "{" (. t := SymTab.NewSet(
|
|
|
- 3654 SymTab.NewSubR(0, 255));
|
|
|
- 3655 astNode := AST.MakeNode(AST.NkSetLit);
|
|
|
- 3656 QbeGen.NewSetTemp(8, q);
|
|
|
- 3657 QbeGen.SetZero(q, 8); .)
|
|
|
- 3658 [ SetElem<t, q, astNode> { "," SetElem<t, q, astNode> } ]
|
|
|
- 3659 "}" (. astCur := astNode; .) .
|
|
|
- 3660 (* Typed brace constructor: TypeName{ elems } — BITSET{0} (a set)
|
|
|
- 3661 or ArrayName{...} (an array constructor, GNU Modula-2). The
|
|
|
- 3662 declared type sets the width (set) or element type (array). *)
|
|
|
- 3663 TypedBraceLit<vt: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
- 3664 (. VAR nw: CARDINAL;
|
|
|
- 3665 astNode: AST.Node;
|
|
|
- 3666 savedCls: INTEGER; .)
|
|
|
- 3667 = "{" (. savedCls := braceCls;
|
|
|
- 3668 astNode := AST.MakeNode(AST.NkBraceLit);
|
|
|
- 3669 IF vt = SymTab.InvalidType THEN
|
|
|
- 3670 braceCls := -1
|
|
|
- 3671 ELSE braceCls :=
|
|
|
- 3672 SymTab.ClassOf(vt)
|
|
|
- 3673 END;
|
|
|
- 3674 IF braceCls = SymTab.ClSet THEN
|
|
|
- 3675 IF vt = SymTab.InvalidType THEN
|
|
|
- 3676 nw := 8
|
|
|
- 3677 ELSE nw := SymTab.SetWords(vt);
|
|
|
- 3678 IF nw = 0 THEN nw := 8 END
|
|
|
- 3679 END;
|
|
|
- 3680 QbeGen.NewSetTemp(nw, q);
|
|
|
- 3681 QbeGen.SetZero(q, nw)
|
|
|
- 3682 ELSIF (braceCls =
|
|
|
- 3683 SymTab.ClArray)
|
|
|
- 3684 OR (braceCls =
|
|
|
- 3685 SymTab.ClRecord)
|
|
|
- 3686 OR (braceCls =
|
|
|
- 3687 SymTab.ClClass) THEN
|
|
|
- 3688 QbeGen.CtorBegin(vt)
|
|
|
- 3689 ELSE
|
|
|
- 3690 IF vt # SymTab.InvalidType THEN
|
|
|
- 3691 SemError(230) END;
|
|
|
- 3692 braceCls := -1
|
|
|
- 3693 END; .)
|
|
|
- 3694 [ BraceElem<vt, q, astNode> { "," BraceElem<vt, q, astNode> } ]
|
|
|
- 3695 "}" (. IF (braceCls = SymTab.ClArray)
|
|
|
- 3696 OR (braceCls =
|
|
|
- 3697 SymTab.ClRecord)
|
|
|
- 3698 OR (braceCls =
|
|
|
- 3699 SymTab.ClClass) THEN
|
|
|
- 3700 QbeGen.CtorEnd(q)
|
|
|
- 3701 ELSIF braceCls # SymTab.ClSet THEN
|
|
|
- 3702 QbeGen.CopyOp("0", q)
|
|
|
- 3703 END;
|
|
|
- 3704 braceCls := savedCls; .)
|
|
|
- 3705 (. astCur := astNode; .) .
|
|
|
- 3706 BraceElem<vt: SymTab.TypeIndex; VAR sq: QbeGen.QVal; node: AST.Node>
|
|
|
- 3707 (. VAR et, et2: SymTab.TypeIndex;
|
|
|
- 3708 qe, q2: QbeGen.QVal;
|
|
|
- 3709 v, v2, reps, k: INTEGER;
|
|
|
- 3710 elem: SymTab.TypeIndex;
|
|
|
- 3711 lo: INTEGER;
|
|
|
- 3712 span: CARDINAL;
|
|
|
- 3713 cl, cl2: INTEGER;
|
|
|
- 3714 hasR, hasB: BOOLEAN;
|
|
|
- 3715 astEl: AST.Node; .)
|
|
|
- 3716 = (. hasR := FALSE; hasB := FALSE; .)
|
|
|
- 3717 Expr<et, qe> (. astEl := astCur; .)
|
|
|
- 3718 [ ".." Expr<et2, q2> (. astEl := AST.MakeBin(
|
|
|
- 3719 AST.NkSubrange, 0, astEl, astCur);
|
|
|
- 3720 hasR := TRUE; .) ]
|
|
|
- 3721 [ "BY" Expr<et2, q2> (. hasB := TRUE; .) ]
|
|
|
- 3722 (. IF braceCls = SymTab.ClSet THEN
|
|
|
- 3723 IF hasB THEN SemError(230) END;
|
|
|
- 3724 lo := SymTab.SetBaseLo(vt);
|
|
|
- 3725 span := SymTab.SetCount(vt);
|
|
|
- 3726 IF (et = SymTab.InvalidType)
|
|
|
- 3727 OR (hasR AND (et2 =
|
|
|
- 3728 SymTab.InvalidType)) THEN
|
|
|
- 3729 ELSE cl :=
|
|
|
- 3730 SymTab.ClassOf(et);
|
|
|
- 3731 IF hasR THEN
|
|
|
- 3732 cl2 :=
|
|
|
- 3733 SymTab.ClassOf(et2)
|
|
|
- 3734 ELSE cl2 := SymTab.ClInt
|
|
|
- 3735 END;
|
|
|
- 3736 IF NOT SymTab.SetElemClassOk(cl)
|
|
|
- 3737 OR (hasR AND NOT
|
|
|
- 3738 SymTab.SetElemClassOk(cl2))
|
|
|
- 3739 THEN
|
|
|
- 3740 SemError(222)
|
|
|
- 3741 ELSIF hasR
|
|
|
- 3742 AND SymTab.ConstInt(qe, v)
|
|
|
- 3743 AND SymTab.ConstInt(q2,
|
|
|
- 3744 v2)
|
|
|
- 3745 AND ((v < lo)
|
|
|
- 3746 OR (v2 < lo)
|
|
|
- 3747 OR (v >= lo +
|
|
|
- 3748 VAL(INTEGER, span))
|
|
|
- 3749 OR (v2 >= lo +
|
|
|
- 3750 VAL(INTEGER, span))
|
|
|
- 3751 OR (v > v2)) THEN
|
|
|
- 3752 SemError(222)
|
|
|
- 3753 ELSIF hasR THEN
|
|
|
- 3754 QbeGen.SetRange(sq, qe, q2,
|
|
|
- 3755 lo, span)
|
|
|
- 3756 ELSIF SymTab.ConstInt(qe,
|
|
|
- 3757 v)
|
|
|
- 3758 AND ((v < lo)
|
|
|
- 3759 OR (v >= lo +
|
|
|
- 3760 VAL(INTEGER,
|
|
|
- 3761 span))) THEN
|
|
|
- 3762 SemError(222)
|
|
|
- 3763 ELSE QbeGen.SetBit(sq, qe,
|
|
|
- 3764 lo, span)
|
|
|
- 3765 END
|
|
|
- 3766 END
|
|
|
- 3767 ELSIF (braceCls = SymTab.ClArray)
|
|
|
- 3768 OR (braceCls =
|
|
|
- 3769 SymTab.ClRecord)
|
|
|
- 3770 OR (braceCls =
|
|
|
- 3771 SymTab.ClClass) THEN
|
|
|
- 3772 IF hasR THEN SemError(230) END;
|
|
|
- 3773 reps := 1;
|
|
|
- 3774 IF hasB THEN
|
|
|
- 3775 IF SymTab.ConstInt(q2, v2)
|
|
|
- 3776 AND (v2 >= 1) THEN
|
|
|
- 3777 reps := v2
|
|
|
- 3778 ELSE SemError(230)
|
|
|
- 3779 END
|
|
|
- 3780 END;
|
|
|
- 3781 k := 0;
|
|
|
- 3782 WHILE k < reps DO
|
|
|
- 3783 QbeGen.CtorElem(qe);
|
|
|
- 3784 INC(k)
|
|
|
- 3785 END
|
|
|
- 3786 END; .)
|
|
|
- 3787 (. AST.SetChild(node,
|
|
|
- 3788 AST.NChild(node), astEl); .) .
|
|
|
- 3789 SetElem<st: SymTab.TypeIndex; sq: QbeGen.QVal; node: AST.Node> (. VAR et, et2: SymTab.TypeIndex;
|
|
|
- 3790 qe, q2: QbeGen.QVal;
|
|
|
- 3791 v, v2: INTEGER;
|
|
|
- 3792 lo: INTEGER;
|
|
|
- 3793 span: CARDINAL;
|
|
|
- 3794 cl, cl2: INTEGER;
|
|
|
- 3795 hasR: BOOLEAN;
|
|
|
- 3796 astEl: AST.Node; .)
|
|
|
- 3797 = (. hasR := FALSE; .)
|
|
|
- 3798 Expr<et, qe> (. astEl := astCur; .)
|
|
|
- 3799 [ ".." Expr<et2, q2> (. astEl := AST.MakeBin(
|
|
|
- 3800 AST.NkSubrange, 0, astEl, astCur);
|
|
|
- 3801 hasR := TRUE; .) ]
|
|
|
- 3802 (. lo := SymTab.SetBaseLo(st);
|
|
|
- 3803 span := SymTab.SetCount(st);
|
|
|
- 3804 IF (et = SymTab.InvalidType)
|
|
|
- 3805 OR (hasR AND (et2 =
|
|
|
- 3806 SymTab.InvalidType)) THEN
|
|
|
- 3807 ELSE cl :=
|
|
|
- 3808 SymTab.ClassOf(et);
|
|
|
- 3809 IF hasR THEN
|
|
|
- 3810 cl2 :=
|
|
|
- 3811 SymTab.ClassOf(et2)
|
|
|
- 3812 ELSE cl2 := SymTab.ClInt
|
|
|
- 3813 END;
|
|
|
- 3814 IF NOT SymTab.SetElemClassOk(cl)
|
|
|
- 3815 OR (hasR AND NOT
|
|
|
- 3816 SymTab.SetElemClassOk(cl2))
|
|
|
- 3817 THEN
|
|
|
- 3818 SemError(222)
|
|
|
- 3819 ELSIF hasR
|
|
|
- 3820 AND SymTab.ConstInt(qe, v)
|
|
|
- 3821 AND SymTab.ConstInt(q2,
|
|
|
- 3822 v2)
|
|
|
- 3823 AND ((v < lo)
|
|
|
- 3824 OR (v2 < lo)
|
|
|
- 3825 OR (v >= lo +
|
|
|
- 3826 VAL(INTEGER, span))
|
|
|
- 3827 OR (v2 >= lo +
|
|
|
- 3828 VAL(INTEGER, span))
|
|
|
- 3829 OR (v > v2)) THEN
|
|
|
- 3830 SemError(222)
|
|
|
- 3831 ELSIF hasR THEN
|
|
|
- 3832 QbeGen.SetRange(sq, qe, q2,
|
|
|
- 3833 lo, span)
|
|
|
- 3834 ELSIF SymTab.ConstInt(qe,
|
|
|
- 3835 v)
|
|
|
- 3836 AND ((v < lo)
|
|
|
- 3837 OR (v >= lo +
|
|
|
- 3838 VAL(INTEGER,
|
|
|
- 3839 span))) THEN
|
|
|
- 3840 SemError(222)
|
|
|
- 3841 ELSE QbeGen.SetBit(sq, qe,
|
|
|
- 3842 lo, span)
|
|
|
- 3843 END
|
|
|
- 3844 END; .)
|
|
|
- 3845 (. AST.SetChild(node,
|
|
|
- 3846 AST.NChild(node), astEl); .) .
|
|
|
- 3847 GetIdent<VAR n: SymTab.Name>
|
|
|
- 3848 = ident (. LexName(n); .) .
|
|
|
- 3849
|
|
|
- 3850 END M2.
|
|
|
+ 3618 SymTab.ClChar)
|
|
|
+ 3619 OR (c2 =
|
|
|
+ 3620 SymTab.ClBool)
|
|
|
+ 3621 OR (c2 =
|
|
|
+ 3622 SymTab.ClEnum)) THEN
|
|
|
+ 3623 t := vt
|
|
|
+ 3624 ELSIF (c1 = SymTab.ClPtr)
|
|
|
+ 3625 AND (c2 = SymTab.ClPtr) THEN
|
|
|
+ 3626 t := vt
|
|
|
+ 3627 ELSIF (c1 = SymTab.ClReal)
|
|
|
+ 3628 AND (c2 = SymTab.ClReal) THEN
|
|
|
+ 3629 t := vt
|
|
|
+ 3630 ELSE SemError(230);
|
|
|
+ 3631 t := SymTab.InvalidType
|
|
|
+ 3632 END
|
|
|
+ 3633 END
|
|
|
+ 3634 END; .)
|
|
|
+ 3635 | "(" Expr<et, q> ")" (. t := et; astIsLit := TRUE; .)
|
|
|
+ 3636 | SetLit<st, sq> (. astIsLit := TRUE; t := st;
|
|
|
+ 3637 QbeGen.CopyOp(sq, q); .)
|
|
|
+ 3638 | ( "NOT" | "~" ) Fact<t2, q2> (. astNot := astCur;
|
|
|
+ 3639 IF SymTab.BoolCheck(t2) THEN
|
|
|
+ 3640 t := SymTab.BoolType()
|
|
|
+ 3641 ELSE SemError(212);
|
|
|
+ 3642 t := SymTab.InvalidType END;
|
|
|
+ 3643 IF t # SymTab.InvalidType THEN
|
|
|
+ 3644 QbeGen.NotQ(q2, q)
|
|
|
+ 3645 ELSE QbeGen.CopyOp("0", q)
|
|
|
+ 3646 END;
|
|
|
+ 3647 astIsLit := TRUE;
|
|
|
+ 3648 astCur := AST.MakeUn(
|
|
|
+ 3649 AST.NkUnary, AST.OpNot, astNot); .)
|
|
|
+ 3650 )
|
|
|
+ 3651 (. IF NOT astIsLit THEN astCur := AST.NoNode END; .) .
|
|
|
+ 3652 (* Set literals are SET OF [0..255] (8 words); elements validated
|
|
|
+ 3653 0..255 statically when foldable (222 otherwise), runtime trap
|
|
|
+ 3654 for computed elements. Ranges always lower via SetRange. *)
|
|
|
+ 3655 SetLit<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
+ 3656 (. VAR astNode: AST.Node; .)
|
|
|
+ 3657 = "{" (. t := SymTab.NewSet(
|
|
|
+ 3658 SymTab.NewSubR(0, 255));
|
|
|
+ 3659 astNode := AST.MakeNode(AST.NkSetLit);
|
|
|
+ 3660 QbeGen.NewSetTemp(8, q);
|
|
|
+ 3661 QbeGen.SetZero(q, 8); .)
|
|
|
+ 3662 [ SetElem<t, q, astNode> { "," SetElem<t, q, astNode> } ]
|
|
|
+ 3663 "}" (. astCur := astNode; .) .
|
|
|
+ 3664 (* Typed brace constructor: TypeName{ elems } — BITSET{0} (a set)
|
|
|
+ 3665 or ArrayName{...} (an array constructor, GNU Modula-2). The
|
|
|
+ 3666 declared type sets the width (set) or element type (array). *)
|
|
|
+ 3667 TypedBraceLit<vt: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
+ 3668 (. VAR nw: CARDINAL;
|
|
|
+ 3669 astNode: AST.Node;
|
|
|
+ 3670 savedCls: INTEGER; .)
|
|
|
+ 3671 = "{" (. savedCls := braceCls;
|
|
|
+ 3672 astNode := AST.MakeNode(AST.NkBraceLit);
|
|
|
+ 3673 IF vt = SymTab.InvalidType THEN
|
|
|
+ 3674 braceCls := -1
|
|
|
+ 3675 ELSE braceCls :=
|
|
|
+ 3676 SymTab.ClassOf(vt)
|
|
|
+ 3677 END;
|
|
|
+ 3678 IF braceCls = SymTab.ClSet THEN
|
|
|
+ 3679 IF vt = SymTab.InvalidType THEN
|
|
|
+ 3680 nw := 8
|
|
|
+ 3681 ELSE nw := SymTab.SetWords(vt);
|
|
|
+ 3682 IF nw = 0 THEN nw := 8 END
|
|
|
+ 3683 END;
|
|
|
+ 3684 QbeGen.NewSetTemp(nw, q);
|
|
|
+ 3685 QbeGen.SetZero(q, nw)
|
|
|
+ 3686 ELSIF (braceCls =
|
|
|
+ 3687 SymTab.ClArray)
|
|
|
+ 3688 OR (braceCls =
|
|
|
+ 3689 SymTab.ClRecord)
|
|
|
+ 3690 OR (braceCls =
|
|
|
+ 3691 SymTab.ClClass) THEN
|
|
|
+ 3692 QbeGen.CtorBegin(vt)
|
|
|
+ 3693 ELSE
|
|
|
+ 3694 IF vt # SymTab.InvalidType THEN
|
|
|
+ 3695 SemError(230) END;
|
|
|
+ 3696 braceCls := -1
|
|
|
+ 3697 END; .)
|
|
|
+ 3698 [ BraceElem<vt, q, astNode> { "," BraceElem<vt, q, astNode> } ]
|
|
|
+ 3699 "}" (. IF (braceCls = SymTab.ClArray)
|
|
|
+ 3700 OR (braceCls =
|
|
|
+ 3701 SymTab.ClRecord)
|
|
|
+ 3702 OR (braceCls =
|
|
|
+ 3703 SymTab.ClClass) THEN
|
|
|
+ 3704 QbeGen.CtorEnd(q)
|
|
|
+ 3705 ELSIF braceCls # SymTab.ClSet THEN
|
|
|
+ 3706 QbeGen.CopyOp("0", q)
|
|
|
+ 3707 END;
|
|
|
+ 3708 braceCls := savedCls; .)
|
|
|
+ 3709 (. astCur := astNode; .) .
|
|
|
+ 3710 BraceElem<vt: SymTab.TypeIndex; VAR sq: QbeGen.QVal; node: AST.Node>
|
|
|
+ 3711 (. VAR et, et2: SymTab.TypeIndex;
|
|
|
+ 3712 qe, q2: QbeGen.QVal;
|
|
|
+ 3713 v, v2, reps, k: INTEGER;
|
|
|
+ 3714 elem: SymTab.TypeIndex;
|
|
|
+ 3715 lo: INTEGER;
|
|
|
+ 3716 span: CARDINAL;
|
|
|
+ 3717 cl, cl2: INTEGER;
|
|
|
+ 3718 hasR, hasB: BOOLEAN;
|
|
|
+ 3719 astEl: AST.Node; .)
|
|
|
+ 3720 = (. hasR := FALSE; hasB := FALSE; .)
|
|
|
+ 3721 Expr<et, qe> (. astEl := astCur; .)
|
|
|
+ 3722 [ ".." Expr<et2, q2> (. astEl := AST.MakeBin(
|
|
|
+ 3723 AST.NkSubrange, 0, astEl, astCur);
|
|
|
+ 3724 hasR := TRUE; .) ]
|
|
|
+ 3725 [ "BY" Expr<et2, q2> (. hasB := TRUE; .) ]
|
|
|
+ 3726 (. IF braceCls = SymTab.ClSet THEN
|
|
|
+ 3727 IF hasB THEN SemError(230) END;
|
|
|
+ 3728 lo := SymTab.SetBaseLo(vt);
|
|
|
+ 3729 span := SymTab.SetCount(vt);
|
|
|
+ 3730 IF (et = SymTab.InvalidType)
|
|
|
+ 3731 OR (hasR AND (et2 =
|
|
|
+ 3732 SymTab.InvalidType)) THEN
|
|
|
+ 3733 ELSE cl :=
|
|
|
+ 3734 SymTab.ClassOf(et);
|
|
|
+ 3735 IF hasR THEN
|
|
|
+ 3736 cl2 :=
|
|
|
+ 3737 SymTab.ClassOf(et2)
|
|
|
+ 3738 ELSE cl2 := SymTab.ClInt
|
|
|
+ 3739 END;
|
|
|
+ 3740 IF NOT SymTab.SetElemClassOk(cl)
|
|
|
+ 3741 OR (hasR AND NOT
|
|
|
+ 3742 SymTab.SetElemClassOk(cl2))
|
|
|
+ 3743 THEN
|
|
|
+ 3744 SemError(222)
|
|
|
+ 3745 ELSIF hasR
|
|
|
+ 3746 AND SymTab.ConstInt(qe, v)
|
|
|
+ 3747 AND SymTab.ConstInt(q2,
|
|
|
+ 3748 v2)
|
|
|
+ 3749 AND ((v < lo)
|
|
|
+ 3750 OR (v2 < lo)
|
|
|
+ 3751 OR (v >= lo +
|
|
|
+ 3752 VAL(INTEGER, span))
|
|
|
+ 3753 OR (v2 >= lo +
|
|
|
+ 3754 VAL(INTEGER, span))
|
|
|
+ 3755 OR (v > v2)) THEN
|
|
|
+ 3756 SemError(222)
|
|
|
+ 3757 ELSIF hasR THEN
|
|
|
+ 3758 QbeGen.SetRange(sq, qe, q2,
|
|
|
+ 3759 lo, span)
|
|
|
+ 3760 ELSIF SymTab.ConstInt(qe,
|
|
|
+ 3761 v)
|
|
|
+ 3762 AND ((v < lo)
|
|
|
+ 3763 OR (v >= lo +
|
|
|
+ 3764 VAL(INTEGER,
|
|
|
+ 3765 span))) THEN
|
|
|
+ 3766 SemError(222)
|
|
|
+ 3767 ELSE QbeGen.SetBit(sq, qe,
|
|
|
+ 3768 lo, span)
|
|
|
+ 3769 END
|
|
|
+ 3770 END
|
|
|
+ 3771 ELSIF (braceCls = SymTab.ClArray)
|
|
|
+ 3772 OR (braceCls =
|
|
|
+ 3773 SymTab.ClRecord)
|
|
|
+ 3774 OR (braceCls =
|
|
|
+ 3775 SymTab.ClClass) THEN
|
|
|
+ 3776 IF hasR THEN SemError(230) END;
|
|
|
+ 3777 reps := 1;
|
|
|
+ 3778 IF hasB THEN
|
|
|
+ 3779 IF SymTab.ConstInt(q2, v2)
|
|
|
+ 3780 AND (v2 >= 1) THEN
|
|
|
+ 3781 reps := v2
|
|
|
+ 3782 ELSE SemError(230)
|
|
|
+ 3783 END
|
|
|
+ 3784 END;
|
|
|
+ 3785 k := 0;
|
|
|
+ 3786 WHILE k < reps DO
|
|
|
+ 3787 QbeGen.CtorElem(qe);
|
|
|
+ 3788 INC(k)
|
|
|
+ 3789 END
|
|
|
+ 3790 END; .)
|
|
|
+ 3791 (. AST.SetChild(node,
|
|
|
+ 3792 AST.NChild(node), astEl); .) .
|
|
|
+ 3793 SetElem<st: SymTab.TypeIndex; sq: QbeGen.QVal; node: AST.Node> (. VAR et, et2: SymTab.TypeIndex;
|
|
|
+ 3794 qe, q2: QbeGen.QVal;
|
|
|
+ 3795 v, v2: INTEGER;
|
|
|
+ 3796 lo: INTEGER;
|
|
|
+ 3797 span: CARDINAL;
|
|
|
+ 3798 cl, cl2: INTEGER;
|
|
|
+ 3799 hasR: BOOLEAN;
|
|
|
+ 3800 astEl: AST.Node; .)
|
|
|
+ 3801 = (. hasR := FALSE; .)
|
|
|
+ 3802 Expr<et, qe> (. astEl := astCur; .)
|
|
|
+ 3803 [ ".." Expr<et2, q2> (. astEl := AST.MakeBin(
|
|
|
+ 3804 AST.NkSubrange, 0, astEl, astCur);
|
|
|
+ 3805 hasR := TRUE; .) ]
|
|
|
+ 3806 (. lo := SymTab.SetBaseLo(st);
|
|
|
+ 3807 span := SymTab.SetCount(st);
|
|
|
+ 3808 IF (et = SymTab.InvalidType)
|
|
|
+ 3809 OR (hasR AND (et2 =
|
|
|
+ 3810 SymTab.InvalidType)) THEN
|
|
|
+ 3811 ELSE cl :=
|
|
|
+ 3812 SymTab.ClassOf(et);
|
|
|
+ 3813 IF hasR THEN
|
|
|
+ 3814 cl2 :=
|
|
|
+ 3815 SymTab.ClassOf(et2)
|
|
|
+ 3816 ELSE cl2 := SymTab.ClInt
|
|
|
+ 3817 END;
|
|
|
+ 3818 IF NOT SymTab.SetElemClassOk(cl)
|
|
|
+ 3819 OR (hasR AND NOT
|
|
|
+ 3820 SymTab.SetElemClassOk(cl2))
|
|
|
+ 3821 THEN
|
|
|
+ 3822 SemError(222)
|
|
|
+ 3823 ELSIF hasR
|
|
|
+ 3824 AND SymTab.ConstInt(qe, v)
|
|
|
+ 3825 AND SymTab.ConstInt(q2,
|
|
|
+ 3826 v2)
|
|
|
+ 3827 AND ((v < lo)
|
|
|
+ 3828 OR (v2 < lo)
|
|
|
+ 3829 OR (v >= lo +
|
|
|
+ 3830 VAL(INTEGER, span))
|
|
|
+ 3831 OR (v2 >= lo +
|
|
|
+ 3832 VAL(INTEGER, span))
|
|
|
+ 3833 OR (v > v2)) THEN
|
|
|
+ 3834 SemError(222)
|
|
|
+ 3835 ELSIF hasR THEN
|
|
|
+ 3836 QbeGen.SetRange(sq, qe, q2,
|
|
|
+ 3837 lo, span)
|
|
|
+ 3838 ELSIF SymTab.ConstInt(qe,
|
|
|
+ 3839 v)
|
|
|
+ 3840 AND ((v < lo)
|
|
|
+ 3841 OR (v >= lo +
|
|
|
+ 3842 VAL(INTEGER,
|
|
|
+ 3843 span))) THEN
|
|
|
+ 3844 SemError(222)
|
|
|
+ 3845 ELSE QbeGen.SetBit(sq, qe,
|
|
|
+ 3846 lo, span)
|
|
|
+ 3847 END
|
|
|
+ 3848 END; .)
|
|
|
+ 3849 (. AST.SetChild(node,
|
|
|
+ 3850 AST.NChild(node), astEl); .) .
|
|
|
+ 3851 GetIdent<VAR n: SymTab.Name>
|
|
|
+ 3852 = ident (. LexName(n); .) .
|
|
|
+ 3853
|
|
|
+ 3854 END M2.
|
|
|
|
|
|
0 errors
|
|
|
|