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