|
@@ -85,3203 +85,3234 @@ Listing:
|
|
|
67 an outer non-literal Fact look literal. *)
|
|
67 an outer non-literal Fact look literal. *)
|
|
|
68 astCur: AST.Node;
|
|
68 astCur: AST.Node;
|
|
|
69
|
|
69
|
|
|
- 70 (* Class of the method named by the last `obj.Method` designator
|
|
|
|
|
- 71 (InvalidType when the callee is an ordinary procedure). Set by
|
|
|
|
|
- 72 Design, consumed by the following ArgList. *)
|
|
|
|
|
- 73 methCls: SymTab.TypeIndex;
|
|
|
|
|
- 74 (* Class of the type of the innermost `TypeName{...}` brace
|
|
|
|
|
- 75 constructor (ClSet or ClArray); dispatches BraceElem. *)
|
|
|
|
|
- 76 braceCls: INTEGER;
|
|
|
|
|
- 77 (* Module-level VAR declarations whose type was still an unresolved
|
|
|
|
|
- 78 forward alias at declaration time; emitted once the TYPE block
|
|
|
|
|
- 79 completes (module scope only). *)
|
|
|
|
|
- 80 nPendVar: CARDINAL;
|
|
|
|
|
- 81 pendVarName: ARRAY [0 .. 255] OF SymTab.Name;
|
|
|
|
|
- 82 pendVarT: ARRAY [0 .. 255] OF SymTab.TypeIndex;
|
|
|
|
|
- 83 (* Forward module-level variables referenced from a procedure body. *)
|
|
|
|
|
- 84 nFvarRefs: CARDINAL;
|
|
|
|
|
- 85 fvarId: ARRAY [0 .. 255] OF INTEGER;
|
|
|
|
|
- 86 fvarSlot: ARRAY [0 .. 255] OF INTEGER;
|
|
|
|
|
- 87
|
|
|
|
|
- 88 PROCEDURE FlushPend;
|
|
|
|
|
- 89 (* Emit module-level globals whose forward type is now resolved. *)
|
|
|
|
|
- 90 VAR k: CARDINAL;
|
|
|
|
|
- 91 BEGIN
|
|
|
|
|
- 92 k := 0;
|
|
|
|
|
- 93 WHILE k < nPendVar DO
|
|
|
|
|
- 94 QbeGen.DeclVar(pendVarName[k], pendVarT[k]);
|
|
|
|
|
- 95 INC(k)
|
|
|
|
|
- 96 END;
|
|
|
|
|
- 97 nPendVar := 0
|
|
|
|
|
- 98 END FlushPend;
|
|
|
|
|
- 99
|
|
|
|
|
- 100 PROCEDURE FwdVarNote (id, slot: INTEGER);
|
|
|
|
|
- 101 BEGIN
|
|
|
|
|
- 102 IF nFvarRefs <= HIGH(fvarId) THEN
|
|
|
|
|
- 103 fvarId[nFvarRefs] := id;
|
|
|
|
|
- 104 fvarSlot[nFvarRefs] := slot;
|
|
|
|
|
- 105 INC(nFvarRefs)
|
|
|
|
|
- 106 END
|
|
|
|
|
- 107 END FwdVarNote;
|
|
|
|
|
- 108
|
|
|
|
|
- 109 PROCEDURE FwdVarFlush;
|
|
|
|
|
- 110 (* At module end: resolve every forward reference against the declared
|
|
|
|
|
- 111 names (an unresolved one is 201) and patch its placeholder symbol. *)
|
|
|
|
|
- 112 VAR k: CARDINAL; nm, g: SymTab.Name; cls: INTEGER; oper: CHAR;
|
|
|
|
|
- 113 t: SymTab.TypeIndex; ok: BOOLEAN;
|
|
|
|
|
- 114 BEGIN
|
|
|
|
|
- 115 k := 0;
|
|
|
|
|
- 116 WHILE k < nFvarRefs DO
|
|
|
|
|
- 117 SymTab.FwdVarName(fvarId[k], nm);
|
|
|
|
|
- 118 IF nm[0] # CHR(0) THEN
|
|
|
|
|
- 119 IF NOT SymTab.FwdVarResolve(fvarId[k]) THEN
|
|
|
|
|
- 120 SemError(201)
|
|
|
|
|
- 121 ELSE
|
|
|
|
|
- 122 t := SymTab.FwdVarType(fvarId[k]);
|
|
|
|
|
- 123 cls := SymTab.ClassOf(t);
|
|
|
|
|
- 124 IF cls = SymTab.ClReal THEN oper := "d"
|
|
|
|
|
- 125 ELSIF SymTab.IsLongFamily(t) THEN oper := "l"
|
|
|
|
|
- 126 ELSE oper := "w"
|
|
|
|
|
- 127 END;
|
|
|
|
|
- 128 ok := SymTab.GlobalRef(nm, g);
|
|
|
|
|
- 129 QbeGen.FwdPatch(fvarSlot[k], fvarSlot[k], nm, oper, ok)
|
|
|
|
|
- 130 END
|
|
|
|
|
- 131 END;
|
|
|
|
|
- 132 INC(k)
|
|
|
|
|
- 133 END;
|
|
|
|
|
- 134 nFvarRefs := 0
|
|
|
|
|
- 135 END FwdVarFlush;
|
|
|
|
|
- 136
|
|
|
|
|
- 137 CHARACTERS
|
|
|
|
|
- 138 eol = CHR(13) .
|
|
|
|
|
- 139 lf = CHR(10) .
|
|
|
|
|
- 140 letter = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" .
|
|
|
|
|
- 141 digit = "0123456789" .
|
|
|
|
|
- 142 hexDigit = digit + "ABCDEFabcdef" .
|
|
|
|
|
- 143 noQuote1 = ANY - "'" - eol .
|
|
|
|
|
- 144 noQuote2 = ANY - '"' - eol .
|
|
|
|
|
- 145
|
|
|
|
|
- 146 IGNORE CHR(9) .. CHR(13)
|
|
|
|
|
- 147
|
|
|
|
|
- 148 COMMENTS FROM "(*" TO "*)" NESTED
|
|
|
|
|
- 149 COMMENTS FROM "//" TO lf
|
|
|
|
|
- 150
|
|
|
|
|
- 151 TOKENS
|
|
|
|
|
- 152 ident = letter { letter | digit } .
|
|
|
|
|
- 153 integer = digit { digit }
|
|
|
|
|
- 154 | digit { digit } CONTEXT("..")
|
|
|
|
|
- 155 | "0x" hexDigit { hexDigit }
|
|
|
|
|
- 156 | "0X" hexDigit { hexDigit } .
|
|
|
|
|
- 157 real = digit { digit } "." { digit }
|
|
|
|
|
- 158 [ ( "E" | "e" ) [ "+" | "-" ] digit { digit } ] .
|
|
|
|
|
- 159 string = "'" { noQuote1 } "'"
|
|
|
|
|
- 160 | '"' { noQuote2 } '"' .
|
|
|
|
|
- 161 charConst = digit { digit } ( "C" | "c" ) .
|
|
|
|
|
- 162 ustring = ( "U" | "u" ) ( "'" { noQuote1 } "'" | '"' { noQuote2 } '"' ) .
|
|
|
|
|
- 163
|
|
|
|
|
- 164 PRODUCTIONS
|
|
|
|
|
- 165 M2
|
|
|
|
|
- 166 = (. AST.Init; twoPhase := TRUE; astCur := AST.NoNode; .)
|
|
|
|
|
- 167 Unit "." .
|
|
|
|
|
- 168 (* Units: program modules compile fully; DEFINITION and
|
|
|
|
|
- 169 IMPLEMENTATION modules parse + check now but lower in step 4
|
|
|
|
|
- 170 (each ends with one 230); same for nested local modules. *)
|
|
|
|
|
- 171 Unit
|
|
|
|
|
- 172 = DefUnit
|
|
|
|
|
- 173 | ImplUnit
|
|
|
|
|
- 174 | ProgModule .
|
|
|
|
|
- 175 (* Step 4.3: one session compiles DEFINITION, its IMPLEMENTATION
|
|
|
|
|
- 176 and one program (last) into one image. Units share the symbol
|
|
|
|
|
- 177 table; imports materialize exported names. *)
|
|
|
|
|
- 178 DefUnit (. VAR m1, m2, pn: SymTab.Name; .)
|
|
|
|
|
- 179 = "DEFINITION" "MODULE"
|
|
|
|
|
- 180 GetIdent<m1> (. IF NOT SymTab.BeginDef(m1) THEN
|
|
|
|
|
- 181 SemError(200) END;
|
|
|
|
|
- 182 QbeGen.SetModule(m1); .)
|
|
|
|
|
- 183 ";"
|
|
|
|
|
- 184 { Import }
|
|
|
|
|
- 185 [ "EXPORT" [ "QUALIFIED" ] (. (* definition-module export
|
|
|
|
|
- 186 list: parsed, and the
|
|
|
|
|
- 187 names are already exported
|
|
|
|
|
- 188 by the module scope *) .)
|
|
|
|
|
- 189 GetIdent<pn> { "," GetIdent<pn> } ";" ]
|
|
|
|
|
- 190 { ConstBlock | TypeBlock<TRUE> | VarBlock
|
|
|
|
|
- 191 | ProcHeading<pn, SymTab.InvalidType> ";"
|
|
|
|
|
- 192 (. SymTab.CloseProc;
|
|
|
|
|
- 193 QbeGen.AbortFunc; .) }
|
|
|
|
|
- 194 "END"
|
|
|
|
|
- 195 GetIdent<m2> (. IF NOT SymTab.Equal(m1, m2) THEN
|
|
|
|
|
- 196 SemError(202) END;
|
|
|
|
|
- 197 SymTab.EndUnit; .) .
|
|
|
|
|
- 198 ImplUnit (. VAR m1, m2: SymTab.Name;
|
|
|
|
|
- 199 k: CARDINAL;
|
|
|
|
|
- 200 fname: SymTab.Name;
|
|
|
|
|
- 201 unres: BOOLEAN; .)
|
|
|
|
|
- 202 = "IMPLEMENTATION" "MODULE"
|
|
|
|
|
- 203 GetIdent<m1> (. IF NOT SymTab.BeginImpl(m1) THEN
|
|
|
|
|
- 204 SemError(201) END;
|
|
|
|
|
- 205 nPendVar := 0;
|
|
|
|
|
- 206 QbeGen.SetModule(m1); .)
|
|
|
|
|
- 207 ";"
|
|
|
|
|
- 208 { Import }
|
|
|
|
|
- 209 DeclSeq
|
|
|
|
|
- 210 [ "BEGIN" (. FlushPend;
|
|
|
|
|
- 211 k := 0;
|
|
|
|
|
- 212 WHILE k < SymTab.FwdPending() DO
|
|
|
|
|
- 213 SymTab.FwdInfo(k, fname, unres);
|
|
|
|
|
- 214 IF unres THEN SemError(201) END;
|
|
|
|
|
- 215 INC(k)
|
|
|
|
|
- 216 END;
|
|
|
|
|
- 217 SymTab.FwdClear;
|
|
|
|
|
- 218 FwdVarFlush;
|
|
|
|
|
- 219 QbeGen.BeginInit(m1); .)
|
|
|
|
|
- 220 [ StatSeq ] (. QbeGen.EndInit; .) ]
|
|
|
|
|
- 221 "END"
|
|
|
|
|
- 222 GetIdent<m2> (. FlushPend;
|
|
|
|
|
- 223 k := 0;
|
|
|
|
|
- 224 WHILE k < SymTab.FwdPending() DO
|
|
|
|
|
- 225 SymTab.FwdInfo(k, fname, unres);
|
|
|
|
|
- 226 IF unres THEN SemError(201) END;
|
|
|
|
|
- 227 INC(k)
|
|
|
|
|
- 228 END;
|
|
|
|
|
- 229 SymTab.FwdClear;
|
|
|
|
|
- 230 FwdVarFlush;
|
|
|
|
|
- 231 IF NOT SymTab.Equal(m1, m2) THEN
|
|
|
|
|
- 232 SemError(202) END;
|
|
|
|
|
- 233 SymTab.EndUnit; .) .
|
|
|
|
|
- 234 ProgModule (. VAR m1, m2: SymTab.Name;
|
|
|
|
|
- 235 k: CARDINAL;
|
|
|
|
|
- 236 fname: SymTab.Name;
|
|
|
|
|
- 237 unres: BOOLEAN; .)
|
|
|
|
|
- 238 = "MODULE"
|
|
|
|
|
- 239 GetIdent<m1> (. IF NOT SymTab.BeginProg(m1) THEN
|
|
|
|
|
- 240 SemError(200) END;
|
|
|
|
|
- 241 nPendVar := 0;
|
|
|
|
|
- 242 QbeGen.SetModule(m1); .)
|
|
|
|
|
- 243 [ Priority ]
|
|
|
|
|
- 244 ";"
|
|
|
|
|
- 245 { Import }
|
|
|
|
|
- 246 DeclSeq
|
|
|
|
|
- 247 [ "BEGIN" (. FlushPend;
|
|
|
|
|
- 248 k := 0;
|
|
|
|
|
- 249 WHILE k < SymTab.FwdPending() DO
|
|
|
|
|
- 250 SymTab.FwdInfo(k, fname, unres);
|
|
|
|
|
- 251 IF unres THEN SemError(201) END;
|
|
|
|
|
- 252 INC(k)
|
|
|
|
|
- 253 END;
|
|
|
|
|
- 254 SymTab.FwdClear;
|
|
|
|
|
- 255 FwdVarFlush;
|
|
|
|
|
- 256 QbeGen.BeginBody; .)
|
|
|
|
|
- 257 [ StatSeq ] ]
|
|
|
|
|
- 258 "END"
|
|
|
|
|
- 259 GetIdent<m2> (. FlushPend;
|
|
|
|
|
- 260 k := 0;
|
|
|
|
|
- 261 WHILE k < SymTab.FwdPending() DO
|
|
|
|
|
- 262 SymTab.FwdInfo(k, fname, unres);
|
|
|
|
|
- 263 IF unres THEN SemError(201) END;
|
|
|
|
|
- 264 INC(k)
|
|
|
|
|
- 265 END;
|
|
|
|
|
- 266 SymTab.FwdClear;
|
|
|
|
|
- 267 FwdVarFlush;
|
|
|
|
|
- 268 IF NOT SymTab.Equal(m1, m2) THEN
|
|
|
|
|
- 269 SemError(202) END;
|
|
|
|
|
- 270 QbeGen.EndModule(m1);
|
|
|
|
|
- 271 SymTab.EndUnit; .) .
|
|
|
|
|
- 272 DeclSeq
|
|
|
|
|
- 273 = { ConstBlock | TypeBlock<FALSE> | VarBlock | ProcDecl ";"
|
|
|
|
|
- 274 | NestedModule ";" | ClassItem ";" } .
|
|
|
|
|
- 275 (* Local module, Wirth form. Declarations lower like top-level ones
|
|
|
|
|
- 276 (same QBE module prefix); a BEGIN body becomes an init function
|
|
|
|
|
- 277 that main calls; the EXPORT list is hoisted into the enclosing
|
|
|
|
|
- 278 scope at END. *)
|
|
|
|
|
- 279 NestedModule (. VAR m1, m2: SymTab.Name;
|
|
|
|
|
- 280 expNames: ARRAY [0 .. 63] OF SymTab.Name;
|
|
|
|
|
- 281 expCount, k: CARDINAL; .)
|
|
|
|
|
- 282 = "MODULE"
|
|
|
|
|
- 283 GetIdent<m1> (. IF NOT SymTab.Enter(m1,
|
|
|
|
|
- 284 SymTab.KindModule) THEN
|
|
|
|
|
- 285 SemError(200) END;
|
|
|
|
|
- 286 SymTab.PushScope;
|
|
|
|
|
- 287 expCount := 0; .)
|
|
|
|
|
- 288 [ Priority ]
|
|
|
|
|
- 289 ";"
|
|
|
|
|
- 290 { Import }
|
|
|
|
|
- 291 [ "EXPORT" [ "QUALIFIED" ]
|
|
|
|
|
- 292 GetIdent<expNames[expCount]> (. INC(expCount); .)
|
|
|
|
|
- 293 { "," GetIdent<expNames[expCount]>
|
|
|
|
|
- 294 (. INC(expCount); .) }
|
|
|
|
|
- 295 ";" ]
|
|
|
|
|
- 296 DeclSeq
|
|
|
|
|
- 297 [ "BEGIN" (. QbeGen.BeginInit(m1); .)
|
|
|
|
|
- 298 [ StatSeq ] (. QbeGen.EndInit; .) ]
|
|
|
|
|
- 299 "END"
|
|
|
|
|
- 300 GetIdent<m2> (. IF NOT SymTab.Equal(m1, m2) THEN
|
|
|
|
|
- 301 SemError(202) END;
|
|
|
|
|
- 302 k := 0;
|
|
|
|
|
- 303 WHILE k < expCount DO
|
|
|
|
|
- 304 SymTab.ExportUp(expNames[k]);
|
|
|
|
|
- 305 INC(k)
|
|
|
|
|
- 306 END;
|
|
|
|
|
- 307 SymTab.PopScope; .) .
|
|
|
|
|
- 308 Priority
|
|
|
|
|
- 309 = "[" integer "]" (. SemError(230); .) .
|
|
|
|
|
- 310 (* Imports (4.3): FROM materializes the names (unqualified use);
|
|
|
|
|
- 311 plain IMPORT only demands the module exists — qualified `L.x`
|
|
|
|
|
- 312 materializes on first use (Design). *)
|
|
|
|
|
- 313 (* Unknown modules stay unchecked stubs (legacy, so hand-written
|
|
|
|
|
- 314 import lines don't fail); a known module's missing export is
|
|
|
|
|
- 315 201. *)
|
|
|
|
|
- 316 Import (. VAR n: SymTab.Name; .)
|
|
|
|
|
- 317 = "FROM"
|
|
|
|
|
- 318 GetIdent<n>
|
|
|
|
|
- 319 "IMPORT"
|
|
|
|
|
- 320 ImpList<n> ";"
|
|
|
|
|
- 321 | "IMPORT"
|
|
|
|
|
- 322 ImpModList ";" .
|
|
|
|
|
- 323 ImpList<mod: SymTab.Name> (. VAR n: SymTab.Name; .)
|
|
|
|
|
- 324 = ImpName<mod>
|
|
|
|
|
- 325 { "," ImpName<mod> } .
|
|
|
|
|
- 326 (* Pervasive built-ins imported from SYSTEM (e.g. TSIZE) are
|
|
|
|
|
- 327 accepted and ignored: the built-in applies regardless. *)
|
|
|
|
|
- 328 ImpName<mod: SymTab.Name> (. VAR n: SymTab.Name; .)
|
|
|
|
|
- 329 = GetIdent<n> (. IF SymTab.Equal(mod, "libc") THEN
|
|
|
|
|
- 330 (* intrinsic C library:
|
|
|
|
|
- 331 permissive external *)
|
|
|
|
|
- 332 IF NOT SymTab.DeclareCProc(n) THEN
|
|
|
|
|
- 333 SemError(201) END
|
|
|
|
|
- 334 ELSIF SymTab.ModKnown(mod)
|
|
|
|
|
- 335 AND NOT SymTab.ImportFrom(mod, n) THEN
|
|
|
|
|
- 336 SemError(201) END; .)
|
|
|
|
|
- 337 | ( "TSIZE" | "SIZE" | "ADR" | "HIGH" | "LEN"
|
|
|
|
|
- 338 | "CHR" | "ORD" | "ORDL" | "VAL" | "ABS" | "CAP"
|
|
|
|
|
- 339 | "UCHR" | "CHR8" | "UORD"
|
|
|
|
|
- 340 | "INC" | "DEC" ) .
|
|
|
|
|
- 341 ImpModList (. VAR n: SymTab.Name; .)
|
|
|
|
|
- 342 = GetIdent<n>
|
|
|
|
|
- 343 { "," GetIdent<n> } .
|
|
|
|
|
- 344 (* Opaque TYPE declarations (definition modules). The targetless
|
|
|
|
|
- 345 alias resolves to InvalidType until step 4 completes it. *)
|
|
|
|
|
- 346 (* Scalar-phase TYPEs: named types, integer subranges, enumerations.
|
|
|
|
|
- 347 Opaque "TYPE T;" needs isDef (definition units); elsewhere 231.
|
|
|
|
|
- 348 Composite forms (ARRAY/RECORD/SET/POINTER) arrive with step 3. *)
|
|
|
|
|
- 349 TypeBlock<isDef: BOOLEAN>
|
|
|
|
|
- 350 = "TYPE" (. SymTab.BeginTypeBlock; .)
|
|
|
|
|
- 351 { TypeItem<isDef> ";" | ClassItem ";" }
|
|
|
|
|
- 352 (. SymTab.EndTypeBlock; .) .
|
|
|
|
|
- 353 TypeItem<isDef: BOOLEAN> (. VAR n: SymTab.Name;
|
|
|
|
|
- 354 t, op: SymTab.TypeIndex; .)
|
|
|
|
|
- 355 = GetIdent<n> (. op := SymTab.OpaqueBase(n);
|
|
|
|
|
- 356 IF op = SymTab.InvalidType THEN
|
|
|
|
|
- 357 IF NOT SymTab.Enter(n,
|
|
|
|
|
- 358 SymTab.KindType) THEN
|
|
|
|
|
- 359 SemError(200) END
|
|
|
|
|
- 360 END; .)
|
|
|
|
|
- 361 ( "=" Type<t, FALSE> (. IF op # SymTab.InvalidType THEN
|
|
|
|
|
- 362 SymTab.SetTarget(op, t)
|
|
|
|
|
- 363 ELSE SymTab.SetSymType(n, t)
|
|
|
|
|
- 364 END; .)
|
|
|
|
|
- 365 | (. IF op # SymTab.InvalidType THEN
|
|
|
|
|
- 366 (* stays opaque *)
|
|
|
|
|
- 367 ELSIF NOT isDef THEN
|
|
|
|
|
- 368 SemError(231)
|
|
|
|
|
- 369 ELSE SymTab.SetSymType(n,
|
|
|
|
|
- 370 SymTab.NewAlias()) END; .) ) .
|
|
|
|
|
- 371 Type<VAR t: SymTab.TypeIndex; allowOpen: BOOLEAN>
|
|
|
|
|
- 372 = TypeIdent<t> [ Subrange<t> ] (* anchored subrange: T[lo..hi] *)
|
|
|
|
|
- 373 | Subrange<t>
|
|
|
|
|
- 374 | Enum<t>
|
|
|
|
|
- 375 | ArrayType<t, allowOpen>
|
|
|
|
|
- 376 | SetType<t>
|
|
|
|
|
- 377 | RecordType<t>
|
|
|
|
|
- 378 | PointerType<t>
|
|
|
|
|
- 379 | ProcType<t> .
|
|
|
|
|
- 380 PointerType<VAR t: SymTab.TypeIndex> (. VAR base: SymTab.TypeIndex; .)
|
|
|
|
|
- 381 = "POINTER" "TO" Type<base, FALSE>(. t := SymTab.NewPtr(base); .) .
|
|
|
|
|
- 382 (* Procedure types (step 8.5): PROCEDURE (params): result. Values
|
|
|
|
|
- 383 are code pointers; params are collected into the descriptor. *)
|
|
|
|
|
- 384 ProcType<VAR t: SymTab.TypeIndex> (. VAR res, pt: SymTab.TypeIndex;
|
|
|
|
|
- 385 isV: BOOLEAN; .)
|
|
|
|
|
- 386 = "PROCEDURE" (. res := SymTab.InvalidType;
|
|
|
|
|
- 387 t := SymTab.NewProcType(res); .)
|
|
|
|
|
- 388 [ "(" [ ProcTypeSection<t> { ";" ProcTypeSection<t> } ] ")" ]
|
|
|
|
|
- 389 [ ":" TypeIdent<res> (. SymTab.SetProcTypeRes(t, res); .) ] .
|
|
|
|
|
- 390 ProcTypeSection<t: SymTab.TypeIndex> (. VAR pt: SymTab.TypeIndex;
|
|
|
|
|
- 391 isV: BOOLEAN;
|
|
|
|
|
- 392 cnt, k: CARDINAL;
|
|
|
|
|
- 393 names: ARRAY [0 .. 15] OF SymTab.Name; .)
|
|
|
|
|
- 394 = (. isV := FALSE; cnt := 0; .)
|
|
|
|
|
- 395 [ "VAR" (. isV := TRUE; .) ]
|
|
|
|
|
- 396 ( GetIdent<names[cnt]> (. INC(cnt); .)
|
|
|
|
|
- 397 { "," GetIdent<names[cnt]> (. INC(cnt); .) }
|
|
|
|
|
- 398 ( ":" Type<pt, TRUE> (. k := 0;
|
|
|
|
|
- 399 WHILE k < cnt DO
|
|
|
|
|
- 400 SymTab.ProcTypeAdd(t, isV, pt);
|
|
|
|
|
- 401 INC(k)
|
|
|
|
|
- 402 END; .)
|
|
|
|
|
- 403 | (. (* type-only parameter list:
|
|
|
|
|
- 404 each name is a type (GNU
|
|
|
|
|
- 405 shorthand used by the
|
|
|
|
|
- 406 Coco/R scanner frame) *)
|
|
|
|
|
- 407 k := 0;
|
|
|
|
|
- 408 WHILE k < cnt DO
|
|
|
|
|
- 409 IF SymTab.Lookup(names[k])
|
|
|
|
|
- 410 AND ((SymTab.SymKind(names[k]) = SymTab.KindType)
|
|
|
|
|
- 411 OR (SymTab.SymKind(names[k]) = SymTab.KindPredef)) THEN
|
|
|
|
|
- 412 pt := SymTab.SymType(names[k])
|
|
|
|
|
- 413 ELSE SemError(201);
|
|
|
|
|
- 414 pt := SymTab.InvalidType
|
|
|
|
|
- 415 END;
|
|
|
|
|
- 416 SymTab.ProcTypeAdd(t, isV, pt);
|
|
|
|
|
- 417 INC(k)
|
|
|
|
|
- 418 END; .) )
|
|
|
|
|
- 419 | Type<pt, TRUE> (. (* unnamed parameter (PIM):
|
|
|
|
|
- 420 e.g. PROCEDURE (VAR ARRAY OF REAL) *)
|
|
|
|
|
- 421 SymTab.ProcTypeAdd(t, isV, pt); .) ) .
|
|
|
|
|
- 422 (* Arrays: "OF" without bounds is an open formal (allowed only
|
|
|
|
|
- 423 where allowOpen); "[lo..hi, ...]" nests bounded levels inside
|
|
|
|
|
- 424 out. Bounds are folded literals (int/char); anything else 230.
|
|
|
|
|
- 425 Bare-type indices ("ARRAY Color OF") wait for enum ordinals. *)
|
|
|
|
|
- 426 ArrayType<VAR t: SymTab.TypeIndex; allowOpen: BOOLEAN>
|
|
|
|
|
- 427 (. VAR elem: SymTab.TypeIndex;
|
|
|
|
|
- 428 ok: BOOLEAN;
|
|
|
|
|
- 429 bnds, bndh: ARRAY [0 .. 7] OF INTEGER;
|
|
|
|
|
- 430 nb, k: CARDINAL;
|
|
|
|
|
- 431 idx: SymTab.TypeIndex;
|
|
|
|
|
- 432 ilo, ihi: INTEGER; .)
|
|
|
|
|
- 433 = "ARRAY"
|
|
|
|
|
- 434 ( "OF" Type<elem, FALSE> (. IF NOT allowOpen THEN
|
|
|
|
|
- 435 SemError(230) END;
|
|
|
|
|
- 436 t := SymTab.NewOpenArray(elem); .)
|
|
|
|
|
- 437 | TypeIdent<idx> [ Subrange<idx> ]
|
|
|
|
|
- 438 "OF" Type<elem, FALSE> (. (* index-type array: the index
|
|
|
|
|
- 439 type's ordinal bounds give the
|
|
|
|
|
- 440 [lo..hi] pair *)
|
|
|
|
|
- 441 IF SymTab.TypeBounds(idx, ilo,
|
|
|
|
|
- 442 ihi)
|
|
|
|
|
- 443 THEN t := SymTab.NewArrayB(elem,
|
|
|
|
|
- 444 ilo, ihi)
|
|
|
|
|
- 445 ELSE SemError(230);
|
|
|
|
|
- 446 t := SymTab.InvalidType
|
|
|
|
|
- 447 END; .)
|
|
|
|
|
- 448 | "[" (. SymTab.BoundBegin; ok := TRUE; .)
|
|
|
|
|
- 449 BoundPair<ok>
|
|
|
|
|
- 450 { "," BoundPair<ok> }
|
|
|
|
|
- 451 "]" (. (* snapshot before the element
|
|
|
|
|
- 452 type, which reuses the bound
|
|
|
|
|
- 453 buffer for a nested ARRAY *)
|
|
|
|
|
- 454 nb := SymTab.BoundCount();
|
|
|
|
|
- 455 k := 0;
|
|
|
|
|
- 456 WHILE k < nb DO
|
|
|
|
|
- 457 bnds[k] := SymTab.BoundLo(k);
|
|
|
|
|
- 458 bndh[k] := SymTab.BoundHi(k);
|
|
|
|
|
- 459 INC(k)
|
|
|
|
|
- 460 END; .)
|
|
|
|
|
- 461 "OF" Type<elem, FALSE>
|
|
|
|
|
- 462 (. IF ok THEN
|
|
|
|
|
- 463 k := nb;
|
|
|
|
|
- 464 WHILE k > 0 DO
|
|
|
|
|
- 465 DEC(k);
|
|
|
|
|
- 466 elem := SymTab.NewArrayB(
|
|
|
|
|
- 467 elem, bnds[k], bndh[k])
|
|
|
|
|
- 468 END;
|
|
|
|
|
- 469 t := elem
|
|
|
|
|
- 470 ELSE t := SymTab.InvalidType
|
|
|
|
|
- 471 END; .) ) .
|
|
|
|
|
- 472 BoundPair<VAR ok: BOOLEAN> (. VAR tlo, thi: SymTab.TypeIndex;
|
|
|
|
|
- 473 qlo, qhi: QbeGen.QVal;
|
|
|
|
|
- 474 lo, hi: INTEGER;
|
|
|
|
|
- 475 cl, cl2: INTEGER; .)
|
|
|
|
|
- 476 = Expr<tlo, qlo> ".." Expr<thi, qhi>
|
|
|
|
|
- 477 (. IF (tlo = SymTab.InvalidType)
|
|
|
|
|
- 478 OR (thi = SymTab.InvalidType) THEN
|
|
|
|
|
- 479 ok := FALSE
|
|
|
|
|
- 480 ELSE cl := SymTab.ClassOf(tlo);
|
|
|
|
|
- 481 cl2 := SymTab.ClassOf(thi);
|
|
|
|
|
- 482 IF ((cl # SymTab.ClInt)
|
|
|
|
|
- 483 AND (cl # SymTab.ClChar))
|
|
|
|
|
- 484 OR ((cl2 # SymTab.ClInt)
|
|
|
|
|
- 485 AND (cl2 # SymTab.ClChar)) THEN
|
|
|
|
|
- 486 SemError(230); ok := FALSE
|
|
|
|
|
- 487 ELSIF NOT SymTab.ConstInt(qlo, lo)
|
|
|
|
|
- 488 OR NOT SymTab.ConstInt(qhi, hi)
|
|
|
|
|
- 489 OR (lo > hi) THEN
|
|
|
|
|
- 490 SemError(230); ok := FALSE
|
|
|
|
|
- 491 ELSIF NOT SymTab.BoundAdd(lo, hi) THEN
|
|
|
|
|
- 492 SemError(230); ok := FALSE
|
|
|
|
|
- 493 END;
|
|
|
|
|
- 494 END; .) .
|
|
|
|
|
- 495 (* Sets: multi-word masks over bases ≤ 256 values (bool, char,
|
|
|
|
|
- 496 bounded subranges; enums wait for ordinals, INTEGER is
|
|
|
|
|
- 497 unbounded). Literals are SET OF [0..255]; assignment and
|
|
|
|
|
- 498 comparison across suitable bases are lenient (masks over min
|
|
|
|
|
- 499 words + zero-check extras), out-of-span literals are 222. *)
|
|
|
|
|
- 500 SetType<VAR t: SymTab.TypeIndex> (. VAR base: SymTab.TypeIndex;
|
|
|
|
|
- 501 blo, bhi, bspan: INTEGER;
|
|
|
|
|
- 502 bcls: INTEGER; .)
|
|
|
|
|
- 503 = "SET" "OF" Type<base, FALSE>
|
|
|
|
|
- 504 (. IF base = SymTab.InvalidType THEN
|
|
|
|
|
- 505 t := SymTab.InvalidType
|
|
|
|
|
- 506 ELSE bcls :=
|
|
|
|
|
- 507 SymTab.ClassOf(base);
|
|
|
|
|
- 508 IF bcls = SymTab.ClBool THEN
|
|
|
|
|
- 509 blo := 0; bspan := 2
|
|
|
|
|
- 510 ELSIF bcls = SymTab.ClChar THEN
|
|
|
|
|
- 511 blo := 0; bspan := 256
|
|
|
|
|
- 512 ELSIF bcls = SymTab.ClEnum THEN
|
|
|
|
|
- 513 blo := 0;
|
|
|
|
|
- 514 bspan := VAL(INTEGER,
|
|
|
|
|
- 515 SymTab.EnumCount(base))
|
|
|
|
|
- 516 ELSIF SymTab.SubBounds(base,
|
|
|
|
|
- 517 blo, bhi) THEN
|
|
|
|
|
- 518 bspan := bhi - blo + 1
|
|
|
|
|
- 519 ELSE bspan := 0 END;
|
|
|
|
|
- 520 IF (bspan <= 0)
|
|
|
|
|
- 521 OR (bspan > 65536) THEN
|
|
|
|
|
- 522 SemError(230);
|
|
|
|
|
- 523 t := SymTab.InvalidType
|
|
|
|
|
- 524 ELSE t := SymTab.NewSet(base)
|
|
|
|
|
- 525 END
|
|
|
|
|
- 526 END; .) .
|
|
|
|
|
- 527 (* Records: flat blobs; array fields are pointers to static
|
|
|
|
|
- 528 descriptors (locked amendment), nested records inline. Field
|
|
|
|
|
- 529 offsets static and declaration-ordered. *)
|
|
|
|
|
- 530 (* Field list: plain fields and (optionally) one variant part. The
|
|
|
|
|
- 531 variant part is a `CASE ... END` item; because it starts with the
|
|
|
|
|
- 532 CASE keyword it is unambiguously distinguishable from a field
|
|
|
|
|
- 533 (which starts with an identifier). *)
|
|
|
|
|
- 534 RecordType<VAR t: SymTab.TypeIndex> (. VAR t2: SymTab.TypeIndex;
|
|
|
|
|
- 535 tagOk: BOOLEAN; .)
|
|
|
|
|
- 536 = "RECORD" (. t := SymTab.NewRecord(); .)
|
|
|
|
|
- 537 [ RecItem<t> { ";" [ RecItem<t> ] } ]
|
|
|
|
|
- 538 "END" .
|
|
|
|
|
- 539 RecItem<rec: SymTab.TypeIndex> (. VAR tt: SymTab.TypeIndex; .)
|
|
|
|
|
- 540 = RecField<rec>
|
|
|
|
|
- 541 | CaseField<rec> (. SymTab.MarkVariant(rec); .) .
|
|
|
|
|
- 542 (* A variant part: CASE tag : Type OF variants. The layout overlays
|
|
|
|
|
- 543 every branch from the tag slot (see SymTab.ComputeOffsets). *)
|
|
|
|
|
- 544 CaseField<rec: SymTab.TypeIndex> (. VAR tagT: SymTab.TypeIndex;
|
|
|
|
|
- 545 tagN: SymTab.Name; .)
|
|
|
|
|
- 546 = "CASE" (. SymTab.ResetFields(rec); .)
|
|
|
|
|
- 547 GetIdent<tagN> (. IF NOT SymTab.FieldPending(rec,
|
|
|
|
|
- 548 tagN) THEN
|
|
|
|
|
- 549 SemError(200) END; .)
|
|
|
|
|
- 550 ":" Type<tagT, FALSE> (. IF (tagT # SymTab.InvalidType)
|
|
|
|
|
- 551 AND NOT SymTab.IsOrdinal(tagT) THEN
|
|
|
|
|
- 552 SemError(224)
|
|
|
|
|
- 553 END;
|
|
|
|
|
- 554 SymTab.FixPendingF(rec, tagT);
|
|
|
|
|
- 555 SymTab.SetVariantTag(rec, tagN); .)
|
|
|
|
|
- 556 "OF"
|
|
|
|
|
- 557 RecFieldList<rec>
|
|
|
|
|
- 558 { "|" (. SymTab.ResetFields(rec); .)
|
|
|
|
|
- 559 RecFieldList<rec> }
|
|
|
|
|
- 560 "END" .
|
|
|
|
|
- 561 RecFieldList<rec: SymTab.TypeIndex> (. VAR lt, lq: SymTab.TypeIndex;
|
|
|
|
|
- 562 lv1, lv2: QbeGen.QVal; .)
|
|
|
|
|
- 563 = VarLabel<lt, lv1> [ ".." VarLabel<lq, lv2> ] ":"
|
|
|
|
|
- 564 RecField<rec> { ";" [ RecField<rec> ] } .
|
|
|
|
|
- 565 (* Variant case label: a constant (or a constant range). Values are
|
|
|
|
|
- 566 not interpreted (the layout overlays regardless). *)
|
|
|
|
|
- 567 VarLabel<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
|
|
- 568 (. VAR lname: SymTab.Name; .)
|
|
|
|
|
- 569 = ( ident (. LexName(lname);
|
|
|
|
|
- 570 QbeGen.CopyOp("0", q);
|
|
|
|
|
- 571 t := SymTab.IntType(); .)
|
|
|
|
|
- 572 | integer (. LexString(lname);
|
|
|
|
|
- 573 QbeGen.CopyOp("0", q);
|
|
|
|
|
- 574 t := SymTab.IntType(); .)
|
|
|
|
|
- 575 | charConst (. LexString(lname);
|
|
|
|
|
|
|
+ 70 (* Actual-argument nodes collected by ActParam for the call being
|
|
|
|
|
+ 71 parsed by ArgList (slice 4). Fact resets the count before the
|
|
|
|
|
+ 72 optional ArgList and then folds the nodes into an NkCall. *)
|
|
|
|
|
+ 73 astNArgs: CARDINAL;
|
|
|
|
|
+ 74 astArgs: ARRAY [0 .. 31] OF AST.Node;
|
|
|
|
|
+ 75
|
|
|
|
|
+ 76 (* Class of the method named by the last `obj.Method` designator
|
|
|
|
|
+ 77 (InvalidType when the callee is an ordinary procedure). Set by
|
|
|
|
|
+ 78 Design, consumed by the following ArgList. *)
|
|
|
|
|
+ 79 methCls: SymTab.TypeIndex;
|
|
|
|
|
+ 80 (* Class of the type of the innermost `TypeName{...}` brace
|
|
|
|
|
+ 81 constructor (ClSet or ClArray); dispatches BraceElem. *)
|
|
|
|
|
+ 82 braceCls: INTEGER;
|
|
|
|
|
+ 83 (* Module-level VAR declarations whose type was still an unresolved
|
|
|
|
|
+ 84 forward alias at declaration time; emitted once the TYPE block
|
|
|
|
|
+ 85 completes (module scope only). *)
|
|
|
|
|
+ 86 nPendVar: CARDINAL;
|
|
|
|
|
+ 87 pendVarName: ARRAY [0 .. 255] OF SymTab.Name;
|
|
|
|
|
+ 88 pendVarT: ARRAY [0 .. 255] OF SymTab.TypeIndex;
|
|
|
|
|
+ 89 (* Forward module-level variables referenced from a procedure body. *)
|
|
|
|
|
+ 90 nFvarRefs: CARDINAL;
|
|
|
|
|
+ 91 fvarId: ARRAY [0 .. 255] OF INTEGER;
|
|
|
|
|
+ 92 fvarSlot: ARRAY [0 .. 255] OF INTEGER;
|
|
|
|
|
+ 93
|
|
|
|
|
+ 94 PROCEDURE FlushPend;
|
|
|
|
|
+ 95 (* Emit module-level globals whose forward type is now resolved. *)
|
|
|
|
|
+ 96 VAR k: CARDINAL;
|
|
|
|
|
+ 97 BEGIN
|
|
|
|
|
+ 98 k := 0;
|
|
|
|
|
+ 99 WHILE k < nPendVar DO
|
|
|
|
|
+ 100 QbeGen.DeclVar(pendVarName[k], pendVarT[k]);
|
|
|
|
|
+ 101 INC(k)
|
|
|
|
|
+ 102 END;
|
|
|
|
|
+ 103 nPendVar := 0
|
|
|
|
|
+ 104 END FlushPend;
|
|
|
|
|
+ 105
|
|
|
|
|
+ 106 PROCEDURE FwdVarNote (id, slot: INTEGER);
|
|
|
|
|
+ 107 BEGIN
|
|
|
|
|
+ 108 IF nFvarRefs <= HIGH(fvarId) THEN
|
|
|
|
|
+ 109 fvarId[nFvarRefs] := id;
|
|
|
|
|
+ 110 fvarSlot[nFvarRefs] := slot;
|
|
|
|
|
+ 111 INC(nFvarRefs)
|
|
|
|
|
+ 112 END
|
|
|
|
|
+ 113 END FwdVarNote;
|
|
|
|
|
+ 114
|
|
|
|
|
+ 115 PROCEDURE FwdVarFlush;
|
|
|
|
|
+ 116 (* At module end: resolve every forward reference against the declared
|
|
|
|
|
+ 117 names (an unresolved one is 201) and patch its placeholder symbol. *)
|
|
|
|
|
+ 118 VAR k: CARDINAL; nm, g: SymTab.Name; cls: INTEGER; oper: CHAR;
|
|
|
|
|
+ 119 t: SymTab.TypeIndex; ok: BOOLEAN;
|
|
|
|
|
+ 120 BEGIN
|
|
|
|
|
+ 121 k := 0;
|
|
|
|
|
+ 122 WHILE k < nFvarRefs DO
|
|
|
|
|
+ 123 SymTab.FwdVarName(fvarId[k], nm);
|
|
|
|
|
+ 124 IF nm[0] # CHR(0) THEN
|
|
|
|
|
+ 125 IF NOT SymTab.FwdVarResolve(fvarId[k]) THEN
|
|
|
|
|
+ 126 SemError(201)
|
|
|
|
|
+ 127 ELSE
|
|
|
|
|
+ 128 t := SymTab.FwdVarType(fvarId[k]);
|
|
|
|
|
+ 129 cls := SymTab.ClassOf(t);
|
|
|
|
|
+ 130 IF cls = SymTab.ClReal THEN oper := "d"
|
|
|
|
|
+ 131 ELSIF SymTab.IsLongFamily(t) THEN oper := "l"
|
|
|
|
|
+ 132 ELSE oper := "w"
|
|
|
|
|
+ 133 END;
|
|
|
|
|
+ 134 ok := SymTab.GlobalRef(nm, g);
|
|
|
|
|
+ 135 QbeGen.FwdPatch(fvarSlot[k], fvarSlot[k], nm, oper, ok)
|
|
|
|
|
+ 136 END
|
|
|
|
|
+ 137 END;
|
|
|
|
|
+ 138 INC(k)
|
|
|
|
|
+ 139 END;
|
|
|
|
|
+ 140 nFvarRefs := 0
|
|
|
|
|
+ 141 END FwdVarFlush;
|
|
|
|
|
+ 142
|
|
|
|
|
+ 143 CHARACTERS
|
|
|
|
|
+ 144 eol = CHR(13) .
|
|
|
|
|
+ 145 lf = CHR(10) .
|
|
|
|
|
+ 146 letter = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" .
|
|
|
|
|
+ 147 digit = "0123456789" .
|
|
|
|
|
+ 148 hexDigit = digit + "ABCDEFabcdef" .
|
|
|
|
|
+ 149 noQuote1 = ANY - "'" - eol .
|
|
|
|
|
+ 150 noQuote2 = ANY - '"' - eol .
|
|
|
|
|
+ 151
|
|
|
|
|
+ 152 IGNORE CHR(9) .. CHR(13)
|
|
|
|
|
+ 153
|
|
|
|
|
+ 154 COMMENTS FROM "(*" TO "*)" NESTED
|
|
|
|
|
+ 155 COMMENTS FROM "//" TO lf
|
|
|
|
|
+ 156
|
|
|
|
|
+ 157 TOKENS
|
|
|
|
|
+ 158 ident = letter { letter | digit } .
|
|
|
|
|
+ 159 integer = digit { digit }
|
|
|
|
|
+ 160 | digit { digit } CONTEXT("..")
|
|
|
|
|
+ 161 | "0x" hexDigit { hexDigit }
|
|
|
|
|
+ 162 | "0X" hexDigit { hexDigit } .
|
|
|
|
|
+ 163 real = digit { digit } "." { digit }
|
|
|
|
|
+ 164 [ ( "E" | "e" ) [ "+" | "-" ] digit { digit } ] .
|
|
|
|
|
+ 165 string = "'" { noQuote1 } "'"
|
|
|
|
|
+ 166 | '"' { noQuote2 } '"' .
|
|
|
|
|
+ 167 charConst = digit { digit } ( "C" | "c" ) .
|
|
|
|
|
+ 168 ustring = ( "U" | "u" ) ( "'" { noQuote1 } "'" | '"' { noQuote2 } '"' ) .
|
|
|
|
|
+ 169
|
|
|
|
|
+ 170 PRODUCTIONS
|
|
|
|
|
+ 171 M2
|
|
|
|
|
+ 172 = (. AST.Init; twoPhase := TRUE; astCur := AST.NoNode; .)
|
|
|
|
|
+ 173 Unit "." .
|
|
|
|
|
+ 174 (* Units: program modules compile fully; DEFINITION and
|
|
|
|
|
+ 175 IMPLEMENTATION modules parse + check now but lower in step 4
|
|
|
|
|
+ 176 (each ends with one 230); same for nested local modules. *)
|
|
|
|
|
+ 177 Unit
|
|
|
|
|
+ 178 = DefUnit
|
|
|
|
|
+ 179 | ImplUnit
|
|
|
|
|
+ 180 | ProgModule .
|
|
|
|
|
+ 181 (* Step 4.3: one session compiles DEFINITION, its IMPLEMENTATION
|
|
|
|
|
+ 182 and one program (last) into one image. Units share the symbol
|
|
|
|
|
+ 183 table; imports materialize exported names. *)
|
|
|
|
|
+ 184 DefUnit (. VAR m1, m2, pn: SymTab.Name; .)
|
|
|
|
|
+ 185 = "DEFINITION" "MODULE"
|
|
|
|
|
+ 186 GetIdent<m1> (. IF NOT SymTab.BeginDef(m1) THEN
|
|
|
|
|
+ 187 SemError(200) END;
|
|
|
|
|
+ 188 QbeGen.SetModule(m1); .)
|
|
|
|
|
+ 189 ";"
|
|
|
|
|
+ 190 { Import }
|
|
|
|
|
+ 191 [ "EXPORT" [ "QUALIFIED" ] (. (* definition-module export
|
|
|
|
|
+ 192 list: parsed, and the
|
|
|
|
|
+ 193 names are already exported
|
|
|
|
|
+ 194 by the module scope *) .)
|
|
|
|
|
+ 195 GetIdent<pn> { "," GetIdent<pn> } ";" ]
|
|
|
|
|
+ 196 { ConstBlock | TypeBlock<TRUE> | VarBlock
|
|
|
|
|
+ 197 | ProcHeading<pn, SymTab.InvalidType> ";"
|
|
|
|
|
+ 198 (. SymTab.CloseProc;
|
|
|
|
|
+ 199 QbeGen.AbortFunc; .) }
|
|
|
|
|
+ 200 "END"
|
|
|
|
|
+ 201 GetIdent<m2> (. IF NOT SymTab.Equal(m1, m2) THEN
|
|
|
|
|
+ 202 SemError(202) END;
|
|
|
|
|
+ 203 SymTab.EndUnit; .) .
|
|
|
|
|
+ 204 ImplUnit (. VAR m1, m2: SymTab.Name;
|
|
|
|
|
+ 205 k: CARDINAL;
|
|
|
|
|
+ 206 fname: SymTab.Name;
|
|
|
|
|
+ 207 unres: BOOLEAN; .)
|
|
|
|
|
+ 208 = "IMPLEMENTATION" "MODULE"
|
|
|
|
|
+ 209 GetIdent<m1> (. IF NOT SymTab.BeginImpl(m1) THEN
|
|
|
|
|
+ 210 SemError(201) END;
|
|
|
|
|
+ 211 nPendVar := 0;
|
|
|
|
|
+ 212 QbeGen.SetModule(m1); .)
|
|
|
|
|
+ 213 ";"
|
|
|
|
|
+ 214 { Import }
|
|
|
|
|
+ 215 DeclSeq
|
|
|
|
|
+ 216 [ "BEGIN" (. FlushPend;
|
|
|
|
|
+ 217 k := 0;
|
|
|
|
|
+ 218 WHILE k < SymTab.FwdPending() DO
|
|
|
|
|
+ 219 SymTab.FwdInfo(k, fname, unres);
|
|
|
|
|
+ 220 IF unres THEN SemError(201) END;
|
|
|
|
|
+ 221 INC(k)
|
|
|
|
|
+ 222 END;
|
|
|
|
|
+ 223 SymTab.FwdClear;
|
|
|
|
|
+ 224 FwdVarFlush;
|
|
|
|
|
+ 225 QbeGen.BeginInit(m1); .)
|
|
|
|
|
+ 226 [ StatSeq ] (. QbeGen.EndInit; .) ]
|
|
|
|
|
+ 227 "END"
|
|
|
|
|
+ 228 GetIdent<m2> (. FlushPend;
|
|
|
|
|
+ 229 k := 0;
|
|
|
|
|
+ 230 WHILE k < SymTab.FwdPending() DO
|
|
|
|
|
+ 231 SymTab.FwdInfo(k, fname, unres);
|
|
|
|
|
+ 232 IF unres THEN SemError(201) END;
|
|
|
|
|
+ 233 INC(k)
|
|
|
|
|
+ 234 END;
|
|
|
|
|
+ 235 SymTab.FwdClear;
|
|
|
|
|
+ 236 FwdVarFlush;
|
|
|
|
|
+ 237 IF NOT SymTab.Equal(m1, m2) THEN
|
|
|
|
|
+ 238 SemError(202) END;
|
|
|
|
|
+ 239 SymTab.EndUnit; .) .
|
|
|
|
|
+ 240 ProgModule (. VAR m1, m2: SymTab.Name;
|
|
|
|
|
+ 241 k: CARDINAL;
|
|
|
|
|
+ 242 fname: SymTab.Name;
|
|
|
|
|
+ 243 unres: BOOLEAN; .)
|
|
|
|
|
+ 244 = "MODULE"
|
|
|
|
|
+ 245 GetIdent<m1> (. IF NOT SymTab.BeginProg(m1) THEN
|
|
|
|
|
+ 246 SemError(200) END;
|
|
|
|
|
+ 247 nPendVar := 0;
|
|
|
|
|
+ 248 QbeGen.SetModule(m1); .)
|
|
|
|
|
+ 249 [ Priority ]
|
|
|
|
|
+ 250 ";"
|
|
|
|
|
+ 251 { Import }
|
|
|
|
|
+ 252 DeclSeq
|
|
|
|
|
+ 253 [ "BEGIN" (. FlushPend;
|
|
|
|
|
+ 254 k := 0;
|
|
|
|
|
+ 255 WHILE k < SymTab.FwdPending() DO
|
|
|
|
|
+ 256 SymTab.FwdInfo(k, fname, unres);
|
|
|
|
|
+ 257 IF unres THEN SemError(201) END;
|
|
|
|
|
+ 258 INC(k)
|
|
|
|
|
+ 259 END;
|
|
|
|
|
+ 260 SymTab.FwdClear;
|
|
|
|
|
+ 261 FwdVarFlush;
|
|
|
|
|
+ 262 QbeGen.BeginBody; .)
|
|
|
|
|
+ 263 [ StatSeq ] ]
|
|
|
|
|
+ 264 "END"
|
|
|
|
|
+ 265 GetIdent<m2> (. FlushPend;
|
|
|
|
|
+ 266 k := 0;
|
|
|
|
|
+ 267 WHILE k < SymTab.FwdPending() DO
|
|
|
|
|
+ 268 SymTab.FwdInfo(k, fname, unres);
|
|
|
|
|
+ 269 IF unres THEN SemError(201) END;
|
|
|
|
|
+ 270 INC(k)
|
|
|
|
|
+ 271 END;
|
|
|
|
|
+ 272 SymTab.FwdClear;
|
|
|
|
|
+ 273 FwdVarFlush;
|
|
|
|
|
+ 274 IF NOT SymTab.Equal(m1, m2) THEN
|
|
|
|
|
+ 275 SemError(202) END;
|
|
|
|
|
+ 276 QbeGen.EndModule(m1);
|
|
|
|
|
+ 277 SymTab.EndUnit; .) .
|
|
|
|
|
+ 278 DeclSeq
|
|
|
|
|
+ 279 = { ConstBlock | TypeBlock<FALSE> | VarBlock | ProcDecl ";"
|
|
|
|
|
+ 280 | NestedModule ";" | ClassItem ";" } .
|
|
|
|
|
+ 281 (* Local module, Wirth form. Declarations lower like top-level ones
|
|
|
|
|
+ 282 (same QBE module prefix); a BEGIN body becomes an init function
|
|
|
|
|
+ 283 that main calls; the EXPORT list is hoisted into the enclosing
|
|
|
|
|
+ 284 scope at END. *)
|
|
|
|
|
+ 285 NestedModule (. VAR m1, m2: SymTab.Name;
|
|
|
|
|
+ 286 expNames: ARRAY [0 .. 63] OF SymTab.Name;
|
|
|
|
|
+ 287 expCount, k: CARDINAL; .)
|
|
|
|
|
+ 288 = "MODULE"
|
|
|
|
|
+ 289 GetIdent<m1> (. IF NOT SymTab.Enter(m1,
|
|
|
|
|
+ 290 SymTab.KindModule) THEN
|
|
|
|
|
+ 291 SemError(200) END;
|
|
|
|
|
+ 292 SymTab.PushScope;
|
|
|
|
|
+ 293 expCount := 0; .)
|
|
|
|
|
+ 294 [ Priority ]
|
|
|
|
|
+ 295 ";"
|
|
|
|
|
+ 296 { Import }
|
|
|
|
|
+ 297 [ "EXPORT" [ "QUALIFIED" ]
|
|
|
|
|
+ 298 GetIdent<expNames[expCount]> (. INC(expCount); .)
|
|
|
|
|
+ 299 { "," GetIdent<expNames[expCount]>
|
|
|
|
|
+ 300 (. INC(expCount); .) }
|
|
|
|
|
+ 301 ";" ]
|
|
|
|
|
+ 302 DeclSeq
|
|
|
|
|
+ 303 [ "BEGIN" (. QbeGen.BeginInit(m1); .)
|
|
|
|
|
+ 304 [ StatSeq ] (. QbeGen.EndInit; .) ]
|
|
|
|
|
+ 305 "END"
|
|
|
|
|
+ 306 GetIdent<m2> (. IF NOT SymTab.Equal(m1, m2) THEN
|
|
|
|
|
+ 307 SemError(202) END;
|
|
|
|
|
+ 308 k := 0;
|
|
|
|
|
+ 309 WHILE k < expCount DO
|
|
|
|
|
+ 310 SymTab.ExportUp(expNames[k]);
|
|
|
|
|
+ 311 INC(k)
|
|
|
|
|
+ 312 END;
|
|
|
|
|
+ 313 SymTab.PopScope; .) .
|
|
|
|
|
+ 314 Priority
|
|
|
|
|
+ 315 = "[" integer "]" (. SemError(230); .) .
|
|
|
|
|
+ 316 (* Imports (4.3): FROM materializes the names (unqualified use);
|
|
|
|
|
+ 317 plain IMPORT only demands the module exists — qualified `L.x`
|
|
|
|
|
+ 318 materializes on first use (Design). *)
|
|
|
|
|
+ 319 (* Unknown modules stay unchecked stubs (legacy, so hand-written
|
|
|
|
|
+ 320 import lines don't fail); a known module's missing export is
|
|
|
|
|
+ 321 201. *)
|
|
|
|
|
+ 322 Import (. VAR n: SymTab.Name; .)
|
|
|
|
|
+ 323 = "FROM"
|
|
|
|
|
+ 324 GetIdent<n>
|
|
|
|
|
+ 325 "IMPORT"
|
|
|
|
|
+ 326 ImpList<n> ";"
|
|
|
|
|
+ 327 | "IMPORT"
|
|
|
|
|
+ 328 ImpModList ";" .
|
|
|
|
|
+ 329 ImpList<mod: SymTab.Name> (. VAR n: SymTab.Name; .)
|
|
|
|
|
+ 330 = ImpName<mod>
|
|
|
|
|
+ 331 { "," ImpName<mod> } .
|
|
|
|
|
+ 332 (* Pervasive built-ins imported from SYSTEM (e.g. TSIZE) are
|
|
|
|
|
+ 333 accepted and ignored: the built-in applies regardless. *)
|
|
|
|
|
+ 334 ImpName<mod: SymTab.Name> (. VAR n: SymTab.Name; .)
|
|
|
|
|
+ 335 = GetIdent<n> (. IF SymTab.Equal(mod, "libc") THEN
|
|
|
|
|
+ 336 (* intrinsic C library:
|
|
|
|
|
+ 337 permissive external *)
|
|
|
|
|
+ 338 IF NOT SymTab.DeclareCProc(n) THEN
|
|
|
|
|
+ 339 SemError(201) END
|
|
|
|
|
+ 340 ELSIF SymTab.ModKnown(mod)
|
|
|
|
|
+ 341 AND NOT SymTab.ImportFrom(mod, n) THEN
|
|
|
|
|
+ 342 SemError(201) END; .)
|
|
|
|
|
+ 343 | ( "TSIZE" | "SIZE" | "ADR" | "HIGH" | "LEN"
|
|
|
|
|
+ 344 | "CHR" | "ORD" | "ORDL" | "VAL" | "ABS" | "CAP"
|
|
|
|
|
+ 345 | "UCHR" | "CHR8" | "UORD"
|
|
|
|
|
+ 346 | "INC" | "DEC" ) .
|
|
|
|
|
+ 347 ImpModList (. VAR n: SymTab.Name; .)
|
|
|
|
|
+ 348 = GetIdent<n>
|
|
|
|
|
+ 349 { "," GetIdent<n> } .
|
|
|
|
|
+ 350 (* Opaque TYPE declarations (definition modules). The targetless
|
|
|
|
|
+ 351 alias resolves to InvalidType until step 4 completes it. *)
|
|
|
|
|
+ 352 (* Scalar-phase TYPEs: named types, integer subranges, enumerations.
|
|
|
|
|
+ 353 Opaque "TYPE T;" needs isDef (definition units); elsewhere 231.
|
|
|
|
|
+ 354 Composite forms (ARRAY/RECORD/SET/POINTER) arrive with step 3. *)
|
|
|
|
|
+ 355 TypeBlock<isDef: BOOLEAN>
|
|
|
|
|
+ 356 = "TYPE" (. SymTab.BeginTypeBlock; .)
|
|
|
|
|
+ 357 { TypeItem<isDef> ";" | ClassItem ";" }
|
|
|
|
|
+ 358 (. SymTab.EndTypeBlock; .) .
|
|
|
|
|
+ 359 TypeItem<isDef: BOOLEAN> (. VAR n: SymTab.Name;
|
|
|
|
|
+ 360 t, op: SymTab.TypeIndex; .)
|
|
|
|
|
+ 361 = GetIdent<n> (. op := SymTab.OpaqueBase(n);
|
|
|
|
|
+ 362 IF op = SymTab.InvalidType THEN
|
|
|
|
|
+ 363 IF NOT SymTab.Enter(n,
|
|
|
|
|
+ 364 SymTab.KindType) THEN
|
|
|
|
|
+ 365 SemError(200) END
|
|
|
|
|
+ 366 END; .)
|
|
|
|
|
+ 367 ( "=" Type<t, FALSE> (. IF op # SymTab.InvalidType THEN
|
|
|
|
|
+ 368 SymTab.SetTarget(op, t)
|
|
|
|
|
+ 369 ELSE SymTab.SetSymType(n, t)
|
|
|
|
|
+ 370 END; .)
|
|
|
|
|
+ 371 | (. IF op # SymTab.InvalidType THEN
|
|
|
|
|
+ 372 (* stays opaque *)
|
|
|
|
|
+ 373 ELSIF NOT isDef THEN
|
|
|
|
|
+ 374 SemError(231)
|
|
|
|
|
+ 375 ELSE SymTab.SetSymType(n,
|
|
|
|
|
+ 376 SymTab.NewAlias()) END; .) ) .
|
|
|
|
|
+ 377 Type<VAR t: SymTab.TypeIndex; allowOpen: BOOLEAN>
|
|
|
|
|
+ 378 = TypeIdent<t> [ Subrange<t> ] (* anchored subrange: T[lo..hi] *)
|
|
|
|
|
+ 379 | Subrange<t>
|
|
|
|
|
+ 380 | Enum<t>
|
|
|
|
|
+ 381 | ArrayType<t, allowOpen>
|
|
|
|
|
+ 382 | SetType<t>
|
|
|
|
|
+ 383 | RecordType<t>
|
|
|
|
|
+ 384 | PointerType<t>
|
|
|
|
|
+ 385 | ProcType<t> .
|
|
|
|
|
+ 386 PointerType<VAR t: SymTab.TypeIndex> (. VAR base: SymTab.TypeIndex; .)
|
|
|
|
|
+ 387 = "POINTER" "TO" Type<base, FALSE>(. t := SymTab.NewPtr(base); .) .
|
|
|
|
|
+ 388 (* Procedure types (step 8.5): PROCEDURE (params): result. Values
|
|
|
|
|
+ 389 are code pointers; params are collected into the descriptor. *)
|
|
|
|
|
+ 390 ProcType<VAR t: SymTab.TypeIndex> (. VAR res, pt: SymTab.TypeIndex;
|
|
|
|
|
+ 391 isV: BOOLEAN; .)
|
|
|
|
|
+ 392 = "PROCEDURE" (. res := SymTab.InvalidType;
|
|
|
|
|
+ 393 t := SymTab.NewProcType(res); .)
|
|
|
|
|
+ 394 [ "(" [ ProcTypeSection<t> { ";" ProcTypeSection<t> } ] ")" ]
|
|
|
|
|
+ 395 [ ":" TypeIdent<res> (. SymTab.SetProcTypeRes(t, res); .) ] .
|
|
|
|
|
+ 396 ProcTypeSection<t: SymTab.TypeIndex> (. VAR pt: SymTab.TypeIndex;
|
|
|
|
|
+ 397 isV: BOOLEAN;
|
|
|
|
|
+ 398 cnt, k: CARDINAL;
|
|
|
|
|
+ 399 names: ARRAY [0 .. 15] OF SymTab.Name; .)
|
|
|
|
|
+ 400 = (. isV := FALSE; cnt := 0; .)
|
|
|
|
|
+ 401 [ "VAR" (. isV := TRUE; .) ]
|
|
|
|
|
+ 402 ( GetIdent<names[cnt]> (. INC(cnt); .)
|
|
|
|
|
+ 403 { "," GetIdent<names[cnt]> (. INC(cnt); .) }
|
|
|
|
|
+ 404 ( ":" Type<pt, TRUE> (. k := 0;
|
|
|
|
|
+ 405 WHILE k < cnt DO
|
|
|
|
|
+ 406 SymTab.ProcTypeAdd(t, isV, pt);
|
|
|
|
|
+ 407 INC(k)
|
|
|
|
|
+ 408 END; .)
|
|
|
|
|
+ 409 | (. (* type-only parameter list:
|
|
|
|
|
+ 410 each name is a type (GNU
|
|
|
|
|
+ 411 shorthand used by the
|
|
|
|
|
+ 412 Coco/R scanner frame) *)
|
|
|
|
|
+ 413 k := 0;
|
|
|
|
|
+ 414 WHILE k < cnt DO
|
|
|
|
|
+ 415 IF SymTab.Lookup(names[k])
|
|
|
|
|
+ 416 AND ((SymTab.SymKind(names[k]) = SymTab.KindType)
|
|
|
|
|
+ 417 OR (SymTab.SymKind(names[k]) = SymTab.KindPredef)) THEN
|
|
|
|
|
+ 418 pt := SymTab.SymType(names[k])
|
|
|
|
|
+ 419 ELSE SemError(201);
|
|
|
|
|
+ 420 pt := SymTab.InvalidType
|
|
|
|
|
+ 421 END;
|
|
|
|
|
+ 422 SymTab.ProcTypeAdd(t, isV, pt);
|
|
|
|
|
+ 423 INC(k)
|
|
|
|
|
+ 424 END; .) )
|
|
|
|
|
+ 425 | Type<pt, TRUE> (. (* unnamed parameter (PIM):
|
|
|
|
|
+ 426 e.g. PROCEDURE (VAR ARRAY OF REAL) *)
|
|
|
|
|
+ 427 SymTab.ProcTypeAdd(t, isV, pt); .) ) .
|
|
|
|
|
+ 428 (* Arrays: "OF" without bounds is an open formal (allowed only
|
|
|
|
|
+ 429 where allowOpen); "[lo..hi, ...]" nests bounded levels inside
|
|
|
|
|
+ 430 out. Bounds are folded literals (int/char); anything else 230.
|
|
|
|
|
+ 431 Bare-type indices ("ARRAY Color OF") wait for enum ordinals. *)
|
|
|
|
|
+ 432 ArrayType<VAR t: SymTab.TypeIndex; allowOpen: BOOLEAN>
|
|
|
|
|
+ 433 (. VAR elem: SymTab.TypeIndex;
|
|
|
|
|
+ 434 ok: BOOLEAN;
|
|
|
|
|
+ 435 bnds, bndh: ARRAY [0 .. 7] OF INTEGER;
|
|
|
|
|
+ 436 nb, k: CARDINAL;
|
|
|
|
|
+ 437 idx: SymTab.TypeIndex;
|
|
|
|
|
+ 438 ilo, ihi: INTEGER; .)
|
|
|
|
|
+ 439 = "ARRAY"
|
|
|
|
|
+ 440 ( "OF" Type<elem, FALSE> (. IF NOT allowOpen THEN
|
|
|
|
|
+ 441 SemError(230) END;
|
|
|
|
|
+ 442 t := SymTab.NewOpenArray(elem); .)
|
|
|
|
|
+ 443 | TypeIdent<idx> [ Subrange<idx> ]
|
|
|
|
|
+ 444 "OF" Type<elem, FALSE> (. (* index-type array: the index
|
|
|
|
|
+ 445 type's ordinal bounds give the
|
|
|
|
|
+ 446 [lo..hi] pair *)
|
|
|
|
|
+ 447 IF SymTab.TypeBounds(idx, ilo,
|
|
|
|
|
+ 448 ihi)
|
|
|
|
|
+ 449 THEN t := SymTab.NewArrayB(elem,
|
|
|
|
|
+ 450 ilo, ihi)
|
|
|
|
|
+ 451 ELSE SemError(230);
|
|
|
|
|
+ 452 t := SymTab.InvalidType
|
|
|
|
|
+ 453 END; .)
|
|
|
|
|
+ 454 | "[" (. SymTab.BoundBegin; ok := TRUE; .)
|
|
|
|
|
+ 455 BoundPair<ok>
|
|
|
|
|
+ 456 { "," BoundPair<ok> }
|
|
|
|
|
+ 457 "]" (. (* snapshot before the element
|
|
|
|
|
+ 458 type, which reuses the bound
|
|
|
|
|
+ 459 buffer for a nested ARRAY *)
|
|
|
|
|
+ 460 nb := SymTab.BoundCount();
|
|
|
|
|
+ 461 k := 0;
|
|
|
|
|
+ 462 WHILE k < nb DO
|
|
|
|
|
+ 463 bnds[k] := SymTab.BoundLo(k);
|
|
|
|
|
+ 464 bndh[k] := SymTab.BoundHi(k);
|
|
|
|
|
+ 465 INC(k)
|
|
|
|
|
+ 466 END; .)
|
|
|
|
|
+ 467 "OF" Type<elem, FALSE>
|
|
|
|
|
+ 468 (. IF ok THEN
|
|
|
|
|
+ 469 k := nb;
|
|
|
|
|
+ 470 WHILE k > 0 DO
|
|
|
|
|
+ 471 DEC(k);
|
|
|
|
|
+ 472 elem := SymTab.NewArrayB(
|
|
|
|
|
+ 473 elem, bnds[k], bndh[k])
|
|
|
|
|
+ 474 END;
|
|
|
|
|
+ 475 t := elem
|
|
|
|
|
+ 476 ELSE t := SymTab.InvalidType
|
|
|
|
|
+ 477 END; .) ) .
|
|
|
|
|
+ 478 BoundPair<VAR ok: BOOLEAN> (. VAR tlo, thi: SymTab.TypeIndex;
|
|
|
|
|
+ 479 qlo, qhi: QbeGen.QVal;
|
|
|
|
|
+ 480 lo, hi: INTEGER;
|
|
|
|
|
+ 481 cl, cl2: INTEGER; .)
|
|
|
|
|
+ 482 = Expr<tlo, qlo> ".." Expr<thi, qhi>
|
|
|
|
|
+ 483 (. IF (tlo = SymTab.InvalidType)
|
|
|
|
|
+ 484 OR (thi = SymTab.InvalidType) THEN
|
|
|
|
|
+ 485 ok := FALSE
|
|
|
|
|
+ 486 ELSE cl := SymTab.ClassOf(tlo);
|
|
|
|
|
+ 487 cl2 := SymTab.ClassOf(thi);
|
|
|
|
|
+ 488 IF ((cl # SymTab.ClInt)
|
|
|
|
|
+ 489 AND (cl # SymTab.ClChar))
|
|
|
|
|
+ 490 OR ((cl2 # SymTab.ClInt)
|
|
|
|
|
+ 491 AND (cl2 # SymTab.ClChar)) THEN
|
|
|
|
|
+ 492 SemError(230); ok := FALSE
|
|
|
|
|
+ 493 ELSIF NOT SymTab.ConstInt(qlo, lo)
|
|
|
|
|
+ 494 OR NOT SymTab.ConstInt(qhi, hi)
|
|
|
|
|
+ 495 OR (lo > hi) THEN
|
|
|
|
|
+ 496 SemError(230); ok := FALSE
|
|
|
|
|
+ 497 ELSIF NOT SymTab.BoundAdd(lo, hi) THEN
|
|
|
|
|
+ 498 SemError(230); ok := FALSE
|
|
|
|
|
+ 499 END;
|
|
|
|
|
+ 500 END; .) .
|
|
|
|
|
+ 501 (* Sets: multi-word masks over bases ≤ 256 values (bool, char,
|
|
|
|
|
+ 502 bounded subranges; enums wait for ordinals, INTEGER is
|
|
|
|
|
+ 503 unbounded). Literals are SET OF [0..255]; assignment and
|
|
|
|
|
+ 504 comparison across suitable bases are lenient (masks over min
|
|
|
|
|
+ 505 words + zero-check extras), out-of-span literals are 222. *)
|
|
|
|
|
+ 506 SetType<VAR t: SymTab.TypeIndex> (. VAR base: SymTab.TypeIndex;
|
|
|
|
|
+ 507 blo, bhi, bspan: INTEGER;
|
|
|
|
|
+ 508 bcls: INTEGER; .)
|
|
|
|
|
+ 509 = "SET" "OF" Type<base, FALSE>
|
|
|
|
|
+ 510 (. IF base = SymTab.InvalidType THEN
|
|
|
|
|
+ 511 t := SymTab.InvalidType
|
|
|
|
|
+ 512 ELSE bcls :=
|
|
|
|
|
+ 513 SymTab.ClassOf(base);
|
|
|
|
|
+ 514 IF bcls = SymTab.ClBool THEN
|
|
|
|
|
+ 515 blo := 0; bspan := 2
|
|
|
|
|
+ 516 ELSIF bcls = SymTab.ClChar THEN
|
|
|
|
|
+ 517 blo := 0; bspan := 256
|
|
|
|
|
+ 518 ELSIF bcls = SymTab.ClEnum THEN
|
|
|
|
|
+ 519 blo := 0;
|
|
|
|
|
+ 520 bspan := VAL(INTEGER,
|
|
|
|
|
+ 521 SymTab.EnumCount(base))
|
|
|
|
|
+ 522 ELSIF SymTab.SubBounds(base,
|
|
|
|
|
+ 523 blo, bhi) THEN
|
|
|
|
|
+ 524 bspan := bhi - blo + 1
|
|
|
|
|
+ 525 ELSE bspan := 0 END;
|
|
|
|
|
+ 526 IF (bspan <= 0)
|
|
|
|
|
+ 527 OR (bspan > 65536) THEN
|
|
|
|
|
+ 528 SemError(230);
|
|
|
|
|
+ 529 t := SymTab.InvalidType
|
|
|
|
|
+ 530 ELSE t := SymTab.NewSet(base)
|
|
|
|
|
+ 531 END
|
|
|
|
|
+ 532 END; .) .
|
|
|
|
|
+ 533 (* Records: flat blobs; array fields are pointers to static
|
|
|
|
|
+ 534 descriptors (locked amendment), nested records inline. Field
|
|
|
|
|
+ 535 offsets static and declaration-ordered. *)
|
|
|
|
|
+ 536 (* Field list: plain fields and (optionally) one variant part. The
|
|
|
|
|
+ 537 variant part is a `CASE ... END` item; because it starts with the
|
|
|
|
|
+ 538 CASE keyword it is unambiguously distinguishable from a field
|
|
|
|
|
+ 539 (which starts with an identifier). *)
|
|
|
|
|
+ 540 RecordType<VAR t: SymTab.TypeIndex> (. VAR t2: SymTab.TypeIndex;
|
|
|
|
|
+ 541 tagOk: BOOLEAN; .)
|
|
|
|
|
+ 542 = "RECORD" (. t := SymTab.NewRecord(); .)
|
|
|
|
|
+ 543 [ RecItem<t> { ";" [ RecItem<t> ] } ]
|
|
|
|
|
+ 544 "END" .
|
|
|
|
|
+ 545 RecItem<rec: SymTab.TypeIndex> (. VAR tt: SymTab.TypeIndex; .)
|
|
|
|
|
+ 546 = RecField<rec>
|
|
|
|
|
+ 547 | CaseField<rec> (. SymTab.MarkVariant(rec); .) .
|
|
|
|
|
+ 548 (* A variant part: CASE tag : Type OF variants. The layout overlays
|
|
|
|
|
+ 549 every branch from the tag slot (see SymTab.ComputeOffsets). *)
|
|
|
|
|
+ 550 CaseField<rec: SymTab.TypeIndex> (. VAR tagT: SymTab.TypeIndex;
|
|
|
|
|
+ 551 tagN: SymTab.Name; .)
|
|
|
|
|
+ 552 = "CASE" (. SymTab.ResetFields(rec); .)
|
|
|
|
|
+ 553 GetIdent<tagN> (. IF NOT SymTab.FieldPending(rec,
|
|
|
|
|
+ 554 tagN) THEN
|
|
|
|
|
+ 555 SemError(200) END; .)
|
|
|
|
|
+ 556 ":" Type<tagT, FALSE> (. IF (tagT # SymTab.InvalidType)
|
|
|
|
|
+ 557 AND NOT SymTab.IsOrdinal(tagT) THEN
|
|
|
|
|
+ 558 SemError(224)
|
|
|
|
|
+ 559 END;
|
|
|
|
|
+ 560 SymTab.FixPendingF(rec, tagT);
|
|
|
|
|
+ 561 SymTab.SetVariantTag(rec, tagN); .)
|
|
|
|
|
+ 562 "OF"
|
|
|
|
|
+ 563 RecFieldList<rec>
|
|
|
|
|
+ 564 { "|" (. SymTab.ResetFields(rec); .)
|
|
|
|
|
+ 565 RecFieldList<rec> }
|
|
|
|
|
+ 566 "END" .
|
|
|
|
|
+ 567 RecFieldList<rec: SymTab.TypeIndex> (. VAR lt, lq: SymTab.TypeIndex;
|
|
|
|
|
+ 568 lv1, lv2: QbeGen.QVal; .)
|
|
|
|
|
+ 569 = VarLabel<lt, lv1> [ ".." VarLabel<lq, lv2> ] ":"
|
|
|
|
|
+ 570 RecField<rec> { ";" [ RecField<rec> ] } .
|
|
|
|
|
+ 571 (* Variant case label: a constant (or a constant range). Values are
|
|
|
|
|
+ 572 not interpreted (the layout overlays regardless). *)
|
|
|
|
|
+ 573 VarLabel<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
|
|
+ 574 (. VAR lname: SymTab.Name; .)
|
|
|
|
|
+ 575 = ( ident (. LexName(lname);
|
|
|
576 QbeGen.CopyOp("0", q);
|
|
576 QbeGen.CopyOp("0", q);
|
|
|
- 577 t := SymTab.CharType(); .) ) .
|
|
|
|
|
- 578 RecField<rec: SymTab.TypeIndex> (. VAR n: SymTab.Name;
|
|
|
|
|
- 579 t2: SymTab.TypeIndex; .)
|
|
|
|
|
- 580 = RecIdents<rec> ":" Type<t2, FALSE>(. SymTab.FixPendingF(rec, t2); .) .
|
|
|
|
|
- 581 RecIdents<rec: SymTab.TypeIndex> (. VAR n: SymTab.Name; .)
|
|
|
|
|
- 582 = GetIdent<n> (. IF NOT SymTab.FieldPending(rec,
|
|
|
|
|
- 583 n) THEN
|
|
|
|
|
- 584 SemError(200) END; .)
|
|
|
|
|
- 585 { "," GetIdent<n> (. IF NOT SymTab.FieldPending(rec,
|
|
|
|
|
- 586 n) THEN
|
|
|
|
|
- 587 SemError(200) END; .) } .
|
|
|
|
|
- 588 TypeIdent<VAR t: SymTab.TypeIndex> (. VAR n, qid: SymTab.Name;
|
|
|
|
|
- 589 k: INTEGER;
|
|
|
|
|
- 590 dotted: BOOLEAN; .)
|
|
|
|
|
- 591 = GetIdent<n> (. dotted := FALSE;
|
|
|
|
|
- 592 IF NOT SymTab.Lookup(n) THEN
|
|
|
|
|
- 593 k := -1;
|
|
|
|
|
- 594 t := SymTab.ForwardType(n);
|
|
|
|
|
- 595 IF t = SymTab.InvalidType THEN
|
|
|
|
|
- 596 SemError(201)
|
|
|
|
|
- 597 END
|
|
|
|
|
- 598 ELSE k := SymTab.SymKind(n);
|
|
|
|
|
- 599 IF (k = SymTab.KindType)
|
|
|
|
|
- 600 OR (k = SymTab.KindPredef) THEN
|
|
|
|
|
- 601 t := SymTab.SymType(n)
|
|
|
|
|
- 602 ELSE t := SymTab.InvalidType
|
|
|
|
|
|
|
+ 577 t := SymTab.IntType(); .)
|
|
|
|
|
+ 578 | integer (. LexString(lname);
|
|
|
|
|
+ 579 QbeGen.CopyOp("0", q);
|
|
|
|
|
+ 580 t := SymTab.IntType(); .)
|
|
|
|
|
+ 581 | charConst (. LexString(lname);
|
|
|
|
|
+ 582 QbeGen.CopyOp("0", q);
|
|
|
|
|
+ 583 t := SymTab.CharType(); .) ) .
|
|
|
|
|
+ 584 RecField<rec: SymTab.TypeIndex> (. VAR n: SymTab.Name;
|
|
|
|
|
+ 585 t2: SymTab.TypeIndex; .)
|
|
|
|
|
+ 586 = RecIdents<rec> ":" Type<t2, FALSE>(. SymTab.FixPendingF(rec, t2); .) .
|
|
|
|
|
+ 587 RecIdents<rec: SymTab.TypeIndex> (. VAR n: SymTab.Name; .)
|
|
|
|
|
+ 588 = GetIdent<n> (. IF NOT SymTab.FieldPending(rec,
|
|
|
|
|
+ 589 n) THEN
|
|
|
|
|
+ 590 SemError(200) END; .)
|
|
|
|
|
+ 591 { "," GetIdent<n> (. IF NOT SymTab.FieldPending(rec,
|
|
|
|
|
+ 592 n) THEN
|
|
|
|
|
+ 593 SemError(200) END; .) } .
|
|
|
|
|
+ 594 TypeIdent<VAR t: SymTab.TypeIndex> (. VAR n, qid: SymTab.Name;
|
|
|
|
|
+ 595 k: INTEGER;
|
|
|
|
|
+ 596 dotted: BOOLEAN; .)
|
|
|
|
|
+ 597 = GetIdent<n> (. dotted := FALSE;
|
|
|
|
|
+ 598 IF NOT SymTab.Lookup(n) THEN
|
|
|
|
|
+ 599 k := -1;
|
|
|
|
|
+ 600 t := SymTab.ForwardType(n);
|
|
|
|
|
+ 601 IF t = SymTab.InvalidType THEN
|
|
|
|
|
+ 602 SemError(201)
|
|
|
603 END
|
|
603 END
|
|
|
- 604 END; .)
|
|
|
|
|
- 605 [ "." GetIdent<qid> (. dotted := TRUE;
|
|
|
|
|
- 606 IF k = SymTab.KindModule THEN
|
|
|
|
|
- 607 t := SymTab.QualType(n, qid);
|
|
|
|
|
- 608 IF t = SymTab.InvalidType THEN
|
|
|
|
|
- 609 SemError(201)
|
|
|
|
|
- 610 END
|
|
|
|
|
- 611 ELSE SemError(221);
|
|
|
|
|
- 612 t := SymTab.InvalidType
|
|
|
|
|
- 613 END; .) ]
|
|
|
|
|
- 614 (. IF NOT dotted THEN
|
|
|
|
|
- 615 IF (k = SymTab.KindModule)
|
|
|
|
|
- 616 OR ((k # SymTab.KindType)
|
|
|
|
|
- 617 AND (k # SymTab.KindPredef)
|
|
|
|
|
- 618 AND (k # SymTab.KindImport)
|
|
|
|
|
- 619 AND (k # -1)) THEN
|
|
|
|
|
- 620 SemError(221)
|
|
|
|
|
- 621 END
|
|
|
|
|
- 622 END; .) .
|
|
|
|
|
- 623 Subrange<VAR t: SymTab.TypeIndex> (. VAR tlo, thi: SymTab.TypeIndex;
|
|
|
|
|
- 624 qlo, qhi: QbeGen.QVal;
|
|
|
|
|
- 625 lo, hi: INTEGER; .)
|
|
|
|
|
- 626 = "[" Expr<tlo, qlo> ".." Expr<thi, qhi>
|
|
|
|
|
- 627 (. IF (tlo = SymTab.InvalidType)
|
|
|
|
|
- 628 OR (thi = SymTab.InvalidType) THEN
|
|
|
|
|
- 629 t := SymTab.InvalidType
|
|
|
|
|
- 630 ELSIF NOT SymTab.IsOrdinal(tlo)
|
|
|
|
|
- 631 OR NOT SymTab.IsOrdinal(thi) THEN
|
|
|
|
|
- 632 SemError(230);
|
|
|
|
|
- 633 t := SymTab.InvalidType
|
|
|
|
|
- 634 ELSIF NOT SymTab.ConstInt(qlo, lo)
|
|
|
|
|
- 635 OR NOT SymTab.ConstInt(qhi, hi)
|
|
|
|
|
- 636 OR (lo > hi) THEN
|
|
|
|
|
- 637 SemError(230);
|
|
|
|
|
- 638 t := SymTab.InvalidType
|
|
|
|
|
- 639 ELSE t := SymTab.NewSubR(lo, hi)
|
|
|
|
|
- 640 END; .)
|
|
|
|
|
- 641 "]" .
|
|
|
|
|
- 642 Enum<VAR t: SymTab.TypeIndex> (. VAR n: SymTab.Name;
|
|
|
|
|
- 643 ord: INTEGER;
|
|
|
|
|
- 644 qv: QbeGen.QVal; .)
|
|
|
|
|
- 645 = "(" (. t := SymTab.NewEnum();
|
|
|
|
|
- 646 ord := 0; .)
|
|
|
|
|
- 647 GetIdent<n> (. IF NOT SymTab.Enter(n,
|
|
|
|
|
- 648 SymTab.KindConst) THEN
|
|
|
|
|
- 649 SemError(200) END;
|
|
|
|
|
- 650 SymTab.SetSymType(n, t);
|
|
|
|
|
- 651 QbeGen.IntStr(ord, qv);
|
|
|
|
|
- 652 SymTab.SetSymVal(n, qv);
|
|
|
|
|
- 653 INC(ord); .)
|
|
|
|
|
- 654 { "," GetIdent<n> (. IF NOT SymTab.Enter(n,
|
|
|
|
|
- 655 SymTab.KindConst) THEN
|
|
|
|
|
- 656 SemError(200) END;
|
|
|
|
|
- 657 SymTab.SetSymType(n, t);
|
|
|
|
|
- 658 QbeGen.IntStr(ord, qv);
|
|
|
|
|
- 659 SymTab.SetSymVal(n, qv);
|
|
|
|
|
- 660 INC(ord); .) }
|
|
|
|
|
- 661 ")" (. SymTab.SetEnumCount(t,
|
|
|
|
|
- 662 VAL(CARDINAL, ord)); .) .
|
|
|
|
|
- 663 (* Clarion-form classes (docs/OOP.txt): declaration + single
|
|
|
|
|
- 664 inheritance + IMPLEMENTATION blocks. Scopes and member checks
|
|
|
|
|
- 665 now; lowering (vtable, dispatch, THIS) later — one 230 per
|
|
|
|
|
- 666 class/impl block. Methods end with ";" per the Table example
|
|
|
|
|
- 667 (not "," as in the sketch). No underscores in identifiers. *)
|
|
|
|
|
- 668 (* Single CLASS item in both loops: separating declaration from
|
|
|
|
|
- 669 IMPLEMENTATION at the loop level needs 2-token lookahead
|
|
|
|
|
- 670 (CLASS ident vs CLASS IMPLEMENTATION), which LL(1) cannot do.
|
|
|
|
|
- 671 The second token decides after CLASS is consumed. A misplaced
|
|
|
|
|
- 672 CLASS IMPLEMENTATION inside TYPE still parses (harmless: the
|
|
|
|
|
- 673 whole unit ends 230 until lowering). *)
|
|
|
|
|
- 674 ClassItem
|
|
|
|
|
- 675 = "CLASS" ( "IMPLEMENTATION" ClassImplRest | ClassRest ) .
|
|
|
|
|
- 676 ClassRest (. VAR cn, m2, pn: SymTab.Name;
|
|
|
|
|
- 677 ct: SymTab.TypeIndex; .)
|
|
|
|
|
- 678 = GetIdent<cn> (. IF NOT SymTab.Enter(cn,
|
|
|
|
|
- 679 SymTab.KindType) THEN
|
|
|
|
|
- 680 SemError(200) END;
|
|
|
|
|
- 681 ct := SymTab.NewClass();
|
|
|
|
|
- 682 SymTab.SetSymType(cn, ct);
|
|
|
|
|
- 683 SymTab.PushClassScope(ct); .)
|
|
|
|
|
- 684 [ Parents<ct> ]
|
|
|
|
|
- 685 ";"
|
|
|
|
|
- 686 { ClassField<ct> ";" }
|
|
|
|
|
- 687 { MethodHeading<pn, SymTab.InvalidType> ";"
|
|
|
|
|
- 688 (. SymTab.CloseProc;
|
|
|
|
|
- 689 QbeGen.AbortFunc; .) }
|
|
|
|
|
- 690 "END"
|
|
|
|
|
- 691 GetIdent<m2> (. IF NOT SymTab.Equal(cn, m2) THEN
|
|
|
|
|
- 692 SemError(202) END;
|
|
|
|
|
- 693 SymTab.LayoutClass(ct);
|
|
|
|
|
- 694 SymTab.PopScope; .) .
|
|
|
|
|
- 695 Parents<ct: SymTab.TypeIndex> (. VAR p: SymTab.Name; .)
|
|
|
|
|
- 696 = "(" Parent1<ct>
|
|
|
|
|
- 697 { "," GetIdent<p> (. SemError(230); .) }
|
|
|
|
|
- 698 ")" .
|
|
|
|
|
- 699 Parent1<ct: SymTab.TypeIndex> (. VAR p: SymTab.Name;
|
|
|
|
|
- 700 pt: SymTab.TypeIndex; .)
|
|
|
|
|
- 701 = GetIdent<p> (. IF NOT SymTab.Lookup(p) THEN
|
|
|
|
|
- 702 SemError(201)
|
|
|
|
|
- 703 ELSE pt := SymTab.SymType(p);
|
|
|
|
|
- 704 IF SymTab.ClassOf(pt) #
|
|
|
|
|
- 705 SymTab.ClClass THEN
|
|
|
|
|
- 706 SemError(230)
|
|
|
|
|
- 707 ELSE SymTab.SetParent(ct, pt)
|
|
|
|
|
- 708 END
|
|
|
|
|
- 709 END; .) .
|
|
|
|
|
- 710 ClassField<ct: SymTab.TypeIndex> (. VAR n, rhs: SymTab.Name;
|
|
|
|
|
- 711 t: SymTab.TypeIndex; .)
|
|
|
|
|
- 712 = GetIdent<n>
|
|
|
|
|
- 713 ( "=" GetIdent<rhs> (. IF NOT SymTab.Enter(n,
|
|
|
|
|
- 714 SymTab.KindConst) THEN
|
|
|
|
|
- 715 SemError(200) END;
|
|
|
|
|
- 716 IF SymTab.Lookup(rhs) THEN
|
|
|
|
|
- 717 SymTab.SetSymType(n,
|
|
|
|
|
- 718 SymTab.SymType(rhs))
|
|
|
|
|
- 719 END; .)
|
|
|
|
|
- 720 | (. IF NOT SymTab.FieldPending(ct,
|
|
|
|
|
- 721 n) THEN
|
|
|
|
|
- 722 SemError(200) END; .)
|
|
|
|
|
- 723 { "," GetIdent<n> (. IF NOT SymTab.FieldPending(ct,
|
|
|
|
|
- 724 n) THEN
|
|
|
|
|
- 725 SemError(200) END; .) }
|
|
|
|
|
- 726 ":" Type<t, FALSE> (. SymTab.FixPendingF(ct, t); .) ) .
|
|
|
|
|
- 727 MethodHeading<VAR pn: SymTab.Name; ct: SymTab.TypeIndex>
|
|
|
|
|
- 728 (. VAR wantVirt: BOOLEAN; .)
|
|
|
|
|
- 729 = (. wantVirt := FALSE; .)
|
|
|
|
|
- 730 [ "VIRTUAL" (. wantVirt := TRUE; .) ]
|
|
|
|
|
- 731 ProcHeading<pn, ct> (. IF wantVirt THEN
|
|
|
|
|
- 732 SymTab.MarkVirtual END; .) .
|
|
|
|
|
- 733 ClassImplRest (. VAR cn, m2: SymTab.Name;
|
|
|
|
|
- 734 ct: SymTab.TypeIndex; .)
|
|
|
|
|
- 735 = GetIdent<cn> (. IF NOT SymTab.Lookup(cn) THEN
|
|
|
|
|
- 736 SemError(201);
|
|
|
|
|
- 737 ct := SymTab.InvalidType
|
|
|
|
|
- 738 ELSE ct := SymTab.SymType(cn);
|
|
|
|
|
- 739 IF SymTab.ClassOf(ct) #
|
|
|
|
|
- 740 SymTab.ClClass THEN
|
|
|
|
|
- 741 SemError(230);
|
|
|
|
|
- 742 ct := SymTab.InvalidType
|
|
|
|
|
- 743 END
|
|
|
|
|
- 744 END;
|
|
|
|
|
- 745 IF ct #
|
|
|
|
|
- 746 SymTab.InvalidType THEN
|
|
|
|
|
- 747 IF NOT SymTab.PushClassMembers(
|
|
|
|
|
- 748 ct) THEN
|
|
|
|
|
- 749 SemError(230) END;
|
|
|
|
|
- 750 SymTab.PushImplClass(ct)
|
|
|
|
|
- 751 END; .)
|
|
|
|
|
- 752 ";" { MethodImpl<ct> ";" }
|
|
|
|
|
- 753 [ "BEGIN" (. QbeGen.BeginInit(cn); .)
|
|
|
|
|
- 754 [ StatSeq ] (. QbeGen.EndInit; .) ]
|
|
|
|
|
- 755 "END"
|
|
|
|
|
- 756 GetIdent<m2> (. IF NOT SymTab.Equal(cn, m2) THEN
|
|
|
|
|
- 757 SemError(202) END;
|
|
|
|
|
- 758 SymTab.PopImplClass;
|
|
|
|
|
- 759 SymTab.PopScope; .) .
|
|
|
|
|
- 760 MethodImpl<ct: SymTab.TypeIndex> (. VAR pn: SymTab.Name;
|
|
|
|
|
- 761 thisQ: QbeGen.QVal;
|
|
|
|
|
- 762 methRes: SymTab.TypeIndex; .)
|
|
|
|
|
- 763 = MethodHeading<pn, ct> ";"
|
|
|
|
|
- 764 (. IF (ct #
|
|
|
|
|
- 765 SymTab.InvalidType)
|
|
|
|
|
- 766 AND NOT SymTab.MethodExists(ct,
|
|
|
|
|
- 767 pn) THEN
|
|
|
|
|
- 768 SemError(201) END; .)
|
|
|
|
|
- 769 ( "FORWARD" (. SymTab.MarkFwd;
|
|
|
|
|
- 770 QbeGen.AbortFunc;
|
|
|
|
|
- 771 SymTab.CloseProc; .)
|
|
|
|
|
- 772 | (. QbeGen.EndFuncHeader;
|
|
|
|
|
- 773 (* bind the receiver: bare
|
|
|
|
|
- 774 field names resolve
|
|
|
|
|
- 775 against THIS *)
|
|
|
|
|
- 776 QbeGen.ThisBase(thisQ);
|
|
|
|
|
- 777 QbeGen.PushWith(thisQ); .)
|
|
|
|
|
- 778 Block<pn> (. QbeGen.PopWith;
|
|
|
|
|
- 779 methRes := SymTab.CurRes();
|
|
|
|
|
- 780 SymTab.CloseProc;
|
|
|
|
|
- 781 QbeGen.EndFunc(methRes); .) ) .
|
|
|
|
|
- 782 ConstBlock
|
|
|
|
|
- 783 = "CONST" { ConstDecl ";" } .
|
|
|
|
|
- 784 ConstDecl (. VAR n: SymTab.Name;
|
|
|
|
|
- 785 t: SymTab.TypeIndex;
|
|
|
|
|
- 786 qv: QbeGen.QVal;
|
|
|
|
|
- 787 cls: INTEGER; .)
|
|
|
|
|
- 788 = GetIdent<n> (. IF NOT SymTab.Enter(n,
|
|
|
|
|
- 789 SymTab.KindConst) THEN
|
|
|
|
|
- 790 SemError(200) END; .)
|
|
|
|
|
- 791 "="
|
|
|
|
|
- 792 Expr<t, qv> (. SymTab.SetSymType(n, t);
|
|
|
|
|
- 793 cls := SymTab.ClassOf(t);
|
|
|
|
|
- 794 IF (cls = SymTab.ClArray)
|
|
|
|
|
- 795 OR (cls = SymTab.ClRecord)
|
|
|
|
|
- 796 OR (cls = SymTab.ClClass)
|
|
|
|
|
- 797 OR (cls = SymTab.ClStr)
|
|
|
|
|
- 798 OR (cls = SymTab.ClUStr) THEN
|
|
|
|
|
- 799 (* an aggregate/string
|
|
|
|
|
- 800 constant: qv is its
|
|
|
|
|
- 801 descriptor address; no
|
|
|
|
|
- 802 scalar data *)
|
|
|
|
|
- 803 SymTab.SetSymVal(n, qv)
|
|
|
|
|
- 804 ELSIF NOT QbeGen.IsImm(qv) THEN
|
|
|
|
|
- 805 SemError(230)
|
|
|
|
|
- 806 ELSE
|
|
|
|
|
- 807 SymTab.SetSymVal(n, qv);
|
|
|
|
|
- 808 QbeGen.DeclConst(n, qv, t)
|
|
|
|
|
- 809 END; .) .
|
|
|
|
|
- 810 VarBlock
|
|
|
|
|
- 811 = "VAR" { VarDecl ";" } .
|
|
|
|
|
- 812 VarDecl (. VAR nm: SymTab.Name;
|
|
|
|
|
- 813 t: SymTab.TypeIndex;
|
|
|
|
|
- 814 i: CARDINAL;
|
|
|
|
|
- 815 cls: INTEGER; .)
|
|
|
|
|
- 816 = VarIdents ":"
|
|
|
|
|
- 817 Type<t, FALSE> (. cls := SymTab.ClassOf(t);
|
|
|
|
|
- 818 IF (t # SymTab.InvalidType)
|
|
|
|
|
- 819 AND NOT SymTab.IsUnresolved(t)
|
|
|
|
|
- 820 AND (cls # SymTab.ClInt)
|
|
|
|
|
- 821 AND (cls # SymTab.ClBool)
|
|
|
|
|
- 822 AND (cls # SymTab.ClChar)
|
|
|
|
|
- 823 AND (cls # SymTab.ClReal)
|
|
|
|
|
- 824 AND (cls # SymTab.ClArray)
|
|
|
|
|
- 825 AND (cls # SymTab.ClSet)
|
|
|
|
|
- 826 AND (cls # SymTab.ClRecord)
|
|
|
|
|
- 827 AND (cls # SymTab.ClPtr)
|
|
|
|
|
- 828 AND (cls # SymTab.ClLong)
|
|
|
|
|
- 829 AND (cls # SymTab.ClProc)
|
|
|
|
|
- 830 AND (cls # SymTab.ClUChar)
|
|
|
|
|
- 831 AND (cls # SymTab.ClUStr)
|
|
|
|
|
- 832 AND (cls # SymTab.ClEnum)
|
|
|
|
|
- 833 AND (cls # SymTab.ClClass) THEN
|
|
|
|
|
- 834 SemError(230) END;
|
|
|
|
|
- 835 IF QbeGen.LocFull() THEN
|
|
|
|
|
- 836 SemError(233) END;
|
|
|
|
|
- 837 i := 0;
|
|
|
|
|
- 838 IF SymTab.IsUnresolved(t)
|
|
|
|
|
- 839 AND NOT SymTab.InProc() THEN
|
|
|
|
|
- 840 (* a forward-typed global:
|
|
|
|
|
- 841 defer emission until the
|
|
|
|
|
- 842 TYPE block completes *)
|
|
|
|
|
- 843 WHILE i < SymTab.PendCount() DO
|
|
|
|
|
- 844 SymTab.PendName(i, nm);
|
|
|
|
|
- 845 IF nPendVar <=
|
|
|
|
|
- 846 HIGH(pendVarName) THEN
|
|
|
|
|
- 847 pendVarName[nPendVar] := nm;
|
|
|
|
|
- 848 pendVarT[nPendVar] := t;
|
|
|
|
|
- 849 INC(nPendVar)
|
|
|
|
|
- 850 END;
|
|
|
|
|
- 851 INC(i)
|
|
|
|
|
- 852 END
|
|
|
|
|
- 853 ELSE
|
|
|
|
|
- 854 WHILE i < SymTab.PendCount() DO
|
|
|
|
|
- 855 SymTab.PendName(i, nm);
|
|
|
|
|
- 856 QbeGen.DeclVar(nm, t);
|
|
|
|
|
|
|
+ 604 ELSE k := SymTab.SymKind(n);
|
|
|
|
|
+ 605 IF (k = SymTab.KindType)
|
|
|
|
|
+ 606 OR (k = SymTab.KindPredef) THEN
|
|
|
|
|
+ 607 t := SymTab.SymType(n)
|
|
|
|
|
+ 608 ELSE t := SymTab.InvalidType
|
|
|
|
|
+ 609 END
|
|
|
|
|
+ 610 END; .)
|
|
|
|
|
+ 611 [ "." GetIdent<qid> (. dotted := TRUE;
|
|
|
|
|
+ 612 IF k = SymTab.KindModule THEN
|
|
|
|
|
+ 613 t := SymTab.QualType(n, qid);
|
|
|
|
|
+ 614 IF t = SymTab.InvalidType THEN
|
|
|
|
|
+ 615 SemError(201)
|
|
|
|
|
+ 616 END
|
|
|
|
|
+ 617 ELSE SemError(221);
|
|
|
|
|
+ 618 t := SymTab.InvalidType
|
|
|
|
|
+ 619 END; .) ]
|
|
|
|
|
+ 620 (. IF NOT dotted THEN
|
|
|
|
|
+ 621 IF (k = SymTab.KindModule)
|
|
|
|
|
+ 622 OR ((k # SymTab.KindType)
|
|
|
|
|
+ 623 AND (k # SymTab.KindPredef)
|
|
|
|
|
+ 624 AND (k # SymTab.KindImport)
|
|
|
|
|
+ 625 AND (k # -1)) THEN
|
|
|
|
|
+ 626 SemError(221)
|
|
|
|
|
+ 627 END
|
|
|
|
|
+ 628 END; .) .
|
|
|
|
|
+ 629 Subrange<VAR t: SymTab.TypeIndex> (. VAR tlo, thi: SymTab.TypeIndex;
|
|
|
|
|
+ 630 qlo, qhi: QbeGen.QVal;
|
|
|
|
|
+ 631 lo, hi: INTEGER; .)
|
|
|
|
|
+ 632 = "[" Expr<tlo, qlo> ".." Expr<thi, qhi>
|
|
|
|
|
+ 633 (. IF (tlo = SymTab.InvalidType)
|
|
|
|
|
+ 634 OR (thi = SymTab.InvalidType) THEN
|
|
|
|
|
+ 635 t := SymTab.InvalidType
|
|
|
|
|
+ 636 ELSIF NOT SymTab.IsOrdinal(tlo)
|
|
|
|
|
+ 637 OR NOT SymTab.IsOrdinal(thi) THEN
|
|
|
|
|
+ 638 SemError(230);
|
|
|
|
|
+ 639 t := SymTab.InvalidType
|
|
|
|
|
+ 640 ELSIF NOT SymTab.ConstInt(qlo, lo)
|
|
|
|
|
+ 641 OR NOT SymTab.ConstInt(qhi, hi)
|
|
|
|
|
+ 642 OR (lo > hi) THEN
|
|
|
|
|
+ 643 SemError(230);
|
|
|
|
|
+ 644 t := SymTab.InvalidType
|
|
|
|
|
+ 645 ELSE t := SymTab.NewSubR(lo, hi)
|
|
|
|
|
+ 646 END; .)
|
|
|
|
|
+ 647 "]" .
|
|
|
|
|
+ 648 Enum<VAR t: SymTab.TypeIndex> (. VAR n: SymTab.Name;
|
|
|
|
|
+ 649 ord: INTEGER;
|
|
|
|
|
+ 650 qv: QbeGen.QVal; .)
|
|
|
|
|
+ 651 = "(" (. t := SymTab.NewEnum();
|
|
|
|
|
+ 652 ord := 0; .)
|
|
|
|
|
+ 653 GetIdent<n> (. IF NOT SymTab.Enter(n,
|
|
|
|
|
+ 654 SymTab.KindConst) THEN
|
|
|
|
|
+ 655 SemError(200) END;
|
|
|
|
|
+ 656 SymTab.SetSymType(n, t);
|
|
|
|
|
+ 657 QbeGen.IntStr(ord, qv);
|
|
|
|
|
+ 658 SymTab.SetSymVal(n, qv);
|
|
|
|
|
+ 659 INC(ord); .)
|
|
|
|
|
+ 660 { "," GetIdent<n> (. IF NOT SymTab.Enter(n,
|
|
|
|
|
+ 661 SymTab.KindConst) THEN
|
|
|
|
|
+ 662 SemError(200) END;
|
|
|
|
|
+ 663 SymTab.SetSymType(n, t);
|
|
|
|
|
+ 664 QbeGen.IntStr(ord, qv);
|
|
|
|
|
+ 665 SymTab.SetSymVal(n, qv);
|
|
|
|
|
+ 666 INC(ord); .) }
|
|
|
|
|
+ 667 ")" (. SymTab.SetEnumCount(t,
|
|
|
|
|
+ 668 VAL(CARDINAL, ord)); .) .
|
|
|
|
|
+ 669 (* Clarion-form classes (docs/OOP.txt): declaration + single
|
|
|
|
|
+ 670 inheritance + IMPLEMENTATION blocks. Scopes and member checks
|
|
|
|
|
+ 671 now; lowering (vtable, dispatch, THIS) later — one 230 per
|
|
|
|
|
+ 672 class/impl block. Methods end with ";" per the Table example
|
|
|
|
|
+ 673 (not "," as in the sketch). No underscores in identifiers. *)
|
|
|
|
|
+ 674 (* Single CLASS item in both loops: separating declaration from
|
|
|
|
|
+ 675 IMPLEMENTATION at the loop level needs 2-token lookahead
|
|
|
|
|
+ 676 (CLASS ident vs CLASS IMPLEMENTATION), which LL(1) cannot do.
|
|
|
|
|
+ 677 The second token decides after CLASS is consumed. A misplaced
|
|
|
|
|
+ 678 CLASS IMPLEMENTATION inside TYPE still parses (harmless: the
|
|
|
|
|
+ 679 whole unit ends 230 until lowering). *)
|
|
|
|
|
+ 680 ClassItem
|
|
|
|
|
+ 681 = "CLASS" ( "IMPLEMENTATION" ClassImplRest | ClassRest ) .
|
|
|
|
|
+ 682 ClassRest (. VAR cn, m2, pn: SymTab.Name;
|
|
|
|
|
+ 683 ct: SymTab.TypeIndex; .)
|
|
|
|
|
+ 684 = GetIdent<cn> (. IF NOT SymTab.Enter(cn,
|
|
|
|
|
+ 685 SymTab.KindType) THEN
|
|
|
|
|
+ 686 SemError(200) END;
|
|
|
|
|
+ 687 ct := SymTab.NewClass();
|
|
|
|
|
+ 688 SymTab.SetSymType(cn, ct);
|
|
|
|
|
+ 689 SymTab.PushClassScope(ct); .)
|
|
|
|
|
+ 690 [ Parents<ct> ]
|
|
|
|
|
+ 691 ";"
|
|
|
|
|
+ 692 { ClassField<ct> ";" }
|
|
|
|
|
+ 693 { MethodHeading<pn, SymTab.InvalidType> ";"
|
|
|
|
|
+ 694 (. SymTab.CloseProc;
|
|
|
|
|
+ 695 QbeGen.AbortFunc; .) }
|
|
|
|
|
+ 696 "END"
|
|
|
|
|
+ 697 GetIdent<m2> (. IF NOT SymTab.Equal(cn, m2) THEN
|
|
|
|
|
+ 698 SemError(202) END;
|
|
|
|
|
+ 699 SymTab.LayoutClass(ct);
|
|
|
|
|
+ 700 SymTab.PopScope; .) .
|
|
|
|
|
+ 701 Parents<ct: SymTab.TypeIndex> (. VAR p: SymTab.Name; .)
|
|
|
|
|
+ 702 = "(" Parent1<ct>
|
|
|
|
|
+ 703 { "," GetIdent<p> (. SemError(230); .) }
|
|
|
|
|
+ 704 ")" .
|
|
|
|
|
+ 705 Parent1<ct: SymTab.TypeIndex> (. VAR p: SymTab.Name;
|
|
|
|
|
+ 706 pt: SymTab.TypeIndex; .)
|
|
|
|
|
+ 707 = GetIdent<p> (. IF NOT SymTab.Lookup(p) THEN
|
|
|
|
|
+ 708 SemError(201)
|
|
|
|
|
+ 709 ELSE pt := SymTab.SymType(p);
|
|
|
|
|
+ 710 IF SymTab.ClassOf(pt) #
|
|
|
|
|
+ 711 SymTab.ClClass THEN
|
|
|
|
|
+ 712 SemError(230)
|
|
|
|
|
+ 713 ELSE SymTab.SetParent(ct, pt)
|
|
|
|
|
+ 714 END
|
|
|
|
|
+ 715 END; .) .
|
|
|
|
|
+ 716 ClassField<ct: SymTab.TypeIndex> (. VAR n, rhs: SymTab.Name;
|
|
|
|
|
+ 717 t: SymTab.TypeIndex; .)
|
|
|
|
|
+ 718 = GetIdent<n>
|
|
|
|
|
+ 719 ( "=" GetIdent<rhs> (. IF NOT SymTab.Enter(n,
|
|
|
|
|
+ 720 SymTab.KindConst) THEN
|
|
|
|
|
+ 721 SemError(200) END;
|
|
|
|
|
+ 722 IF SymTab.Lookup(rhs) THEN
|
|
|
|
|
+ 723 SymTab.SetSymType(n,
|
|
|
|
|
+ 724 SymTab.SymType(rhs))
|
|
|
|
|
+ 725 END; .)
|
|
|
|
|
+ 726 | (. IF NOT SymTab.FieldPending(ct,
|
|
|
|
|
+ 727 n) THEN
|
|
|
|
|
+ 728 SemError(200) END; .)
|
|
|
|
|
+ 729 { "," GetIdent<n> (. IF NOT SymTab.FieldPending(ct,
|
|
|
|
|
+ 730 n) THEN
|
|
|
|
|
+ 731 SemError(200) END; .) }
|
|
|
|
|
+ 732 ":" Type<t, FALSE> (. SymTab.FixPendingF(ct, t); .) ) .
|
|
|
|
|
+ 733 MethodHeading<VAR pn: SymTab.Name; ct: SymTab.TypeIndex>
|
|
|
|
|
+ 734 (. VAR wantVirt: BOOLEAN; .)
|
|
|
|
|
+ 735 = (. wantVirt := FALSE; .)
|
|
|
|
|
+ 736 [ "VIRTUAL" (. wantVirt := TRUE; .) ]
|
|
|
|
|
+ 737 ProcHeading<pn, ct> (. IF wantVirt THEN
|
|
|
|
|
+ 738 SymTab.MarkVirtual END; .) .
|
|
|
|
|
+ 739 ClassImplRest (. VAR cn, m2: SymTab.Name;
|
|
|
|
|
+ 740 ct: SymTab.TypeIndex; .)
|
|
|
|
|
+ 741 = GetIdent<cn> (. IF NOT SymTab.Lookup(cn) THEN
|
|
|
|
|
+ 742 SemError(201);
|
|
|
|
|
+ 743 ct := SymTab.InvalidType
|
|
|
|
|
+ 744 ELSE ct := SymTab.SymType(cn);
|
|
|
|
|
+ 745 IF SymTab.ClassOf(ct) #
|
|
|
|
|
+ 746 SymTab.ClClass THEN
|
|
|
|
|
+ 747 SemError(230);
|
|
|
|
|
+ 748 ct := SymTab.InvalidType
|
|
|
|
|
+ 749 END
|
|
|
|
|
+ 750 END;
|
|
|
|
|
+ 751 IF ct #
|
|
|
|
|
+ 752 SymTab.InvalidType THEN
|
|
|
|
|
+ 753 IF NOT SymTab.PushClassMembers(
|
|
|
|
|
+ 754 ct) THEN
|
|
|
|
|
+ 755 SemError(230) END;
|
|
|
|
|
+ 756 SymTab.PushImplClass(ct)
|
|
|
|
|
+ 757 END; .)
|
|
|
|
|
+ 758 ";" { MethodImpl<ct> ";" }
|
|
|
|
|
+ 759 [ "BEGIN" (. QbeGen.BeginInit(cn); .)
|
|
|
|
|
+ 760 [ StatSeq ] (. QbeGen.EndInit; .) ]
|
|
|
|
|
+ 761 "END"
|
|
|
|
|
+ 762 GetIdent<m2> (. IF NOT SymTab.Equal(cn, m2) THEN
|
|
|
|
|
+ 763 SemError(202) END;
|
|
|
|
|
+ 764 SymTab.PopImplClass;
|
|
|
|
|
+ 765 SymTab.PopScope; .) .
|
|
|
|
|
+ 766 MethodImpl<ct: SymTab.TypeIndex> (. VAR pn: SymTab.Name;
|
|
|
|
|
+ 767 thisQ: QbeGen.QVal;
|
|
|
|
|
+ 768 methRes: SymTab.TypeIndex; .)
|
|
|
|
|
+ 769 = MethodHeading<pn, ct> ";"
|
|
|
|
|
+ 770 (. IF (ct #
|
|
|
|
|
+ 771 SymTab.InvalidType)
|
|
|
|
|
+ 772 AND NOT SymTab.MethodExists(ct,
|
|
|
|
|
+ 773 pn) THEN
|
|
|
|
|
+ 774 SemError(201) END; .)
|
|
|
|
|
+ 775 ( "FORWARD" (. SymTab.MarkFwd;
|
|
|
|
|
+ 776 QbeGen.AbortFunc;
|
|
|
|
|
+ 777 SymTab.CloseProc; .)
|
|
|
|
|
+ 778 | (. QbeGen.EndFuncHeader;
|
|
|
|
|
+ 779 (* bind the receiver: bare
|
|
|
|
|
+ 780 field names resolve
|
|
|
|
|
+ 781 against THIS *)
|
|
|
|
|
+ 782 QbeGen.ThisBase(thisQ);
|
|
|
|
|
+ 783 QbeGen.PushWith(thisQ); .)
|
|
|
|
|
+ 784 Block<pn> (. QbeGen.PopWith;
|
|
|
|
|
+ 785 methRes := SymTab.CurRes();
|
|
|
|
|
+ 786 SymTab.CloseProc;
|
|
|
|
|
+ 787 QbeGen.EndFunc(methRes); .) ) .
|
|
|
|
|
+ 788 ConstBlock
|
|
|
|
|
+ 789 = "CONST" { ConstDecl ";" } .
|
|
|
|
|
+ 790 ConstDecl (. VAR n: SymTab.Name;
|
|
|
|
|
+ 791 t: SymTab.TypeIndex;
|
|
|
|
|
+ 792 qv: QbeGen.QVal;
|
|
|
|
|
+ 793 cls: INTEGER; .)
|
|
|
|
|
+ 794 = GetIdent<n> (. IF NOT SymTab.Enter(n,
|
|
|
|
|
+ 795 SymTab.KindConst) THEN
|
|
|
|
|
+ 796 SemError(200) END; .)
|
|
|
|
|
+ 797 "="
|
|
|
|
|
+ 798 Expr<t, qv> (. SymTab.SetSymType(n, t);
|
|
|
|
|
+ 799 cls := SymTab.ClassOf(t);
|
|
|
|
|
+ 800 IF (cls = SymTab.ClArray)
|
|
|
|
|
+ 801 OR (cls = SymTab.ClRecord)
|
|
|
|
|
+ 802 OR (cls = SymTab.ClClass)
|
|
|
|
|
+ 803 OR (cls = SymTab.ClStr)
|
|
|
|
|
+ 804 OR (cls = SymTab.ClUStr) THEN
|
|
|
|
|
+ 805 (* an aggregate/string
|
|
|
|
|
+ 806 constant: qv is its
|
|
|
|
|
+ 807 descriptor address; no
|
|
|
|
|
+ 808 scalar data *)
|
|
|
|
|
+ 809 SymTab.SetSymVal(n, qv)
|
|
|
|
|
+ 810 ELSIF NOT QbeGen.IsImm(qv) THEN
|
|
|
|
|
+ 811 SemError(230)
|
|
|
|
|
+ 812 ELSE
|
|
|
|
|
+ 813 SymTab.SetSymVal(n, qv);
|
|
|
|
|
+ 814 QbeGen.DeclConst(n, qv, t)
|
|
|
|
|
+ 815 END; .) .
|
|
|
|
|
+ 816 VarBlock
|
|
|
|
|
+ 817 = "VAR" { VarDecl ";" } .
|
|
|
|
|
+ 818 VarDecl (. VAR nm: SymTab.Name;
|
|
|
|
|
+ 819 t: SymTab.TypeIndex;
|
|
|
|
|
+ 820 i: CARDINAL;
|
|
|
|
|
+ 821 cls: INTEGER; .)
|
|
|
|
|
+ 822 = VarIdents ":"
|
|
|
|
|
+ 823 Type<t, FALSE> (. cls := SymTab.ClassOf(t);
|
|
|
|
|
+ 824 IF (t # SymTab.InvalidType)
|
|
|
|
|
+ 825 AND NOT SymTab.IsUnresolved(t)
|
|
|
|
|
+ 826 AND (cls # SymTab.ClInt)
|
|
|
|
|
+ 827 AND (cls # SymTab.ClBool)
|
|
|
|
|
+ 828 AND (cls # SymTab.ClChar)
|
|
|
|
|
+ 829 AND (cls # SymTab.ClReal)
|
|
|
|
|
+ 830 AND (cls # SymTab.ClArray)
|
|
|
|
|
+ 831 AND (cls # SymTab.ClSet)
|
|
|
|
|
+ 832 AND (cls # SymTab.ClRecord)
|
|
|
|
|
+ 833 AND (cls # SymTab.ClPtr)
|
|
|
|
|
+ 834 AND (cls # SymTab.ClLong)
|
|
|
|
|
+ 835 AND (cls # SymTab.ClProc)
|
|
|
|
|
+ 836 AND (cls # SymTab.ClUChar)
|
|
|
|
|
+ 837 AND (cls # SymTab.ClUStr)
|
|
|
|
|
+ 838 AND (cls # SymTab.ClEnum)
|
|
|
|
|
+ 839 AND (cls # SymTab.ClClass) THEN
|
|
|
|
|
+ 840 SemError(230) END;
|
|
|
|
|
+ 841 IF QbeGen.LocFull() THEN
|
|
|
|
|
+ 842 SemError(233) END;
|
|
|
|
|
+ 843 i := 0;
|
|
|
|
|
+ 844 IF SymTab.IsUnresolved(t)
|
|
|
|
|
+ 845 AND NOT SymTab.InProc() THEN
|
|
|
|
|
+ 846 (* a forward-typed global:
|
|
|
|
|
+ 847 defer emission until the
|
|
|
|
|
+ 848 TYPE block completes *)
|
|
|
|
|
+ 849 WHILE i < SymTab.PendCount() DO
|
|
|
|
|
+ 850 SymTab.PendName(i, nm);
|
|
|
|
|
+ 851 IF nPendVar <=
|
|
|
|
|
+ 852 HIGH(pendVarName) THEN
|
|
|
|
|
+ 853 pendVarName[nPendVar] := nm;
|
|
|
|
|
+ 854 pendVarT[nPendVar] := t;
|
|
|
|
|
+ 855 INC(nPendVar)
|
|
|
|
|
+ 856 END;
|
|
|
857 INC(i)
|
|
857 INC(i)
|
|
|
858 END
|
|
858 END
|
|
|
- 859 END;
|
|
|
|
|
- 860 (* a plain VAR list, not a
|
|
|
|
|
- 861 heading: the signature
|
|
|
|
|
- 862 result is discarded *)
|
|
|
|
|
- 863 IF NOT SymTab.FixPending(t) THEN
|
|
|
|
|
- 864 END; .) .
|
|
|
|
|
- 865 VarIdents (. VAR n: SymTab.Name; .)
|
|
|
|
|
- 866 = GetIdent<n> (. IF NOT SymTab.EnterPending(n,
|
|
|
|
|
- 867 SymTab.KindVar) THEN
|
|
|
|
|
- 868 SemError(200) END; .)
|
|
|
|
|
- 869 { ","
|
|
|
|
|
- 870 GetIdent<n> (. IF NOT SymTab.EnterPending(n,
|
|
|
|
|
- 871 SymTab.KindVar) THEN
|
|
|
|
|
- 872 SemError(200) END; .) } .
|
|
|
|
|
- 873 ParIdents<isV: BOOLEAN> (. VAR n: SymTab.Name; .)
|
|
|
|
|
- 874 = GetIdent<n> (. IF NOT SymTab.EnterParam(n, isV) THEN
|
|
|
|
|
- 875 SemError(200) END; .)
|
|
|
|
|
- 876 { "," GetIdent<n> (. IF NOT SymTab.EnterParam(n, isV) THEN
|
|
|
|
|
- 877 SemError(200) END; .) } .
|
|
|
|
|
- 878 (* Procedure headings enter scopes/params/result and buffer the
|
|
|
|
|
- 879 QBE header; bodies lower to functions (4.1, module level only).
|
|
|
|
|
- 880 FORWARD marks; the body heading re-enters (signature compare
|
|
|
|
|
- 881 deferred). Nested procedures parse + check, lowering = 4.2. *)
|
|
|
|
|
- 882 ProcHeading<VAR pn: SymTab.Name; methCls: SymTab.TypeIndex>
|
|
|
|
|
- 883 (. VAR t: SymTab.TypeIndex;
|
|
|
|
|
- 884 mg: QbeGen.QVal; .)
|
|
|
|
|
- 885 = "PROCEDURE"
|
|
|
|
|
- 886 GetIdent<pn> (. IF methCls #
|
|
|
|
|
- 887 SymTab.InvalidType THEN
|
|
|
|
|
- 888 (* a method: resume the
|
|
|
|
|
- 889 declared symbol (reuse
|
|
|
|
|
- 890 its uid) *)
|
|
|
|
|
- 891 IF NOT SymTab.ResumeMethod(
|
|
|
|
|
- 892 methCls, pn) THEN
|
|
|
|
|
- 893 SemError(200) END
|
|
|
|
|
- 894 ELSIF NOT SymTab.EnterProc(pn) THEN
|
|
|
|
|
- 895 IF NOT SymTab.ReenterProc(pn) THEN
|
|
|
|
|
- 896 IF NOT SymTab.ResumeProc(pn) THEN
|
|
|
|
|
- 897 SemError(200) END
|
|
|
|
|
- 898 END
|
|
|
|
|
- 899 END;
|
|
|
|
|
- 900 IF methCls #
|
|
|
|
|
- 901 SymTab.InvalidType THEN
|
|
|
|
|
- 902 QbeGen.Mangled(pn,
|
|
|
|
|
- 903 SymTab.MethUid(), mg)
|
|
|
|
|
- 904 ELSE
|
|
|
|
|
- 905 QbeGen.Mangled(pn,
|
|
|
|
|
- 906 SymTab.ProcUid(pn), mg)
|
|
|
|
|
- 907 END;
|
|
|
|
|
- 908 QbeGen.BeginFunc(mg);
|
|
|
|
|
- 909 IF methCls #
|
|
|
|
|
- 910 SymTab.InvalidType THEN
|
|
|
|
|
- 911 (* hidden THIS receiver:
|
|
|
|
|
- 912 a VAR param of the
|
|
|
|
|
- 913 class type, pushed as
|
|
|
|
|
- 914 the WITH base *)
|
|
|
|
|
- 915 IF NOT SymTab.EnterThisParam(
|
|
|
|
|
- 916 methCls) THEN
|
|
|
|
|
- 917 SemError(200) END;
|
|
|
|
|
- 918 IF NOT QbeGen.FuncParam(
|
|
|
|
|
- 919 "THIS", TRUE,
|
|
|
|
|
- 920 methCls) THEN
|
|
|
|
|
- 921 SemError(233) END
|
|
|
|
|
- 922 END; .)
|
|
|
|
|
- 923 [ FormalParams ]
|
|
|
|
|
- 924 [ ":" TypeIdent<t> (. IF NOT SymTab.SetProcRes(t) THEN
|
|
|
|
|
- 925 SemError(235) END;
|
|
|
|
|
- 926 QbeGen.SetFuncRes(t);
|
|
|
|
|
- 927 IF (t #
|
|
|
|
|
- 928 SymTab.InvalidType)
|
|
|
|
|
- 929 AND ((SymTab.ClassOf(t)
|
|
|
|
|
- 930 = SymTab.ClArray)
|
|
|
|
|
- 931 OR (SymTab.ClassOf(t)
|
|
|
|
|
- 932 = SymTab.ClRecord)
|
|
|
|
|
- 933 OR (SymTab.ClassOf(t)
|
|
|
|
|
- 934 = SymTab.ClSet)
|
|
|
|
|
- 935 OR (SymTab.ClassOf(t)
|
|
|
|
|
- 936 = SymTab.ClClass)) THEN
|
|
|
|
|
- 937 SemError(230) END; .) ] .
|
|
|
|
|
- 938 FormalParams
|
|
|
|
|
- 939 = "(" [ ParamSection { ";" ParamSection } ] ")" .
|
|
|
|
|
- 940 ParamSection (. VAR t: SymTab.TypeIndex;
|
|
|
|
|
- 941 nm: SymTab.Name;
|
|
|
|
|
- 942 i: CARDINAL;
|
|
|
|
|
- 943 isV: BOOLEAN; .)
|
|
|
|
|
- 944 = (. isV := FALSE; .)
|
|
|
|
|
- 945 [ "VAR" (. isV := TRUE; .) ]
|
|
|
|
|
- 946 ParIdents<isV> ":" Type<t, TRUE> (. i := 0;
|
|
|
|
|
- 947 WHILE i < SymTab.PendCount() DO
|
|
|
|
|
- 948 SymTab.PendName(i, nm);
|
|
|
|
|
- 949 (* value open arrays are
|
|
|
|
|
- 950 passed as descriptor
|
|
|
|
|
- 951 addresses (no copy):
|
|
|
|
|
- 952 same representation as
|
|
|
|
|
- 953 VAR formals *)
|
|
|
|
|
- 954 IF NOT QbeGen.FuncParam(nm,
|
|
|
|
|
- 955 isV
|
|
|
|
|
- 956 OR SymTab.IsOpenArray(t),
|
|
|
|
|
- 957 t) THEN
|
|
|
|
|
- 958 SemError(233) END;
|
|
|
|
|
- 959 INC(i)
|
|
|
|
|
- 960 END;
|
|
|
|
|
- 961 IF NOT SymTab.FixPending(t) THEN
|
|
|
|
|
- 962 SemError(235) END; .) .
|
|
|
|
|
- 963 (* Nested procedures lower like top-level ones (4.2): the
|
|
|
|
|
- 964 static link gives them their parent's frame. Methods keep
|
|
|
|
|
- 965 parse-now/230-later. *)
|
|
|
|
|
- 966 ProcDecl (. VAR pn: SymTab.Name; .)
|
|
|
|
|
- 967 = ProcHeading<pn, SymTab.InvalidType> ";"
|
|
|
|
|
- 968 ( "FORWARD" (. SymTab.MarkFwd;
|
|
|
|
|
- 969 SymTab.CloseProc;
|
|
|
|
|
- 970 QbeGen.AbortFunc; .)
|
|
|
|
|
- 971 | "EXTERNAL" (. SymTab.MarkExternal("");
|
|
|
|
|
- 972 SymTab.CloseProc;
|
|
|
|
|
- 973 QbeGen.AbortFunc; .)
|
|
|
|
|
- 974 | (. QbeGen.EndFuncHeader; .)
|
|
|
|
|
- 975 Block<pn> (. SymTab.CloseProc;
|
|
|
|
|
- 976 QbeGen.EndFunc(
|
|
|
|
|
- 977 SymTab.ProcRes(pn)); .) ) .
|
|
|
|
|
- 978 Block<pn: SymTab.Name> (. VAR m2: SymTab.Name; .)
|
|
|
|
|
- 979 = DeclSeq
|
|
|
|
|
- 980 [ "BEGIN"
|
|
|
|
|
- 981 [ StatSeq ] ]
|
|
|
|
|
- 982 "END"
|
|
|
|
|
- 983 GetIdent<m2> (. IF NOT SymTab.Equal(pn, m2) THEN
|
|
|
|
|
- 984 SemError(202) END; .) .
|
|
|
|
|
- 985 StatSeq
|
|
|
|
|
- 986 = Statement { ";" [ Statement ] } .
|
|
|
|
|
- 987 (* Trailing/empty statements (`a; ; b`, Coco/R's generated `;;`)
|
|
|
|
|
- 988 are accepted: the statement after ';' is optional. *)
|
|
|
|
|
- 989 Statement (. VAR lx: QbeGen.QVal; .)
|
|
|
|
|
- 990 = AssOrCall
|
|
|
|
|
- 991 | IfStat
|
|
|
|
|
- 992 | WhileStat
|
|
|
|
|
- 993 | RepeatStat
|
|
|
|
|
- 994 | LoopStat
|
|
|
|
|
- 995 | ForStat
|
|
|
|
|
- 996 | CaseStat
|
|
|
|
|
- 997 | WithStat
|
|
|
|
|
- 998 | ReturnStat
|
|
|
|
|
- 999 | HaltStat
|
|
|
|
|
- 1000 | NewStat
|
|
|
|
|
- 1001 | DisposeStat
|
|
|
|
|
- 1002 | IncDecStat
|
|
|
|
|
- 1003 | InclExclStat
|
|
|
|
|
- 1004 | "EXIT" (. IF QbeGen.TopLoop(lx) THEN
|
|
|
|
|
- 1005 QbeGen.Jmp(lx)
|
|
|
|
|
- 1006 ELSE SemError(230) END; .) .
|
|
|
|
|
- 1007 (* INCL(set, elem) / EXCL(set, elem): PIM set-element builtins. *)
|
|
|
|
|
- 1008 InclExclStat (. VAR at, et2: SymTab.TypeIndex;
|
|
|
|
|
- 1009 dk: INTEGER;
|
|
|
|
|
- 1010 qd, qe: QbeGen.QVal;
|
|
|
|
|
- 1011 qn: SymTab.Name;
|
|
|
|
|
- 1012 sfx, isInc: BOOLEAN; .)
|
|
|
|
|
- 1013 = ( "INCL" (. isInc := TRUE; .)
|
|
|
|
|
- 1014 | "EXCL" (. isInc := FALSE; .) )
|
|
|
|
|
- 1015 "(" Design<at, dk, qd, qn, sfx> ","
|
|
|
|
|
- 1016 Expr<et2, qe> ")"
|
|
|
|
|
- 1017 (. IF at = SymTab.InvalidType THEN
|
|
|
|
|
- 1018 ELSIF SymTab.ClassOf(at) #
|
|
|
|
|
- 1019 SymTab.ClSet THEN
|
|
|
|
|
- 1020 SemError(222)
|
|
|
|
|
- 1021 ELSE
|
|
|
|
|
- 1022 IF isInc THEN
|
|
|
|
|
- 1023 QbeGen.SetBit(qd, qe,
|
|
|
|
|
- 1024 SymTab.SetBaseLo(at),
|
|
|
|
|
- 1025 SymTab.SetCount(at))
|
|
|
|
|
- 1026 ELSE
|
|
|
|
|
- 1027 QbeGen.SetClearBit(qd, qe,
|
|
|
|
|
- 1028 SymTab.SetBaseLo(at),
|
|
|
|
|
- 1029 SymTab.SetCount(at))
|
|
|
|
|
- 1030 END
|
|
|
|
|
- 1031 END; .) .
|
|
|
|
|
- 1032 (* INC(v [,step]) / DEC(v [,step]) as builtin statements over an
|
|
|
|
|
- 1033 integer designator. *)
|
|
|
|
|
- 1034 IncDecStat (. VAR dt, et2: SymTab.TypeIndex;
|
|
|
|
|
- 1035 dk: INTEGER;
|
|
|
|
|
- 1036 qd, qv, qn2, qstep:
|
|
|
|
|
- 1037 QbeGen.QVal;
|
|
|
|
|
- 1038 qn: SymTab.Name;
|
|
|
|
|
- 1039 sfx, isInc: BOOLEAN; .)
|
|
|
|
|
- 1040 = (. isInc := TRUE; .)
|
|
|
|
|
- 1041 ( "INC" (. isInc := TRUE; .)
|
|
|
|
|
- 1042 | "DEC" (. isInc := FALSE; .) )
|
|
|
|
|
- 1043 "(" (. QbeGen.CopyOp("1", qstep); .)
|
|
|
|
|
- 1044 Design<dt, dk, qd, qn, sfx>
|
|
|
|
|
- 1045 [ "," Expr<et2, qstep> ]
|
|
|
|
|
- 1046 ")" (. IF dt = SymTab.InvalidType THEN
|
|
|
|
|
- 1047 ELSIF (dk # SymTab.KindVar)
|
|
|
|
|
- 1048 AND (dk # SymTab.KindParam)
|
|
|
|
|
- 1049 AND (dk # SymTab.KindField) THEN
|
|
|
|
|
- 1050 SemError(210)
|
|
|
|
|
- 1051 ELSIF NOT SymTab.IsIntFamily(dt) THEN
|
|
|
|
|
- 1052 SemError(211)
|
|
|
|
|
- 1053 ELSE
|
|
|
|
|
- 1054 IF sfx
|
|
|
|
|
- 1055 OR (dk = SymTab.KindField) THEN
|
|
|
|
|
- 1056 QbeGen.ElemLoad(qd, dt, qv)
|
|
|
|
|
- 1057 ELSE QbeGen.LoadVar(qn,
|
|
|
|
|
- 1058 FALSE, qv)
|
|
|
|
|
- 1059 END;
|
|
|
|
|
- 1060 QbeGen.NewTemp(qn2);
|
|
|
|
|
- 1061 IF isInc THEN
|
|
|
|
|
- 1062 QbeGen.Op3("add", qn2, qv,
|
|
|
|
|
- 1063 qstep, FALSE)
|
|
|
|
|
- 1064 ELSE QbeGen.Op3("sub", qn2, qv,
|
|
|
|
|
- 1065 qstep, FALSE)
|
|
|
|
|
- 1066 END;
|
|
|
|
|
- 1067 IF sfx
|
|
|
|
|
- 1068 OR (dk = SymTab.KindField) THEN
|
|
|
|
|
- 1069 QbeGen.ElemStore(qd, qn2,
|
|
|
|
|
- 1070 dt)
|
|
|
|
|
- 1071 ELSE QbeGen.StoreVar(qn,
|
|
|
|
|
- 1072 qn2, FALSE)
|
|
|
|
|
- 1073 END
|
|
|
|
|
- 1074 END; .) .
|
|
|
|
|
- 1075 (* NEW/DISPOSE as builtin statements (no call syntax until step 4).
|
|
|
|
|
- 1076 Targets are pointer designators; DISPOSE nils afterwards (safer
|
|
|
|
|
- 1077 than Wirth-undefined; documented). DISPOSE is shallow. *)
|
|
|
|
|
- 1078 NewStat (. VAR dt: SymTab.TypeIndex;
|
|
|
|
|
- 1079 dk: INTEGER;
|
|
|
|
|
- 1080 qd, qm: QbeGen.QVal;
|
|
|
|
|
- 1081 qn: SymTab.Name;
|
|
|
|
|
- 1082 sfx: BOOLEAN;
|
|
|
|
|
- 1083 bt: SymTab.TypeIndex; .)
|
|
|
|
|
- 1084 = "NEW" "(" Design<dt, dk, qd, qn, sfx> ")"
|
|
|
|
|
- 1085 (. IF dt = SymTab.InvalidType THEN
|
|
|
|
|
- 1086 ELSIF (dk # SymTab.KindVar)
|
|
|
|
|
- 1087 AND (dk # SymTab.KindParam)
|
|
|
|
|
- 1088 AND (dk # SymTab.KindField) THEN
|
|
|
|
|
- 1089 SemError(210)
|
|
|
|
|
- 1090 ELSIF SymTab.ClassOf(dt) #
|
|
|
|
|
- 1091 SymTab.ClPtr THEN
|
|
|
|
|
- 1092 SemError(219)
|
|
|
|
|
- 1093 ELSE bt := SymTab.PtrBase(dt);
|
|
|
|
|
- 1094 IF bt #
|
|
|
|
|
- 1095 SymTab.InvalidType THEN
|
|
|
|
|
- 1096 QbeGen.NewHeap(bt, qm);
|
|
|
|
|
- 1097 QbeGen.InitHeap(qm, bt);
|
|
|
|
|
- 1098 IF sfx
|
|
|
|
|
- 1099 OR (dk =
|
|
|
|
|
- 1100 SymTab.KindField) THEN
|
|
|
|
|
- 1101 QbeGen.ElemStore(qd, qm,
|
|
|
|
|
- 1102 dt)
|
|
|
|
|
- 1103 ELSE QbeGen.StorePtr(qn,
|
|
|
|
|
- 1104 qm)
|
|
|
|
|
- 1105 END
|
|
|
|
|
- 1106 END
|
|
|
|
|
- 1107 END; .) .
|
|
|
|
|
- 1108 DisposeStat (. VAR dt: SymTab.TypeIndex;
|
|
|
|
|
- 1109 dk: INTEGER;
|
|
|
|
|
- 1110 qd, qv: QbeGen.QVal;
|
|
|
|
|
- 1111 qn: SymTab.Name;
|
|
|
|
|
- 1112 sfx: BOOLEAN; .)
|
|
|
|
|
- 1113 = "DISPOSE" "(" Design<dt, dk, qd, qn, sfx> ")"
|
|
|
|
|
- 1114 (. IF dt = SymTab.InvalidType THEN
|
|
|
|
|
- 1115 ELSIF (dk # SymTab.KindVar)
|
|
|
|
|
- 1116 AND (dk # SymTab.KindParam)
|
|
|
|
|
- 1117 AND (dk # SymTab.KindField) THEN
|
|
|
|
|
- 1118 SemError(210)
|
|
|
|
|
- 1119 ELSIF SymTab.ClassOf(dt) #
|
|
|
|
|
- 1120 SymTab.ClPtr THEN
|
|
|
|
|
- 1121 SemError(219)
|
|
|
|
|
- 1122 ELSE
|
|
|
|
|
- 1123 IF sfx
|
|
|
|
|
- 1124 OR (dk =
|
|
|
|
|
- 1125 SymTab.KindField) THEN
|
|
|
|
|
- 1126 QbeGen.ElemLoad(qd, dt,
|
|
|
|
|
- 1127 qv)
|
|
|
|
|
- 1128 ELSE QbeGen.LoadPtr(qn, qv)
|
|
|
|
|
- 1129 END;
|
|
|
|
|
- 1130 QbeGen.FreeHeap(qv);
|
|
|
|
|
- 1131 IF sfx
|
|
|
|
|
- 1132 OR (dk =
|
|
|
|
|
- 1133 SymTab.KindField) THEN
|
|
|
|
|
- 1134 QbeGen.ElemStore(qd, "0",
|
|
|
|
|
- 1135 dt)
|
|
|
|
|
- 1136 ELSE QbeGen.StorePtr(qn,
|
|
|
|
|
- 1137 "0")
|
|
|
|
|
- 1138 END
|
|
|
|
|
- 1139 END; .) .
|
|
|
|
|
- 1140 (* WITH pushes each record's fields (inner wins) plus its base
|
|
|
|
|
- 1141 address; field designators resolve through both stacks. *)
|
|
|
|
|
- 1142 WithStat (. VAR nW: CARDINAL; .)
|
|
|
|
|
- 1143 = "WITH" (. nW := 0; .)
|
|
|
|
|
- 1144 WithItem<nW> { "," WithItem<nW> }
|
|
|
|
|
- 1145 "DO" [ StatSeq ] "END"
|
|
|
|
|
- 1146 (. WHILE nW > 0 DO
|
|
|
|
|
- 1147 SymTab.PopScope;
|
|
|
|
|
- 1148 QbeGen.PopWith;
|
|
|
|
|
- 1149 DEC(nW)
|
|
|
|
|
- 1150 END; .) .
|
|
|
|
|
- 1151 WithItem<VAR nW: CARDINAL> (. VAR dt: SymTab.TypeIndex;
|
|
|
|
|
- 1152 dk: INTEGER;
|
|
|
|
|
- 1153 qd, qe: QbeGen.QVal;
|
|
|
|
|
- 1154 qn: SymTab.Name;
|
|
|
|
|
- 1155 sfx: BOOLEAN; .)
|
|
|
|
|
- 1156 = Design<dt, dk, qd, qn, sfx>
|
|
|
|
|
- 1157 (. IF dt = SymTab.InvalidType THEN
|
|
|
|
|
- 1158 ELSIF (SymTab.ClassOf(dt) #
|
|
|
|
|
- 1159 SymTab.ClRecord)
|
|
|
|
|
- 1160 AND (SymTab.ClassOf(dt) #
|
|
|
|
|
- 1161 SymTab.ClClass) THEN
|
|
|
|
|
- 1162 SemError(215)
|
|
|
|
|
- 1163 ELSIF SymTab.PushRecord(dt) THEN
|
|
|
|
|
- 1164 QbeGen.PushWith(qd);
|
|
|
|
|
- 1165 INC(nW)
|
|
|
|
|
- 1166 END; .) .
|
|
|
|
|
- 1167 (* Assignment or procedure-statement call (4.1, module level).
|
|
|
|
|
- 1168 Bare `P;` is a syntax error; function-as-statement is 233. *)
|
|
|
|
|
- 1169 AssOrCall (. VAR dt, et: SymTab.TypeIndex;
|
|
|
|
|
- 1170 dk: INTEGER;
|
|
|
|
|
- 1171 qd, qe, qt, ql: QbeGen.QVal;
|
|
|
|
|
- 1172 qn: SymTab.Name;
|
|
|
|
|
- 1173 ct2, res0: SymTab.TypeIndex;
|
|
|
|
|
- 1174 q2, mg0: QbeGen.QVal;
|
|
|
|
|
- 1175 isR, conv, wconv: BOOLEAN;
|
|
|
|
|
- 1176 called, sfx: BOOLEAN; .)
|
|
|
|
|
- 1177 = Design<dt, dk, qd, qn, sfx>
|
|
|
|
|
- 1178 ( ":="
|
|
|
|
|
- 1179 Expr<et, qe> (. IF (dt # SymTab.InvalidType)
|
|
|
|
|
- 1180 AND (dk # SymTab.KindVar)
|
|
|
|
|
- 1181 AND (dk # SymTab.KindParam)
|
|
|
|
|
- 1182 AND (dk # SymTab.KindField) THEN
|
|
|
|
|
- 1183 SemError(210)
|
|
|
|
|
- 1184 ELSIF NOT SymTab.Assignable(et,
|
|
|
|
|
- 1185 dt) THEN
|
|
|
|
|
- 1186 SemError(210)
|
|
|
|
|
- 1187 ELSIF (dt # SymTab.InvalidType)
|
|
|
|
|
- 1188 AND (SymTab.ClassOf(dt) =
|
|
|
|
|
- 1189 SymTab.ClClass) THEN
|
|
|
|
|
- 1190 SemError(230) END;
|
|
|
|
|
- 1191 isR := (dt #
|
|
|
|
|
- 1192 SymTab.InvalidType)
|
|
|
|
|
- 1193 AND (SymTab.ClassOf(dt)
|
|
|
|
|
- 1194 = SymTab.ClReal);
|
|
|
|
|
- 1195 conv := isR
|
|
|
|
|
- 1196 AND SymTab.IsIntFamily(et);
|
|
|
|
|
- 1197 wconv := (dt #
|
|
|
|
|
- 1198 SymTab.InvalidType)
|
|
|
|
|
- 1199 AND SymTab.IsLongFamily(dt)
|
|
|
|
|
- 1200 AND SymTab.IsIntFamily(et);
|
|
|
|
|
- 1201 IF ((dk = SymTab.KindVar)
|
|
|
|
|
- 1202 OR (dk = SymTab.KindParam)
|
|
|
|
|
- 1203 OR (dk = SymTab.KindField))
|
|
|
|
|
- 1204 AND (dt # SymTab.InvalidType)
|
|
|
|
|
- 1205 AND (et # SymTab.InvalidType)
|
|
|
|
|
- 1206 AND (SymTab.ClassOf(dt) #
|
|
|
|
|
- 1207 SymTab.ClClass) THEN
|
|
|
|
|
- 1208 IF sfx
|
|
|
|
|
- 1209 OR (dk = SymTab.KindField) THEN
|
|
|
|
|
- 1210 IF SymTab.ClassOf(dt) =
|
|
|
|
|
- 1211 SymTab.ClArray THEN
|
|
|
|
|
- 1212 IF (et # SymTab.InvalidType)
|
|
|
|
|
- 1213 AND (SymTab.ClassOf(et) = SymTab.ClUStr)
|
|
|
|
|
- 1214 AND SymTab.IsUCharArray(dt) THEN
|
|
|
|
|
- 1215 QbeGen.UAssign(qd, qe)
|
|
|
|
|
- 1216 ELSIF SymTab.StrCompat(dt,
|
|
|
|
|
- 1217 et) THEN
|
|
|
|
|
- 1218 QbeGen.StrAssign(qd,
|
|
|
|
|
- 1219 qe)
|
|
|
|
|
- 1220 ELSE
|
|
|
|
|
- 1221 QbeGen.CopyArray(qd,
|
|
|
|
|
- 1222 qe, dt)
|
|
|
|
|
- 1223 END
|
|
|
|
|
- 1224 ELSIF SymTab.ClassOf(dt) =
|
|
|
|
|
- 1225 SymTab.ClSet THEN
|
|
|
|
|
- 1226 QbeGen.CopySet(qd, qe,
|
|
|
|
|
- 1227 SymTab.SetWords(dt),
|
|
|
|
|
- 1228 SymTab.SetWords(et))
|
|
|
|
|
- 1229 ELSIF SymTab.ClassOf(dt) =
|
|
|
|
|
- 1230 SymTab.ClRecord THEN
|
|
|
|
|
- 1231 QbeGen.CopyRecord(qd, qe,
|
|
|
|
|
- 1232 dt)
|
|
|
|
|
- 1233 ELSIF SymTab.IsLongFamily(dt) THEN
|
|
|
|
|
- 1234 IF wconv THEN
|
|
|
|
|
- 1235 QbeGen.WidenLong(qe, ql);
|
|
|
|
|
- 1236 QbeGen.ElemStore(qd, ql,
|
|
|
|
|
- 1237 dt)
|
|
|
|
|
- 1238 ELSE QbeGen.ElemStore(qd, qe,
|
|
|
|
|
- 1239 dt)
|
|
|
|
|
- 1240 END
|
|
|
|
|
- 1241 ELSIF conv THEN
|
|
|
|
|
- 1242 QbeGen.ConvIR(qe, qt);
|
|
|
|
|
- 1243 QbeGen.ElemStore(qd, qt,
|
|
|
|
|
- 1244 dt)
|
|
|
|
|
- 1245 ELSE QbeGen.ElemStore(qd, qe,
|
|
|
|
|
- 1246 dt)
|
|
|
|
|
- 1247 END
|
|
|
|
|
- 1248 ELSIF SymTab.ClassOf(dt) =
|
|
|
|
|
- 1249 SymTab.ClArray THEN
|
|
|
|
|
- 1250 IF (et # SymTab.InvalidType)
|
|
|
|
|
- 1251 AND (SymTab.ClassOf(et) = SymTab.ClUStr)
|
|
|
|
|
- 1252 AND SymTab.IsUCharArray(dt) THEN
|
|
|
|
|
- 1253 QbeGen.UAssign(qd, qe)
|
|
|
|
|
- 1254 ELSIF SymTab.StrCompat(dt,
|
|
|
|
|
- 1255 et) THEN
|
|
|
|
|
- 1256 QbeGen.StrAssign(qd, qe)
|
|
|
|
|
- 1257 ELSE
|
|
|
|
|
- 1258 QbeGen.CopyArray(qd, qe,
|
|
|
|
|
- 1259 dt)
|
|
|
|
|
- 1260 END
|
|
|
|
|
- 1261 ELSIF SymTab.ClassOf(dt) =
|
|
|
|
|
- 1262 SymTab.ClSet THEN
|
|
|
|
|
- 1263 QbeGen.CopySet(qd, qe,
|
|
|
|
|
- 1264 SymTab.SetWords(dt),
|
|
|
|
|
- 1265 SymTab.SetWords(et))
|
|
|
|
|
- 1266 ELSIF SymTab.ClassOf(dt) =
|
|
|
|
|
- 1267 SymTab.ClRecord THEN
|
|
|
|
|
- 1268 QbeGen.CopyRecord(qd, qe, dt)
|
|
|
|
|
- 1269 ELSIF (SymTab.ClassOf(dt) =
|
|
|
|
|
- 1270 SymTab.ClPtr)
|
|
|
|
|
- 1271 OR (SymTab.ClassOf(dt) =
|
|
|
|
|
- 1272 SymTab.ClProc) THEN
|
|
|
|
|
- 1273 QbeGen.StorePtr(qn, qe)
|
|
|
|
|
- 1274 ELSIF SymTab.IsLongFamily(dt) THEN
|
|
|
|
|
- 1275 IF wconv THEN
|
|
|
|
|
- 1276 QbeGen.WidenLong(qe, ql);
|
|
|
|
|
- 1277 QbeGen.StoreLong(qn, ql)
|
|
|
|
|
- 1278 ELSE QbeGen.StoreLong(qn, qe)
|
|
|
|
|
- 1279 END
|
|
|
|
|
- 1280 ELSIF conv THEN
|
|
|
|
|
- 1281 QbeGen.ConvIR(qe, qt);
|
|
|
|
|
- 1282 QbeGen.StoreVar(qn, qt, TRUE)
|
|
|
|
|
- 1283 ELSE
|
|
|
|
|
- 1284 QbeGen.StoreVar(qn, qe, isR)
|
|
|
|
|
- 1285 END
|
|
|
|
|
- 1286 END; .)
|
|
|
|
|
- 1287 | ArgList<qn, dt, qd, FALSE, FALSE, methCls, ct2, q2, called>
|
|
|
|
|
- 1288 | (* bare `P;`: proper parameterless
|
|
|
|
|
- 1289 procedure call; anything else
|
|
|
|
|
- 1290 here is 233 (was a bare syntax
|
|
|
|
|
- 1291 error before 4.2) *)
|
|
|
|
|
- 1292 (. IF (dk = SymTab.KindProc)
|
|
|
|
|
- 1293 AND NOT sfx THEN
|
|
|
|
|
- 1294 res0 := SymTab.ProcRes(qn);
|
|
|
|
|
- 1295 IF res0 #
|
|
|
|
|
- 1296 SymTab.InvalidType THEN
|
|
|
|
|
- 1297 SemError(233)
|
|
|
|
|
- 1298 ELSIF SymTab.ProcNPar(qn) #
|
|
|
|
|
- 1299 0 THEN
|
|
|
|
|
- 1300 SemError(233)
|
|
|
|
|
- 1301 ELSE QbeGen.Mangled(qn,
|
|
|
|
|
- 1302 SymTab.ProcUid(qn), mg0);
|
|
|
|
|
- 1303 QbeGen.CallBegin(mg0,
|
|
|
|
|
- 1304 res0,
|
|
|
|
|
- 1305 SymTab.ProcDepthOf(qn),
|
|
|
|
|
- 1306 SymTab.IsExternal(qn));
|
|
|
|
|
- 1307 QbeGen.CallEnd(FALSE, q2)
|
|
|
|
|
- 1308 END
|
|
|
|
|
- 1309 ELSE SemError(233)
|
|
|
|
|
- 1310 END; .) ) .
|
|
|
|
|
- 1311 (* Actual-parameter list shared by statement and expression calls.
|
|
|
|
|
- 1312 want selects CallEnd's result handling; t/q carry the call
|
|
|
|
|
- 1313 value (statement calls discard). Arity/type failures are 233;
|
|
|
|
|
- 1314 evaluation code still emits so the .ssa stays assembleable. *)
|
|
|
|
|
- 1315 ArgList<pn: SymTab.Name; pt: SymTab.TypeIndex; callee: QbeGen.QVal;
|
|
|
|
|
- 1316 want: BOOLEAN; soft: BOOLEAN; methCls: SymTab.TypeIndex;
|
|
|
|
|
- 1317 VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal;
|
|
|
|
|
- 1318 VAR called: BOOLEAN> (. VAR i, np: CARDINAL;
|
|
|
|
|
- 1319 vs: INTEGER;
|
|
|
|
|
- 1320 res: SymTab.TypeIndex;
|
|
|
|
|
- 1321 mg: QbeGen.QVal;
|
|
|
|
|
- 1322 ok, ind, isMeth, va: BOOLEAN; .)
|
|
|
|
|
- 1323 = "(" (. called := TRUE;
|
|
|
|
|
- 1324 ok := TRUE;
|
|
|
|
|
- 1325 ind := FALSE;
|
|
|
|
|
- 1326 isMeth := methCls #
|
|
|
|
|
- 1327 SymTab.InvalidType;
|
|
|
|
|
- 1328 IF isMeth THEN
|
|
|
|
|
- 1329 (* class method: the
|
|
|
|
|
- 1330 receiver is armed.
|
|
|
|
|
- 1331 Virtual -> dispatch
|
|
|
|
|
- 1332 through the vtable;
|
|
|
|
|
- 1333 otherwise a static
|
|
|
|
|
- 1334 call. *)
|
|
|
|
|
- 1335 res := SymTab.ClassMethodRes(
|
|
|
|
|
- 1336 methCls, pn);
|
|
|
|
|
- 1337 vs := SymTab.VirtSlot(
|
|
|
|
|
- 1338 methCls, pn);
|
|
|
|
|
- 1339 IF vs >= 0 THEN
|
|
|
|
|
- 1340 QbeGen.VirtCallBegin(
|
|
|
|
|
- 1341 callee, vs, res)
|
|
|
|
|
- 1342 ELSE
|
|
|
|
|
- 1343 QbeGen.Mangled(pn,
|
|
|
|
|
- 1344 SymTab.ClassMethodUid(
|
|
|
|
|
- 1345 methCls, pn), mg);
|
|
|
|
|
- 1346 QbeGen.CallBegin(mg, res, 0,
|
|
|
|
|
- 1347 FALSE)
|
|
|
|
|
- 1348 END
|
|
|
|
|
- 1349 ELSIF SymTab.SymKind(pn) =
|
|
|
|
|
- 1350 SymTab.KindProc THEN
|
|
|
|
|
- 1351 res := SymTab.ProcRes(pn);
|
|
|
|
|
- 1352 QbeGen.Mangled(pn,
|
|
|
|
|
- 1353 SymTab.ProcUid(pn), mg);
|
|
|
|
|
- 1354 QbeGen.CallBegin(mg, res,
|
|
|
|
|
- 1355 SymTab.ProcDepthOf(pn),
|
|
|
|
|
- 1356 SymTab.IsExternal(pn))
|
|
|
|
|
- 1357 ELSIF (pt # SymTab.InvalidType)
|
|
|
|
|
- 1358 AND (SymTab.ClassOf(pt) = SymTab.ClProc) THEN
|
|
|
|
|
- 1359 ind := TRUE;
|
|
|
|
|
- 1360 res :=
|
|
|
|
|
- 1361 SymTab.ProcTypeRes(pt);
|
|
|
|
|
- 1362 QbeGen.CallBeginInd(callee,
|
|
|
|
|
- 1363 res, FALSE)
|
|
|
|
|
- 1364 ELSE SemError(233);
|
|
|
|
|
- 1365 ok := FALSE;
|
|
|
|
|
- 1366 res := SymTab.InvalidType
|
|
|
|
|
- 1367 END;
|
|
|
|
|
- 1368 i := 0; .)
|
|
|
|
|
- 1369 [ ActParam<pn, pt, ind, methCls, i> (. INC(i); .)
|
|
|
|
|
- 1370 { "," ActParam<pn, pt, ind, methCls, i> (. INC(i); .) } ]
|
|
|
|
|
- 1371 ")" (. IF ok THEN
|
|
|
|
|
- 1372 IF isMeth THEN
|
|
|
|
|
- 1373 np := SymTab.ClassMethodNPar(
|
|
|
|
|
- 1374 methCls, pn)
|
|
|
|
|
- 1375 ELSIF ind THEN
|
|
|
|
|
- 1376 np := SymTab.ProcTypeNPar(pt)
|
|
|
|
|
- 1377 ELSE np := SymTab.ProcNPar(pn)
|
|
|
|
|
- 1378 END;
|
|
|
|
|
- 1379 va := (NOT isMeth) AND (NOT ind)
|
|
|
|
|
- 1380 AND (SymTab.SymKind(pn) =
|
|
|
|
|
- 1381 SymTab.KindProc)
|
|
|
|
|
- 1382 AND SymTab.Varargs(pn);
|
|
|
|
|
- 1383 IF (i # np) AND NOT va THEN
|
|
|
|
|
- 1384 SemError(233); ok := FALSE
|
|
|
|
|
- 1385 END
|
|
|
|
|
- 1386 END;
|
|
|
|
|
- 1387 IF NOT ok THEN
|
|
|
|
|
- 1388 t := SymTab.InvalidType;
|
|
|
|
|
- 1389 QbeGen.CopyOp("0", q)
|
|
|
|
|
- 1390 ELSIF want THEN
|
|
|
|
|
- 1391 IF res =
|
|
|
|
|
- 1392 SymTab.InvalidType THEN
|
|
|
|
|
- 1393 SemError(233);
|
|
|
|
|
- 1394 t := SymTab.InvalidType;
|
|
|
|
|
- 1395 QbeGen.CopyOp("0", q)
|
|
|
|
|
- 1396 ELSE t := res;
|
|
|
|
|
- 1397 QbeGen.CallEnd(TRUE, q)
|
|
|
|
|
- 1398 END
|
|
|
|
|
- 1399 ELSE
|
|
|
|
|
- 1400 IF res #
|
|
|
|
|
- 1401 SymTab.InvalidType THEN
|
|
|
|
|
- 1402 SemError(233)
|
|
|
|
|
- 1403 END;
|
|
|
|
|
- 1404 t := SymTab.InvalidType;
|
|
|
|
|
- 1405 QbeGen.CopyOp("0", q);
|
|
|
|
|
- 1406 QbeGen.CallEnd(FALSE, q)
|
|
|
|
|
- 1407 END; .) .
|
|
|
|
|
- 1408 (* One actual: VAR formals take recorded designator addresses
|
|
|
|
|
- 1409 (233 otherwise); value formals take converted expressions. *)
|
|
|
|
|
- 1410 ActParam<pn: SymTab.Name; pt: SymTab.TypeIndex; ind: BOOLEAN;
|
|
|
|
|
- 1411 methCls: SymTab.TypeIndex; i: CARDINAL>
|
|
|
|
|
- 1412 (. VAR at, ft: SymTab.TypeIndex;
|
|
|
|
|
- 1413 qe, qa, qt: QbeGen.QVal;
|
|
|
|
|
- 1414 isV, conv, va: BOOLEAN;
|
|
|
|
|
- 1415 cl: CHAR; .)
|
|
|
|
|
- 1416 = Expr<at, qe> (. va := (NOT ind)
|
|
|
|
|
- 1417 AND (methCls =
|
|
|
|
|
- 1418 SymTab.InvalidType)
|
|
|
|
|
- 1419 AND (SymTab.SymKind(pn) =
|
|
|
|
|
- 1420 SymTab.KindProc)
|
|
|
|
|
- 1421 AND SymTab.Varargs(pn);
|
|
|
|
|
- 1422 IF ind THEN
|
|
|
|
|
- 1423 ft :=
|
|
|
|
|
- 1424 SymTab.ProcTypeParamType(pt,
|
|
|
|
|
- 1425 i);
|
|
|
|
|
- 1426 isV :=
|
|
|
|
|
- 1427 SymTab.ProcTypeParamIsVar(pt,
|
|
|
|
|
- 1428 i)
|
|
|
|
|
- 1429 ELSIF methCls #
|
|
|
|
|
- 1430 SymTab.InvalidType THEN
|
|
|
|
|
- 1431 ft :=
|
|
|
|
|
- 1432 SymTab.ClassMethodParamType(
|
|
|
|
|
- 1433 methCls, pn, i);
|
|
|
|
|
- 1434 isV :=
|
|
|
|
|
- 1435 SymTab.ClassMethodParamIsVar(
|
|
|
|
|
- 1436 methCls, pn, i)
|
|
|
|
|
- 1437 ELSE
|
|
|
|
|
- 1438 ft := SymTab.ParamType(pn, i);
|
|
|
|
|
- 1439 isV := SymTab.ParamIsVar(pn, i)
|
|
|
|
|
- 1440 END;
|
|
|
|
|
- 1441 IF (at = SymTab.InvalidType) THEN
|
|
|
|
|
- 1442 ELSIF ft = SymTab.InvalidType THEN
|
|
|
|
|
- 1443 IF va THEN
|
|
|
|
|
- 1444 QbeGen.CArgAdd(qe, at, qa, cl)
|
|
|
|
|
- 1445 END
|
|
|
|
|
- 1446 ELSIF isV THEN
|
|
|
|
|
- 1447 IF (SymTab.ClassOf(at)
|
|
|
|
|
- 1448 = SymTab.ClChar)
|
|
|
|
|
- 1449 AND (SymTab.ClassOf(ft) = SymTab.ClArray)
|
|
|
|
|
- 1450 AND (SymTab.ClassOf(SymTab.ArrayElem(ft))
|
|
|
|
|
- 1451 = SymTab.ClChar)
|
|
|
|
|
- 1452 AND QbeGen.IsImm(qe) THEN
|
|
|
|
|
- 1453 (* 1-char string
|
|
|
|
|
- 1454 literal passed to
|
|
|
|
|
- 1455 a VAR ARRAY OF CHAR *)
|
|
|
|
|
- 1456 QbeGen.DeclCharStr(qe,
|
|
|
|
|
- 1457 qa);
|
|
|
|
|
- 1458 IF NOT QbeGen.CallArg(qa,
|
|
|
|
|
- 1459 "l") THEN
|
|
|
|
|
- 1460 SemError(233)
|
|
|
|
|
- 1461 END
|
|
|
|
|
- 1462 ELSIF NOT QbeGen.AddrOfVal(qe,
|
|
|
|
|
- 1463 qa) THEN
|
|
|
|
|
- 1464 SemError(233)
|
|
|
|
|
- 1465 ELSIF NOT SymTab.VarParamOk(at,
|
|
|
|
|
- 1466 ft) THEN
|
|
|
|
|
- 1467 SemError(233)
|
|
|
|
|
- 1468 ELSIF NOT QbeGen.CallArg(qa,
|
|
|
|
|
- 1469 "l") THEN
|
|
|
|
|
- 1470 SemError(233)
|
|
|
|
|
- 1471 END
|
|
|
|
|
- 1472 ELSE
|
|
|
|
|
- 1473 IF (SymTab.ClassOf(at)
|
|
|
|
|
- 1474 = SymTab.ClChar)
|
|
|
|
|
- 1475 AND (SymTab.ClassOf(ft) = SymTab.ClArray)
|
|
|
|
|
- 1476 AND (SymTab.ClassOf(SymTab.ArrayElem(ft))
|
|
|
|
|
- 1477 = SymTab.ClChar)
|
|
|
|
|
- 1478 AND QbeGen.IsImm(qe) THEN
|
|
|
|
|
- 1479 (* 1-char string
|
|
|
|
|
- 1480 literal passed to
|
|
|
|
|
- 1481 ARRAY OF CHAR *)
|
|
|
|
|
- 1482 QbeGen.DeclCharStr(qe,
|
|
|
|
|
- 1483 qa);
|
|
|
|
|
- 1484 IF NOT QbeGen.CallArg(qa,
|
|
|
|
|
- 1485 "l") THEN
|
|
|
|
|
- 1486 SemError(233)
|
|
|
|
|
- 1487 END
|
|
|
|
|
- 1488 ELSIF NOT SymTab.Assignable(at,
|
|
|
|
|
- 1489 ft) THEN
|
|
|
|
|
- 1490 SemError(233)
|
|
|
|
|
- 1491 ELSE
|
|
|
|
|
- 1492 conv := (SymTab.ClassOf(
|
|
|
|
|
- 1493 ft) = SymTab.ClReal)
|
|
|
|
|
- 1494 AND SymTab.IsIntFamily(at);
|
|
|
|
|
- 1495 IF conv THEN
|
|
|
|
|
- 1496 QbeGen.ConvIR(qe, qt);
|
|
|
|
|
- 1497 IF NOT QbeGen.CallArg(qt,
|
|
|
|
|
- 1498 "d") THEN
|
|
|
|
|
- 1499 SemError(233)
|
|
|
|
|
- 1500 END
|
|
|
|
|
- 1501 ELSIF NOT QbeGen.CallArg(qe,
|
|
|
|
|
- 1502 QbeGen.ArgClass(ft)) THEN
|
|
|
|
|
- 1503 SemError(233)
|
|
|
|
|
- 1504 END
|
|
|
|
|
- 1505 END
|
|
|
|
|
- 1506 END; .) .
|
|
|
|
|
- 1507 IfStat (. VAR t: SymTab.TypeIndex;
|
|
|
|
|
- 1508 q, lThen, lElse, lEnd:
|
|
|
|
|
- 1509 QbeGen.QVal;
|
|
|
|
|
- 1510 hasElse: BOOLEAN; .)
|
|
|
|
|
- 1511 = "IF" (. hasElse := FALSE; .)
|
|
|
|
|
- 1512 Expr<t, q> (. IF NOT SymTab.BoolCheck(t) THEN
|
|
|
|
|
- 1513 SemError(214) END;
|
|
|
|
|
- 1514 QbeGen.NewLabel(lThen);
|
|
|
|
|
- 1515 QbeGen.NewLabel(lElse);
|
|
|
|
|
- 1516 QbeGen.NewLabel(lEnd);
|
|
|
|
|
- 1517 QbeGen.Jnz(q, lThen, lElse);
|
|
|
|
|
- 1518 QbeGen.EmitLabel(lThen); .)
|
|
|
|
|
- 1519 "THEN" [ StatSeq ] (. QbeGen.Jmp(lEnd); .)
|
|
|
|
|
- 1520 { "ELSIF" (. QbeGen.EmitLabel(lElse);
|
|
|
|
|
- 1521 QbeGen.NewLabel(lElse); .)
|
|
|
|
|
- 1522 Expr<t, q> (. IF NOT SymTab.BoolCheck(t) THEN
|
|
|
|
|
|
|
+ 859 ELSE
|
|
|
|
|
+ 860 WHILE i < SymTab.PendCount() DO
|
|
|
|
|
+ 861 SymTab.PendName(i, nm);
|
|
|
|
|
+ 862 QbeGen.DeclVar(nm, t);
|
|
|
|
|
+ 863 INC(i)
|
|
|
|
|
+ 864 END
|
|
|
|
|
+ 865 END;
|
|
|
|
|
+ 866 (* a plain VAR list, not a
|
|
|
|
|
+ 867 heading: the signature
|
|
|
|
|
+ 868 result is discarded *)
|
|
|
|
|
+ 869 IF NOT SymTab.FixPending(t) THEN
|
|
|
|
|
+ 870 END; .) .
|
|
|
|
|
+ 871 VarIdents (. VAR n: SymTab.Name; .)
|
|
|
|
|
+ 872 = GetIdent<n> (. IF NOT SymTab.EnterPending(n,
|
|
|
|
|
+ 873 SymTab.KindVar) THEN
|
|
|
|
|
+ 874 SemError(200) END; .)
|
|
|
|
|
+ 875 { ","
|
|
|
|
|
+ 876 GetIdent<n> (. IF NOT SymTab.EnterPending(n,
|
|
|
|
|
+ 877 SymTab.KindVar) THEN
|
|
|
|
|
+ 878 SemError(200) END; .) } .
|
|
|
|
|
+ 879 ParIdents<isV: BOOLEAN> (. VAR n: SymTab.Name; .)
|
|
|
|
|
+ 880 = GetIdent<n> (. IF NOT SymTab.EnterParam(n, isV) THEN
|
|
|
|
|
+ 881 SemError(200) END; .)
|
|
|
|
|
+ 882 { "," GetIdent<n> (. IF NOT SymTab.EnterParam(n, isV) THEN
|
|
|
|
|
+ 883 SemError(200) END; .) } .
|
|
|
|
|
+ 884 (* Procedure headings enter scopes/params/result and buffer the
|
|
|
|
|
+ 885 QBE header; bodies lower to functions (4.1, module level only).
|
|
|
|
|
+ 886 FORWARD marks; the body heading re-enters (signature compare
|
|
|
|
|
+ 887 deferred). Nested procedures parse + check, lowering = 4.2. *)
|
|
|
|
|
+ 888 ProcHeading<VAR pn: SymTab.Name; methCls: SymTab.TypeIndex>
|
|
|
|
|
+ 889 (. VAR t: SymTab.TypeIndex;
|
|
|
|
|
+ 890 mg: QbeGen.QVal; .)
|
|
|
|
|
+ 891 = "PROCEDURE"
|
|
|
|
|
+ 892 GetIdent<pn> (. IF methCls #
|
|
|
|
|
+ 893 SymTab.InvalidType THEN
|
|
|
|
|
+ 894 (* a method: resume the
|
|
|
|
|
+ 895 declared symbol (reuse
|
|
|
|
|
+ 896 its uid) *)
|
|
|
|
|
+ 897 IF NOT SymTab.ResumeMethod(
|
|
|
|
|
+ 898 methCls, pn) THEN
|
|
|
|
|
+ 899 SemError(200) END
|
|
|
|
|
+ 900 ELSIF NOT SymTab.EnterProc(pn) THEN
|
|
|
|
|
+ 901 IF NOT SymTab.ReenterProc(pn) THEN
|
|
|
|
|
+ 902 IF NOT SymTab.ResumeProc(pn) THEN
|
|
|
|
|
+ 903 SemError(200) END
|
|
|
|
|
+ 904 END
|
|
|
|
|
+ 905 END;
|
|
|
|
|
+ 906 IF methCls #
|
|
|
|
|
+ 907 SymTab.InvalidType THEN
|
|
|
|
|
+ 908 QbeGen.Mangled(pn,
|
|
|
|
|
+ 909 SymTab.MethUid(), mg)
|
|
|
|
|
+ 910 ELSE
|
|
|
|
|
+ 911 QbeGen.Mangled(pn,
|
|
|
|
|
+ 912 SymTab.ProcUid(pn), mg)
|
|
|
|
|
+ 913 END;
|
|
|
|
|
+ 914 QbeGen.BeginFunc(mg);
|
|
|
|
|
+ 915 IF methCls #
|
|
|
|
|
+ 916 SymTab.InvalidType THEN
|
|
|
|
|
+ 917 (* hidden THIS receiver:
|
|
|
|
|
+ 918 a VAR param of the
|
|
|
|
|
+ 919 class type, pushed as
|
|
|
|
|
+ 920 the WITH base *)
|
|
|
|
|
+ 921 IF NOT SymTab.EnterThisParam(
|
|
|
|
|
+ 922 methCls) THEN
|
|
|
|
|
+ 923 SemError(200) END;
|
|
|
|
|
+ 924 IF NOT QbeGen.FuncParam(
|
|
|
|
|
+ 925 "THIS", TRUE,
|
|
|
|
|
+ 926 methCls) THEN
|
|
|
|
|
+ 927 SemError(233) END
|
|
|
|
|
+ 928 END; .)
|
|
|
|
|
+ 929 [ FormalParams ]
|
|
|
|
|
+ 930 [ ":" TypeIdent<t> (. IF NOT SymTab.SetProcRes(t) THEN
|
|
|
|
|
+ 931 SemError(235) END;
|
|
|
|
|
+ 932 QbeGen.SetFuncRes(t);
|
|
|
|
|
+ 933 IF (t #
|
|
|
|
|
+ 934 SymTab.InvalidType)
|
|
|
|
|
+ 935 AND ((SymTab.ClassOf(t)
|
|
|
|
|
+ 936 = SymTab.ClArray)
|
|
|
|
|
+ 937 OR (SymTab.ClassOf(t)
|
|
|
|
|
+ 938 = SymTab.ClRecord)
|
|
|
|
|
+ 939 OR (SymTab.ClassOf(t)
|
|
|
|
|
+ 940 = SymTab.ClSet)
|
|
|
|
|
+ 941 OR (SymTab.ClassOf(t)
|
|
|
|
|
+ 942 = SymTab.ClClass)) THEN
|
|
|
|
|
+ 943 SemError(230) END; .) ] .
|
|
|
|
|
+ 944 FormalParams
|
|
|
|
|
+ 945 = "(" [ ParamSection { ";" ParamSection } ] ")" .
|
|
|
|
|
+ 946 ParamSection (. VAR t: SymTab.TypeIndex;
|
|
|
|
|
+ 947 nm: SymTab.Name;
|
|
|
|
|
+ 948 i: CARDINAL;
|
|
|
|
|
+ 949 isV: BOOLEAN; .)
|
|
|
|
|
+ 950 = (. isV := FALSE; .)
|
|
|
|
|
+ 951 [ "VAR" (. isV := TRUE; .) ]
|
|
|
|
|
+ 952 ParIdents<isV> ":" Type<t, TRUE> (. i := 0;
|
|
|
|
|
+ 953 WHILE i < SymTab.PendCount() DO
|
|
|
|
|
+ 954 SymTab.PendName(i, nm);
|
|
|
|
|
+ 955 (* value open arrays are
|
|
|
|
|
+ 956 passed as descriptor
|
|
|
|
|
+ 957 addresses (no copy):
|
|
|
|
|
+ 958 same representation as
|
|
|
|
|
+ 959 VAR formals *)
|
|
|
|
|
+ 960 IF NOT QbeGen.FuncParam(nm,
|
|
|
|
|
+ 961 isV
|
|
|
|
|
+ 962 OR SymTab.IsOpenArray(t),
|
|
|
|
|
+ 963 t) THEN
|
|
|
|
|
+ 964 SemError(233) END;
|
|
|
|
|
+ 965 INC(i)
|
|
|
|
|
+ 966 END;
|
|
|
|
|
+ 967 IF NOT SymTab.FixPending(t) THEN
|
|
|
|
|
+ 968 SemError(235) END; .) .
|
|
|
|
|
+ 969 (* Nested procedures lower like top-level ones (4.2): the
|
|
|
|
|
+ 970 static link gives them their parent's frame. Methods keep
|
|
|
|
|
+ 971 parse-now/230-later. *)
|
|
|
|
|
+ 972 ProcDecl (. VAR pn: SymTab.Name; .)
|
|
|
|
|
+ 973 = ProcHeading<pn, SymTab.InvalidType> ";"
|
|
|
|
|
+ 974 ( "FORWARD" (. SymTab.MarkFwd;
|
|
|
|
|
+ 975 SymTab.CloseProc;
|
|
|
|
|
+ 976 QbeGen.AbortFunc; .)
|
|
|
|
|
+ 977 | "EXTERNAL" (. SymTab.MarkExternal("");
|
|
|
|
|
+ 978 SymTab.CloseProc;
|
|
|
|
|
+ 979 QbeGen.AbortFunc; .)
|
|
|
|
|
+ 980 | (. QbeGen.EndFuncHeader; .)
|
|
|
|
|
+ 981 Block<pn> (. SymTab.CloseProc;
|
|
|
|
|
+ 982 QbeGen.EndFunc(
|
|
|
|
|
+ 983 SymTab.ProcRes(pn)); .) ) .
|
|
|
|
|
+ 984 Block<pn: SymTab.Name> (. VAR m2: SymTab.Name; .)
|
|
|
|
|
+ 985 = DeclSeq
|
|
|
|
|
+ 986 [ "BEGIN"
|
|
|
|
|
+ 987 [ StatSeq ] ]
|
|
|
|
|
+ 988 "END"
|
|
|
|
|
+ 989 GetIdent<m2> (. IF NOT SymTab.Equal(pn, m2) THEN
|
|
|
|
|
+ 990 SemError(202) END; .) .
|
|
|
|
|
+ 991 StatSeq
|
|
|
|
|
+ 992 = Statement { ";" [ Statement ] } .
|
|
|
|
|
+ 993 (* Trailing/empty statements (`a; ; b`, Coco/R's generated `;;`)
|
|
|
|
|
+ 994 are accepted: the statement after ';' is optional. *)
|
|
|
|
|
+ 995 Statement (. VAR lx: QbeGen.QVal; .)
|
|
|
|
|
+ 996 = AssOrCall
|
|
|
|
|
+ 997 | IfStat
|
|
|
|
|
+ 998 | WhileStat
|
|
|
|
|
+ 999 | RepeatStat
|
|
|
|
|
+ 1000 | LoopStat
|
|
|
|
|
+ 1001 | ForStat
|
|
|
|
|
+ 1002 | CaseStat
|
|
|
|
|
+ 1003 | WithStat
|
|
|
|
|
+ 1004 | ReturnStat
|
|
|
|
|
+ 1005 | HaltStat
|
|
|
|
|
+ 1006 | NewStat
|
|
|
|
|
+ 1007 | DisposeStat
|
|
|
|
|
+ 1008 | IncDecStat
|
|
|
|
|
+ 1009 | InclExclStat
|
|
|
|
|
+ 1010 | "EXIT" (. IF QbeGen.TopLoop(lx) THEN
|
|
|
|
|
+ 1011 QbeGen.Jmp(lx)
|
|
|
|
|
+ 1012 ELSE SemError(230) END; .) .
|
|
|
|
|
+ 1013 (* INCL(set, elem) / EXCL(set, elem): PIM set-element builtins. *)
|
|
|
|
|
+ 1014 InclExclStat (. VAR at, et2: SymTab.TypeIndex;
|
|
|
|
|
+ 1015 dk: INTEGER;
|
|
|
|
|
+ 1016 qd, qe: QbeGen.QVal;
|
|
|
|
|
+ 1017 qn: SymTab.Name;
|
|
|
|
|
+ 1018 sfx, isInc: BOOLEAN; .)
|
|
|
|
|
+ 1019 = ( "INCL" (. isInc := TRUE; .)
|
|
|
|
|
+ 1020 | "EXCL" (. isInc := FALSE; .) )
|
|
|
|
|
+ 1021 "(" Design<at, dk, qd, qn, sfx> ","
|
|
|
|
|
+ 1022 Expr<et2, qe> ")"
|
|
|
|
|
+ 1023 (. IF at = SymTab.InvalidType THEN
|
|
|
|
|
+ 1024 ELSIF SymTab.ClassOf(at) #
|
|
|
|
|
+ 1025 SymTab.ClSet THEN
|
|
|
|
|
+ 1026 SemError(222)
|
|
|
|
|
+ 1027 ELSE
|
|
|
|
|
+ 1028 IF isInc THEN
|
|
|
|
|
+ 1029 QbeGen.SetBit(qd, qe,
|
|
|
|
|
+ 1030 SymTab.SetBaseLo(at),
|
|
|
|
|
+ 1031 SymTab.SetCount(at))
|
|
|
|
|
+ 1032 ELSE
|
|
|
|
|
+ 1033 QbeGen.SetClearBit(qd, qe,
|
|
|
|
|
+ 1034 SymTab.SetBaseLo(at),
|
|
|
|
|
+ 1035 SymTab.SetCount(at))
|
|
|
|
|
+ 1036 END
|
|
|
|
|
+ 1037 END; .) .
|
|
|
|
|
+ 1038 (* INC(v [,step]) / DEC(v [,step]) as builtin statements over an
|
|
|
|
|
+ 1039 integer designator. *)
|
|
|
|
|
+ 1040 IncDecStat (. VAR dt, et2: SymTab.TypeIndex;
|
|
|
|
|
+ 1041 dk: INTEGER;
|
|
|
|
|
+ 1042 qd, qv, qn2, qstep:
|
|
|
|
|
+ 1043 QbeGen.QVal;
|
|
|
|
|
+ 1044 qn: SymTab.Name;
|
|
|
|
|
+ 1045 sfx, isInc: BOOLEAN; .)
|
|
|
|
|
+ 1046 = (. isInc := TRUE; .)
|
|
|
|
|
+ 1047 ( "INC" (. isInc := TRUE; .)
|
|
|
|
|
+ 1048 | "DEC" (. isInc := FALSE; .) )
|
|
|
|
|
+ 1049 "(" (. QbeGen.CopyOp("1", qstep); .)
|
|
|
|
|
+ 1050 Design<dt, dk, qd, qn, sfx>
|
|
|
|
|
+ 1051 [ "," Expr<et2, qstep> ]
|
|
|
|
|
+ 1052 ")" (. IF dt = SymTab.InvalidType THEN
|
|
|
|
|
+ 1053 ELSIF (dk # SymTab.KindVar)
|
|
|
|
|
+ 1054 AND (dk # SymTab.KindParam)
|
|
|
|
|
+ 1055 AND (dk # SymTab.KindField) THEN
|
|
|
|
|
+ 1056 SemError(210)
|
|
|
|
|
+ 1057 ELSIF NOT SymTab.IsIntFamily(dt) THEN
|
|
|
|
|
+ 1058 SemError(211)
|
|
|
|
|
+ 1059 ELSE
|
|
|
|
|
+ 1060 IF sfx
|
|
|
|
|
+ 1061 OR (dk = SymTab.KindField) THEN
|
|
|
|
|
+ 1062 QbeGen.ElemLoad(qd, dt, qv)
|
|
|
|
|
+ 1063 ELSE QbeGen.LoadVar(qn,
|
|
|
|
|
+ 1064 FALSE, qv)
|
|
|
|
|
+ 1065 END;
|
|
|
|
|
+ 1066 QbeGen.NewTemp(qn2);
|
|
|
|
|
+ 1067 IF isInc THEN
|
|
|
|
|
+ 1068 QbeGen.Op3("add", qn2, qv,
|
|
|
|
|
+ 1069 qstep, FALSE)
|
|
|
|
|
+ 1070 ELSE QbeGen.Op3("sub", qn2, qv,
|
|
|
|
|
+ 1071 qstep, FALSE)
|
|
|
|
|
+ 1072 END;
|
|
|
|
|
+ 1073 IF sfx
|
|
|
|
|
+ 1074 OR (dk = SymTab.KindField) THEN
|
|
|
|
|
+ 1075 QbeGen.ElemStore(qd, qn2,
|
|
|
|
|
+ 1076 dt)
|
|
|
|
|
+ 1077 ELSE QbeGen.StoreVar(qn,
|
|
|
|
|
+ 1078 qn2, FALSE)
|
|
|
|
|
+ 1079 END
|
|
|
|
|
+ 1080 END; .) .
|
|
|
|
|
+ 1081 (* NEW/DISPOSE as builtin statements (no call syntax until step 4).
|
|
|
|
|
+ 1082 Targets are pointer designators; DISPOSE nils afterwards (safer
|
|
|
|
|
+ 1083 than Wirth-undefined; documented). DISPOSE is shallow. *)
|
|
|
|
|
+ 1084 NewStat (. VAR dt: SymTab.TypeIndex;
|
|
|
|
|
+ 1085 dk: INTEGER;
|
|
|
|
|
+ 1086 qd, qm: QbeGen.QVal;
|
|
|
|
|
+ 1087 qn: SymTab.Name;
|
|
|
|
|
+ 1088 sfx: BOOLEAN;
|
|
|
|
|
+ 1089 bt: SymTab.TypeIndex; .)
|
|
|
|
|
+ 1090 = "NEW" "(" Design<dt, dk, qd, qn, sfx> ")"
|
|
|
|
|
+ 1091 (. IF dt = SymTab.InvalidType THEN
|
|
|
|
|
+ 1092 ELSIF (dk # SymTab.KindVar)
|
|
|
|
|
+ 1093 AND (dk # SymTab.KindParam)
|
|
|
|
|
+ 1094 AND (dk # SymTab.KindField) THEN
|
|
|
|
|
+ 1095 SemError(210)
|
|
|
|
|
+ 1096 ELSIF SymTab.ClassOf(dt) #
|
|
|
|
|
+ 1097 SymTab.ClPtr THEN
|
|
|
|
|
+ 1098 SemError(219)
|
|
|
|
|
+ 1099 ELSE bt := SymTab.PtrBase(dt);
|
|
|
|
|
+ 1100 IF bt #
|
|
|
|
|
+ 1101 SymTab.InvalidType THEN
|
|
|
|
|
+ 1102 QbeGen.NewHeap(bt, qm);
|
|
|
|
|
+ 1103 QbeGen.InitHeap(qm, bt);
|
|
|
|
|
+ 1104 IF sfx
|
|
|
|
|
+ 1105 OR (dk =
|
|
|
|
|
+ 1106 SymTab.KindField) THEN
|
|
|
|
|
+ 1107 QbeGen.ElemStore(qd, qm,
|
|
|
|
|
+ 1108 dt)
|
|
|
|
|
+ 1109 ELSE QbeGen.StorePtr(qn,
|
|
|
|
|
+ 1110 qm)
|
|
|
|
|
+ 1111 END
|
|
|
|
|
+ 1112 END
|
|
|
|
|
+ 1113 END; .) .
|
|
|
|
|
+ 1114 DisposeStat (. VAR dt: SymTab.TypeIndex;
|
|
|
|
|
+ 1115 dk: INTEGER;
|
|
|
|
|
+ 1116 qd, qv: QbeGen.QVal;
|
|
|
|
|
+ 1117 qn: SymTab.Name;
|
|
|
|
|
+ 1118 sfx: BOOLEAN; .)
|
|
|
|
|
+ 1119 = "DISPOSE" "(" Design<dt, dk, qd, qn, sfx> ")"
|
|
|
|
|
+ 1120 (. IF dt = SymTab.InvalidType THEN
|
|
|
|
|
+ 1121 ELSIF (dk # SymTab.KindVar)
|
|
|
|
|
+ 1122 AND (dk # SymTab.KindParam)
|
|
|
|
|
+ 1123 AND (dk # SymTab.KindField) THEN
|
|
|
|
|
+ 1124 SemError(210)
|
|
|
|
|
+ 1125 ELSIF SymTab.ClassOf(dt) #
|
|
|
|
|
+ 1126 SymTab.ClPtr THEN
|
|
|
|
|
+ 1127 SemError(219)
|
|
|
|
|
+ 1128 ELSE
|
|
|
|
|
+ 1129 IF sfx
|
|
|
|
|
+ 1130 OR (dk =
|
|
|
|
|
+ 1131 SymTab.KindField) THEN
|
|
|
|
|
+ 1132 QbeGen.ElemLoad(qd, dt,
|
|
|
|
|
+ 1133 qv)
|
|
|
|
|
+ 1134 ELSE QbeGen.LoadPtr(qn, qv)
|
|
|
|
|
+ 1135 END;
|
|
|
|
|
+ 1136 QbeGen.FreeHeap(qv);
|
|
|
|
|
+ 1137 IF sfx
|
|
|
|
|
+ 1138 OR (dk =
|
|
|
|
|
+ 1139 SymTab.KindField) THEN
|
|
|
|
|
+ 1140 QbeGen.ElemStore(qd, "0",
|
|
|
|
|
+ 1141 dt)
|
|
|
|
|
+ 1142 ELSE QbeGen.StorePtr(qn,
|
|
|
|
|
+ 1143 "0")
|
|
|
|
|
+ 1144 END
|
|
|
|
|
+ 1145 END; .) .
|
|
|
|
|
+ 1146 (* WITH pushes each record's fields (inner wins) plus its base
|
|
|
|
|
+ 1147 address; field designators resolve through both stacks. *)
|
|
|
|
|
+ 1148 WithStat (. VAR nW: CARDINAL; .)
|
|
|
|
|
+ 1149 = "WITH" (. nW := 0; .)
|
|
|
|
|
+ 1150 WithItem<nW> { "," WithItem<nW> }
|
|
|
|
|
+ 1151 "DO" [ StatSeq ] "END"
|
|
|
|
|
+ 1152 (. WHILE nW > 0 DO
|
|
|
|
|
+ 1153 SymTab.PopScope;
|
|
|
|
|
+ 1154 QbeGen.PopWith;
|
|
|
|
|
+ 1155 DEC(nW)
|
|
|
|
|
+ 1156 END; .) .
|
|
|
|
|
+ 1157 WithItem<VAR nW: CARDINAL> (. VAR dt: SymTab.TypeIndex;
|
|
|
|
|
+ 1158 dk: INTEGER;
|
|
|
|
|
+ 1159 qd, qe: QbeGen.QVal;
|
|
|
|
|
+ 1160 qn: SymTab.Name;
|
|
|
|
|
+ 1161 sfx: BOOLEAN; .)
|
|
|
|
|
+ 1162 = Design<dt, dk, qd, qn, sfx>
|
|
|
|
|
+ 1163 (. IF dt = SymTab.InvalidType THEN
|
|
|
|
|
+ 1164 ELSIF (SymTab.ClassOf(dt) #
|
|
|
|
|
+ 1165 SymTab.ClRecord)
|
|
|
|
|
+ 1166 AND (SymTab.ClassOf(dt) #
|
|
|
|
|
+ 1167 SymTab.ClClass) THEN
|
|
|
|
|
+ 1168 SemError(215)
|
|
|
|
|
+ 1169 ELSIF SymTab.PushRecord(dt) THEN
|
|
|
|
|
+ 1170 QbeGen.PushWith(qd);
|
|
|
|
|
+ 1171 INC(nW)
|
|
|
|
|
+ 1172 END; .) .
|
|
|
|
|
+ 1173 (* Assignment or procedure-statement call (4.1, module level).
|
|
|
|
|
+ 1174 Bare `P;` is a syntax error; function-as-statement is 233. *)
|
|
|
|
|
+ 1175 AssOrCall (. VAR dt, et: SymTab.TypeIndex;
|
|
|
|
|
+ 1176 dk: INTEGER;
|
|
|
|
|
+ 1177 qd, qe, qt, ql: QbeGen.QVal;
|
|
|
|
|
+ 1178 qn: SymTab.Name;
|
|
|
|
|
+ 1179 ct2, res0: SymTab.TypeIndex;
|
|
|
|
|
+ 1180 q2, mg0: QbeGen.QVal;
|
|
|
|
|
+ 1181 isR, conv, wconv: BOOLEAN;
|
|
|
|
|
+ 1182 called, sfx: BOOLEAN; .)
|
|
|
|
|
+ 1183 = Design<dt, dk, qd, qn, sfx>
|
|
|
|
|
+ 1184 ( ":="
|
|
|
|
|
+ 1185 Expr<et, qe> (. IF (dt # SymTab.InvalidType)
|
|
|
|
|
+ 1186 AND (dk # SymTab.KindVar)
|
|
|
|
|
+ 1187 AND (dk # SymTab.KindParam)
|
|
|
|
|
+ 1188 AND (dk # SymTab.KindField) THEN
|
|
|
|
|
+ 1189 SemError(210)
|
|
|
|
|
+ 1190 ELSIF NOT SymTab.Assignable(et,
|
|
|
|
|
+ 1191 dt) THEN
|
|
|
|
|
+ 1192 SemError(210)
|
|
|
|
|
+ 1193 ELSIF (dt # SymTab.InvalidType)
|
|
|
|
|
+ 1194 AND (SymTab.ClassOf(dt) =
|
|
|
|
|
+ 1195 SymTab.ClClass) THEN
|
|
|
|
|
+ 1196 SemError(230) END;
|
|
|
|
|
+ 1197 isR := (dt #
|
|
|
|
|
+ 1198 SymTab.InvalidType)
|
|
|
|
|
+ 1199 AND (SymTab.ClassOf(dt)
|
|
|
|
|
+ 1200 = SymTab.ClReal);
|
|
|
|
|
+ 1201 conv := isR
|
|
|
|
|
+ 1202 AND SymTab.IsIntFamily(et);
|
|
|
|
|
+ 1203 wconv := (dt #
|
|
|
|
|
+ 1204 SymTab.InvalidType)
|
|
|
|
|
+ 1205 AND SymTab.IsLongFamily(dt)
|
|
|
|
|
+ 1206 AND SymTab.IsIntFamily(et);
|
|
|
|
|
+ 1207 IF ((dk = SymTab.KindVar)
|
|
|
|
|
+ 1208 OR (dk = SymTab.KindParam)
|
|
|
|
|
+ 1209 OR (dk = SymTab.KindField))
|
|
|
|
|
+ 1210 AND (dt # SymTab.InvalidType)
|
|
|
|
|
+ 1211 AND (et # SymTab.InvalidType)
|
|
|
|
|
+ 1212 AND (SymTab.ClassOf(dt) #
|
|
|
|
|
+ 1213 SymTab.ClClass) THEN
|
|
|
|
|
+ 1214 IF sfx
|
|
|
|
|
+ 1215 OR (dk = SymTab.KindField) THEN
|
|
|
|
|
+ 1216 IF SymTab.ClassOf(dt) =
|
|
|
|
|
+ 1217 SymTab.ClArray THEN
|
|
|
|
|
+ 1218 IF (et # SymTab.InvalidType)
|
|
|
|
|
+ 1219 AND (SymTab.ClassOf(et) = SymTab.ClUStr)
|
|
|
|
|
+ 1220 AND SymTab.IsUCharArray(dt) THEN
|
|
|
|
|
+ 1221 QbeGen.UAssign(qd, qe)
|
|
|
|
|
+ 1222 ELSIF SymTab.StrCompat(dt,
|
|
|
|
|
+ 1223 et) THEN
|
|
|
|
|
+ 1224 QbeGen.StrAssign(qd,
|
|
|
|
|
+ 1225 qe)
|
|
|
|
|
+ 1226 ELSE
|
|
|
|
|
+ 1227 QbeGen.CopyArray(qd,
|
|
|
|
|
+ 1228 qe, dt)
|
|
|
|
|
+ 1229 END
|
|
|
|
|
+ 1230 ELSIF SymTab.ClassOf(dt) =
|
|
|
|
|
+ 1231 SymTab.ClSet THEN
|
|
|
|
|
+ 1232 QbeGen.CopySet(qd, qe,
|
|
|
|
|
+ 1233 SymTab.SetWords(dt),
|
|
|
|
|
+ 1234 SymTab.SetWords(et))
|
|
|
|
|
+ 1235 ELSIF SymTab.ClassOf(dt) =
|
|
|
|
|
+ 1236 SymTab.ClRecord THEN
|
|
|
|
|
+ 1237 QbeGen.CopyRecord(qd, qe,
|
|
|
|
|
+ 1238 dt)
|
|
|
|
|
+ 1239 ELSIF SymTab.IsLongFamily(dt) THEN
|
|
|
|
|
+ 1240 IF wconv THEN
|
|
|
|
|
+ 1241 QbeGen.WidenLong(qe, ql);
|
|
|
|
|
+ 1242 QbeGen.ElemStore(qd, ql,
|
|
|
|
|
+ 1243 dt)
|
|
|
|
|
+ 1244 ELSE QbeGen.ElemStore(qd, qe,
|
|
|
|
|
+ 1245 dt)
|
|
|
|
|
+ 1246 END
|
|
|
|
|
+ 1247 ELSIF conv THEN
|
|
|
|
|
+ 1248 QbeGen.ConvIR(qe, qt);
|
|
|
|
|
+ 1249 QbeGen.ElemStore(qd, qt,
|
|
|
|
|
+ 1250 dt)
|
|
|
|
|
+ 1251 ELSE QbeGen.ElemStore(qd, qe,
|
|
|
|
|
+ 1252 dt)
|
|
|
|
|
+ 1253 END
|
|
|
|
|
+ 1254 ELSIF SymTab.ClassOf(dt) =
|
|
|
|
|
+ 1255 SymTab.ClArray THEN
|
|
|
|
|
+ 1256 IF (et # SymTab.InvalidType)
|
|
|
|
|
+ 1257 AND (SymTab.ClassOf(et) = SymTab.ClUStr)
|
|
|
|
|
+ 1258 AND SymTab.IsUCharArray(dt) THEN
|
|
|
|
|
+ 1259 QbeGen.UAssign(qd, qe)
|
|
|
|
|
+ 1260 ELSIF SymTab.StrCompat(dt,
|
|
|
|
|
+ 1261 et) THEN
|
|
|
|
|
+ 1262 QbeGen.StrAssign(qd, qe)
|
|
|
|
|
+ 1263 ELSE
|
|
|
|
|
+ 1264 QbeGen.CopyArray(qd, qe,
|
|
|
|
|
+ 1265 dt)
|
|
|
|
|
+ 1266 END
|
|
|
|
|
+ 1267 ELSIF SymTab.ClassOf(dt) =
|
|
|
|
|
+ 1268 SymTab.ClSet THEN
|
|
|
|
|
+ 1269 QbeGen.CopySet(qd, qe,
|
|
|
|
|
+ 1270 SymTab.SetWords(dt),
|
|
|
|
|
+ 1271 SymTab.SetWords(et))
|
|
|
|
|
+ 1272 ELSIF SymTab.ClassOf(dt) =
|
|
|
|
|
+ 1273 SymTab.ClRecord THEN
|
|
|
|
|
+ 1274 QbeGen.CopyRecord(qd, qe, dt)
|
|
|
|
|
+ 1275 ELSIF (SymTab.ClassOf(dt) =
|
|
|
|
|
+ 1276 SymTab.ClPtr)
|
|
|
|
|
+ 1277 OR (SymTab.ClassOf(dt) =
|
|
|
|
|
+ 1278 SymTab.ClProc) THEN
|
|
|
|
|
+ 1279 QbeGen.StorePtr(qn, qe)
|
|
|
|
|
+ 1280 ELSIF SymTab.IsLongFamily(dt) THEN
|
|
|
|
|
+ 1281 IF wconv THEN
|
|
|
|
|
+ 1282 QbeGen.WidenLong(qe, ql);
|
|
|
|
|
+ 1283 QbeGen.StoreLong(qn, ql)
|
|
|
|
|
+ 1284 ELSE QbeGen.StoreLong(qn, qe)
|
|
|
|
|
+ 1285 END
|
|
|
|
|
+ 1286 ELSIF conv THEN
|
|
|
|
|
+ 1287 QbeGen.ConvIR(qe, qt);
|
|
|
|
|
+ 1288 QbeGen.StoreVar(qn, qt, TRUE)
|
|
|
|
|
+ 1289 ELSE
|
|
|
|
|
+ 1290 QbeGen.StoreVar(qn, qe, isR)
|
|
|
|
|
+ 1291 END
|
|
|
|
|
+ 1292 END; .)
|
|
|
|
|
+ 1293 | ArgList<qn, dt, qd, FALSE, FALSE, methCls, ct2, q2, called>
|
|
|
|
|
+ 1294 | (* bare `P;`: proper parameterless
|
|
|
|
|
+ 1295 procedure call; anything else
|
|
|
|
|
+ 1296 here is 233 (was a bare syntax
|
|
|
|
|
+ 1297 error before 4.2) *)
|
|
|
|
|
+ 1298 (. IF (dk = SymTab.KindProc)
|
|
|
|
|
+ 1299 AND NOT sfx THEN
|
|
|
|
|
+ 1300 res0 := SymTab.ProcRes(qn);
|
|
|
|
|
+ 1301 IF res0 #
|
|
|
|
|
+ 1302 SymTab.InvalidType THEN
|
|
|
|
|
+ 1303 SemError(233)
|
|
|
|
|
+ 1304 ELSIF SymTab.ProcNPar(qn) #
|
|
|
|
|
+ 1305 0 THEN
|
|
|
|
|
+ 1306 SemError(233)
|
|
|
|
|
+ 1307 ELSE QbeGen.Mangled(qn,
|
|
|
|
|
+ 1308 SymTab.ProcUid(qn), mg0);
|
|
|
|
|
+ 1309 QbeGen.CallBegin(mg0,
|
|
|
|
|
+ 1310 res0,
|
|
|
|
|
+ 1311 SymTab.ProcDepthOf(qn),
|
|
|
|
|
+ 1312 SymTab.IsExternal(qn));
|
|
|
|
|
+ 1313 QbeGen.CallEnd(FALSE, q2)
|
|
|
|
|
+ 1314 END
|
|
|
|
|
+ 1315 ELSE SemError(233)
|
|
|
|
|
+ 1316 END; .) ) .
|
|
|
|
|
+ 1317 (* Actual-parameter list shared by statement and expression calls.
|
|
|
|
|
+ 1318 want selects CallEnd's result handling; t/q carry the call
|
|
|
|
|
+ 1319 value (statement calls discard). Arity/type failures are 233;
|
|
|
|
|
+ 1320 evaluation code still emits so the .ssa stays assembleable. *)
|
|
|
|
|
+ 1321 ArgList<pn: SymTab.Name; pt: SymTab.TypeIndex; callee: QbeGen.QVal;
|
|
|
|
|
+ 1322 want: BOOLEAN; soft: BOOLEAN; methCls: SymTab.TypeIndex;
|
|
|
|
|
+ 1323 VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal;
|
|
|
|
|
+ 1324 VAR called: BOOLEAN> (. VAR i, np: CARDINAL;
|
|
|
|
|
+ 1325 vs: INTEGER;
|
|
|
|
|
+ 1326 res: SymTab.TypeIndex;
|
|
|
|
|
+ 1327 mg: QbeGen.QVal;
|
|
|
|
|
+ 1328 ok, ind, isMeth, va: BOOLEAN; .)
|
|
|
|
|
+ 1329 = "(" (. called := TRUE;
|
|
|
|
|
+ 1330 ok := TRUE;
|
|
|
|
|
+ 1331 ind := FALSE;
|
|
|
|
|
+ 1332 isMeth := methCls #
|
|
|
|
|
+ 1333 SymTab.InvalidType;
|
|
|
|
|
+ 1334 IF isMeth THEN
|
|
|
|
|
+ 1335 (* class method: the
|
|
|
|
|
+ 1336 receiver is armed.
|
|
|
|
|
+ 1337 Virtual -> dispatch
|
|
|
|
|
+ 1338 through the vtable;
|
|
|
|
|
+ 1339 otherwise a static
|
|
|
|
|
+ 1340 call. *)
|
|
|
|
|
+ 1341 res := SymTab.ClassMethodRes(
|
|
|
|
|
+ 1342 methCls, pn);
|
|
|
|
|
+ 1343 vs := SymTab.VirtSlot(
|
|
|
|
|
+ 1344 methCls, pn);
|
|
|
|
|
+ 1345 IF vs >= 0 THEN
|
|
|
|
|
+ 1346 QbeGen.VirtCallBegin(
|
|
|
|
|
+ 1347 callee, vs, res)
|
|
|
|
|
+ 1348 ELSE
|
|
|
|
|
+ 1349 QbeGen.Mangled(pn,
|
|
|
|
|
+ 1350 SymTab.ClassMethodUid(
|
|
|
|
|
+ 1351 methCls, pn), mg);
|
|
|
|
|
+ 1352 QbeGen.CallBegin(mg, res, 0,
|
|
|
|
|
+ 1353 FALSE)
|
|
|
|
|
+ 1354 END
|
|
|
|
|
+ 1355 ELSIF SymTab.SymKind(pn) =
|
|
|
|
|
+ 1356 SymTab.KindProc THEN
|
|
|
|
|
+ 1357 res := SymTab.ProcRes(pn);
|
|
|
|
|
+ 1358 QbeGen.Mangled(pn,
|
|
|
|
|
+ 1359 SymTab.ProcUid(pn), mg);
|
|
|
|
|
+ 1360 QbeGen.CallBegin(mg, res,
|
|
|
|
|
+ 1361 SymTab.ProcDepthOf(pn),
|
|
|
|
|
+ 1362 SymTab.IsExternal(pn))
|
|
|
|
|
+ 1363 ELSIF (pt # SymTab.InvalidType)
|
|
|
|
|
+ 1364 AND (SymTab.ClassOf(pt) = SymTab.ClProc) THEN
|
|
|
|
|
+ 1365 ind := TRUE;
|
|
|
|
|
+ 1366 res :=
|
|
|
|
|
+ 1367 SymTab.ProcTypeRes(pt);
|
|
|
|
|
+ 1368 QbeGen.CallBeginInd(callee,
|
|
|
|
|
+ 1369 res, FALSE)
|
|
|
|
|
+ 1370 ELSE SemError(233);
|
|
|
|
|
+ 1371 ok := FALSE;
|
|
|
|
|
+ 1372 res := SymTab.InvalidType
|
|
|
|
|
+ 1373 END;
|
|
|
|
|
+ 1374 i := 0; .)
|
|
|
|
|
+ 1375 [ ActParam<pn, pt, ind, methCls, i> (. INC(i); .)
|
|
|
|
|
+ 1376 { "," ActParam<pn, pt, ind, methCls, i> (. INC(i); .) } ]
|
|
|
|
|
+ 1377 ")" (. IF ok THEN
|
|
|
|
|
+ 1378 IF isMeth THEN
|
|
|
|
|
+ 1379 np := SymTab.ClassMethodNPar(
|
|
|
|
|
+ 1380 methCls, pn)
|
|
|
|
|
+ 1381 ELSIF ind THEN
|
|
|
|
|
+ 1382 np := SymTab.ProcTypeNPar(pt)
|
|
|
|
|
+ 1383 ELSE np := SymTab.ProcNPar(pn)
|
|
|
|
|
+ 1384 END;
|
|
|
|
|
+ 1385 va := (NOT isMeth) AND (NOT ind)
|
|
|
|
|
+ 1386 AND (SymTab.SymKind(pn) =
|
|
|
|
|
+ 1387 SymTab.KindProc)
|
|
|
|
|
+ 1388 AND SymTab.Varargs(pn);
|
|
|
|
|
+ 1389 IF (i # np) AND NOT va THEN
|
|
|
|
|
+ 1390 SemError(233); ok := FALSE
|
|
|
|
|
+ 1391 END
|
|
|
|
|
+ 1392 END;
|
|
|
|
|
+ 1393 IF NOT ok THEN
|
|
|
|
|
+ 1394 t := SymTab.InvalidType;
|
|
|
|
|
+ 1395 QbeGen.CopyOp("0", q)
|
|
|
|
|
+ 1396 ELSIF want THEN
|
|
|
|
|
+ 1397 IF res =
|
|
|
|
|
+ 1398 SymTab.InvalidType THEN
|
|
|
|
|
+ 1399 SemError(233);
|
|
|
|
|
+ 1400 t := SymTab.InvalidType;
|
|
|
|
|
+ 1401 QbeGen.CopyOp("0", q)
|
|
|
|
|
+ 1402 ELSE t := res;
|
|
|
|
|
+ 1403 QbeGen.CallEnd(TRUE, q)
|
|
|
|
|
+ 1404 END
|
|
|
|
|
+ 1405 ELSE
|
|
|
|
|
+ 1406 IF res #
|
|
|
|
|
+ 1407 SymTab.InvalidType THEN
|
|
|
|
|
+ 1408 SemError(233)
|
|
|
|
|
+ 1409 END;
|
|
|
|
|
+ 1410 t := SymTab.InvalidType;
|
|
|
|
|
+ 1411 QbeGen.CopyOp("0", q);
|
|
|
|
|
+ 1412 QbeGen.CallEnd(FALSE, q)
|
|
|
|
|
+ 1413 END; .) .
|
|
|
|
|
+ 1414 (* One actual: VAR formals take recorded designator addresses
|
|
|
|
|
+ 1415 (233 otherwise); value formals take converted expressions. *)
|
|
|
|
|
+ 1416 ActParam<pn: SymTab.Name; pt: SymTab.TypeIndex; ind: BOOLEAN;
|
|
|
|
|
+ 1417 methCls: SymTab.TypeIndex; i: CARDINAL>
|
|
|
|
|
+ 1418 (. VAR at, ft: SymTab.TypeIndex;
|
|
|
|
|
+ 1419 qe, qa, qt: QbeGen.QVal;
|
|
|
|
|
+ 1420 isV, conv, va: BOOLEAN;
|
|
|
|
|
+ 1421 cl: CHAR; .)
|
|
|
|
|
+ 1422 = Expr<at, qe> (. IF astNArgs <= HIGH(astArgs) THEN
|
|
|
|
|
+ 1423 astArgs[astNArgs] := astCur;
|
|
|
|
|
+ 1424 INC(astNArgs)
|
|
|
|
|
+ 1425 END;
|
|
|
|
|
+ 1426 va := (NOT ind)
|
|
|
|
|
+ 1427 AND (methCls =
|
|
|
|
|
+ 1428 SymTab.InvalidType)
|
|
|
|
|
+ 1429 AND (SymTab.SymKind(pn) =
|
|
|
|
|
+ 1430 SymTab.KindProc)
|
|
|
|
|
+ 1431 AND SymTab.Varargs(pn);
|
|
|
|
|
+ 1432 IF ind THEN
|
|
|
|
|
+ 1433 ft :=
|
|
|
|
|
+ 1434 SymTab.ProcTypeParamType(pt,
|
|
|
|
|
+ 1435 i);
|
|
|
|
|
+ 1436 isV :=
|
|
|
|
|
+ 1437 SymTab.ProcTypeParamIsVar(pt,
|
|
|
|
|
+ 1438 i)
|
|
|
|
|
+ 1439 ELSIF methCls #
|
|
|
|
|
+ 1440 SymTab.InvalidType THEN
|
|
|
|
|
+ 1441 ft :=
|
|
|
|
|
+ 1442 SymTab.ClassMethodParamType(
|
|
|
|
|
+ 1443 methCls, pn, i);
|
|
|
|
|
+ 1444 isV :=
|
|
|
|
|
+ 1445 SymTab.ClassMethodParamIsVar(
|
|
|
|
|
+ 1446 methCls, pn, i)
|
|
|
|
|
+ 1447 ELSE
|
|
|
|
|
+ 1448 ft := SymTab.ParamType(pn, i);
|
|
|
|
|
+ 1449 isV := SymTab.ParamIsVar(pn, i)
|
|
|
|
|
+ 1450 END;
|
|
|
|
|
+ 1451 IF (at = SymTab.InvalidType) THEN
|
|
|
|
|
+ 1452 ELSIF ft = SymTab.InvalidType THEN
|
|
|
|
|
+ 1453 IF va THEN
|
|
|
|
|
+ 1454 QbeGen.CArgAdd(qe, at, qa, cl)
|
|
|
|
|
+ 1455 END
|
|
|
|
|
+ 1456 ELSIF isV THEN
|
|
|
|
|
+ 1457 IF (SymTab.ClassOf(at)
|
|
|
|
|
+ 1458 = SymTab.ClChar)
|
|
|
|
|
+ 1459 AND (SymTab.ClassOf(ft) = SymTab.ClArray)
|
|
|
|
|
+ 1460 AND (SymTab.ClassOf(SymTab.ArrayElem(ft))
|
|
|
|
|
+ 1461 = SymTab.ClChar)
|
|
|
|
|
+ 1462 AND QbeGen.IsImm(qe) THEN
|
|
|
|
|
+ 1463 (* 1-char string
|
|
|
|
|
+ 1464 literal passed to
|
|
|
|
|
+ 1465 a VAR ARRAY OF CHAR *)
|
|
|
|
|
+ 1466 QbeGen.DeclCharStr(qe,
|
|
|
|
|
+ 1467 qa);
|
|
|
|
|
+ 1468 IF NOT QbeGen.CallArg(qa,
|
|
|
|
|
+ 1469 "l") THEN
|
|
|
|
|
+ 1470 SemError(233)
|
|
|
|
|
+ 1471 END
|
|
|
|
|
+ 1472 ELSIF NOT QbeGen.AddrOfVal(qe,
|
|
|
|
|
+ 1473 qa) THEN
|
|
|
|
|
+ 1474 SemError(233)
|
|
|
|
|
+ 1475 ELSIF NOT SymTab.VarParamOk(at,
|
|
|
|
|
+ 1476 ft) THEN
|
|
|
|
|
+ 1477 SemError(233)
|
|
|
|
|
+ 1478 ELSIF NOT QbeGen.CallArg(qa,
|
|
|
|
|
+ 1479 "l") THEN
|
|
|
|
|
+ 1480 SemError(233)
|
|
|
|
|
+ 1481 END
|
|
|
|
|
+ 1482 ELSE
|
|
|
|
|
+ 1483 IF (SymTab.ClassOf(at)
|
|
|
|
|
+ 1484 = SymTab.ClChar)
|
|
|
|
|
+ 1485 AND (SymTab.ClassOf(ft) = SymTab.ClArray)
|
|
|
|
|
+ 1486 AND (SymTab.ClassOf(SymTab.ArrayElem(ft))
|
|
|
|
|
+ 1487 = SymTab.ClChar)
|
|
|
|
|
+ 1488 AND QbeGen.IsImm(qe) THEN
|
|
|
|
|
+ 1489 (* 1-char string
|
|
|
|
|
+ 1490 literal passed to
|
|
|
|
|
+ 1491 ARRAY OF CHAR *)
|
|
|
|
|
+ 1492 QbeGen.DeclCharStr(qe,
|
|
|
|
|
+ 1493 qa);
|
|
|
|
|
+ 1494 IF NOT QbeGen.CallArg(qa,
|
|
|
|
|
+ 1495 "l") THEN
|
|
|
|
|
+ 1496 SemError(233)
|
|
|
|
|
+ 1497 END
|
|
|
|
|
+ 1498 ELSIF NOT SymTab.Assignable(at,
|
|
|
|
|
+ 1499 ft) THEN
|
|
|
|
|
+ 1500 SemError(233)
|
|
|
|
|
+ 1501 ELSE
|
|
|
|
|
+ 1502 conv := (SymTab.ClassOf(
|
|
|
|
|
+ 1503 ft) = SymTab.ClReal)
|
|
|
|
|
+ 1504 AND SymTab.IsIntFamily(at);
|
|
|
|
|
+ 1505 IF conv THEN
|
|
|
|
|
+ 1506 QbeGen.ConvIR(qe, qt);
|
|
|
|
|
+ 1507 IF NOT QbeGen.CallArg(qt,
|
|
|
|
|
+ 1508 "d") THEN
|
|
|
|
|
+ 1509 SemError(233)
|
|
|
|
|
+ 1510 END
|
|
|
|
|
+ 1511 ELSIF NOT QbeGen.CallArg(qe,
|
|
|
|
|
+ 1512 QbeGen.ArgClass(ft)) THEN
|
|
|
|
|
+ 1513 SemError(233)
|
|
|
|
|
+ 1514 END
|
|
|
|
|
+ 1515 END
|
|
|
|
|
+ 1516 END; .) .
|
|
|
|
|
+ 1517 IfStat (. VAR t: SymTab.TypeIndex;
|
|
|
|
|
+ 1518 q, lThen, lElse, lEnd:
|
|
|
|
|
+ 1519 QbeGen.QVal;
|
|
|
|
|
+ 1520 hasElse: BOOLEAN; .)
|
|
|
|
|
+ 1521 = "IF" (. hasElse := FALSE; .)
|
|
|
|
|
+ 1522 Expr<t, q> (. IF NOT SymTab.BoolCheck(t) THEN
|
|
|
1523 SemError(214) END;
|
|
1523 SemError(214) END;
|
|
|
1524 QbeGen.NewLabel(lThen);
|
|
1524 QbeGen.NewLabel(lThen);
|
|
|
- 1525 QbeGen.Jnz(q, lThen, lElse);
|
|
|
|
|
- 1526 QbeGen.EmitLabel(lThen); .)
|
|
|
|
|
- 1527 "THEN" [ StatSeq ] (. QbeGen.Jmp(lEnd); .) }
|
|
|
|
|
- 1528 [ "ELSE" (. QbeGen.EmitLabel(lElse);
|
|
|
|
|
- 1529 hasElse := TRUE; .)
|
|
|
|
|
- 1530 [ StatSeq ] ]
|
|
|
|
|
- 1531 "END" (. IF hasElse THEN
|
|
|
|
|
- 1532 QbeGen.EmitLabel(lEnd)
|
|
|
|
|
- 1533 ELSE QbeGen.EmitLabel(lElse);
|
|
|
|
|
- 1534 QbeGen.EmitLabel(lEnd)
|
|
|
|
|
- 1535 END; .) .
|
|
|
|
|
- 1536 WhileStat (. VAR t: SymTab.TypeIndex;
|
|
|
|
|
- 1537 q, lTop, lBody, lEnd:
|
|
|
|
|
- 1538 QbeGen.QVal; .)
|
|
|
|
|
- 1539 = "WHILE" (. QbeGen.NewLabel(lTop);
|
|
|
|
|
- 1540 QbeGen.NewLabel(lBody);
|
|
|
|
|
- 1541 QbeGen.NewLabel(lEnd);
|
|
|
|
|
- 1542 QbeGen.EmitLabel(lTop); .)
|
|
|
|
|
- 1543 Expr<t, q> (. IF NOT SymTab.BoolCheck(t) THEN
|
|
|
|
|
- 1544 SemError(214) END;
|
|
|
|
|
- 1545 QbeGen.Jnz(q, lBody, lEnd);
|
|
|
|
|
- 1546 QbeGen.EmitLabel(lBody); .)
|
|
|
|
|
- 1547 "DO" [ StatSeq ] (. QbeGen.Jmp(lTop); .)
|
|
|
|
|
- 1548 "END" (. QbeGen.EmitLabel(lEnd); .) .
|
|
|
|
|
- 1549 RepeatStat (. VAR t: SymTab.TypeIndex;
|
|
|
|
|
- 1550 q, lTop, lEnd: QbeGen.QVal; .)
|
|
|
|
|
- 1551 = "REPEAT" (. QbeGen.NewLabel(lTop);
|
|
|
|
|
- 1552 QbeGen.NewLabel(lEnd);
|
|
|
|
|
- 1553 QbeGen.EmitLabel(lTop); .)
|
|
|
|
|
- 1554 [ StatSeq ]
|
|
|
|
|
- 1555 "UNTIL" Expr<t, q> (. IF NOT SymTab.BoolCheck(t) THEN
|
|
|
|
|
- 1556 SemError(214) END;
|
|
|
|
|
- 1557 QbeGen.Jnz(q, lEnd, lTop);
|
|
|
|
|
- 1558 QbeGen.EmitLabel(lEnd); .) .
|
|
|
|
|
- 1559 LoopStat (. VAR lTop, lEnd: QbeGen.QVal; .)
|
|
|
|
|
- 1560 = "LOOP" (. QbeGen.NewLabel(lTop);
|
|
|
|
|
- 1561 QbeGen.NewLabel(lEnd);
|
|
|
|
|
- 1562 QbeGen.PushLoop(lEnd);
|
|
|
|
|
|
|
+ 1525 QbeGen.NewLabel(lElse);
|
|
|
|
|
+ 1526 QbeGen.NewLabel(lEnd);
|
|
|
|
|
+ 1527 QbeGen.Jnz(q, lThen, lElse);
|
|
|
|
|
+ 1528 QbeGen.EmitLabel(lThen); .)
|
|
|
|
|
+ 1529 "THEN" [ StatSeq ] (. QbeGen.Jmp(lEnd); .)
|
|
|
|
|
+ 1530 { "ELSIF" (. QbeGen.EmitLabel(lElse);
|
|
|
|
|
+ 1531 QbeGen.NewLabel(lElse); .)
|
|
|
|
|
+ 1532 Expr<t, q> (. IF NOT SymTab.BoolCheck(t) THEN
|
|
|
|
|
+ 1533 SemError(214) END;
|
|
|
|
|
+ 1534 QbeGen.NewLabel(lThen);
|
|
|
|
|
+ 1535 QbeGen.Jnz(q, lThen, lElse);
|
|
|
|
|
+ 1536 QbeGen.EmitLabel(lThen); .)
|
|
|
|
|
+ 1537 "THEN" [ StatSeq ] (. QbeGen.Jmp(lEnd); .) }
|
|
|
|
|
+ 1538 [ "ELSE" (. QbeGen.EmitLabel(lElse);
|
|
|
|
|
+ 1539 hasElse := TRUE; .)
|
|
|
|
|
+ 1540 [ StatSeq ] ]
|
|
|
|
|
+ 1541 "END" (. IF hasElse THEN
|
|
|
|
|
+ 1542 QbeGen.EmitLabel(lEnd)
|
|
|
|
|
+ 1543 ELSE QbeGen.EmitLabel(lElse);
|
|
|
|
|
+ 1544 QbeGen.EmitLabel(lEnd)
|
|
|
|
|
+ 1545 END; .) .
|
|
|
|
|
+ 1546 WhileStat (. VAR t: SymTab.TypeIndex;
|
|
|
|
|
+ 1547 q, lTop, lBody, lEnd:
|
|
|
|
|
+ 1548 QbeGen.QVal; .)
|
|
|
|
|
+ 1549 = "WHILE" (. QbeGen.NewLabel(lTop);
|
|
|
|
|
+ 1550 QbeGen.NewLabel(lBody);
|
|
|
|
|
+ 1551 QbeGen.NewLabel(lEnd);
|
|
|
|
|
+ 1552 QbeGen.EmitLabel(lTop); .)
|
|
|
|
|
+ 1553 Expr<t, q> (. IF NOT SymTab.BoolCheck(t) THEN
|
|
|
|
|
+ 1554 SemError(214) END;
|
|
|
|
|
+ 1555 QbeGen.Jnz(q, lBody, lEnd);
|
|
|
|
|
+ 1556 QbeGen.EmitLabel(lBody); .)
|
|
|
|
|
+ 1557 "DO" [ StatSeq ] (. QbeGen.Jmp(lTop); .)
|
|
|
|
|
+ 1558 "END" (. QbeGen.EmitLabel(lEnd); .) .
|
|
|
|
|
+ 1559 RepeatStat (. VAR t: SymTab.TypeIndex;
|
|
|
|
|
+ 1560 q, lTop, lEnd: QbeGen.QVal; .)
|
|
|
|
|
+ 1561 = "REPEAT" (. QbeGen.NewLabel(lTop);
|
|
|
|
|
+ 1562 QbeGen.NewLabel(lEnd);
|
|
|
1563 QbeGen.EmitLabel(lTop); .)
|
|
1563 QbeGen.EmitLabel(lTop); .)
|
|
|
1564 [ StatSeq ]
|
|
1564 [ StatSeq ]
|
|
|
- 1565 "END" (. QbeGen.Jmp(lTop);
|
|
|
|
|
- 1566 QbeGen.PopLoop;
|
|
|
|
|
- 1567 QbeGen.EmitLabel(lEnd); .) .
|
|
|
|
|
- 1568 (* FOR with static-sign BY (literal, non-zero; 220 otherwise).
|
|
|
|
|
- 1569 Runtime direction would need a compare-select; the literal
|
|
|
|
|
- 1570 sign picks cslew/csegew at "DO" time. *)
|
|
|
|
|
- 1571 ForStat (. VAR lv: SymTab.Name;
|
|
|
|
|
- 1572 tlo, thi, tby:
|
|
|
|
|
- 1573 SymTab.TypeIndex;
|
|
|
|
|
- 1574 qlo, qhi, qby, qt, qk, qb:
|
|
|
|
|
- 1575 QbeGen.QVal;
|
|
|
|
|
- 1576 lTop, lBody, lEnd:
|
|
|
|
|
- 1577 QbeGen.QVal;
|
|
|
|
|
- 1578 by: INTEGER;
|
|
|
|
|
- 1579 ok: BOOLEAN; .)
|
|
|
|
|
- 1580 = "FOR" (. by := 1; .)
|
|
|
|
|
- 1581 GetIdent<lv> (. ok := SymTab.Lookup(lv);
|
|
|
|
|
- 1582 IF NOT ok THEN
|
|
|
|
|
- 1583 SemError(201)
|
|
|
|
|
- 1584 ELSIF (SymTab.SymKind(lv) #
|
|
|
|
|
- 1585 SymTab.KindVar)
|
|
|
|
|
- 1586 AND (SymTab.SymKind(lv) #
|
|
|
|
|
- 1587 SymTab.KindParam) THEN
|
|
|
|
|
- 1588 SemError(220); ok := FALSE
|
|
|
|
|
- 1589 ELSIF NOT SymTab.IsIntFamily(
|
|
|
|
|
- 1590 SymTab.SymType(lv)) THEN
|
|
|
|
|
- 1591 SemError(220); ok := FALSE
|
|
|
|
|
- 1592 END; .)
|
|
|
|
|
- 1593 ":=" Expr<tlo, qlo> (. IF NOT SymTab.IsIntFamily(tlo) THEN
|
|
|
|
|
- 1594 SemError(220); ok := FALSE
|
|
|
|
|
- 1595 END; .)
|
|
|
|
|
- 1596 "TO" Expr<thi, qhi> (. IF NOT SymTab.IsIntFamily(thi) THEN
|
|
|
|
|
- 1597 SemError(220); ok := FALSE
|
|
|
|
|
- 1598 END; .)
|
|
|
|
|
- 1599 [ "BY" Expr<tby, qby> (. IF (tby #
|
|
|
|
|
- 1600 SymTab.InvalidType)
|
|
|
|
|
- 1601 AND NOT SymTab.IsIntFamily(tby) THEN
|
|
|
|
|
- 1602 SemError(220); ok := FALSE
|
|
|
|
|
- 1603 END;
|
|
|
|
|
- 1604 IF NOT SymTab.ConstInt(qby, by) THEN
|
|
|
|
|
- 1605 SemError(230); by := 1
|
|
|
|
|
- 1606 ELSIF by = 0 THEN
|
|
|
|
|
- 1607 SemError(220); by := 1
|
|
|
|
|
- 1608 END; .) ]
|
|
|
|
|
- 1609 "DO" (. IF ok THEN
|
|
|
|
|
- 1610 QbeGen.StoreVar(lv, qlo,
|
|
|
|
|
- 1611 FALSE) END;
|
|
|
|
|
- 1612 QbeGen.NewLabel(lTop);
|
|
|
|
|
- 1613 QbeGen.NewLabel(lBody);
|
|
|
|
|
- 1614 QbeGen.NewLabel(lEnd);
|
|
|
|
|
- 1615 QbeGen.EmitLabel(lTop);
|
|
|
|
|
- 1616 QbeGen.LoadVar(lv, FALSE, qt);
|
|
|
|
|
- 1617 QbeGen.NewTemp(qk);
|
|
|
|
|
- 1618 IF by > 0 THEN
|
|
|
|
|
- 1619 QbeGen.Op3("cslew", qk,
|
|
|
|
|
- 1620 qt, qhi, FALSE)
|
|
|
|
|
- 1621 ELSE QbeGen.Op3("csgew", qk,
|
|
|
|
|
- 1622 qt, qhi, FALSE)
|
|
|
|
|
- 1623 END;
|
|
|
|
|
- 1624 QbeGen.Jnz(qk, lBody, lEnd);
|
|
|
|
|
- 1625 QbeGen.EmitLabel(lBody); .)
|
|
|
|
|
- 1626 [ StatSeq ]
|
|
|
|
|
- 1627 "END" (. IF ok THEN
|
|
|
|
|
- 1628 QbeGen.LoadVar(lv, FALSE,
|
|
|
|
|
- 1629 qt);
|
|
|
|
|
- 1630 QbeGen.IntStr(by, qb);
|
|
|
|
|
- 1631 QbeGen.NewTemp(qk);
|
|
|
|
|
- 1632 QbeGen.Op3("add", qk,
|
|
|
|
|
- 1633 qt, qb, FALSE);
|
|
|
|
|
- 1634 QbeGen.StoreVar(lv, qk,
|
|
|
|
|
- 1635 FALSE) END;
|
|
|
|
|
- 1636 QbeGen.Jmp(lTop);
|
|
|
|
|
- 1637 QbeGen.EmitLabel(lEnd); .) .
|
|
|
|
|
- 1638 CaseStat (. VAR tsel: SymTab.TypeIndex;
|
|
|
|
|
- 1639 qsel, lEnd: QbeGen.QVal; .)
|
|
|
|
|
- 1640 = "CASE" Expr<tsel, qsel> (. QbeGen.NewLabel(lEnd); .)
|
|
|
|
|
- 1641 "OF" CaseAlt<tsel, qsel, lEnd>
|
|
|
|
|
- 1642 { "|" CaseAlt<tsel, qsel, lEnd> }
|
|
|
|
|
- 1643 [ "ELSE" [ StatSeq ] ]
|
|
|
|
|
- 1644 "END" (. QbeGen.EmitLabel(lEnd); .) .
|
|
|
|
|
- 1645 (* Compare-chain lowering: each alternative ends its match-tests
|
|
|
|
|
- 1646 with "jmp lAfter", so the no-match fallthrough skips the body:
|
|
|
|
|
- 1647 "cmp; jnz(lBody,lF); lF: ... ; jmp lAfter; lBody: S; jmp lEnd;
|
|
|
|
|
- 1648 lAfter:". Falls into the next alternative, ELSE, or END. *)
|
|
|
|
|
- 1649 CaseAlt<tsel: SymTab.TypeIndex; qsel: QbeGen.QVal;
|
|
|
|
|
- 1650 lEnd: QbeGen.QVal> (. VAR lBody, lAfter: QbeGen.QVal; .)
|
|
|
|
|
- 1651 = (. QbeGen.NewLabel(lBody);
|
|
|
|
|
- 1652 QbeGen.NewLabel(lAfter); .)
|
|
|
|
|
- 1653 CaseLabel<tsel, qsel, lBody>
|
|
|
|
|
- 1654 { "," CaseLabel<tsel, qsel, lBody> }
|
|
|
|
|
- 1655 ":" (. QbeGen.Jmp(lAfter);
|
|
|
|
|
- 1656 QbeGen.EmitLabel(lBody); .)
|
|
|
|
|
- 1657 [ StatSeq ] (. QbeGen.Jmp(lEnd);
|
|
|
|
|
- 1658 QbeGen.EmitLabel(lAfter); .) .
|
|
|
|
|
- 1659 CaseLabel<tsel: SymTab.TypeIndex; qsel: QbeGen.QVal;
|
|
|
|
|
- 1660 lBody: QbeGen.QVal> (. VAR t2, t3: SymTab.TypeIndex;
|
|
|
|
|
- 1661 q2, q3, qc, qd, qe:
|
|
|
|
|
- 1662 QbeGen.QVal;
|
|
|
|
|
- 1663 lNext: QbeGen.QVal; .)
|
|
|
|
|
- 1664 = Expr<t2, q2> (. IF (t2 #
|
|
|
|
|
- 1665 SymTab.InvalidType)
|
|
|
|
|
- 1666 AND (tsel #
|
|
|
|
|
- 1667 SymTab.InvalidType)
|
|
|
|
|
- 1668 AND ((SymTab.ClassOf(t2) =
|
|
|
|
|
- 1669 SymTab.ClSet)
|
|
|
|
|
- 1670 OR (SymTab.ClassOf(tsel) =
|
|
|
|
|
- 1671 SymTab.ClSet)) THEN
|
|
|
|
|
- 1672 SemError(230)
|
|
|
|
|
- 1673 ELSIF (t2 #
|
|
|
|
|
- 1674 SymTab.InvalidType)
|
|
|
|
|
- 1675 AND (tsel #
|
|
|
|
|
- 1676 SymTab.InvalidType)
|
|
|
|
|
- 1677 AND NOT SymTab.EqCheck(t2,
|
|
|
|
|
- 1678 tsel) THEN
|
|
|
|
|
- 1679 SemError(213) END;
|
|
|
|
|
- 1680 IF NOT QbeGen.IsImm(q2) THEN
|
|
|
|
|
- 1681 SemError(230);
|
|
|
|
|
- 1682 QbeGen.CopyOp("0", q2)
|
|
|
|
|
- 1683 END;
|
|
|
|
|
- 1684 QbeGen.NewLabel(lNext);
|
|
|
|
|
- 1685 QbeGen.Cmp(SymTab.OpEq,
|
|
|
|
|
- 1686 qsel, q2, qc, FALSE);
|
|
|
|
|
- 1687 QbeGen.Jnz(qc, lBody, lNext);
|
|
|
|
|
- 1688 QbeGen.EmitLabel(lNext); .)
|
|
|
|
|
- 1689 [ ".." Expr<t3, q3> (. IF (t3 #
|
|
|
|
|
- 1690 SymTab.InvalidType)
|
|
|
|
|
- 1691 AND (tsel #
|
|
|
|
|
- 1692 SymTab.InvalidType)
|
|
|
|
|
- 1693 AND NOT SymTab.EqCheck(t3,
|
|
|
|
|
- 1694 tsel) THEN
|
|
|
|
|
- 1695 SemError(213) END;
|
|
|
|
|
- 1696 IF NOT QbeGen.IsImm(q3) THEN
|
|
|
|
|
- 1697 SemError(230);
|
|
|
|
|
- 1698 QbeGen.CopyOp("0", q3)
|
|
|
|
|
- 1699 END;
|
|
|
|
|
- 1700 QbeGen.Cmp(SymTab.OpGe,
|
|
|
|
|
- 1701 qsel, q2, qc, FALSE);
|
|
|
|
|
- 1702 QbeGen.Cmp(SymTab.OpLe,
|
|
|
|
|
- 1703 qsel, q3, qd, FALSE);
|
|
|
|
|
- 1704 QbeGen.NewTemp(qe);
|
|
|
|
|
- 1705 QbeGen.Op3("and", qe, qc, qd,
|
|
|
|
|
- 1706 FALSE);
|
|
|
|
|
- 1707 QbeGen.NewLabel(lNext);
|
|
|
|
|
- 1708 QbeGen.Jnz(qe, lBody, lNext);
|
|
|
|
|
- 1709 QbeGen.EmitLabel(lNext); .) ] .
|
|
|
|
|
- 1710 ReturnStat (. VAR t: SymTab.TypeIndex;
|
|
|
|
|
- 1711 q, qt: QbeGen.QVal;
|
|
|
|
|
- 1712 res: SymTab.TypeIndex;
|
|
|
|
|
- 1713 hadE, conv: BOOLEAN; .)
|
|
|
|
|
- 1714 = "RETURN" (. hadE := FALSE; .)
|
|
|
|
|
- 1715 [ Expr<t, q> (. hadE := TRUE; .) ]
|
|
|
|
|
- 1716 (. conv := FALSE;
|
|
|
|
|
- 1717 IF NOT SymTab.InProc() THEN
|
|
|
|
|
- 1718 SemError(232)
|
|
|
|
|
- 1719 ELSE res := SymTab.CurRes();
|
|
|
|
|
- 1720 IF NOT hadE THEN
|
|
|
|
|
- 1721 IF res #
|
|
|
|
|
- 1722 SymTab.InvalidType THEN
|
|
|
|
|
- 1723 SemError(232)
|
|
|
|
|
- 1724 ELSE QbeGen.EmitRet(q,
|
|
|
|
|
- 1725 FALSE)
|
|
|
|
|
- 1726 END
|
|
|
|
|
- 1727 ELSIF (res =
|
|
|
|
|
- 1728 SymTab.InvalidType)
|
|
|
|
|
- 1729 OR (t #
|
|
|
|
|
- 1730 SymTab.InvalidType)
|
|
|
|
|
- 1731 AND NOT SymTab.Assignable(t,
|
|
|
|
|
- 1732 res) THEN
|
|
|
|
|
- 1733 SemError(232)
|
|
|
|
|
- 1734 ELSE
|
|
|
|
|
- 1735 conv := (SymTab.ClassOf(
|
|
|
|
|
- 1736 res) = SymTab.ClReal)
|
|
|
|
|
- 1737 AND SymTab.IsIntFamily(t);
|
|
|
|
|
- 1738 IF conv THEN
|
|
|
|
|
- 1739 QbeGen.ConvIR(q, qt);
|
|
|
|
|
- 1740 QbeGen.EmitRet(qt, TRUE)
|
|
|
|
|
- 1741 ELSE QbeGen.EmitRet(q, TRUE)
|
|
|
|
|
- 1742 END
|
|
|
|
|
- 1743 END
|
|
|
|
|
- 1744 END; .) .
|
|
|
|
|
- 1745 HaltStat (. VAR t: SymTab.TypeIndex;
|
|
|
|
|
- 1746 q: QbeGen.QVal; .)
|
|
|
|
|
- 1747 = "HALT" [ "(" Expr<t, q> ")" ] (. QbeGen.HaltQ; .) .
|
|
|
|
|
- 1748 (* Designator: scalar loads, array addresses, and index suffixes.
|
|
|
|
|
- 1749 Each index descends one level (bounds-checked, trap on breach);
|
|
|
|
|
- 1750 nested levels reload the inner descriptor address. q ends as the
|
|
|
|
|
- 1751 value (scalars), the descriptor address (plain arrays), or the
|
|
|
|
|
- 1752 element address (indexed); sfx marks the indexed form. *)
|
|
|
|
|
- 1753 Design<VAR t: SymTab.TypeIndex; VAR k: INTEGER;
|
|
|
|
|
- 1754 VAR q: QbeGen.QVal; VAR qn: SymTab.Name; VAR sfx: BOOLEAN>
|
|
|
|
|
- 1755 (. VAR n, fn, mal: SymTab.Name;
|
|
|
|
|
- 1756 cls: INTEGER;
|
|
|
|
|
- 1757 ic: SymTab.TypeIndex;
|
|
|
|
|
- 1758 curT, it, eT, bt:
|
|
|
|
|
- 1759 SymTab.TypeIndex;
|
|
|
|
|
- 1760 iq, ql, qlo, qhi, qe:
|
|
|
|
|
- 1761 QbeGen.QVal;
|
|
|
|
|
- 1762 lo, hi: INTEGER;
|
|
|
|
|
- 1763 fo: INTEGER;
|
|
|
|
|
- 1764 isOpen: BOOLEAN;
|
|
|
|
|
- 1765 qb, cv: QbeGen.QVal;
|
|
|
|
|
- 1766 fid, fref, slot: INTEGER;
|
|
|
|
|
- 1767 r: BOOLEAN;
|
|
|
|
|
- 1768 astDes, astSel: AST.Node; .)
|
|
|
|
|
- 1769 = GetIdent<n> (. methCls := SymTab.InvalidType;
|
|
|
|
|
- 1770 QbeGen.CopyOp(n, qn);
|
|
|
|
|
- 1771 sfx := FALSE;
|
|
|
|
|
- 1772 fid := 0; fref := 0; slot := 0;
|
|
|
|
|
- 1773 IF NOT SymTab.Lookup(n) THEN
|
|
|
|
|
- 1774 (* a bare method name inside
|
|
|
|
|
- 1775 a CLASS IMPLEMENTATION
|
|
|
|
|
- 1776 is a sibling call on
|
|
|
|
|
- 1777 THIS *)
|
|
|
|
|
- 1778 ic := SymTab.CurImplClass();
|
|
|
|
|
- 1779 IF (ic #
|
|
|
|
|
- 1780 SymTab.InvalidType)
|
|
|
|
|
- 1781 AND SymTab.MethodExists(ic, n) THEN
|
|
|
|
|
- 1782 sfx := FALSE;
|
|
|
|
|
- 1783 QbeGen.ThisBase(q);
|
|
|
|
|
- 1784 QbeGen.ArmRecv(q);
|
|
|
|
|
- 1785 methCls := ic;
|
|
|
|
|
- 1786 k := SymTab.KindProc;
|
|
|
|
|
- 1787 t := SymTab.InvalidType
|
|
|
|
|
- 1788 ELSIF SymTab.InProc() THEN
|
|
|
|
|
- 1789 (* not declared yet: a
|
|
|
|
|
- 1790 forward reference to a
|
|
|
|
|
- 1791 module-level variable
|
|
|
|
|
- 1792 declared further down. *)
|
|
|
|
|
- 1793 k := SymTab.KindVar;
|
|
|
|
|
- 1794 r := SymTab.FwdVarRef(n, k,
|
|
|
|
|
- 1795 fref, t);
|
|
|
|
|
- 1796 slot := QbeGen.FwdDesignator();
|
|
|
|
|
- 1797 FwdVarNote(fref, slot);
|
|
|
|
|
- 1798 fid := slot;
|
|
|
|
|
- 1799 QbeGen.FwdAddrOper(fid, q);
|
|
|
|
|
- 1800 sfx := TRUE
|
|
|
|
|
- 1801 ELSE
|
|
|
|
|
- 1802 SemError(201);
|
|
|
|
|
- 1803 t :=
|
|
|
|
|
- 1804 SymTab.InvalidType;
|
|
|
|
|
- 1805 k := -1;
|
|
|
|
|
- 1806 QbeGen.CopyOp("0", q)
|
|
|
|
|
- 1807 END
|
|
|
|
|
- 1808 ELSE
|
|
|
|
|
- 1809 t := SymTab.SymType(n);
|
|
|
|
|
- 1810 k := SymTab.SymKind(n);
|
|
|
|
|
- 1811 IF k = SymTab.KindConst THEN
|
|
|
|
|
- 1812 IF SymTab.Equal(n,
|
|
|
|
|
- 1813 "TRUE") THEN
|
|
|
|
|
- 1814 t := SymTab.BoolType();
|
|
|
|
|
- 1815 QbeGen.CopyOp("1", q)
|
|
|
|
|
- 1816 ELSIF SymTab.Equal(n,
|
|
|
|
|
- 1817 "FALSE") THEN
|
|
|
|
|
- 1818 t := SymTab.BoolType();
|
|
|
|
|
- 1819 QbeGen.CopyOp("0", q)
|
|
|
|
|
- 1820 ELSIF SymTab.Equal(n,
|
|
|
|
|
- 1821 "NIL") THEN
|
|
|
|
|
- 1822 QbeGen.CopyOp("0", q)
|
|
|
|
|
- 1823 ELSE
|
|
|
|
|
- 1824 cls :=
|
|
|
|
|
- 1825 SymTab.ClassOf(t);
|
|
|
|
|
- 1826 IF (t #
|
|
|
|
|
- 1827 SymTab.InvalidType)
|
|
|
|
|
- 1828 AND ((cls = SymTab.ClInt)
|
|
|
|
|
- 1829 OR (cls
|
|
|
|
|
- 1830 = SymTab.ClChar)
|
|
|
|
|
- 1831 OR (cls
|
|
|
|
|
- 1832 = SymTab.ClEnum)
|
|
|
|
|
- 1833 OR (cls
|
|
|
|
|
- 1834 = SymTab.ClReal)
|
|
|
|
|
- 1835 OR (cls
|
|
|
|
|
- 1836 = SymTab.ClLong)
|
|
|
|
|
- 1837 OR (cls
|
|
|
|
|
- 1838 = SymTab.ClNil)) THEN
|
|
|
|
|
- 1839 IF cls = SymTab.ClNil THEN
|
|
|
|
|
- 1840 QbeGen.CopyOp("0", q)
|
|
|
|
|
- 1841 ELSIF ((cls
|
|
|
|
|
- 1842 = SymTab.ClInt)
|
|
|
|
|
- 1843 OR (cls
|
|
|
|
|
- 1844 = SymTab.ClChar)
|
|
|
|
|
- 1845 OR (cls
|
|
|
|
|
- 1846 = SymTab.ClEnum)
|
|
|
|
|
- 1847 OR (cls
|
|
|
|
|
- 1848 = SymTab.ClLong))
|
|
|
|
|
- 1849 AND SymTab.GetSymVal(n, cv)
|
|
|
|
|
- 1850 AND QbeGen.IsImm(cv) THEN
|
|
|
|
|
- 1851 QbeGen.CopyOp(cv, q)
|
|
|
|
|
- 1852 ELSE
|
|
|
|
|
- 1853 QbeGen.LoadVar(n,
|
|
|
|
|
- 1854 cls = SymTab.ClReal,
|
|
|
|
|
- 1855 q)
|
|
|
|
|
- 1856 END
|
|
|
|
|
- 1857 ELSIF (cls = SymTab.ClArray)
|
|
|
|
|
- 1858 OR (cls = SymTab.ClRecord)
|
|
|
|
|
- 1859 OR (cls = SymTab.ClClass)
|
|
|
|
|
- 1860 OR (cls = SymTab.ClStr)
|
|
|
|
|
- 1861 OR (cls = SymTab.ClUStr) THEN
|
|
|
|
|
- 1862 (* aggregate constant:
|
|
|
|
|
- 1863 its value IS the
|
|
|
|
|
- 1864 descriptor address *)
|
|
|
|
|
- 1865 IF SymTab.GetSymVal(n, cv) THEN
|
|
|
|
|
- 1866 QbeGen.CopyOp(cv, q)
|
|
|
|
|
- 1867 ELSE
|
|
|
|
|
- 1868 QbeGen.CopyOp("0", q)
|
|
|
|
|
- 1869 END
|
|
|
|
|
- 1870 ELSE
|
|
|
|
|
- 1871 IF t #
|
|
|
|
|
- 1872 SymTab.InvalidType THEN
|
|
|
|
|
- 1873 SemError(230)
|
|
|
|
|
- 1874 END;
|
|
|
|
|
- 1875 QbeGen.CopyOp("0", q)
|
|
|
|
|
- 1876 END
|
|
|
|
|
- 1877 END
|
|
|
|
|
- 1878 ELSIF (k = SymTab.KindVar)
|
|
|
|
|
- 1879 OR (k = SymTab.KindParam) THEN
|
|
|
|
|
- 1880 cls :=
|
|
|
|
|
- 1881 SymTab.ClassOf(t);
|
|
|
|
|
- 1882 IF (cls = SymTab.ClInt)
|
|
|
|
|
- 1883 OR (cls = SymTab.ClBool)
|
|
|
|
|
- 1884 OR (cls = SymTab.ClChar)
|
|
|
|
|
- 1885 OR (cls = SymTab.ClUChar)
|
|
|
|
|
- 1886 OR (cls = SymTab.ClEnum)
|
|
|
|
|
- 1887 OR (cls
|
|
|
|
|
- 1888 = SymTab.ClReal) THEN
|
|
|
|
|
- 1889 QbeGen.LoadVar(n,
|
|
|
|
|
- 1890 cls = SymTab.ClReal, q)
|
|
|
|
|
- 1891 ELSIF (cls = SymTab.ClPtr)
|
|
|
|
|
- 1892 OR (cls = SymTab.ClProc) THEN
|
|
|
|
|
- 1893 QbeGen.LoadPtr(n, q)
|
|
|
|
|
- 1894 ELSIF cls = SymTab.ClLong THEN
|
|
|
|
|
- 1895 QbeGen.LoadLong(n, q)
|
|
|
|
|
- 1896 ELSIF (cls
|
|
|
|
|
- 1897 = SymTab.ClArray)
|
|
|
|
|
- 1898 OR (cls
|
|
|
|
|
- 1899 = SymTab.ClSet)
|
|
|
|
|
- 1900 OR (cls
|
|
|
|
|
- 1901 = SymTab.ClRecord)
|
|
|
|
|
- 1902 OR (cls
|
|
|
|
|
- 1903 = SymTab.ClUStr)
|
|
|
|
|
- 1904 OR (cls
|
|
|
|
|
- 1905 = SymTab.ClClass) THEN
|
|
|
|
|
- 1906 QbeGen.AddrOf(n, q)
|
|
|
|
|
- 1907 ELSE SemError(230);
|
|
|
|
|
- 1908 QbeGen.CopyOp("0", q)
|
|
|
|
|
- 1909 END
|
|
|
|
|
- 1910 ELSE QbeGen.CopyOp("0", q);
|
|
|
|
|
- 1911 IF k = SymTab.KindImport THEN
|
|
|
|
|
- 1912 SemError(230)
|
|
|
|
|
- 1913 ELSIF k =
|
|
|
|
|
- 1914 SymTab.KindProc THEN
|
|
|
|
|
- 1915 (* bare procedure name:
|
|
|
|
|
- 1916 a following ArgList
|
|
|
|
|
- 1917 makes it a call;
|
|
|
|
|
- 1918 otherwise Fact
|
|
|
|
|
- 1919 reports 230 *)
|
|
|
|
|
- 1920 ELSE
|
|
|
|
|
- 1921 IF k = SymTab.KindField THEN
|
|
|
|
|
- 1922 IF QbeGen.TopWith(qb) THEN
|
|
|
|
|
- 1923 fo :=
|
|
|
|
|
- 1924 SymTab.FieldOffset(
|
|
|
|
|
- 1925 SymTab.FieldOwner(n),
|
|
|
|
|
- 1926 n);
|
|
|
|
|
- 1927 QbeGen.FieldAddr(qb,
|
|
|
|
|
- 1928 fo, q);
|
|
|
|
|
- 1929 sfx := TRUE
|
|
|
|
|
- 1930 ELSE SemError(230);
|
|
|
|
|
- 1931 QbeGen.CopyOp("0", q)
|
|
|
|
|
- 1932 END
|
|
|
|
|
- 1933 END
|
|
|
|
|
- 1934 END
|
|
|
|
|
- 1935 END
|
|
|
|
|
- 1936 END; .)
|
|
|
|
|
- 1937 (. astDes := AST.MakeNode(AST.NkDesignator);
|
|
|
|
|
- 1938 AST.SetChild(astDes, AST.NChild(astDes), AST.MakeLeaf(AST.NkIdent, n)); .)
|
|
|
|
|
- 1939 { "[" Expr<it, iq>
|
|
|
|
|
- 1940 (. AST.SetChild(astDes, AST.NChild(astDes),
|
|
|
|
|
- 1941 AST.MakeUn(AST.NkSelector, AST.SelIndex, astCur)); IF t = SymTab.InvalidType THEN
|
|
|
|
|
- 1942 ELSIF SymTab.ClassOf(t) #
|
|
|
|
|
- 1943 SymTab.ClArray THEN
|
|
|
|
|
- 1944 SemError(217);
|
|
|
|
|
- 1945 t := SymTab.InvalidType
|
|
|
|
|
- 1946 ELSIF NOT SymTab.IsIntFamily(it)
|
|
|
|
|
- 1947 AND (SymTab.ClassOf(it) #
|
|
|
|
|
- 1948 SymTab.ClChar)
|
|
|
|
|
- 1949 AND (SymTab.ClassOf(it) #
|
|
|
|
|
- 1950 SymTab.ClEnum) THEN
|
|
|
|
|
- 1951 SemError(218);
|
|
|
|
|
- 1952 t := SymTab.InvalidType
|
|
|
|
|
- 1953 ELSE
|
|
|
|
|
- 1954 QbeGen.WidenIndex(iq, ql);
|
|
|
|
|
- 1955 isOpen :=
|
|
|
|
|
- 1956 SymTab.IsOpenArray(t);
|
|
|
|
|
- 1957 IF isOpen THEN
|
|
|
|
|
- 1958 QbeGen.CopyOp("0", qlo);
|
|
|
|
|
- 1959 IF SymTab.IsCharArray(t)
|
|
|
|
|
- 1960 OR SymTab.IsUCharArray(t) THEN
|
|
|
|
|
- 1961 QbeGen.OpenHiChar(q, qhi)
|
|
|
|
|
- 1962 ELSE QbeGen.OpenHi(q, qhi)
|
|
|
|
|
- 1963 END
|
|
|
|
|
- 1964 ELSE
|
|
|
|
|
- 1965 lo := SymTab.ArrayLo(t);
|
|
|
|
|
- 1966 hi := SymTab.ArrayHi(t);
|
|
|
|
|
- 1967 IF SymTab.IsCharArray(t)
|
|
|
|
|
- 1968 OR SymTab.IsUCharArray(t) THEN
|
|
|
|
|
- 1969 hi := hi + 1
|
|
|
|
|
- 1970 END;
|
|
|
|
|
- 1971 QbeGen.IntStr(lo, qlo);
|
|
|
|
|
- 1972 QbeGen.IntStr(hi, qhi)
|
|
|
|
|
- 1973 END;
|
|
|
|
|
- 1974 QbeGen.CheckRange(ql, qlo,
|
|
|
|
|
- 1975 qhi);
|
|
|
|
|
- 1976 eT := SymTab.ArrayElem(t);
|
|
|
|
|
- 1977 QbeGen.ElemAddr(q, ql, qlo,
|
|
|
|
|
- 1978 t, qe);
|
|
|
|
|
- 1979 IF SymTab.ClassOf(eT) =
|
|
|
|
|
- 1980 SymTab.ClArray THEN
|
|
|
|
|
- 1981 QbeGen.ElemLoad(qe, eT, q)
|
|
|
|
|
- 1982 ELSE QbeGen.CopyOp(qe, q)
|
|
|
|
|
|
|
+ 1565 "UNTIL" Expr<t, q> (. IF NOT SymTab.BoolCheck(t) THEN
|
|
|
|
|
+ 1566 SemError(214) END;
|
|
|
|
|
+ 1567 QbeGen.Jnz(q, lEnd, lTop);
|
|
|
|
|
+ 1568 QbeGen.EmitLabel(lEnd); .) .
|
|
|
|
|
+ 1569 LoopStat (. VAR lTop, lEnd: QbeGen.QVal; .)
|
|
|
|
|
+ 1570 = "LOOP" (. QbeGen.NewLabel(lTop);
|
|
|
|
|
+ 1571 QbeGen.NewLabel(lEnd);
|
|
|
|
|
+ 1572 QbeGen.PushLoop(lEnd);
|
|
|
|
|
+ 1573 QbeGen.EmitLabel(lTop); .)
|
|
|
|
|
+ 1574 [ StatSeq ]
|
|
|
|
|
+ 1575 "END" (. QbeGen.Jmp(lTop);
|
|
|
|
|
+ 1576 QbeGen.PopLoop;
|
|
|
|
|
+ 1577 QbeGen.EmitLabel(lEnd); .) .
|
|
|
|
|
+ 1578 (* FOR with static-sign BY (literal, non-zero; 220 otherwise).
|
|
|
|
|
+ 1579 Runtime direction would need a compare-select; the literal
|
|
|
|
|
+ 1580 sign picks cslew/csegew at "DO" time. *)
|
|
|
|
|
+ 1581 ForStat (. VAR lv: SymTab.Name;
|
|
|
|
|
+ 1582 tlo, thi, tby:
|
|
|
|
|
+ 1583 SymTab.TypeIndex;
|
|
|
|
|
+ 1584 qlo, qhi, qby, qt, qk, qb:
|
|
|
|
|
+ 1585 QbeGen.QVal;
|
|
|
|
|
+ 1586 lTop, lBody, lEnd:
|
|
|
|
|
+ 1587 QbeGen.QVal;
|
|
|
|
|
+ 1588 by: INTEGER;
|
|
|
|
|
+ 1589 ok: BOOLEAN; .)
|
|
|
|
|
+ 1590 = "FOR" (. by := 1; .)
|
|
|
|
|
+ 1591 GetIdent<lv> (. ok := SymTab.Lookup(lv);
|
|
|
|
|
+ 1592 IF NOT ok THEN
|
|
|
|
|
+ 1593 SemError(201)
|
|
|
|
|
+ 1594 ELSIF (SymTab.SymKind(lv) #
|
|
|
|
|
+ 1595 SymTab.KindVar)
|
|
|
|
|
+ 1596 AND (SymTab.SymKind(lv) #
|
|
|
|
|
+ 1597 SymTab.KindParam) THEN
|
|
|
|
|
+ 1598 SemError(220); ok := FALSE
|
|
|
|
|
+ 1599 ELSIF NOT SymTab.IsIntFamily(
|
|
|
|
|
+ 1600 SymTab.SymType(lv)) THEN
|
|
|
|
|
+ 1601 SemError(220); ok := FALSE
|
|
|
|
|
+ 1602 END; .)
|
|
|
|
|
+ 1603 ":=" Expr<tlo, qlo> (. IF NOT SymTab.IsIntFamily(tlo) THEN
|
|
|
|
|
+ 1604 SemError(220); ok := FALSE
|
|
|
|
|
+ 1605 END; .)
|
|
|
|
|
+ 1606 "TO" Expr<thi, qhi> (. IF NOT SymTab.IsIntFamily(thi) THEN
|
|
|
|
|
+ 1607 SemError(220); ok := FALSE
|
|
|
|
|
+ 1608 END; .)
|
|
|
|
|
+ 1609 [ "BY" Expr<tby, qby> (. IF (tby #
|
|
|
|
|
+ 1610 SymTab.InvalidType)
|
|
|
|
|
+ 1611 AND NOT SymTab.IsIntFamily(tby) THEN
|
|
|
|
|
+ 1612 SemError(220); ok := FALSE
|
|
|
|
|
+ 1613 END;
|
|
|
|
|
+ 1614 IF NOT SymTab.ConstInt(qby, by) THEN
|
|
|
|
|
+ 1615 SemError(230); by := 1
|
|
|
|
|
+ 1616 ELSIF by = 0 THEN
|
|
|
|
|
+ 1617 SemError(220); by := 1
|
|
|
|
|
+ 1618 END; .) ]
|
|
|
|
|
+ 1619 "DO" (. IF ok THEN
|
|
|
|
|
+ 1620 QbeGen.StoreVar(lv, qlo,
|
|
|
|
|
+ 1621 FALSE) END;
|
|
|
|
|
+ 1622 QbeGen.NewLabel(lTop);
|
|
|
|
|
+ 1623 QbeGen.NewLabel(lBody);
|
|
|
|
|
+ 1624 QbeGen.NewLabel(lEnd);
|
|
|
|
|
+ 1625 QbeGen.EmitLabel(lTop);
|
|
|
|
|
+ 1626 QbeGen.LoadVar(lv, FALSE, qt);
|
|
|
|
|
+ 1627 QbeGen.NewTemp(qk);
|
|
|
|
|
+ 1628 IF by > 0 THEN
|
|
|
|
|
+ 1629 QbeGen.Op3("cslew", qk,
|
|
|
|
|
+ 1630 qt, qhi, FALSE)
|
|
|
|
|
+ 1631 ELSE QbeGen.Op3("csgew", qk,
|
|
|
|
|
+ 1632 qt, qhi, FALSE)
|
|
|
|
|
+ 1633 END;
|
|
|
|
|
+ 1634 QbeGen.Jnz(qk, lBody, lEnd);
|
|
|
|
|
+ 1635 QbeGen.EmitLabel(lBody); .)
|
|
|
|
|
+ 1636 [ StatSeq ]
|
|
|
|
|
+ 1637 "END" (. IF ok THEN
|
|
|
|
|
+ 1638 QbeGen.LoadVar(lv, FALSE,
|
|
|
|
|
+ 1639 qt);
|
|
|
|
|
+ 1640 QbeGen.IntStr(by, qb);
|
|
|
|
|
+ 1641 QbeGen.NewTemp(qk);
|
|
|
|
|
+ 1642 QbeGen.Op3("add", qk,
|
|
|
|
|
+ 1643 qt, qb, FALSE);
|
|
|
|
|
+ 1644 QbeGen.StoreVar(lv, qk,
|
|
|
|
|
+ 1645 FALSE) END;
|
|
|
|
|
+ 1646 QbeGen.Jmp(lTop);
|
|
|
|
|
+ 1647 QbeGen.EmitLabel(lEnd); .) .
|
|
|
|
|
+ 1648 CaseStat (. VAR tsel: SymTab.TypeIndex;
|
|
|
|
|
+ 1649 qsel, lEnd: QbeGen.QVal; .)
|
|
|
|
|
+ 1650 = "CASE" Expr<tsel, qsel> (. QbeGen.NewLabel(lEnd); .)
|
|
|
|
|
+ 1651 "OF" CaseAlt<tsel, qsel, lEnd>
|
|
|
|
|
+ 1652 { "|" CaseAlt<tsel, qsel, lEnd> }
|
|
|
|
|
+ 1653 [ "ELSE" [ StatSeq ] ]
|
|
|
|
|
+ 1654 "END" (. QbeGen.EmitLabel(lEnd); .) .
|
|
|
|
|
+ 1655 (* Compare-chain lowering: each alternative ends its match-tests
|
|
|
|
|
+ 1656 with "jmp lAfter", so the no-match fallthrough skips the body:
|
|
|
|
|
+ 1657 "cmp; jnz(lBody,lF); lF: ... ; jmp lAfter; lBody: S; jmp lEnd;
|
|
|
|
|
+ 1658 lAfter:". Falls into the next alternative, ELSE, or END. *)
|
|
|
|
|
+ 1659 CaseAlt<tsel: SymTab.TypeIndex; qsel: QbeGen.QVal;
|
|
|
|
|
+ 1660 lEnd: QbeGen.QVal> (. VAR lBody, lAfter: QbeGen.QVal; .)
|
|
|
|
|
+ 1661 = (. QbeGen.NewLabel(lBody);
|
|
|
|
|
+ 1662 QbeGen.NewLabel(lAfter); .)
|
|
|
|
|
+ 1663 CaseLabel<tsel, qsel, lBody>
|
|
|
|
|
+ 1664 { "," CaseLabel<tsel, qsel, lBody> }
|
|
|
|
|
+ 1665 ":" (. QbeGen.Jmp(lAfter);
|
|
|
|
|
+ 1666 QbeGen.EmitLabel(lBody); .)
|
|
|
|
|
+ 1667 [ StatSeq ] (. QbeGen.Jmp(lEnd);
|
|
|
|
|
+ 1668 QbeGen.EmitLabel(lAfter); .) .
|
|
|
|
|
+ 1669 CaseLabel<tsel: SymTab.TypeIndex; qsel: QbeGen.QVal;
|
|
|
|
|
+ 1670 lBody: QbeGen.QVal> (. VAR t2, t3: SymTab.TypeIndex;
|
|
|
|
|
+ 1671 q2, q3, qc, qd, qe:
|
|
|
|
|
+ 1672 QbeGen.QVal;
|
|
|
|
|
+ 1673 lNext: QbeGen.QVal; .)
|
|
|
|
|
+ 1674 = Expr<t2, q2> (. IF (t2 #
|
|
|
|
|
+ 1675 SymTab.InvalidType)
|
|
|
|
|
+ 1676 AND (tsel #
|
|
|
|
|
+ 1677 SymTab.InvalidType)
|
|
|
|
|
+ 1678 AND ((SymTab.ClassOf(t2) =
|
|
|
|
|
+ 1679 SymTab.ClSet)
|
|
|
|
|
+ 1680 OR (SymTab.ClassOf(tsel) =
|
|
|
|
|
+ 1681 SymTab.ClSet)) THEN
|
|
|
|
|
+ 1682 SemError(230)
|
|
|
|
|
+ 1683 ELSIF (t2 #
|
|
|
|
|
+ 1684 SymTab.InvalidType)
|
|
|
|
|
+ 1685 AND (tsel #
|
|
|
|
|
+ 1686 SymTab.InvalidType)
|
|
|
|
|
+ 1687 AND NOT SymTab.EqCheck(t2,
|
|
|
|
|
+ 1688 tsel) THEN
|
|
|
|
|
+ 1689 SemError(213) END;
|
|
|
|
|
+ 1690 IF NOT QbeGen.IsImm(q2) THEN
|
|
|
|
|
+ 1691 SemError(230);
|
|
|
|
|
+ 1692 QbeGen.CopyOp("0", q2)
|
|
|
|
|
+ 1693 END;
|
|
|
|
|
+ 1694 QbeGen.NewLabel(lNext);
|
|
|
|
|
+ 1695 QbeGen.Cmp(SymTab.OpEq,
|
|
|
|
|
+ 1696 qsel, q2, qc, FALSE);
|
|
|
|
|
+ 1697 QbeGen.Jnz(qc, lBody, lNext);
|
|
|
|
|
+ 1698 QbeGen.EmitLabel(lNext); .)
|
|
|
|
|
+ 1699 [ ".." Expr<t3, q3> (. IF (t3 #
|
|
|
|
|
+ 1700 SymTab.InvalidType)
|
|
|
|
|
+ 1701 AND (tsel #
|
|
|
|
|
+ 1702 SymTab.InvalidType)
|
|
|
|
|
+ 1703 AND NOT SymTab.EqCheck(t3,
|
|
|
|
|
+ 1704 tsel) THEN
|
|
|
|
|
+ 1705 SemError(213) END;
|
|
|
|
|
+ 1706 IF NOT QbeGen.IsImm(q3) THEN
|
|
|
|
|
+ 1707 SemError(230);
|
|
|
|
|
+ 1708 QbeGen.CopyOp("0", q3)
|
|
|
|
|
+ 1709 END;
|
|
|
|
|
+ 1710 QbeGen.Cmp(SymTab.OpGe,
|
|
|
|
|
+ 1711 qsel, q2, qc, FALSE);
|
|
|
|
|
+ 1712 QbeGen.Cmp(SymTab.OpLe,
|
|
|
|
|
+ 1713 qsel, q3, qd, FALSE);
|
|
|
|
|
+ 1714 QbeGen.NewTemp(qe);
|
|
|
|
|
+ 1715 QbeGen.Op3("and", qe, qc, qd,
|
|
|
|
|
+ 1716 FALSE);
|
|
|
|
|
+ 1717 QbeGen.NewLabel(lNext);
|
|
|
|
|
+ 1718 QbeGen.Jnz(qe, lBody, lNext);
|
|
|
|
|
+ 1719 QbeGen.EmitLabel(lNext); .) ] .
|
|
|
|
|
+ 1720 ReturnStat (. VAR t: SymTab.TypeIndex;
|
|
|
|
|
+ 1721 q, qt: QbeGen.QVal;
|
|
|
|
|
+ 1722 res: SymTab.TypeIndex;
|
|
|
|
|
+ 1723 hadE, conv: BOOLEAN; .)
|
|
|
|
|
+ 1724 = "RETURN" (. hadE := FALSE; .)
|
|
|
|
|
+ 1725 [ Expr<t, q> (. hadE := TRUE; .) ]
|
|
|
|
|
+ 1726 (. conv := FALSE;
|
|
|
|
|
+ 1727 IF NOT SymTab.InProc() THEN
|
|
|
|
|
+ 1728 SemError(232)
|
|
|
|
|
+ 1729 ELSE res := SymTab.CurRes();
|
|
|
|
|
+ 1730 IF NOT hadE THEN
|
|
|
|
|
+ 1731 IF res #
|
|
|
|
|
+ 1732 SymTab.InvalidType THEN
|
|
|
|
|
+ 1733 SemError(232)
|
|
|
|
|
+ 1734 ELSE QbeGen.EmitRet(q,
|
|
|
|
|
+ 1735 FALSE)
|
|
|
|
|
+ 1736 END
|
|
|
|
|
+ 1737 ELSIF (res =
|
|
|
|
|
+ 1738 SymTab.InvalidType)
|
|
|
|
|
+ 1739 OR (t #
|
|
|
|
|
+ 1740 SymTab.InvalidType)
|
|
|
|
|
+ 1741 AND NOT SymTab.Assignable(t,
|
|
|
|
|
+ 1742 res) THEN
|
|
|
|
|
+ 1743 SemError(232)
|
|
|
|
|
+ 1744 ELSE
|
|
|
|
|
+ 1745 conv := (SymTab.ClassOf(
|
|
|
|
|
+ 1746 res) = SymTab.ClReal)
|
|
|
|
|
+ 1747 AND SymTab.IsIntFamily(t);
|
|
|
|
|
+ 1748 IF conv THEN
|
|
|
|
|
+ 1749 QbeGen.ConvIR(q, qt);
|
|
|
|
|
+ 1750 QbeGen.EmitRet(qt, TRUE)
|
|
|
|
|
+ 1751 ELSE QbeGen.EmitRet(q, TRUE)
|
|
|
|
|
+ 1752 END
|
|
|
|
|
+ 1753 END
|
|
|
|
|
+ 1754 END; .) .
|
|
|
|
|
+ 1755 HaltStat (. VAR t: SymTab.TypeIndex;
|
|
|
|
|
+ 1756 q: QbeGen.QVal; .)
|
|
|
|
|
+ 1757 = "HALT" [ "(" Expr<t, q> ")" ] (. QbeGen.HaltQ; .) .
|
|
|
|
|
+ 1758 (* Designator: scalar loads, array addresses, and index suffixes.
|
|
|
|
|
+ 1759 Each index descends one level (bounds-checked, trap on breach);
|
|
|
|
|
+ 1760 nested levels reload the inner descriptor address. q ends as the
|
|
|
|
|
+ 1761 value (scalars), the descriptor address (plain arrays), or the
|
|
|
|
|
+ 1762 element address (indexed); sfx marks the indexed form. *)
|
|
|
|
|
+ 1763 Design<VAR t: SymTab.TypeIndex; VAR k: INTEGER;
|
|
|
|
|
+ 1764 VAR q: QbeGen.QVal; VAR qn: SymTab.Name; VAR sfx: BOOLEAN>
|
|
|
|
|
+ 1765 (. VAR n, fn, mal: SymTab.Name;
|
|
|
|
|
+ 1766 cls: INTEGER;
|
|
|
|
|
+ 1767 ic: SymTab.TypeIndex;
|
|
|
|
|
+ 1768 curT, it, eT, bt:
|
|
|
|
|
+ 1769 SymTab.TypeIndex;
|
|
|
|
|
+ 1770 iq, ql, qlo, qhi, qe:
|
|
|
|
|
+ 1771 QbeGen.QVal;
|
|
|
|
|
+ 1772 lo, hi: INTEGER;
|
|
|
|
|
+ 1773 fo: INTEGER;
|
|
|
|
|
+ 1774 isOpen: BOOLEAN;
|
|
|
|
|
+ 1775 qb, cv: QbeGen.QVal;
|
|
|
|
|
+ 1776 fid, fref, slot: INTEGER;
|
|
|
|
|
+ 1777 r: BOOLEAN;
|
|
|
|
|
+ 1778 astDes, astSel: AST.Node; .)
|
|
|
|
|
+ 1779 = GetIdent<n> (. methCls := SymTab.InvalidType;
|
|
|
|
|
+ 1780 QbeGen.CopyOp(n, qn);
|
|
|
|
|
+ 1781 sfx := FALSE;
|
|
|
|
|
+ 1782 fid := 0; fref := 0; slot := 0;
|
|
|
|
|
+ 1783 IF NOT SymTab.Lookup(n) THEN
|
|
|
|
|
+ 1784 (* a bare method name inside
|
|
|
|
|
+ 1785 a CLASS IMPLEMENTATION
|
|
|
|
|
+ 1786 is a sibling call on
|
|
|
|
|
+ 1787 THIS *)
|
|
|
|
|
+ 1788 ic := SymTab.CurImplClass();
|
|
|
|
|
+ 1789 IF (ic #
|
|
|
|
|
+ 1790 SymTab.InvalidType)
|
|
|
|
|
+ 1791 AND SymTab.MethodExists(ic, n) THEN
|
|
|
|
|
+ 1792 sfx := FALSE;
|
|
|
|
|
+ 1793 QbeGen.ThisBase(q);
|
|
|
|
|
+ 1794 QbeGen.ArmRecv(q);
|
|
|
|
|
+ 1795 methCls := ic;
|
|
|
|
|
+ 1796 k := SymTab.KindProc;
|
|
|
|
|
+ 1797 t := SymTab.InvalidType
|
|
|
|
|
+ 1798 ELSIF SymTab.InProc() THEN
|
|
|
|
|
+ 1799 (* not declared yet: a
|
|
|
|
|
+ 1800 forward reference to a
|
|
|
|
|
+ 1801 module-level variable
|
|
|
|
|
+ 1802 declared further down. *)
|
|
|
|
|
+ 1803 k := SymTab.KindVar;
|
|
|
|
|
+ 1804 r := SymTab.FwdVarRef(n, k,
|
|
|
|
|
+ 1805 fref, t);
|
|
|
|
|
+ 1806 slot := QbeGen.FwdDesignator();
|
|
|
|
|
+ 1807 FwdVarNote(fref, slot);
|
|
|
|
|
+ 1808 fid := slot;
|
|
|
|
|
+ 1809 QbeGen.FwdAddrOper(fid, q);
|
|
|
|
|
+ 1810 sfx := TRUE
|
|
|
|
|
+ 1811 ELSE
|
|
|
|
|
+ 1812 SemError(201);
|
|
|
|
|
+ 1813 t :=
|
|
|
|
|
+ 1814 SymTab.InvalidType;
|
|
|
|
|
+ 1815 k := -1;
|
|
|
|
|
+ 1816 QbeGen.CopyOp("0", q)
|
|
|
|
|
+ 1817 END
|
|
|
|
|
+ 1818 ELSE
|
|
|
|
|
+ 1819 t := SymTab.SymType(n);
|
|
|
|
|
+ 1820 k := SymTab.SymKind(n);
|
|
|
|
|
+ 1821 IF k = SymTab.KindConst THEN
|
|
|
|
|
+ 1822 IF SymTab.Equal(n,
|
|
|
|
|
+ 1823 "TRUE") THEN
|
|
|
|
|
+ 1824 t := SymTab.BoolType();
|
|
|
|
|
+ 1825 QbeGen.CopyOp("1", q)
|
|
|
|
|
+ 1826 ELSIF SymTab.Equal(n,
|
|
|
|
|
+ 1827 "FALSE") THEN
|
|
|
|
|
+ 1828 t := SymTab.BoolType();
|
|
|
|
|
+ 1829 QbeGen.CopyOp("0", q)
|
|
|
|
|
+ 1830 ELSIF SymTab.Equal(n,
|
|
|
|
|
+ 1831 "NIL") THEN
|
|
|
|
|
+ 1832 QbeGen.CopyOp("0", q)
|
|
|
|
|
+ 1833 ELSE
|
|
|
|
|
+ 1834 cls :=
|
|
|
|
|
+ 1835 SymTab.ClassOf(t);
|
|
|
|
|
+ 1836 IF (t #
|
|
|
|
|
+ 1837 SymTab.InvalidType)
|
|
|
|
|
+ 1838 AND ((cls = SymTab.ClInt)
|
|
|
|
|
+ 1839 OR (cls
|
|
|
|
|
+ 1840 = SymTab.ClChar)
|
|
|
|
|
+ 1841 OR (cls
|
|
|
|
|
+ 1842 = SymTab.ClEnum)
|
|
|
|
|
+ 1843 OR (cls
|
|
|
|
|
+ 1844 = SymTab.ClReal)
|
|
|
|
|
+ 1845 OR (cls
|
|
|
|
|
+ 1846 = SymTab.ClLong)
|
|
|
|
|
+ 1847 OR (cls
|
|
|
|
|
+ 1848 = SymTab.ClNil)) THEN
|
|
|
|
|
+ 1849 IF cls = SymTab.ClNil THEN
|
|
|
|
|
+ 1850 QbeGen.CopyOp("0", q)
|
|
|
|
|
+ 1851 ELSIF ((cls
|
|
|
|
|
+ 1852 = SymTab.ClInt)
|
|
|
|
|
+ 1853 OR (cls
|
|
|
|
|
+ 1854 = SymTab.ClChar)
|
|
|
|
|
+ 1855 OR (cls
|
|
|
|
|
+ 1856 = SymTab.ClEnum)
|
|
|
|
|
+ 1857 OR (cls
|
|
|
|
|
+ 1858 = SymTab.ClLong))
|
|
|
|
|
+ 1859 AND SymTab.GetSymVal(n, cv)
|
|
|
|
|
+ 1860 AND QbeGen.IsImm(cv) THEN
|
|
|
|
|
+ 1861 QbeGen.CopyOp(cv, q)
|
|
|
|
|
+ 1862 ELSE
|
|
|
|
|
+ 1863 QbeGen.LoadVar(n,
|
|
|
|
|
+ 1864 cls = SymTab.ClReal,
|
|
|
|
|
+ 1865 q)
|
|
|
|
|
+ 1866 END
|
|
|
|
|
+ 1867 ELSIF (cls = SymTab.ClArray)
|
|
|
|
|
+ 1868 OR (cls = SymTab.ClRecord)
|
|
|
|
|
+ 1869 OR (cls = SymTab.ClClass)
|
|
|
|
|
+ 1870 OR (cls = SymTab.ClStr)
|
|
|
|
|
+ 1871 OR (cls = SymTab.ClUStr) THEN
|
|
|
|
|
+ 1872 (* aggregate constant:
|
|
|
|
|
+ 1873 its value IS the
|
|
|
|
|
+ 1874 descriptor address *)
|
|
|
|
|
+ 1875 IF SymTab.GetSymVal(n, cv) THEN
|
|
|
|
|
+ 1876 QbeGen.CopyOp(cv, q)
|
|
|
|
|
+ 1877 ELSE
|
|
|
|
|
+ 1878 QbeGen.CopyOp("0", q)
|
|
|
|
|
+ 1879 END
|
|
|
|
|
+ 1880 ELSE
|
|
|
|
|
+ 1881 IF t #
|
|
|
|
|
+ 1882 SymTab.InvalidType THEN
|
|
|
|
|
+ 1883 SemError(230)
|
|
|
|
|
+ 1884 END;
|
|
|
|
|
+ 1885 QbeGen.CopyOp("0", q)
|
|
|
|
|
+ 1886 END
|
|
|
|
|
+ 1887 END
|
|
|
|
|
+ 1888 ELSIF (k = SymTab.KindVar)
|
|
|
|
|
+ 1889 OR (k = SymTab.KindParam) THEN
|
|
|
|
|
+ 1890 cls :=
|
|
|
|
|
+ 1891 SymTab.ClassOf(t);
|
|
|
|
|
+ 1892 IF (cls = SymTab.ClInt)
|
|
|
|
|
+ 1893 OR (cls = SymTab.ClBool)
|
|
|
|
|
+ 1894 OR (cls = SymTab.ClChar)
|
|
|
|
|
+ 1895 OR (cls = SymTab.ClUChar)
|
|
|
|
|
+ 1896 OR (cls = SymTab.ClEnum)
|
|
|
|
|
+ 1897 OR (cls
|
|
|
|
|
+ 1898 = SymTab.ClReal) THEN
|
|
|
|
|
+ 1899 QbeGen.LoadVar(n,
|
|
|
|
|
+ 1900 cls = SymTab.ClReal, q)
|
|
|
|
|
+ 1901 ELSIF (cls = SymTab.ClPtr)
|
|
|
|
|
+ 1902 OR (cls = SymTab.ClProc) THEN
|
|
|
|
|
+ 1903 QbeGen.LoadPtr(n, q)
|
|
|
|
|
+ 1904 ELSIF cls = SymTab.ClLong THEN
|
|
|
|
|
+ 1905 QbeGen.LoadLong(n, q)
|
|
|
|
|
+ 1906 ELSIF (cls
|
|
|
|
|
+ 1907 = SymTab.ClArray)
|
|
|
|
|
+ 1908 OR (cls
|
|
|
|
|
+ 1909 = SymTab.ClSet)
|
|
|
|
|
+ 1910 OR (cls
|
|
|
|
|
+ 1911 = SymTab.ClRecord)
|
|
|
|
|
+ 1912 OR (cls
|
|
|
|
|
+ 1913 = SymTab.ClUStr)
|
|
|
|
|
+ 1914 OR (cls
|
|
|
|
|
+ 1915 = SymTab.ClClass) THEN
|
|
|
|
|
+ 1916 QbeGen.AddrOf(n, q)
|
|
|
|
|
+ 1917 ELSE SemError(230);
|
|
|
|
|
+ 1918 QbeGen.CopyOp("0", q)
|
|
|
|
|
+ 1919 END
|
|
|
|
|
+ 1920 ELSE QbeGen.CopyOp("0", q);
|
|
|
|
|
+ 1921 IF k = SymTab.KindImport THEN
|
|
|
|
|
+ 1922 SemError(230)
|
|
|
|
|
+ 1923 ELSIF k =
|
|
|
|
|
+ 1924 SymTab.KindProc THEN
|
|
|
|
|
+ 1925 (* bare procedure name:
|
|
|
|
|
+ 1926 a following ArgList
|
|
|
|
|
+ 1927 makes it a call;
|
|
|
|
|
+ 1928 otherwise Fact
|
|
|
|
|
+ 1929 reports 230 *)
|
|
|
|
|
+ 1930 ELSE
|
|
|
|
|
+ 1931 IF k = SymTab.KindField THEN
|
|
|
|
|
+ 1932 IF QbeGen.TopWith(qb) THEN
|
|
|
|
|
+ 1933 fo :=
|
|
|
|
|
+ 1934 SymTab.FieldOffset(
|
|
|
|
|
+ 1935 SymTab.FieldOwner(n),
|
|
|
|
|
+ 1936 n);
|
|
|
|
|
+ 1937 QbeGen.FieldAddr(qb,
|
|
|
|
|
+ 1938 fo, q);
|
|
|
|
|
+ 1939 sfx := TRUE
|
|
|
|
|
+ 1940 ELSE SemError(230);
|
|
|
|
|
+ 1941 QbeGen.CopyOp("0", q)
|
|
|
|
|
+ 1942 END
|
|
|
|
|
+ 1943 END
|
|
|
|
|
+ 1944 END
|
|
|
|
|
+ 1945 END
|
|
|
|
|
+ 1946 END; .)
|
|
|
|
|
+ 1947 (. astDes := AST.MakeNode(AST.NkDesignator);
|
|
|
|
|
+ 1948 AST.SetChild(astDes, AST.NChild(astDes), AST.MakeLeaf(AST.NkIdent, n)); .)
|
|
|
|
|
+ 1949 { "[" Expr<it, iq>
|
|
|
|
|
+ 1950 (. AST.SetChild(astDes, AST.NChild(astDes),
|
|
|
|
|
+ 1951 AST.MakeUn(AST.NkSelector, AST.SelIndex, astCur)); IF t = SymTab.InvalidType THEN
|
|
|
|
|
+ 1952 ELSIF SymTab.ClassOf(t) #
|
|
|
|
|
+ 1953 SymTab.ClArray THEN
|
|
|
|
|
+ 1954 SemError(217);
|
|
|
|
|
+ 1955 t := SymTab.InvalidType
|
|
|
|
|
+ 1956 ELSIF NOT SymTab.IsIntFamily(it)
|
|
|
|
|
+ 1957 AND (SymTab.ClassOf(it) #
|
|
|
|
|
+ 1958 SymTab.ClChar)
|
|
|
|
|
+ 1959 AND (SymTab.ClassOf(it) #
|
|
|
|
|
+ 1960 SymTab.ClEnum) THEN
|
|
|
|
|
+ 1961 SemError(218);
|
|
|
|
|
+ 1962 t := SymTab.InvalidType
|
|
|
|
|
+ 1963 ELSE
|
|
|
|
|
+ 1964 QbeGen.WidenIndex(iq, ql);
|
|
|
|
|
+ 1965 isOpen :=
|
|
|
|
|
+ 1966 SymTab.IsOpenArray(t);
|
|
|
|
|
+ 1967 IF isOpen THEN
|
|
|
|
|
+ 1968 QbeGen.CopyOp("0", qlo);
|
|
|
|
|
+ 1969 IF SymTab.IsCharArray(t)
|
|
|
|
|
+ 1970 OR SymTab.IsUCharArray(t) THEN
|
|
|
|
|
+ 1971 QbeGen.OpenHiChar(q, qhi)
|
|
|
|
|
+ 1972 ELSE QbeGen.OpenHi(q, qhi)
|
|
|
|
|
+ 1973 END
|
|
|
|
|
+ 1974 ELSE
|
|
|
|
|
+ 1975 lo := SymTab.ArrayLo(t);
|
|
|
|
|
+ 1976 hi := SymTab.ArrayHi(t);
|
|
|
|
|
+ 1977 IF SymTab.IsCharArray(t)
|
|
|
|
|
+ 1978 OR SymTab.IsUCharArray(t) THEN
|
|
|
|
|
+ 1979 hi := hi + 1
|
|
|
|
|
+ 1980 END;
|
|
|
|
|
+ 1981 QbeGen.IntStr(lo, qlo);
|
|
|
|
|
+ 1982 QbeGen.IntStr(hi, qhi)
|
|
|
1983 END;
|
|
1983 END;
|
|
|
- 1984 t := eT; sfx := TRUE
|
|
|
|
|
- 1985 END; .)
|
|
|
|
|
- 1986 { "," Expr<it, iq>
|
|
|
|
|
- 1987 (. AST.SetChild(astDes, AST.NChild(astDes),
|
|
|
|
|
- 1988 AST.MakeUn(AST.NkSelector, AST.SelIndex, astCur)); IF t = SymTab.InvalidType THEN
|
|
|
|
|
- 1989 ELSIF SymTab.ClassOf(t) #
|
|
|
|
|
- 1990 SymTab.ClArray THEN
|
|
|
|
|
- 1991 SemError(217);
|
|
|
|
|
- 1992 t := SymTab.InvalidType
|
|
|
|
|
- 1993 ELSIF NOT SymTab.IsIntFamily(it)
|
|
|
|
|
- 1994 AND (SymTab.ClassOf(it) #
|
|
|
|
|
- 1995 SymTab.ClChar)
|
|
|
|
|
- 1996 AND (SymTab.ClassOf(it) #
|
|
|
|
|
- 1997 SymTab.ClEnum) THEN
|
|
|
|
|
- 1998 SemError(218);
|
|
|
|
|
- 1999 t := SymTab.InvalidType
|
|
|
|
|
- 2000 ELSE
|
|
|
|
|
- 2001 QbeGen.WidenIndex(iq, ql);
|
|
|
|
|
- 2002 isOpen :=
|
|
|
|
|
- 2003 SymTab.IsOpenArray(t);
|
|
|
|
|
- 2004 IF isOpen THEN
|
|
|
|
|
- 2005 QbeGen.CopyOp("0", qlo);
|
|
|
|
|
- 2006 IF SymTab.IsCharArray(t)
|
|
|
|
|
- 2007 OR SymTab.IsUCharArray(t) THEN
|
|
|
|
|
- 2008 QbeGen.OpenHiChar(q, qhi)
|
|
|
|
|
- 2009 ELSE QbeGen.OpenHi(q, qhi)
|
|
|
|
|
- 2010 END
|
|
|
|
|
- 2011 ELSE
|
|
|
|
|
- 2012 lo := SymTab.ArrayLo(t);
|
|
|
|
|
- 2013 hi := SymTab.ArrayHi(t);
|
|
|
|
|
- 2014 IF SymTab.IsCharArray(t)
|
|
|
|
|
- 2015 OR SymTab.IsUCharArray(t) THEN
|
|
|
|
|
- 2016 hi := hi + 1
|
|
|
|
|
- 2017 END;
|
|
|
|
|
- 2018 QbeGen.IntStr(lo, qlo);
|
|
|
|
|
- 2019 QbeGen.IntStr(hi, qhi)
|
|
|
|
|
- 2020 END;
|
|
|
|
|
- 2021 QbeGen.CheckRange(ql, qlo,
|
|
|
|
|
- 2022 qhi);
|
|
|
|
|
- 2023 eT := SymTab.ArrayElem(t);
|
|
|
|
|
- 2024 QbeGen.ElemAddr(q, ql, qlo,
|
|
|
|
|
- 2025 t, qe);
|
|
|
|
|
- 2026 IF SymTab.ClassOf(eT) =
|
|
|
|
|
- 2027 SymTab.ClArray THEN
|
|
|
|
|
- 2028 QbeGen.ElemLoad(qe, eT, q)
|
|
|
|
|
- 2029 ELSE QbeGen.CopyOp(qe, q)
|
|
|
|
|
|
|
+ 1984 QbeGen.CheckRange(ql, qlo,
|
|
|
|
|
+ 1985 qhi);
|
|
|
|
|
+ 1986 eT := SymTab.ArrayElem(t);
|
|
|
|
|
+ 1987 QbeGen.ElemAddr(q, ql, qlo,
|
|
|
|
|
+ 1988 t, qe);
|
|
|
|
|
+ 1989 IF SymTab.ClassOf(eT) =
|
|
|
|
|
+ 1990 SymTab.ClArray THEN
|
|
|
|
|
+ 1991 QbeGen.ElemLoad(qe, eT, q)
|
|
|
|
|
+ 1992 ELSE QbeGen.CopyOp(qe, q)
|
|
|
|
|
+ 1993 END;
|
|
|
|
|
+ 1994 t := eT; sfx := TRUE
|
|
|
|
|
+ 1995 END; .)
|
|
|
|
|
+ 1996 { "," Expr<it, iq>
|
|
|
|
|
+ 1997 (. AST.SetChild(astDes, AST.NChild(astDes),
|
|
|
|
|
+ 1998 AST.MakeUn(AST.NkSelector, AST.SelIndex, astCur)); IF t = SymTab.InvalidType THEN
|
|
|
|
|
+ 1999 ELSIF SymTab.ClassOf(t) #
|
|
|
|
|
+ 2000 SymTab.ClArray THEN
|
|
|
|
|
+ 2001 SemError(217);
|
|
|
|
|
+ 2002 t := SymTab.InvalidType
|
|
|
|
|
+ 2003 ELSIF NOT SymTab.IsIntFamily(it)
|
|
|
|
|
+ 2004 AND (SymTab.ClassOf(it) #
|
|
|
|
|
+ 2005 SymTab.ClChar)
|
|
|
|
|
+ 2006 AND (SymTab.ClassOf(it) #
|
|
|
|
|
+ 2007 SymTab.ClEnum) THEN
|
|
|
|
|
+ 2008 SemError(218);
|
|
|
|
|
+ 2009 t := SymTab.InvalidType
|
|
|
|
|
+ 2010 ELSE
|
|
|
|
|
+ 2011 QbeGen.WidenIndex(iq, ql);
|
|
|
|
|
+ 2012 isOpen :=
|
|
|
|
|
+ 2013 SymTab.IsOpenArray(t);
|
|
|
|
|
+ 2014 IF isOpen THEN
|
|
|
|
|
+ 2015 QbeGen.CopyOp("0", qlo);
|
|
|
|
|
+ 2016 IF SymTab.IsCharArray(t)
|
|
|
|
|
+ 2017 OR SymTab.IsUCharArray(t) THEN
|
|
|
|
|
+ 2018 QbeGen.OpenHiChar(q, qhi)
|
|
|
|
|
+ 2019 ELSE QbeGen.OpenHi(q, qhi)
|
|
|
|
|
+ 2020 END
|
|
|
|
|
+ 2021 ELSE
|
|
|
|
|
+ 2022 lo := SymTab.ArrayLo(t);
|
|
|
|
|
+ 2023 hi := SymTab.ArrayHi(t);
|
|
|
|
|
+ 2024 IF SymTab.IsCharArray(t)
|
|
|
|
|
+ 2025 OR SymTab.IsUCharArray(t) THEN
|
|
|
|
|
+ 2026 hi := hi + 1
|
|
|
|
|
+ 2027 END;
|
|
|
|
|
+ 2028 QbeGen.IntStr(lo, qlo);
|
|
|
|
|
+ 2029 QbeGen.IntStr(hi, qhi)
|
|
|
2030 END;
|
|
2030 END;
|
|
|
- 2031 t := eT; sfx := TRUE
|
|
|
|
|
- 2032 END; .) }
|
|
|
|
|
- 2033 "]"
|
|
|
|
|
- 2034 | "." GetIdent<fn>
|
|
|
|
|
- 2035 (. astSel := AST.MakeNode(AST.NkSelector);
|
|
|
|
|
- 2036 AST.SetOp(astSel, AST.SelField);
|
|
|
|
|
- 2037 AST.SetChild(astSel, 0, AST.MakeLeaf(AST.NkIdent, fn));
|
|
|
|
|
- 2038 AST.SetChild(astDes, AST.NChild(astDes), astSel); IF k = SymTab.KindModule THEN
|
|
|
|
|
- 2039 (* qualified L.x: materialize
|
|
|
|
|
- 2040 the export, then load it *)
|
|
|
|
|
- 2041 IF NOT SymTab.MaterializeAlias(n,
|
|
|
|
|
- 2042 fn, mal) THEN
|
|
|
|
|
- 2043 SemError(201);
|
|
|
|
|
- 2044 t := SymTab.InvalidType;
|
|
|
|
|
- 2045 QbeGen.CopyOp("0", q)
|
|
|
|
|
- 2046 ELSE
|
|
|
|
|
- 2047 QbeGen.CopyOp(mal, qn);
|
|
|
|
|
- 2048 t := SymTab.SymType(mal);
|
|
|
|
|
- 2049 k := SymTab.SymKind(mal);
|
|
|
|
|
- 2050 sfx := FALSE;
|
|
|
|
|
- 2051 IF k = SymTab.KindProc THEN
|
|
|
|
|
- 2052 (* call: ArgList supplies
|
|
|
|
|
- 2053 the value *)
|
|
|
|
|
- 2054 QbeGen.CopyOp("0", q)
|
|
|
|
|
- 2055 ELSIF NOT QbeGen.LoadDesignator(
|
|
|
|
|
- 2056 mal, t, k, q) THEN
|
|
|
|
|
- 2057 SemError(230);
|
|
|
|
|
- 2058 QbeGen.CopyOp("0", q)
|
|
|
|
|
- 2059 END
|
|
|
|
|
- 2060 END
|
|
|
|
|
- 2061 ELSIF t = SymTab.InvalidType THEN
|
|
|
|
|
- 2062 ELSIF (SymTab.ClassOf(t) #
|
|
|
|
|
- 2063 SymTab.ClRecord)
|
|
|
|
|
- 2064 AND (SymTab.ClassOf(t) #
|
|
|
|
|
- 2065 SymTab.ClClass) THEN
|
|
|
|
|
- 2066 SemError(215);
|
|
|
|
|
- 2067 t := SymTab.InvalidType
|
|
|
|
|
- 2068 ELSIF (SymTab.ClassOf(t) =
|
|
|
|
|
- 2069 SymTab.ClClass)
|
|
|
|
|
- 2070 AND SymTab.MethodExists(t, fn) THEN
|
|
|
|
|
- 2071 (* obj.Method: bind the
|
|
|
|
|
- 2072 method and pass obj as
|
|
|
|
|
- 2073 the hidden receiver; q
|
|
|
|
|
- 2074 already holds the
|
|
|
|
|
- 2075 object's address *)
|
|
|
|
|
- 2076 QbeGen.ArmRecv(q);
|
|
|
|
|
- 2077 QbeGen.CopyOp(fn, n);
|
|
|
|
|
- 2078 QbeGen.CopyOp(fn, qn);
|
|
|
|
|
- 2079 methCls := t;
|
|
|
|
|
- 2080 k := SymTab.KindProc;
|
|
|
|
|
- 2081 t := SymTab.InvalidType
|
|
|
|
|
- 2082 ELSIF NOT SymTab.FieldExists(t,
|
|
|
|
|
- 2083 fn) THEN
|
|
|
|
|
- 2084 SemError(216);
|
|
|
|
|
- 2085 t := SymTab.InvalidType
|
|
|
|
|
- 2086 ELSE
|
|
|
|
|
- 2087 fo := SymTab.FieldOffset(t,
|
|
|
|
|
- 2088 fn);
|
|
|
|
|
- 2089 t := SymTab.FieldType(t, fn);
|
|
|
|
|
- 2090 QbeGen.FieldAddr(q, fo, qe);
|
|
|
|
|
- 2091 (* array fields are inline:
|
|
|
|
|
- 2092 the field address is the
|
|
|
|
|
- 2093 descriptor, like records *)
|
|
|
|
|
- 2094 QbeGen.CopyOp(qe, q);
|
|
|
|
|
- 2095 sfx := TRUE
|
|
|
|
|
- 2096 END; .)
|
|
|
|
|
- 2097 | "^"
|
|
|
|
|
- 2098 (. astSel := AST.MakeNode(AST.NkSelector);
|
|
|
|
|
- 2099 AST.SetOp(astSel, AST.SelDeref);
|
|
|
|
|
- 2100 AST.SetChild(astDes, AST.NChild(astDes), astSel); IF t = SymTab.InvalidType THEN
|
|
|
|
|
- 2101 ELSIF SymTab.ClassOf(t) #
|
|
|
|
|
- 2102 SymTab.ClPtr THEN
|
|
|
|
|
- 2103 SemError(219);
|
|
|
|
|
- 2104 t := SymTab.InvalidType
|
|
|
|
|
- 2105 ELSE
|
|
|
|
|
- 2106 bt := SymTab.PtrBase(t);
|
|
|
|
|
- 2107 IF bt = SymTab.InvalidType THEN
|
|
|
|
|
- 2108 ELSE
|
|
|
|
|
- 2109 IF sfx THEN
|
|
|
|
|
- 2110 QbeGen.ElemLoad(q, t,
|
|
|
|
|
- 2111 qb);
|
|
|
|
|
- 2112 QbeGen.CopyOp(qb, q)
|
|
|
|
|
- 2113 END;
|
|
|
|
|
- 2114 t := bt;
|
|
|
|
|
- 2115 (* q holds the pointee
|
|
|
|
|
- 2116 address: Fact loads
|
|
|
|
|
- 2117 scalars/pointers and uses
|
|
|
|
|
- 2118 the address for
|
|
|
|
|
- 2119 aggregates; the VAR-actual
|
|
|
|
|
- 2120 note is q itself. *)
|
|
|
|
|
- 2121 sfx := TRUE
|
|
|
|
|
- 2122 END
|
|
|
|
|
- 2123 END; .) } (. astCur := astDes; .) .
|
|
|
|
|
- 2124 (* Result suffix (ISO component after a function call): `F()^`,
|
|
|
|
|
- 2125 `F()[i]`, `F().field`. The call result is in t/q with sfx FALSE
|
|
|
|
|
- 2126 (a value, or a descriptor address for aggregates); each component
|
|
|
|
|
- 2127 descends one level exactly like the Design components. *)
|
|
|
|
|
- 2128 ResultComp<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal;
|
|
|
|
|
- 2129 VAR sfx: BOOLEAN> (. VAR it, eT, bt: SymTab.TypeIndex;
|
|
|
|
|
- 2130 iq, ql, qlo, qhi, qe, qb:
|
|
|
|
|
- 2131 QbeGen.QVal;
|
|
|
|
|
- 2132 lo, hi, fo: INTEGER;
|
|
|
|
|
- 2133 isOpen: BOOLEAN;
|
|
|
|
|
- 2134 fname: SymTab.Name; .)
|
|
|
|
|
- 2135 = "[" Expr<it, iq>
|
|
|
|
|
- 2136 (. IF t = SymTab.InvalidType THEN
|
|
|
|
|
- 2137 ELSIF SymTab.ClassOf(t) #
|
|
|
|
|
- 2138 SymTab.ClArray THEN
|
|
|
|
|
- 2139 SemError(217);
|
|
|
|
|
- 2140 t := SymTab.InvalidType
|
|
|
|
|
- 2141 ELSIF NOT SymTab.IsIntFamily(it)
|
|
|
|
|
- 2142 AND (SymTab.ClassOf(it) # SymTab.ClChar)
|
|
|
|
|
- 2143 AND (SymTab.ClassOf(it) # SymTab.ClEnum) THEN
|
|
|
|
|
- 2144 SemError(218);
|
|
|
|
|
- 2145 t := SymTab.InvalidType
|
|
|
|
|
- 2146 ELSE
|
|
|
|
|
- 2147 QbeGen.WidenIndex(iq, ql);
|
|
|
|
|
- 2148 isOpen :=
|
|
|
|
|
- 2149 SymTab.IsOpenArray(t);
|
|
|
|
|
- 2150 IF isOpen THEN
|
|
|
|
|
- 2151 QbeGen.CopyOp("0", qlo);
|
|
|
|
|
- 2152 IF SymTab.IsCharArray(t)
|
|
|
|
|
- 2153 OR SymTab.IsUCharArray(t) THEN
|
|
|
|
|
- 2154 QbeGen.OpenHiChar(q, qhi)
|
|
|
|
|
- 2155 ELSE QbeGen.OpenHi(q, qhi)
|
|
|
|
|
- 2156 END
|
|
|
|
|
- 2157 ELSE
|
|
|
|
|
- 2158 lo := SymTab.ArrayLo(t);
|
|
|
|
|
- 2159 hi := SymTab.ArrayHi(t);
|
|
|
|
|
- 2160 IF SymTab.IsCharArray(t)
|
|
|
|
|
- 2161 OR SymTab.IsUCharArray(t) THEN
|
|
|
|
|
- 2162 hi := hi + 1
|
|
|
|
|
- 2163 END;
|
|
|
|
|
- 2164 QbeGen.IntStr(lo, qlo);
|
|
|
|
|
- 2165 QbeGen.IntStr(hi, qhi)
|
|
|
|
|
- 2166 END;
|
|
|
|
|
- 2167 QbeGen.CheckRange(ql, qlo,
|
|
|
|
|
- 2168 qhi);
|
|
|
|
|
- 2169 eT := SymTab.ArrayElem(t);
|
|
|
|
|
- 2170 QbeGen.ElemAddr(q, ql, qlo,
|
|
|
|
|
- 2171 t, qe);
|
|
|
|
|
- 2172 IF SymTab.ClassOf(eT) =
|
|
|
|
|
- 2173 SymTab.ClArray THEN
|
|
|
|
|
- 2174 QbeGen.ElemLoad(qe, eT, q)
|
|
|
|
|
- 2175 ELSE QbeGen.CopyOp(qe, q)
|
|
|
|
|
|
|
+ 2031 QbeGen.CheckRange(ql, qlo,
|
|
|
|
|
+ 2032 qhi);
|
|
|
|
|
+ 2033 eT := SymTab.ArrayElem(t);
|
|
|
|
|
+ 2034 QbeGen.ElemAddr(q, ql, qlo,
|
|
|
|
|
+ 2035 t, qe);
|
|
|
|
|
+ 2036 IF SymTab.ClassOf(eT) =
|
|
|
|
|
+ 2037 SymTab.ClArray THEN
|
|
|
|
|
+ 2038 QbeGen.ElemLoad(qe, eT, q)
|
|
|
|
|
+ 2039 ELSE QbeGen.CopyOp(qe, q)
|
|
|
|
|
+ 2040 END;
|
|
|
|
|
+ 2041 t := eT; sfx := TRUE
|
|
|
|
|
+ 2042 END; .) }
|
|
|
|
|
+ 2043 "]"
|
|
|
|
|
+ 2044 | "." GetIdent<fn>
|
|
|
|
|
+ 2045 (. astSel := AST.MakeNode(AST.NkSelector);
|
|
|
|
|
+ 2046 AST.SetOp(astSel, AST.SelField);
|
|
|
|
|
+ 2047 AST.SetChild(astSel, 0, AST.MakeLeaf(AST.NkIdent, fn));
|
|
|
|
|
+ 2048 AST.SetChild(astDes, AST.NChild(astDes), astSel); IF k = SymTab.KindModule THEN
|
|
|
|
|
+ 2049 (* qualified L.x: materialize
|
|
|
|
|
+ 2050 the export, then load it *)
|
|
|
|
|
+ 2051 IF NOT SymTab.MaterializeAlias(n,
|
|
|
|
|
+ 2052 fn, mal) THEN
|
|
|
|
|
+ 2053 SemError(201);
|
|
|
|
|
+ 2054 t := SymTab.InvalidType;
|
|
|
|
|
+ 2055 QbeGen.CopyOp("0", q)
|
|
|
|
|
+ 2056 ELSE
|
|
|
|
|
+ 2057 QbeGen.CopyOp(mal, qn);
|
|
|
|
|
+ 2058 t := SymTab.SymType(mal);
|
|
|
|
|
+ 2059 k := SymTab.SymKind(mal);
|
|
|
|
|
+ 2060 sfx := FALSE;
|
|
|
|
|
+ 2061 IF k = SymTab.KindProc THEN
|
|
|
|
|
+ 2062 (* call: ArgList supplies
|
|
|
|
|
+ 2063 the value *)
|
|
|
|
|
+ 2064 QbeGen.CopyOp("0", q)
|
|
|
|
|
+ 2065 ELSIF NOT QbeGen.LoadDesignator(
|
|
|
|
|
+ 2066 mal, t, k, q) THEN
|
|
|
|
|
+ 2067 SemError(230);
|
|
|
|
|
+ 2068 QbeGen.CopyOp("0", q)
|
|
|
|
|
+ 2069 END
|
|
|
|
|
+ 2070 END
|
|
|
|
|
+ 2071 ELSIF t = SymTab.InvalidType THEN
|
|
|
|
|
+ 2072 ELSIF (SymTab.ClassOf(t) #
|
|
|
|
|
+ 2073 SymTab.ClRecord)
|
|
|
|
|
+ 2074 AND (SymTab.ClassOf(t) #
|
|
|
|
|
+ 2075 SymTab.ClClass) THEN
|
|
|
|
|
+ 2076 SemError(215);
|
|
|
|
|
+ 2077 t := SymTab.InvalidType
|
|
|
|
|
+ 2078 ELSIF (SymTab.ClassOf(t) =
|
|
|
|
|
+ 2079 SymTab.ClClass)
|
|
|
|
|
+ 2080 AND SymTab.MethodExists(t, fn) THEN
|
|
|
|
|
+ 2081 (* obj.Method: bind the
|
|
|
|
|
+ 2082 method and pass obj as
|
|
|
|
|
+ 2083 the hidden receiver; q
|
|
|
|
|
+ 2084 already holds the
|
|
|
|
|
+ 2085 object's address *)
|
|
|
|
|
+ 2086 QbeGen.ArmRecv(q);
|
|
|
|
|
+ 2087 QbeGen.CopyOp(fn, n);
|
|
|
|
|
+ 2088 QbeGen.CopyOp(fn, qn);
|
|
|
|
|
+ 2089 methCls := t;
|
|
|
|
|
+ 2090 k := SymTab.KindProc;
|
|
|
|
|
+ 2091 t := SymTab.InvalidType
|
|
|
|
|
+ 2092 ELSIF NOT SymTab.FieldExists(t,
|
|
|
|
|
+ 2093 fn) THEN
|
|
|
|
|
+ 2094 SemError(216);
|
|
|
|
|
+ 2095 t := SymTab.InvalidType
|
|
|
|
|
+ 2096 ELSE
|
|
|
|
|
+ 2097 fo := SymTab.FieldOffset(t,
|
|
|
|
|
+ 2098 fn);
|
|
|
|
|
+ 2099 t := SymTab.FieldType(t, fn);
|
|
|
|
|
+ 2100 QbeGen.FieldAddr(q, fo, qe);
|
|
|
|
|
+ 2101 (* array fields are inline:
|
|
|
|
|
+ 2102 the field address is the
|
|
|
|
|
+ 2103 descriptor, like records *)
|
|
|
|
|
+ 2104 QbeGen.CopyOp(qe, q);
|
|
|
|
|
+ 2105 sfx := TRUE
|
|
|
|
|
+ 2106 END; .)
|
|
|
|
|
+ 2107 | "^"
|
|
|
|
|
+ 2108 (. astSel := AST.MakeNode(AST.NkSelector);
|
|
|
|
|
+ 2109 AST.SetOp(astSel, AST.SelDeref);
|
|
|
|
|
+ 2110 AST.SetChild(astDes, AST.NChild(astDes), astSel); IF t = SymTab.InvalidType THEN
|
|
|
|
|
+ 2111 ELSIF SymTab.ClassOf(t) #
|
|
|
|
|
+ 2112 SymTab.ClPtr THEN
|
|
|
|
|
+ 2113 SemError(219);
|
|
|
|
|
+ 2114 t := SymTab.InvalidType
|
|
|
|
|
+ 2115 ELSE
|
|
|
|
|
+ 2116 bt := SymTab.PtrBase(t);
|
|
|
|
|
+ 2117 IF bt = SymTab.InvalidType THEN
|
|
|
|
|
+ 2118 ELSE
|
|
|
|
|
+ 2119 IF sfx THEN
|
|
|
|
|
+ 2120 QbeGen.ElemLoad(q, t,
|
|
|
|
|
+ 2121 qb);
|
|
|
|
|
+ 2122 QbeGen.CopyOp(qb, q)
|
|
|
|
|
+ 2123 END;
|
|
|
|
|
+ 2124 t := bt;
|
|
|
|
|
+ 2125 (* q holds the pointee
|
|
|
|
|
+ 2126 address: Fact loads
|
|
|
|
|
+ 2127 scalars/pointers and uses
|
|
|
|
|
+ 2128 the address for
|
|
|
|
|
+ 2129 aggregates; the VAR-actual
|
|
|
|
|
+ 2130 note is q itself. *)
|
|
|
|
|
+ 2131 sfx := TRUE
|
|
|
|
|
+ 2132 END
|
|
|
|
|
+ 2133 END; .) } (. astCur := astDes; .) .
|
|
|
|
|
+ 2134 (* Result suffix (ISO component after a function call): `F()^`,
|
|
|
|
|
+ 2135 `F()[i]`, `F().field`. The call result is in t/q with sfx FALSE
|
|
|
|
|
+ 2136 (a value, or a descriptor address for aggregates); each component
|
|
|
|
|
+ 2137 descends one level exactly like the Design components. *)
|
|
|
|
|
+ 2138 ResultComp<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal;
|
|
|
|
|
+ 2139 VAR sfx: BOOLEAN> (. VAR it, eT, bt: SymTab.TypeIndex;
|
|
|
|
|
+ 2140 iq, ql, qlo, qhi, qe, qb:
|
|
|
|
|
+ 2141 QbeGen.QVal;
|
|
|
|
|
+ 2142 lo, hi, fo: INTEGER;
|
|
|
|
|
+ 2143 isOpen: BOOLEAN;
|
|
|
|
|
+ 2144 fname: SymTab.Name; .)
|
|
|
|
|
+ 2145 = "[" Expr<it, iq>
|
|
|
|
|
+ 2146 (. IF t = SymTab.InvalidType THEN
|
|
|
|
|
+ 2147 ELSIF SymTab.ClassOf(t) #
|
|
|
|
|
+ 2148 SymTab.ClArray THEN
|
|
|
|
|
+ 2149 SemError(217);
|
|
|
|
|
+ 2150 t := SymTab.InvalidType
|
|
|
|
|
+ 2151 ELSIF NOT SymTab.IsIntFamily(it)
|
|
|
|
|
+ 2152 AND (SymTab.ClassOf(it) # SymTab.ClChar)
|
|
|
|
|
+ 2153 AND (SymTab.ClassOf(it) # SymTab.ClEnum) THEN
|
|
|
|
|
+ 2154 SemError(218);
|
|
|
|
|
+ 2155 t := SymTab.InvalidType
|
|
|
|
|
+ 2156 ELSE
|
|
|
|
|
+ 2157 QbeGen.WidenIndex(iq, ql);
|
|
|
|
|
+ 2158 isOpen :=
|
|
|
|
|
+ 2159 SymTab.IsOpenArray(t);
|
|
|
|
|
+ 2160 IF isOpen THEN
|
|
|
|
|
+ 2161 QbeGen.CopyOp("0", qlo);
|
|
|
|
|
+ 2162 IF SymTab.IsCharArray(t)
|
|
|
|
|
+ 2163 OR SymTab.IsUCharArray(t) THEN
|
|
|
|
|
+ 2164 QbeGen.OpenHiChar(q, qhi)
|
|
|
|
|
+ 2165 ELSE QbeGen.OpenHi(q, qhi)
|
|
|
|
|
+ 2166 END
|
|
|
|
|
+ 2167 ELSE
|
|
|
|
|
+ 2168 lo := SymTab.ArrayLo(t);
|
|
|
|
|
+ 2169 hi := SymTab.ArrayHi(t);
|
|
|
|
|
+ 2170 IF SymTab.IsCharArray(t)
|
|
|
|
|
+ 2171 OR SymTab.IsUCharArray(t) THEN
|
|
|
|
|
+ 2172 hi := hi + 1
|
|
|
|
|
+ 2173 END;
|
|
|
|
|
+ 2174 QbeGen.IntStr(lo, qlo);
|
|
|
|
|
+ 2175 QbeGen.IntStr(hi, qhi)
|
|
|
2176 END;
|
|
2176 END;
|
|
|
- 2177 t := eT; sfx := TRUE
|
|
|
|
|
- 2178 END; .)
|
|
|
|
|
- 2179 "]"
|
|
|
|
|
- 2180 | "." GetIdent<fname>
|
|
|
|
|
- 2181 (. IF t = SymTab.InvalidType THEN
|
|
|
|
|
- 2182 ELSIF (SymTab.ClassOf(t) #
|
|
|
|
|
- 2183 SymTab.ClRecord)
|
|
|
|
|
- 2184 AND (SymTab.ClassOf(t) # SymTab.ClClass) THEN
|
|
|
|
|
- 2185 SemError(215);
|
|
|
|
|
- 2186 t := SymTab.InvalidType
|
|
|
|
|
- 2187 ELSIF NOT SymTab.FieldExists(t,
|
|
|
|
|
- 2188 fname) THEN
|
|
|
|
|
- 2189 SemError(216);
|
|
|
|
|
- 2190 t := SymTab.InvalidType
|
|
|
|
|
- 2191 ELSE
|
|
|
|
|
- 2192 fo := SymTab.FieldOffset(t,
|
|
|
|
|
- 2193 fname);
|
|
|
|
|
- 2194 t := SymTab.FieldType(t, fname);
|
|
|
|
|
- 2195 QbeGen.FieldAddr(q, fo, qe);
|
|
|
|
|
- 2196 QbeGen.CopyOp(qe, q);
|
|
|
|
|
- 2197 sfx := TRUE
|
|
|
|
|
- 2198 END; .)
|
|
|
|
|
- 2199 | "^" (. IF t = SymTab.InvalidType THEN
|
|
|
|
|
- 2200 ELSIF SymTab.ClassOf(t) #
|
|
|
|
|
- 2201 SymTab.ClPtr THEN
|
|
|
|
|
- 2202 SemError(219);
|
|
|
|
|
- 2203 t := SymTab.InvalidType
|
|
|
|
|
- 2204 ELSE
|
|
|
|
|
- 2205 bt := SymTab.PtrBase(t);
|
|
|
|
|
- 2206 IF bt # SymTab.InvalidType THEN
|
|
|
|
|
- 2207 IF sfx THEN
|
|
|
|
|
- 2208 QbeGen.ElemLoad(q, t, qb);
|
|
|
|
|
- 2209 QbeGen.CopyOp(qb, q)
|
|
|
|
|
- 2210 END;
|
|
|
|
|
- 2211 t := bt; sfx := TRUE
|
|
|
|
|
- 2212 END
|
|
|
|
|
- 2213 END; .) .
|
|
|
|
|
- 2214 Expr<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
|
|
- 2215 (. VAR t2: SymTab.TypeIndex;
|
|
|
|
|
- 2216 op: INTEGER;
|
|
|
|
|
- 2217 q2, qt, wl: QbeGen.QVal;
|
|
|
|
|
- 2218 astA, astB: AST.Node;
|
|
|
|
|
- 2219 astOp: INTEGER;
|
|
|
|
|
- 2220 astMade: BOOLEAN;
|
|
|
|
|
- 2221 isR: BOOLEAN; .)
|
|
|
|
|
- 2222 = SimExpr<t, q> (. astA := astCur; astMade := FALSE; .)
|
|
|
|
|
- 2223 [ Rel<op> SimExpr<t2, q2>
|
|
|
|
|
- 2224 (. astB := astCur; astMade := TRUE;
|
|
|
|
|
- 2225 astOp := AST.OpEq;
|
|
|
|
|
- 2226 IF op = SymTab.OpNeq1 THEN astOp := AST.OpNe
|
|
|
|
|
- 2227 ELSIF op = SymTab.OpNeq2 THEN astOp := AST.OpNe
|
|
|
|
|
- 2228 ELSIF op = SymTab.OpLt THEN astOp := AST.OpLt
|
|
|
|
|
- 2229 ELSIF op = SymTab.OpLe THEN astOp := AST.OpLe
|
|
|
|
|
- 2230 ELSIF op = SymTab.OpGt THEN astOp := AST.OpGt
|
|
|
|
|
- 2231 ELSIF op = SymTab.OpGe THEN astOp := AST.OpGe
|
|
|
|
|
- 2232 ELSIF op = SymTab.OpIn THEN astOp := AST.OpIn
|
|
|
|
|
- 2233 END;
|
|
|
|
|
- 2234 IF op = SymTab.OpIn THEN
|
|
|
|
|
- 2235 IF SymTab.InCheck(t, t2) THEN
|
|
|
|
|
- 2236 IF (t = SymTab.InvalidType)
|
|
|
|
|
- 2237 OR (t2 = SymTab.InvalidType) THEN
|
|
|
|
|
- 2238 t := SymTab.BoolType(); QbeGen.CopyOp("0", q)
|
|
|
|
|
- 2239 ELSE
|
|
|
|
|
- 2240 QbeGen.InSet(q, q2, SymTab.SetBaseLo(t2),
|
|
|
|
|
- 2241 SymTab.SetCount(t2), qt);
|
|
|
|
|
- 2242 t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
|
|
|
|
|
- 2243 END
|
|
|
|
|
- 2244 ELSE SemError(222); t := SymTab.InvalidType;
|
|
|
|
|
- 2245 QbeGen.CopyOp("0", q)
|
|
|
|
|
- 2246 END
|
|
|
|
|
- 2247 ELSIF SymTab.RelCheck(t, t2, op) THEN
|
|
|
|
|
- 2248 IF (t = SymTab.InvalidType)
|
|
|
|
|
- 2249 OR (t2 = SymTab.InvalidType) THEN
|
|
|
|
|
- 2250 t := SymTab.BoolType(); QbeGen.CopyOp("0", q)
|
|
|
|
|
- 2251 ELSIF (SymTab.ClassOf(t) = SymTab.ClPtr)
|
|
|
|
|
- 2252 OR (SymTab.ClassOf(t2) = SymTab.ClPtr) THEN
|
|
|
|
|
- 2253 IF SymTab.IsFwdVar(t) OR SymTab.IsFwdVar(t2) THEN
|
|
|
|
|
- 2254 QbeGen.Cmp(op, q, q2, qt, FALSE);
|
|
|
|
|
- 2255 t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
|
|
|
|
|
- 2256 ELSIF (op # SymTab.OpEq) AND (op # SymTab.OpNeq1)
|
|
|
|
|
- 2257 AND (op # SymTab.OpNeq2) THEN
|
|
|
|
|
- 2258 SemError(213); t := SymTab.InvalidType;
|
|
|
|
|
- 2259 QbeGen.CopyOp("0", q)
|
|
|
|
|
- 2260 ELSE
|
|
|
|
|
- 2261 QbeGen.CmpL(op, q, q2, qt);
|
|
|
|
|
- 2262 t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
|
|
|
|
|
- 2263 END
|
|
|
|
|
- 2264 ELSIF (SymTab.ClassOf(t) = SymTab.ClSet)
|
|
|
|
|
- 2265 OR (SymTab.ClassOf(t2) = SymTab.ClSet) THEN
|
|
|
|
|
- 2266 QbeGen.CmpSet(op, q, q2,
|
|
|
|
|
- 2267 SymTab.SetWords(t), SymTab.SetWords(t2), qt);
|
|
|
|
|
- 2268 t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
|
|
|
|
|
- 2269 ELSIF SymTab.StrCompat(t, t2) THEN
|
|
|
|
|
- 2270 QbeGen.StrEq(op, q, q2, qt);
|
|
|
|
|
- 2271 t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
|
|
|
|
|
- 2272 ELSIF SymTab.IsLongFamily(t)
|
|
|
|
|
- 2273 OR SymTab.IsLongFamily(t2) THEN
|
|
|
|
|
- 2274 IF SymTab.IsIntFamily(t) THEN
|
|
|
|
|
- 2275 QbeGen.WidenLong(q, wl); QbeGen.CopyOp(wl, q)
|
|
|
|
|
- 2276 END;
|
|
|
|
|
- 2277 IF SymTab.IsIntFamily(t2) THEN
|
|
|
|
|
- 2278 QbeGen.WidenLong(q2, wl); QbeGen.CopyOp(wl, q2)
|
|
|
|
|
- 2279 END;
|
|
|
|
|
- 2280 QbeGen.CmpLong(op, q, q2, qt);
|
|
|
|
|
|
|
+ 2177 QbeGen.CheckRange(ql, qlo,
|
|
|
|
|
+ 2178 qhi);
|
|
|
|
|
+ 2179 eT := SymTab.ArrayElem(t);
|
|
|
|
|
+ 2180 QbeGen.ElemAddr(q, ql, qlo,
|
|
|
|
|
+ 2181 t, qe);
|
|
|
|
|
+ 2182 IF SymTab.ClassOf(eT) =
|
|
|
|
|
+ 2183 SymTab.ClArray THEN
|
|
|
|
|
+ 2184 QbeGen.ElemLoad(qe, eT, q)
|
|
|
|
|
+ 2185 ELSE QbeGen.CopyOp(qe, q)
|
|
|
|
|
+ 2186 END;
|
|
|
|
|
+ 2187 t := eT; sfx := TRUE
|
|
|
|
|
+ 2188 END; .)
|
|
|
|
|
+ 2189 "]"
|
|
|
|
|
+ 2190 | "." GetIdent<fname>
|
|
|
|
|
+ 2191 (. IF t = SymTab.InvalidType THEN
|
|
|
|
|
+ 2192 ELSIF (SymTab.ClassOf(t) #
|
|
|
|
|
+ 2193 SymTab.ClRecord)
|
|
|
|
|
+ 2194 AND (SymTab.ClassOf(t) # SymTab.ClClass) THEN
|
|
|
|
|
+ 2195 SemError(215);
|
|
|
|
|
+ 2196 t := SymTab.InvalidType
|
|
|
|
|
+ 2197 ELSIF NOT SymTab.FieldExists(t,
|
|
|
|
|
+ 2198 fname) THEN
|
|
|
|
|
+ 2199 SemError(216);
|
|
|
|
|
+ 2200 t := SymTab.InvalidType
|
|
|
|
|
+ 2201 ELSE
|
|
|
|
|
+ 2202 fo := SymTab.FieldOffset(t,
|
|
|
|
|
+ 2203 fname);
|
|
|
|
|
+ 2204 t := SymTab.FieldType(t, fname);
|
|
|
|
|
+ 2205 QbeGen.FieldAddr(q, fo, qe);
|
|
|
|
|
+ 2206 QbeGen.CopyOp(qe, q);
|
|
|
|
|
+ 2207 sfx := TRUE
|
|
|
|
|
+ 2208 END; .)
|
|
|
|
|
+ 2209 | "^" (. IF t = SymTab.InvalidType THEN
|
|
|
|
|
+ 2210 ELSIF SymTab.ClassOf(t) #
|
|
|
|
|
+ 2211 SymTab.ClPtr THEN
|
|
|
|
|
+ 2212 SemError(219);
|
|
|
|
|
+ 2213 t := SymTab.InvalidType
|
|
|
|
|
+ 2214 ELSE
|
|
|
|
|
+ 2215 bt := SymTab.PtrBase(t);
|
|
|
|
|
+ 2216 IF bt # SymTab.InvalidType THEN
|
|
|
|
|
+ 2217 IF sfx THEN
|
|
|
|
|
+ 2218 QbeGen.ElemLoad(q, t, qb);
|
|
|
|
|
+ 2219 QbeGen.CopyOp(qb, q)
|
|
|
|
|
+ 2220 END;
|
|
|
|
|
+ 2221 t := bt; sfx := TRUE
|
|
|
|
|
+ 2222 END
|
|
|
|
|
+ 2223 END; .) .
|
|
|
|
|
+ 2224 Expr<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
|
|
+ 2225 (. VAR t2: SymTab.TypeIndex;
|
|
|
|
|
+ 2226 op: INTEGER;
|
|
|
|
|
+ 2227 q2, qt, wl: QbeGen.QVal;
|
|
|
|
|
+ 2228 astA, astB: AST.Node;
|
|
|
|
|
+ 2229 astOp: INTEGER;
|
|
|
|
|
+ 2230 astMade: BOOLEAN;
|
|
|
|
|
+ 2231 isR: BOOLEAN; .)
|
|
|
|
|
+ 2232 = SimExpr<t, q> (. astA := astCur; astMade := FALSE; .)
|
|
|
|
|
+ 2233 [ Rel<op> SimExpr<t2, q2>
|
|
|
|
|
+ 2234 (. astB := astCur; astMade := TRUE;
|
|
|
|
|
+ 2235 astOp := AST.OpEq;
|
|
|
|
|
+ 2236 IF op = SymTab.OpNeq1 THEN astOp := AST.OpNe
|
|
|
|
|
+ 2237 ELSIF op = SymTab.OpNeq2 THEN astOp := AST.OpNe
|
|
|
|
|
+ 2238 ELSIF op = SymTab.OpLt THEN astOp := AST.OpLt
|
|
|
|
|
+ 2239 ELSIF op = SymTab.OpLe THEN astOp := AST.OpLe
|
|
|
|
|
+ 2240 ELSIF op = SymTab.OpGt THEN astOp := AST.OpGt
|
|
|
|
|
+ 2241 ELSIF op = SymTab.OpGe THEN astOp := AST.OpGe
|
|
|
|
|
+ 2242 ELSIF op = SymTab.OpIn THEN astOp := AST.OpIn
|
|
|
|
|
+ 2243 END;
|
|
|
|
|
+ 2244 IF op = SymTab.OpIn THEN
|
|
|
|
|
+ 2245 IF SymTab.InCheck(t, t2) THEN
|
|
|
|
|
+ 2246 IF (t = SymTab.InvalidType)
|
|
|
|
|
+ 2247 OR (t2 = SymTab.InvalidType) THEN
|
|
|
|
|
+ 2248 t := SymTab.BoolType(); QbeGen.CopyOp("0", q)
|
|
|
|
|
+ 2249 ELSE
|
|
|
|
|
+ 2250 QbeGen.InSet(q, q2, SymTab.SetBaseLo(t2),
|
|
|
|
|
+ 2251 SymTab.SetCount(t2), qt);
|
|
|
|
|
+ 2252 t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
|
|
|
|
|
+ 2253 END
|
|
|
|
|
+ 2254 ELSE SemError(222); t := SymTab.InvalidType;
|
|
|
|
|
+ 2255 QbeGen.CopyOp("0", q)
|
|
|
|
|
+ 2256 END
|
|
|
|
|
+ 2257 ELSIF SymTab.RelCheck(t, t2, op) THEN
|
|
|
|
|
+ 2258 IF (t = SymTab.InvalidType)
|
|
|
|
|
+ 2259 OR (t2 = SymTab.InvalidType) THEN
|
|
|
|
|
+ 2260 t := SymTab.BoolType(); QbeGen.CopyOp("0", q)
|
|
|
|
|
+ 2261 ELSIF (SymTab.ClassOf(t) = SymTab.ClPtr)
|
|
|
|
|
+ 2262 OR (SymTab.ClassOf(t2) = SymTab.ClPtr) THEN
|
|
|
|
|
+ 2263 IF SymTab.IsFwdVar(t) OR SymTab.IsFwdVar(t2) THEN
|
|
|
|
|
+ 2264 QbeGen.Cmp(op, q, q2, qt, FALSE);
|
|
|
|
|
+ 2265 t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
|
|
|
|
|
+ 2266 ELSIF (op # SymTab.OpEq) AND (op # SymTab.OpNeq1)
|
|
|
|
|
+ 2267 AND (op # SymTab.OpNeq2) THEN
|
|
|
|
|
+ 2268 SemError(213); t := SymTab.InvalidType;
|
|
|
|
|
+ 2269 QbeGen.CopyOp("0", q)
|
|
|
|
|
+ 2270 ELSE
|
|
|
|
|
+ 2271 QbeGen.CmpL(op, q, q2, qt);
|
|
|
|
|
+ 2272 t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
|
|
|
|
|
+ 2273 END
|
|
|
|
|
+ 2274 ELSIF (SymTab.ClassOf(t) = SymTab.ClSet)
|
|
|
|
|
+ 2275 OR (SymTab.ClassOf(t2) = SymTab.ClSet) THEN
|
|
|
|
|
+ 2276 QbeGen.CmpSet(op, q, q2,
|
|
|
|
|
+ 2277 SymTab.SetWords(t), SymTab.SetWords(t2), qt);
|
|
|
|
|
+ 2278 t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
|
|
|
|
|
+ 2279 ELSIF SymTab.StrCompat(t, t2) THEN
|
|
|
|
|
+ 2280 QbeGen.StrEq(op, q, q2, qt);
|
|
|
2281 t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
|
|
2281 t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
|
|
|
- 2282 ELSE
|
|
|
|
|
- 2283 isR := SymTab.ClassOf(t) = SymTab.ClReal;
|
|
|
|
|
- 2284 t := SymTab.BoolType();
|
|
|
|
|
- 2285 QbeGen.Cmp(op, q, q2, qt, isR);
|
|
|
|
|
- 2286 QbeGen.CopyOp(qt, q)
|
|
|
|
|
- 2287 END
|
|
|
|
|
- 2288 ELSE SemError(213); t := SymTab.InvalidType;
|
|
|
|
|
- 2289 QbeGen.CopyOp("0", q)
|
|
|
|
|
- 2290 END;
|
|
|
|
|
- 2291 astCur := AST.MakeBin(AST.NkBinExpr, astOp, astA, astB); .) ]
|
|
|
|
|
- 2292 (. IF NOT astMade THEN astCur := astA END; .) .
|
|
|
|
|
- 2293 Rel<VAR op: INTEGER>
|
|
|
|
|
- 2294 = "=" (. op := SymTab.OpEq; .)
|
|
|
|
|
- 2295 | "#" (. op := SymTab.OpNeq1; .)
|
|
|
|
|
- 2296 | "<" (. op := SymTab.OpLt; .)
|
|
|
|
|
- 2297 | "<=" (. op := SymTab.OpLe; .)
|
|
|
|
|
- 2298 | ">" (. op := SymTab.OpGt; .)
|
|
|
|
|
- 2299 | ">=" (. op := SymTab.OpGe; .)
|
|
|
|
|
- 2300 | "IN" (. op := SymTab.OpIn; .) .
|
|
|
|
|
- 2301 SimExpr<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
|
|
- 2302 (. VAR t2, res2, lt, rt:
|
|
|
|
|
- 2303 SymTab.TypeIndex;
|
|
|
|
|
- 2304 op: INTEGER;
|
|
|
|
|
- 2305 q2, qt, wq, qf, q2a, q2b:
|
|
|
|
|
- 2306 QbeGen.QVal;
|
|
|
|
|
- 2307 neg, isR, isL, folded:
|
|
|
|
|
- 2308 BOOLEAN;
|
|
|
|
|
- 2309 fok: BOOLEAN;
|
|
|
|
|
- 2310 lw, rw, mw: CARDINAL;
|
|
|
|
|
- 2311 lTrue, lNext, lDone, qr, qs: QbeGen.QVal;
|
|
|
|
|
- 2312 astA, astB: AST.Node;
|
|
|
|
|
- 2313 astSign, astOp: INTEGER; .)
|
|
|
|
|
- 2314 = (. neg := FALSE; astSign := 0; .)
|
|
|
|
|
- 2315 [ "+" (. neg := TRUE; astSign := 1; .)
|
|
|
|
|
- 2316 | "-" (. neg := TRUE; astSign := -1; .) ]
|
|
|
|
|
- 2317 Term<t, q> (. astA := astCur; IF neg THEN
|
|
|
|
|
- 2318 IF QbeGen.IsImm(q) THEN
|
|
|
|
|
- 2319 QbeGen.NegFold(q, q)
|
|
|
|
|
- 2320 ELSE QbeGen.NewTemp(qt);
|
|
|
|
|
- 2321 QbeGen.NegQ(q, qt,
|
|
|
|
|
- 2322 SymTab.ClassOf(t)
|
|
|
|
|
- 2323 = SymTab.ClReal);
|
|
|
|
|
- 2324 QbeGen.CopyOp(qt, q)
|
|
|
|
|
- 2325 END
|
|
|
|
|
- 2326 END;
|
|
|
|
|
- 2327 IF astSign < 0 THEN
|
|
|
|
|
- 2328 astCur := AST.MakeUn(
|
|
|
|
|
- 2329 AST.NkUnary, AST.OpSub, astA);
|
|
|
|
|
- 2330 astA := astCur
|
|
|
|
|
- 2331 END; .)
|
|
|
|
|
- 2332 { AddOp<op> (. IF op = SymTab.OpOr THEN
|
|
|
|
|
- 2333 QbeGen.DelayBegin END; .)
|
|
|
|
|
- 2334 Term<t2, q2> (. astB := astCur; IF op = SymTab.OpOr THEN
|
|
|
|
|
- 2335 QbeGen.DelayEnd END; .)
|
|
|
|
|
- 2336 (. astOp := AST.OpAdd;
|
|
|
|
|
- 2337 IF op = SymTab.OpSub THEN astOp := AST.OpSub
|
|
|
|
|
- 2338 ELSIF op = SymTab.OpOr THEN astOp := AST.OpOr END;
|
|
|
|
|
- 2339 astA := AST.MakeBin(AST.NkBinExpr, astOp, astA, astB);
|
|
|
|
|
- 2340 astCur := astA;
|
|
|
|
|
- 2341 IF op = SymTab.OpOr THEN
|
|
|
|
|
- 2342 (* short-circuit: if q is true the RHS is skipped *)
|
|
|
|
|
- 2343 IF SymTab.BoolCheck(t) AND SymTab.BoolCheck(t2) THEN
|
|
|
|
|
- 2344 t := SymTab.BoolType()
|
|
|
|
|
- 2345 ELSE SemError(212); t := SymTab.InvalidType END;
|
|
|
|
|
- 2346 IF t # SymTab.InvalidType THEN
|
|
|
|
|
- 2347 QbeGen.Slot4(qs);
|
|
|
|
|
- 2348 QbeGen.NewLabel(lTrue);
|
|
|
|
|
- 2349 QbeGen.NewLabel(lNext);
|
|
|
|
|
- 2350 QbeGen.NewLabel(lDone);
|
|
|
|
|
- 2351 QbeGen.Jnz(q, lTrue, lNext);
|
|
|
|
|
- 2352 QbeGen.EmitLabel(lTrue);
|
|
|
|
|
- 2353 QbeGen.StoreW(qs, "1");
|
|
|
|
|
- 2354 QbeGen.Jmp(lDone);
|
|
|
|
|
- 2355 QbeGen.EmitLabel(lNext);
|
|
|
|
|
- 2356 QbeGen.DelayFlush;
|
|
|
|
|
- 2357 QbeGen.StoreW(qs, q2);
|
|
|
|
|
- 2358 QbeGen.Jmp(lDone);
|
|
|
|
|
- 2359 QbeGen.EmitLabel(lDone);
|
|
|
|
|
- 2360 QbeGen.LoadW(qs, qr);
|
|
|
|
|
- 2361 QbeGen.CopyOp(qr, q)
|
|
|
|
|
- 2362 ELSE QbeGen.DelayFlush; QbeGen.CopyOp("0", q)
|
|
|
|
|
- 2363 END
|
|
|
|
|
- 2364 ELSIF (op = SymTab.OpAdd)
|
|
|
|
|
- 2365 AND (SymTab.UStrCompat(t, t2)
|
|
|
|
|
- 2366 OR ((SymTab.ClassOf(t) = SymTab.ClUChar)
|
|
|
|
|
- 2367 AND (SymTab.ClassOf(t2) = SymTab.ClUStr))
|
|
|
|
|
- 2368 OR ((SymTab.ClassOf(t) = SymTab.ClUStr)
|
|
|
|
|
- 2369 AND (SymTab.ClassOf(t2) = SymTab.ClUChar))
|
|
|
|
|
- 2370 OR ((SymTab.ClassOf(t) = SymTab.ClUChar)
|
|
|
|
|
- 2371 AND (SymTab.ClassOf(t2) = SymTab.ClUChar))) THEN
|
|
|
|
|
- 2372 (* UString concatenation: a UCHAR operand becomes a
|
|
|
|
|
- 2373 1-codepoint UString; the result is a descriptor in the
|
|
|
|
|
- 2374 shim's concat buffer. Work on copies so neither
|
|
|
|
|
- 2375 operand is clobbered. *)
|
|
|
|
|
- 2376 IF SymTab.ClassOf(t) = SymTab.ClUStr THEN
|
|
|
|
|
- 2377 QbeGen.CopyOp(q, q2a)
|
|
|
|
|
- 2378 ELSE
|
|
|
|
|
- 2379 QbeGen.UStrFrom(q, q2a)
|
|
|
|
|
- 2380 END;
|
|
|
|
|
- 2381 IF SymTab.ClassOf(t2) = SymTab.ClUStr THEN
|
|
|
|
|
- 2382 QbeGen.UStrCat(q2a, q2, qt)
|
|
|
|
|
- 2383 ELSE
|
|
|
|
|
- 2384 QbeGen.UStrFrom(q2, q2b);
|
|
|
|
|
- 2385 QbeGen.UStrCat(q2a, q2b, qt)
|
|
|
|
|
- 2386 END;
|
|
|
|
|
- 2387 t := SymTab.NewUStr();
|
|
|
|
|
- 2388 QbeGen.CopyOp(qt, q)
|
|
|
|
|
- 2389 ELSIF (op = SymTab.OpAdd)
|
|
|
|
|
- 2390 AND (SymTab.StrCompat(t, t2)
|
|
|
|
|
- 2391 OR (SymTab.IsStrType(t)
|
|
|
|
|
- 2392 AND (SymTab.ClassOf(t2) = SymTab.ClChar))
|
|
|
|
|
- 2393 OR ((SymTab.ClassOf(t) = SymTab.ClChar)
|
|
|
|
|
- 2394 AND SymTab.IsStrType(t2))) THEN
|
|
|
|
|
- 2395 (* string concatenation; a CHAR operand becomes a
|
|
|
|
|
- 2396 1-character string literal. When both operands are
|
|
|
|
|
- 2397 constants, fold to a single string literal so a
|
|
|
|
|
- 2398 constructor element stays compile-time. *)
|
|
|
|
|
- 2399 QbeGen.StrFold(q, q2, SymTab.ClassOf(t), SymTab.ClassOf(t2),
|
|
|
|
|
- 2400 qt, fok);
|
|
|
|
|
- 2401 IF NOT fok THEN
|
|
|
|
|
- 2402 IF SymTab.StrCompat(t, t2) THEN
|
|
|
|
|
- 2403 QbeGen.StrCat(q, q2, qt)
|
|
|
|
|
- 2404 ELSIF SymTab.IsStrType(t) THEN
|
|
|
|
|
- 2405 QbeGen.DeclCharStr(q2, qs);
|
|
|
|
|
- 2406 QbeGen.StrCat(q, qs, qt)
|
|
|
|
|
- 2407 ELSE
|
|
|
|
|
- 2408 QbeGen.DeclCharStr(q, qs);
|
|
|
|
|
- 2409 QbeGen.StrCat(qs, q2, qt)
|
|
|
|
|
- 2410 END
|
|
|
|
|
- 2411 END;
|
|
|
|
|
- 2412 t := SymTab.NewStr();
|
|
|
|
|
- 2413 QbeGen.CopyOp(qt, q)
|
|
|
|
|
- 2414 ELSIF (t # SymTab.InvalidType) AND (t2 # SymTab.InvalidType)
|
|
|
|
|
- 2415 AND (SymTab.ClassOf(t) = SymTab.ClSet)
|
|
|
|
|
- 2416 AND (SymTab.ClassOf(t2) = SymTab.ClSet) THEN
|
|
|
|
|
- 2417 lw := SymTab.SetWords(t); rw := SymTab.SetWords(t2);
|
|
|
|
|
- 2418 mw := lw;
|
|
|
|
|
- 2419 IF rw > mw THEN mw := rw END;
|
|
|
|
|
- 2420 IF op = SymTab.OpAdd THEN
|
|
|
|
|
- 2421 QbeGen.SetBinOp(0, q, q2, lw, rw, qt)
|
|
|
|
|
- 2422 ELSE
|
|
|
|
|
- 2423 QbeGen.SetBinOp(2, q, q2, lw, rw, qt)
|
|
|
|
|
- 2424 END;
|
|
|
|
|
- 2425 t := SymTab.NewSet(
|
|
|
|
|
- 2426 SymTab.NewSubR(0,
|
|
|
|
|
- 2427 VAL(INTEGER, mw) * 32 - 1));
|
|
|
|
|
- 2428 QbeGen.CopyOp(qt, q)
|
|
|
|
|
- 2429 ELSE
|
|
|
|
|
- 2430 IF SymTab.ArithCheck(t, t2, FALSE, res2) THEN
|
|
|
|
|
- 2431 lt := t; rt := t2; t := res2
|
|
|
|
|
- 2432 ELSE SemError(211); t := SymTab.InvalidType END;
|
|
|
|
|
- 2433 IF t # SymTab.InvalidType THEN
|
|
|
|
|
- 2434 isL := SymTab.IsLongFamily(t);
|
|
|
|
|
- 2435 isR := SymTab.ClassOf(t) = SymTab.ClReal;
|
|
|
|
|
- 2436 folded := FALSE;
|
|
|
|
|
- 2437 IF (NOT isL) AND (NOT isR)
|
|
|
|
|
- 2438 AND QbeGen.IsImm(q) AND QbeGen.IsImm(q2) THEN
|
|
|
|
|
- 2439 IF op = SymTab.OpAdd THEN
|
|
|
|
|
- 2440 folded := QbeGen.Fold2(0, q, q2, qf)
|
|
|
|
|
- 2441 ELSE
|
|
|
|
|
- 2442 folded := QbeGen.Fold2(1, q, q2, qf)
|
|
|
|
|
- 2443 END
|
|
|
|
|
- 2444 END;
|
|
|
|
|
- 2445 IF folded THEN QbeGen.CopyOp(qf, q)
|
|
|
|
|
- 2446 ELSE
|
|
|
|
|
- 2447 IF isL THEN
|
|
|
|
|
- 2448 IF SymTab.IsIntFamily(lt) THEN
|
|
|
|
|
- 2449 QbeGen.WidenLong(q, wq); QbeGen.CopyOp(wq, q)
|
|
|
|
|
- 2450 END;
|
|
|
|
|
- 2451 IF SymTab.IsIntFamily(rt) THEN
|
|
|
|
|
- 2452 QbeGen.WidenLong(q2, wq); QbeGen.CopyOp(wq, q2)
|
|
|
|
|
- 2453 END;
|
|
|
|
|
- 2454 QbeGen.NewTemp(qt);
|
|
|
|
|
- 2455 IF op = SymTab.OpAdd THEN
|
|
|
|
|
- 2456 QbeGen.Op3L("add", qt, q, q2)
|
|
|
|
|
- 2457 ELSE
|
|
|
|
|
- 2458 QbeGen.Op3L("sub", qt, q, q2)
|
|
|
|
|
- 2459 END
|
|
|
|
|
- 2460 ELSE
|
|
|
|
|
- 2461 QbeGen.NewTemp(qt);
|
|
|
|
|
- 2462 IF op = SymTab.OpAdd THEN
|
|
|
|
|
- 2463 QbeGen.Op3("add", qt, q, q2, isR)
|
|
|
|
|
- 2464 ELSE
|
|
|
|
|
- 2465 QbeGen.Op3("sub", qt, q, q2, isR)
|
|
|
|
|
- 2466 END
|
|
|
|
|
- 2467 END;
|
|
|
|
|
- 2468 QbeGen.CopyOp(qt, q)
|
|
|
|
|
- 2469 END
|
|
|
|
|
- 2470 ELSE QbeGen.CopyOp("0", q)
|
|
|
|
|
- 2471 END
|
|
|
|
|
- 2472 END; .) } .
|
|
|
|
|
- 2473 AddOp<VAR op: INTEGER>
|
|
|
|
|
- 2474 = "+" (. op := SymTab.OpAdd; .)
|
|
|
|
|
- 2475 | "-" (. op := SymTab.OpSub; .)
|
|
|
|
|
- 2476 | "OR" (. op := SymTab.OpOr; .) .
|
|
|
|
|
- 2477 Term<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
|
|
- 2478 (. VAR t2, res2, lt, rt:
|
|
|
|
|
- 2479 SymTab.TypeIndex;
|
|
|
|
|
- 2480 op: INTEGER;
|
|
|
|
|
- 2481 q2, qt, wq, qf:
|
|
|
|
|
- 2482 QbeGen.QVal;
|
|
|
|
|
- 2483 isR, isL, folded: BOOLEAN;
|
|
|
|
|
- 2484 lw, rw, mw: CARDINAL;
|
|
|
|
|
- 2485 lNext, lFalse, lDone, qr, qs: QbeGen.QVal;
|
|
|
|
|
- 2486 astA, astB: AST.Node;
|
|
|
|
|
- 2487 astOp: INTEGER; .)
|
|
|
|
|
- 2488 = Fact<t, q> (. astA := astCur; .) { MulOp<op> (. IF op = SymTab.OpAnd THEN
|
|
|
|
|
- 2489 QbeGen.DelayBegin END; .)
|
|
|
|
|
- 2490 Fact<t2, q2> (. astB := astCur; IF op = SymTab.OpAnd THEN
|
|
|
|
|
- 2491 QbeGen.DelayEnd END; .)
|
|
|
|
|
- 2492 (. astOp := AST.OpMul;
|
|
|
|
|
- 2493 IF op = SymTab.OpSlash THEN astOp := AST.OpDiv
|
|
|
|
|
- 2494 ELSIF op = SymTab.OpDiv THEN astOp := AST.OpDiv
|
|
|
|
|
- 2495 ELSIF op = SymTab.OpMod THEN astOp := AST.OpMod
|
|
|
|
|
- 2496 ELSIF op = SymTab.OpAnd THEN astOp := AST.OpAnd END;
|
|
|
|
|
- 2497 astA := AST.MakeBin(AST.NkBinExpr, astOp, astA, astB);
|
|
|
|
|
- 2498 astCur := astA;
|
|
|
|
|
- 2499 IF op = SymTab.OpAnd THEN
|
|
|
|
|
- 2500 (* short-circuit: if q is false the RHS is skipped *)
|
|
|
|
|
- 2501 IF SymTab.BoolCheck(t) AND SymTab.BoolCheck(t2) THEN
|
|
|
|
|
- 2502 t := SymTab.BoolType()
|
|
|
|
|
- 2503 ELSE SemError(212); t := SymTab.InvalidType END;
|
|
|
|
|
- 2504 IF t # SymTab.InvalidType THEN
|
|
|
|
|
- 2505 QbeGen.Slot4(qs);
|
|
|
|
|
- 2506 QbeGen.NewLabel(lNext);
|
|
|
|
|
- 2507 QbeGen.NewLabel(lFalse);
|
|
|
|
|
- 2508 QbeGen.NewLabel(lDone);
|
|
|
|
|
- 2509 QbeGen.Jnz(q, lNext, lFalse);
|
|
|
|
|
- 2510 QbeGen.EmitLabel(lNext);
|
|
|
|
|
- 2511 QbeGen.DelayFlush;
|
|
|
|
|
- 2512 QbeGen.StoreW(qs, q2);
|
|
|
|
|
- 2513 QbeGen.Jmp(lDone);
|
|
|
|
|
- 2514 QbeGen.EmitLabel(lFalse);
|
|
|
|
|
- 2515 QbeGen.StoreW(qs, "0");
|
|
|
|
|
- 2516 QbeGen.Jmp(lDone);
|
|
|
|
|
- 2517 QbeGen.EmitLabel(lDone);
|
|
|
|
|
- 2518 QbeGen.LoadW(qs, qr);
|
|
|
|
|
- 2519 QbeGen.CopyOp(qr, q)
|
|
|
|
|
- 2520 ELSE QbeGen.DelayFlush; QbeGen.CopyOp("0", q)
|
|
|
|
|
- 2521 END
|
|
|
|
|
- 2522 ELSIF (t # SymTab.InvalidType) AND (t2 # SymTab.InvalidType)
|
|
|
|
|
- 2523 AND (SymTab.ClassOf(t) = SymTab.ClSet)
|
|
|
|
|
- 2524 AND (SymTab.ClassOf(t2) = SymTab.ClSet) THEN
|
|
|
|
|
- 2525 lw := SymTab.SetWords(t); rw := SymTab.SetWords(t2);
|
|
|
|
|
- 2526 mw := lw;
|
|
|
|
|
- 2527 IF rw > mw THEN mw := rw END;
|
|
|
|
|
- 2528 IF op = SymTab.OpTimes THEN
|
|
|
|
|
- 2529 QbeGen.SetBinOp(1, q, q2, lw, rw, qt)
|
|
|
|
|
- 2530 ELSE
|
|
|
|
|
- 2531 QbeGen.SetBinOp(3, q, q2, lw, rw, qt)
|
|
|
|
|
- 2532 END;
|
|
|
|
|
- 2533 t := SymTab.NewSet(
|
|
|
|
|
- 2534 SymTab.NewSubR(0,
|
|
|
|
|
- 2535 VAL(INTEGER, mw) * 32 - 1));
|
|
|
|
|
- 2536 QbeGen.CopyOp(qt, q)
|
|
|
|
|
- 2537 ELSE
|
|
|
|
|
- 2538 IF SymTab.ArithCheck(t, t2,
|
|
|
|
|
- 2539 (op = SymTab.OpDiv) OR (op = SymTab.OpMod),
|
|
|
|
|
- 2540 res2) THEN
|
|
|
|
|
- 2541 lt := t; rt := t2; t := res2
|
|
|
|
|
- 2542 ELSE SemError(211); t := SymTab.InvalidType END;
|
|
|
|
|
- 2543 IF t # SymTab.InvalidType THEN
|
|
|
|
|
- 2544 isL := SymTab.IsLongFamily(t);
|
|
|
|
|
- 2545 isR := SymTab.ClassOf(t) = SymTab.ClReal;
|
|
|
|
|
- 2546 folded := FALSE;
|
|
|
|
|
- 2547 IF (NOT isL) AND (NOT isR)
|
|
|
|
|
- 2548 AND QbeGen.IsImm(q) AND QbeGen.IsImm(q2) THEN
|
|
|
|
|
- 2549 IF op = SymTab.OpTimes THEN
|
|
|
|
|
- 2550 folded := QbeGen.Fold2(2, q, q2, qf)
|
|
|
|
|
- 2551 ELSIF op = SymTab.OpDiv THEN
|
|
|
|
|
- 2552 folded := QbeGen.Fold2(3, q, q2, qf)
|
|
|
|
|
- 2553 ELSIF op = SymTab.OpMod THEN
|
|
|
|
|
- 2554 folded := QbeGen.Fold2(4, q, q2, qf)
|
|
|
|
|
- 2555 END
|
|
|
|
|
- 2556 END;
|
|
|
|
|
- 2557 IF folded THEN QbeGen.CopyOp(qf, q)
|
|
|
|
|
- 2558 ELSE
|
|
|
|
|
- 2559 IF isL THEN
|
|
|
|
|
- 2560 IF SymTab.IsIntFamily(lt) THEN
|
|
|
|
|
- 2561 QbeGen.WidenLong(q, wq); QbeGen.CopyOp(wq, q)
|
|
|
|
|
- 2562 END;
|
|
|
|
|
- 2563 IF SymTab.IsIntFamily(rt) THEN
|
|
|
|
|
- 2564 QbeGen.WidenLong(q2, wq); QbeGen.CopyOp(wq, q2)
|
|
|
|
|
- 2565 END;
|
|
|
|
|
- 2566 QbeGen.NewTemp(qt);
|
|
|
|
|
- 2567 IF op = SymTab.OpTimes THEN
|
|
|
|
|
- 2568 QbeGen.Op3L("mul", qt, q, q2)
|
|
|
|
|
- 2569 ELSIF (op = SymTab.OpDiv)
|
|
|
|
|
- 2570 OR (op = SymTab.OpSlash) THEN
|
|
|
|
|
- 2571 QbeGen.Op3L("div", qt, q, q2)
|
|
|
|
|
- 2572 ELSE
|
|
|
|
|
- 2573 QbeGen.Op3L("rem", qt, q, q2)
|
|
|
|
|
- 2574 END
|
|
|
|
|
- 2575 ELSE
|
|
|
|
|
|
|
+ 2282 ELSIF SymTab.IsLongFamily(t)
|
|
|
|
|
+ 2283 OR SymTab.IsLongFamily(t2) THEN
|
|
|
|
|
+ 2284 IF SymTab.IsIntFamily(t) THEN
|
|
|
|
|
+ 2285 QbeGen.WidenLong(q, wl); QbeGen.CopyOp(wl, q)
|
|
|
|
|
+ 2286 END;
|
|
|
|
|
+ 2287 IF SymTab.IsIntFamily(t2) THEN
|
|
|
|
|
+ 2288 QbeGen.WidenLong(q2, wl); QbeGen.CopyOp(wl, q2)
|
|
|
|
|
+ 2289 END;
|
|
|
|
|
+ 2290 QbeGen.CmpLong(op, q, q2, qt);
|
|
|
|
|
+ 2291 t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
|
|
|
|
|
+ 2292 ELSE
|
|
|
|
|
+ 2293 isR := SymTab.ClassOf(t) = SymTab.ClReal;
|
|
|
|
|
+ 2294 t := SymTab.BoolType();
|
|
|
|
|
+ 2295 QbeGen.Cmp(op, q, q2, qt, isR);
|
|
|
|
|
+ 2296 QbeGen.CopyOp(qt, q)
|
|
|
|
|
+ 2297 END
|
|
|
|
|
+ 2298 ELSE SemError(213); t := SymTab.InvalidType;
|
|
|
|
|
+ 2299 QbeGen.CopyOp("0", q)
|
|
|
|
|
+ 2300 END;
|
|
|
|
|
+ 2301 astCur := AST.MakeBin(AST.NkBinExpr, astOp, astA, astB); .) ]
|
|
|
|
|
+ 2302 (. IF NOT astMade THEN astCur := astA END; .) .
|
|
|
|
|
+ 2303 Rel<VAR op: INTEGER>
|
|
|
|
|
+ 2304 = "=" (. op := SymTab.OpEq; .)
|
|
|
|
|
+ 2305 | "#" (. op := SymTab.OpNeq1; .)
|
|
|
|
|
+ 2306 | "<" (. op := SymTab.OpLt; .)
|
|
|
|
|
+ 2307 | "<=" (. op := SymTab.OpLe; .)
|
|
|
|
|
+ 2308 | ">" (. op := SymTab.OpGt; .)
|
|
|
|
|
+ 2309 | ">=" (. op := SymTab.OpGe; .)
|
|
|
|
|
+ 2310 | "IN" (. op := SymTab.OpIn; .) .
|
|
|
|
|
+ 2311 SimExpr<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
|
|
+ 2312 (. VAR t2, res2, lt, rt:
|
|
|
|
|
+ 2313 SymTab.TypeIndex;
|
|
|
|
|
+ 2314 op: INTEGER;
|
|
|
|
|
+ 2315 q2, qt, wq, qf, q2a, q2b:
|
|
|
|
|
+ 2316 QbeGen.QVal;
|
|
|
|
|
+ 2317 neg, isR, isL, folded:
|
|
|
|
|
+ 2318 BOOLEAN;
|
|
|
|
|
+ 2319 fok: BOOLEAN;
|
|
|
|
|
+ 2320 lw, rw, mw: CARDINAL;
|
|
|
|
|
+ 2321 lTrue, lNext, lDone, qr, qs: QbeGen.QVal;
|
|
|
|
|
+ 2322 astA, astB: AST.Node;
|
|
|
|
|
+ 2323 astSign, astOp: INTEGER; .)
|
|
|
|
|
+ 2324 = (. neg := FALSE; astSign := 0; .)
|
|
|
|
|
+ 2325 [ "+" (. neg := TRUE; astSign := 1; .)
|
|
|
|
|
+ 2326 | "-" (. neg := TRUE; astSign := -1; .) ]
|
|
|
|
|
+ 2327 Term<t, q> (. astA := astCur; IF neg THEN
|
|
|
|
|
+ 2328 IF QbeGen.IsImm(q) THEN
|
|
|
|
|
+ 2329 QbeGen.NegFold(q, q)
|
|
|
|
|
+ 2330 ELSE QbeGen.NewTemp(qt);
|
|
|
|
|
+ 2331 QbeGen.NegQ(q, qt,
|
|
|
|
|
+ 2332 SymTab.ClassOf(t)
|
|
|
|
|
+ 2333 = SymTab.ClReal);
|
|
|
|
|
+ 2334 QbeGen.CopyOp(qt, q)
|
|
|
|
|
+ 2335 END
|
|
|
|
|
+ 2336 END;
|
|
|
|
|
+ 2337 IF astSign < 0 THEN
|
|
|
|
|
+ 2338 astCur := AST.MakeUn(
|
|
|
|
|
+ 2339 AST.NkUnary, AST.OpSub, astA);
|
|
|
|
|
+ 2340 astA := astCur
|
|
|
|
|
+ 2341 END; .)
|
|
|
|
|
+ 2342 { AddOp<op> (. IF op = SymTab.OpOr THEN
|
|
|
|
|
+ 2343 QbeGen.DelayBegin END; .)
|
|
|
|
|
+ 2344 Term<t2, q2> (. astB := astCur; IF op = SymTab.OpOr THEN
|
|
|
|
|
+ 2345 QbeGen.DelayEnd END; .)
|
|
|
|
|
+ 2346 (. astOp := AST.OpAdd;
|
|
|
|
|
+ 2347 IF op = SymTab.OpSub THEN astOp := AST.OpSub
|
|
|
|
|
+ 2348 ELSIF op = SymTab.OpOr THEN astOp := AST.OpOr END;
|
|
|
|
|
+ 2349 astA := AST.MakeBin(AST.NkBinExpr, astOp, astA, astB);
|
|
|
|
|
+ 2350 astCur := astA;
|
|
|
|
|
+ 2351 IF op = SymTab.OpOr THEN
|
|
|
|
|
+ 2352 (* short-circuit: if q is true the RHS is skipped *)
|
|
|
|
|
+ 2353 IF SymTab.BoolCheck(t) AND SymTab.BoolCheck(t2) THEN
|
|
|
|
|
+ 2354 t := SymTab.BoolType()
|
|
|
|
|
+ 2355 ELSE SemError(212); t := SymTab.InvalidType END;
|
|
|
|
|
+ 2356 IF t # SymTab.InvalidType THEN
|
|
|
|
|
+ 2357 QbeGen.Slot4(qs);
|
|
|
|
|
+ 2358 QbeGen.NewLabel(lTrue);
|
|
|
|
|
+ 2359 QbeGen.NewLabel(lNext);
|
|
|
|
|
+ 2360 QbeGen.NewLabel(lDone);
|
|
|
|
|
+ 2361 QbeGen.Jnz(q, lTrue, lNext);
|
|
|
|
|
+ 2362 QbeGen.EmitLabel(lTrue);
|
|
|
|
|
+ 2363 QbeGen.StoreW(qs, "1");
|
|
|
|
|
+ 2364 QbeGen.Jmp(lDone);
|
|
|
|
|
+ 2365 QbeGen.EmitLabel(lNext);
|
|
|
|
|
+ 2366 QbeGen.DelayFlush;
|
|
|
|
|
+ 2367 QbeGen.StoreW(qs, q2);
|
|
|
|
|
+ 2368 QbeGen.Jmp(lDone);
|
|
|
|
|
+ 2369 QbeGen.EmitLabel(lDone);
|
|
|
|
|
+ 2370 QbeGen.LoadW(qs, qr);
|
|
|
|
|
+ 2371 QbeGen.CopyOp(qr, q)
|
|
|
|
|
+ 2372 ELSE QbeGen.DelayFlush; QbeGen.CopyOp("0", q)
|
|
|
|
|
+ 2373 END
|
|
|
|
|
+ 2374 ELSIF (op = SymTab.OpAdd)
|
|
|
|
|
+ 2375 AND (SymTab.UStrCompat(t, t2)
|
|
|
|
|
+ 2376 OR ((SymTab.ClassOf(t) = SymTab.ClUChar)
|
|
|
|
|
+ 2377 AND (SymTab.ClassOf(t2) = SymTab.ClUStr))
|
|
|
|
|
+ 2378 OR ((SymTab.ClassOf(t) = SymTab.ClUStr)
|
|
|
|
|
+ 2379 AND (SymTab.ClassOf(t2) = SymTab.ClUChar))
|
|
|
|
|
+ 2380 OR ((SymTab.ClassOf(t) = SymTab.ClUChar)
|
|
|
|
|
+ 2381 AND (SymTab.ClassOf(t2) = SymTab.ClUChar))) THEN
|
|
|
|
|
+ 2382 (* UString concatenation: a UCHAR operand becomes a
|
|
|
|
|
+ 2383 1-codepoint UString; the result is a descriptor in the
|
|
|
|
|
+ 2384 shim's concat buffer. Work on copies so neither
|
|
|
|
|
+ 2385 operand is clobbered. *)
|
|
|
|
|
+ 2386 IF SymTab.ClassOf(t) = SymTab.ClUStr THEN
|
|
|
|
|
+ 2387 QbeGen.CopyOp(q, q2a)
|
|
|
|
|
+ 2388 ELSE
|
|
|
|
|
+ 2389 QbeGen.UStrFrom(q, q2a)
|
|
|
|
|
+ 2390 END;
|
|
|
|
|
+ 2391 IF SymTab.ClassOf(t2) = SymTab.ClUStr THEN
|
|
|
|
|
+ 2392 QbeGen.UStrCat(q2a, q2, qt)
|
|
|
|
|
+ 2393 ELSE
|
|
|
|
|
+ 2394 QbeGen.UStrFrom(q2, q2b);
|
|
|
|
|
+ 2395 QbeGen.UStrCat(q2a, q2b, qt)
|
|
|
|
|
+ 2396 END;
|
|
|
|
|
+ 2397 t := SymTab.NewUStr();
|
|
|
|
|
+ 2398 QbeGen.CopyOp(qt, q)
|
|
|
|
|
+ 2399 ELSIF (op = SymTab.OpAdd)
|
|
|
|
|
+ 2400 AND (SymTab.StrCompat(t, t2)
|
|
|
|
|
+ 2401 OR (SymTab.IsStrType(t)
|
|
|
|
|
+ 2402 AND (SymTab.ClassOf(t2) = SymTab.ClChar))
|
|
|
|
|
+ 2403 OR ((SymTab.ClassOf(t) = SymTab.ClChar)
|
|
|
|
|
+ 2404 AND SymTab.IsStrType(t2))) THEN
|
|
|
|
|
+ 2405 (* string concatenation; a CHAR operand becomes a
|
|
|
|
|
+ 2406 1-character string literal. When both operands are
|
|
|
|
|
+ 2407 constants, fold to a single string literal so a
|
|
|
|
|
+ 2408 constructor element stays compile-time. *)
|
|
|
|
|
+ 2409 QbeGen.StrFold(q, q2, SymTab.ClassOf(t), SymTab.ClassOf(t2),
|
|
|
|
|
+ 2410 qt, fok);
|
|
|
|
|
+ 2411 IF NOT fok THEN
|
|
|
|
|
+ 2412 IF SymTab.StrCompat(t, t2) THEN
|
|
|
|
|
+ 2413 QbeGen.StrCat(q, q2, qt)
|
|
|
|
|
+ 2414 ELSIF SymTab.IsStrType(t) THEN
|
|
|
|
|
+ 2415 QbeGen.DeclCharStr(q2, qs);
|
|
|
|
|
+ 2416 QbeGen.StrCat(q, qs, qt)
|
|
|
|
|
+ 2417 ELSE
|
|
|
|
|
+ 2418 QbeGen.DeclCharStr(q, qs);
|
|
|
|
|
+ 2419 QbeGen.StrCat(qs, q2, qt)
|
|
|
|
|
+ 2420 END
|
|
|
|
|
+ 2421 END;
|
|
|
|
|
+ 2422 t := SymTab.NewStr();
|
|
|
|
|
+ 2423 QbeGen.CopyOp(qt, q)
|
|
|
|
|
+ 2424 ELSIF (t # SymTab.InvalidType) AND (t2 # SymTab.InvalidType)
|
|
|
|
|
+ 2425 AND (SymTab.ClassOf(t) = SymTab.ClSet)
|
|
|
|
|
+ 2426 AND (SymTab.ClassOf(t2) = SymTab.ClSet) THEN
|
|
|
|
|
+ 2427 lw := SymTab.SetWords(t); rw := SymTab.SetWords(t2);
|
|
|
|
|
+ 2428 mw := lw;
|
|
|
|
|
+ 2429 IF rw > mw THEN mw := rw END;
|
|
|
|
|
+ 2430 IF op = SymTab.OpAdd THEN
|
|
|
|
|
+ 2431 QbeGen.SetBinOp(0, q, q2, lw, rw, qt)
|
|
|
|
|
+ 2432 ELSE
|
|
|
|
|
+ 2433 QbeGen.SetBinOp(2, q, q2, lw, rw, qt)
|
|
|
|
|
+ 2434 END;
|
|
|
|
|
+ 2435 t := SymTab.NewSet(
|
|
|
|
|
+ 2436 SymTab.NewSubR(0,
|
|
|
|
|
+ 2437 VAL(INTEGER, mw) * 32 - 1));
|
|
|
|
|
+ 2438 QbeGen.CopyOp(qt, q)
|
|
|
|
|
+ 2439 ELSE
|
|
|
|
|
+ 2440 IF SymTab.ArithCheck(t, t2, FALSE, res2) THEN
|
|
|
|
|
+ 2441 lt := t; rt := t2; t := res2
|
|
|
|
|
+ 2442 ELSE SemError(211); t := SymTab.InvalidType END;
|
|
|
|
|
+ 2443 IF t # SymTab.InvalidType THEN
|
|
|
|
|
+ 2444 isL := SymTab.IsLongFamily(t);
|
|
|
|
|
+ 2445 isR := SymTab.ClassOf(t) = SymTab.ClReal;
|
|
|
|
|
+ 2446 folded := FALSE;
|
|
|
|
|
+ 2447 IF (NOT isL) AND (NOT isR)
|
|
|
|
|
+ 2448 AND QbeGen.IsImm(q) AND QbeGen.IsImm(q2) THEN
|
|
|
|
|
+ 2449 IF op = SymTab.OpAdd THEN
|
|
|
|
|
+ 2450 folded := QbeGen.Fold2(0, q, q2, qf)
|
|
|
|
|
+ 2451 ELSE
|
|
|
|
|
+ 2452 folded := QbeGen.Fold2(1, q, q2, qf)
|
|
|
|
|
+ 2453 END
|
|
|
|
|
+ 2454 END;
|
|
|
|
|
+ 2455 IF folded THEN QbeGen.CopyOp(qf, q)
|
|
|
|
|
+ 2456 ELSE
|
|
|
|
|
+ 2457 IF isL THEN
|
|
|
|
|
+ 2458 IF SymTab.IsIntFamily(lt) THEN
|
|
|
|
|
+ 2459 QbeGen.WidenLong(q, wq); QbeGen.CopyOp(wq, q)
|
|
|
|
|
+ 2460 END;
|
|
|
|
|
+ 2461 IF SymTab.IsIntFamily(rt) THEN
|
|
|
|
|
+ 2462 QbeGen.WidenLong(q2, wq); QbeGen.CopyOp(wq, q2)
|
|
|
|
|
+ 2463 END;
|
|
|
|
|
+ 2464 QbeGen.NewTemp(qt);
|
|
|
|
|
+ 2465 IF op = SymTab.OpAdd THEN
|
|
|
|
|
+ 2466 QbeGen.Op3L("add", qt, q, q2)
|
|
|
|
|
+ 2467 ELSE
|
|
|
|
|
+ 2468 QbeGen.Op3L("sub", qt, q, q2)
|
|
|
|
|
+ 2469 END
|
|
|
|
|
+ 2470 ELSE
|
|
|
|
|
+ 2471 QbeGen.NewTemp(qt);
|
|
|
|
|
+ 2472 IF op = SymTab.OpAdd THEN
|
|
|
|
|
+ 2473 QbeGen.Op3("add", qt, q, q2, isR)
|
|
|
|
|
+ 2474 ELSE
|
|
|
|
|
+ 2475 QbeGen.Op3("sub", qt, q, q2, isR)
|
|
|
|
|
+ 2476 END
|
|
|
|
|
+ 2477 END;
|
|
|
|
|
+ 2478 QbeGen.CopyOp(qt, q)
|
|
|
|
|
+ 2479 END
|
|
|
|
|
+ 2480 ELSE QbeGen.CopyOp("0", q)
|
|
|
|
|
+ 2481 END
|
|
|
|
|
+ 2482 END; .) } .
|
|
|
|
|
+ 2483 AddOp<VAR op: INTEGER>
|
|
|
|
|
+ 2484 = "+" (. op := SymTab.OpAdd; .)
|
|
|
|
|
+ 2485 | "-" (. op := SymTab.OpSub; .)
|
|
|
|
|
+ 2486 | "OR" (. op := SymTab.OpOr; .) .
|
|
|
|
|
+ 2487 Term<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
|
|
+ 2488 (. VAR t2, res2, lt, rt:
|
|
|
|
|
+ 2489 SymTab.TypeIndex;
|
|
|
|
|
+ 2490 op: INTEGER;
|
|
|
|
|
+ 2491 q2, qt, wq, qf:
|
|
|
|
|
+ 2492 QbeGen.QVal;
|
|
|
|
|
+ 2493 isR, isL, folded: BOOLEAN;
|
|
|
|
|
+ 2494 lw, rw, mw: CARDINAL;
|
|
|
|
|
+ 2495 lNext, lFalse, lDone, qr, qs: QbeGen.QVal;
|
|
|
|
|
+ 2496 astA, astB: AST.Node;
|
|
|
|
|
+ 2497 astOp: INTEGER; .)
|
|
|
|
|
+ 2498 = Fact<t, q> (. astA := astCur; .) { MulOp<op> (. IF op = SymTab.OpAnd THEN
|
|
|
|
|
+ 2499 QbeGen.DelayBegin END; .)
|
|
|
|
|
+ 2500 Fact<t2, q2> (. astB := astCur; IF op = SymTab.OpAnd THEN
|
|
|
|
|
+ 2501 QbeGen.DelayEnd END; .)
|
|
|
|
|
+ 2502 (. astOp := AST.OpMul;
|
|
|
|
|
+ 2503 IF op = SymTab.OpSlash THEN astOp := AST.OpDiv
|
|
|
|
|
+ 2504 ELSIF op = SymTab.OpDiv THEN astOp := AST.OpDiv
|
|
|
|
|
+ 2505 ELSIF op = SymTab.OpMod THEN astOp := AST.OpMod
|
|
|
|
|
+ 2506 ELSIF op = SymTab.OpAnd THEN astOp := AST.OpAnd END;
|
|
|
|
|
+ 2507 astA := AST.MakeBin(AST.NkBinExpr, astOp, astA, astB);
|
|
|
|
|
+ 2508 astCur := astA;
|
|
|
|
|
+ 2509 IF op = SymTab.OpAnd THEN
|
|
|
|
|
+ 2510 (* short-circuit: if q is false the RHS is skipped *)
|
|
|
|
|
+ 2511 IF SymTab.BoolCheck(t) AND SymTab.BoolCheck(t2) THEN
|
|
|
|
|
+ 2512 t := SymTab.BoolType()
|
|
|
|
|
+ 2513 ELSE SemError(212); t := SymTab.InvalidType END;
|
|
|
|
|
+ 2514 IF t # SymTab.InvalidType THEN
|
|
|
|
|
+ 2515 QbeGen.Slot4(qs);
|
|
|
|
|
+ 2516 QbeGen.NewLabel(lNext);
|
|
|
|
|
+ 2517 QbeGen.NewLabel(lFalse);
|
|
|
|
|
+ 2518 QbeGen.NewLabel(lDone);
|
|
|
|
|
+ 2519 QbeGen.Jnz(q, lNext, lFalse);
|
|
|
|
|
+ 2520 QbeGen.EmitLabel(lNext);
|
|
|
|
|
+ 2521 QbeGen.DelayFlush;
|
|
|
|
|
+ 2522 QbeGen.StoreW(qs, q2);
|
|
|
|
|
+ 2523 QbeGen.Jmp(lDone);
|
|
|
|
|
+ 2524 QbeGen.EmitLabel(lFalse);
|
|
|
|
|
+ 2525 QbeGen.StoreW(qs, "0");
|
|
|
|
|
+ 2526 QbeGen.Jmp(lDone);
|
|
|
|
|
+ 2527 QbeGen.EmitLabel(lDone);
|
|
|
|
|
+ 2528 QbeGen.LoadW(qs, qr);
|
|
|
|
|
+ 2529 QbeGen.CopyOp(qr, q)
|
|
|
|
|
+ 2530 ELSE QbeGen.DelayFlush; QbeGen.CopyOp("0", q)
|
|
|
|
|
+ 2531 END
|
|
|
|
|
+ 2532 ELSIF (t # SymTab.InvalidType) AND (t2 # SymTab.InvalidType)
|
|
|
|
|
+ 2533 AND (SymTab.ClassOf(t) = SymTab.ClSet)
|
|
|
|
|
+ 2534 AND (SymTab.ClassOf(t2) = SymTab.ClSet) THEN
|
|
|
|
|
+ 2535 lw := SymTab.SetWords(t); rw := SymTab.SetWords(t2);
|
|
|
|
|
+ 2536 mw := lw;
|
|
|
|
|
+ 2537 IF rw > mw THEN mw := rw END;
|
|
|
|
|
+ 2538 IF op = SymTab.OpTimes THEN
|
|
|
|
|
+ 2539 QbeGen.SetBinOp(1, q, q2, lw, rw, qt)
|
|
|
|
|
+ 2540 ELSE
|
|
|
|
|
+ 2541 QbeGen.SetBinOp(3, q, q2, lw, rw, qt)
|
|
|
|
|
+ 2542 END;
|
|
|
|
|
+ 2543 t := SymTab.NewSet(
|
|
|
|
|
+ 2544 SymTab.NewSubR(0,
|
|
|
|
|
+ 2545 VAL(INTEGER, mw) * 32 - 1));
|
|
|
|
|
+ 2546 QbeGen.CopyOp(qt, q)
|
|
|
|
|
+ 2547 ELSE
|
|
|
|
|
+ 2548 IF SymTab.ArithCheck(t, t2,
|
|
|
|
|
+ 2549 (op = SymTab.OpDiv) OR (op = SymTab.OpMod),
|
|
|
|
|
+ 2550 res2) THEN
|
|
|
|
|
+ 2551 lt := t; rt := t2; t := res2
|
|
|
|
|
+ 2552 ELSE SemError(211); t := SymTab.InvalidType END;
|
|
|
|
|
+ 2553 IF t # SymTab.InvalidType THEN
|
|
|
|
|
+ 2554 isL := SymTab.IsLongFamily(t);
|
|
|
|
|
+ 2555 isR := SymTab.ClassOf(t) = SymTab.ClReal;
|
|
|
|
|
+ 2556 folded := FALSE;
|
|
|
|
|
+ 2557 IF (NOT isL) AND (NOT isR)
|
|
|
|
|
+ 2558 AND QbeGen.IsImm(q) AND QbeGen.IsImm(q2) THEN
|
|
|
|
|
+ 2559 IF op = SymTab.OpTimes THEN
|
|
|
|
|
+ 2560 folded := QbeGen.Fold2(2, q, q2, qf)
|
|
|
|
|
+ 2561 ELSIF op = SymTab.OpDiv THEN
|
|
|
|
|
+ 2562 folded := QbeGen.Fold2(3, q, q2, qf)
|
|
|
|
|
+ 2563 ELSIF op = SymTab.OpMod THEN
|
|
|
|
|
+ 2564 folded := QbeGen.Fold2(4, q, q2, qf)
|
|
|
|
|
+ 2565 END
|
|
|
|
|
+ 2566 END;
|
|
|
|
|
+ 2567 IF folded THEN QbeGen.CopyOp(qf, q)
|
|
|
|
|
+ 2568 ELSE
|
|
|
|
|
+ 2569 IF isL THEN
|
|
|
|
|
+ 2570 IF SymTab.IsIntFamily(lt) THEN
|
|
|
|
|
+ 2571 QbeGen.WidenLong(q, wq); QbeGen.CopyOp(wq, q)
|
|
|
|
|
+ 2572 END;
|
|
|
|
|
+ 2573 IF SymTab.IsIntFamily(rt) THEN
|
|
|
|
|
+ 2574 QbeGen.WidenLong(q2, wq); QbeGen.CopyOp(wq, q2)
|
|
|
|
|
+ 2575 END;
|
|
|
2576 QbeGen.NewTemp(qt);
|
|
2576 QbeGen.NewTemp(qt);
|
|
|
2577 IF op = SymTab.OpTimes THEN
|
|
2577 IF op = SymTab.OpTimes THEN
|
|
|
- 2578 QbeGen.Op3("mul", qt, q, q2, isR)
|
|
|
|
|
|
|
+ 2578 QbeGen.Op3L("mul", qt, q, q2)
|
|
|
2579 ELSIF (op = SymTab.OpDiv)
|
|
2579 ELSIF (op = SymTab.OpDiv)
|
|
|
2580 OR (op = SymTab.OpSlash) THEN
|
|
2580 OR (op = SymTab.OpSlash) THEN
|
|
|
- 2581 QbeGen.Op3("div", qt, q, q2, isR)
|
|
|
|
|
|
|
+ 2581 QbeGen.Op3L("div", qt, q, q2)
|
|
|
2582 ELSE
|
|
2582 ELSE
|
|
|
- 2583 QbeGen.Op3("rem", qt, q, q2, isR)
|
|
|
|
|
|
|
+ 2583 QbeGen.Op3L("rem", qt, q, q2)
|
|
|
2584 END
|
|
2584 END
|
|
|
- 2585 END;
|
|
|
|
|
- 2586 QbeGen.CopyOp(qt, q)
|
|
|
|
|
- 2587 END
|
|
|
|
|
- 2588 ELSE QbeGen.CopyOp("0", q)
|
|
|
|
|
- 2589 END
|
|
|
|
|
- 2590 END; .) } .
|
|
|
|
|
- 2591 MulOp<VAR op: INTEGER>
|
|
|
|
|
- 2592 = "*" (. op := SymTab.OpTimes; .)
|
|
|
|
|
- 2593 | "/" (. op := SymTab.OpSlash; .)
|
|
|
|
|
- 2594 | "DIV" (. op := SymTab.OpDiv; .)
|
|
|
|
|
- 2595 | "MOD" (. op := SymTab.OpMod; .)
|
|
|
|
|
- 2596 | ( "AND" | "&" ) (. op := SymTab.OpAnd; .) .
|
|
|
|
|
- 2597 Fact<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
|
|
- 2598 (. VAR s: ARRAY [0 .. 255] OF CHAR;
|
|
|
|
|
- 2599 et, dt, t2, st, ct2, et2:
|
|
|
|
|
- 2600 SymTab.TypeIndex;
|
|
|
|
|
- 2601 dk: INTEGER;
|
|
|
|
|
- 2602 qd, q2, sq, qa, qm0, qr, qt:
|
|
|
|
|
- 2603 QbeGen.QVal;
|
|
|
|
|
- 2604 qn, vn: SymTab.Name;
|
|
|
|
|
- 2605 vt: SymTab.TypeIndex;
|
|
|
|
|
- 2606 c1, c2: INTEGER;
|
|
|
|
|
- 2607 lo, hi: INTEGER;
|
|
|
|
|
- 2608 isMax: BOOLEAN;
|
|
|
|
|
- 2609 called, isHigh, sfx, isCh,
|
|
|
|
|
- 2610 isU, uok, isStr: BOOLEAN;
|
|
|
|
|
- 2611 ucp: INTEGER; astIsLit: BOOLEAN;
|
|
|
|
|
- 2612 astD: AST.Node;
|
|
|
|
|
- 2613 astCall: BOOLEAN; .)
|
|
|
|
|
- 2614 = (. astIsLit := FALSE; .)
|
|
|
|
|
- 2615 ( integer (. LexString(s);
|
|
|
|
|
- 2616 QbeGen.NormInt(s, q); IF twoPhase THEN astIsLit := TRUE; astCur := AST.MakeLeaf(AST.NkIntLit, s) END;
|
|
|
|
|
- 2617 t := SymTab.IntType(); .)
|
|
|
|
|
- 2618 | charConst (. LexString(s);
|
|
|
|
|
- 2619 QbeGen.NormLit(s, q, isCh);
|
|
|
|
|
- 2620 IF twoPhase THEN
|
|
|
|
|
- 2621 astIsLit := TRUE;
|
|
|
|
|
- 2622 astCur := AST.MakeLeaf(
|
|
|
|
|
- 2623 AST.NkCharLit, s)
|
|
|
|
|
- 2624 END;
|
|
|
|
|
- 2625 t := SymTab.CharType(); .)
|
|
|
|
|
- 2626 | real (. LexString(s);
|
|
|
|
|
- 2627 QbeGen.NormReal(s, q);
|
|
|
|
|
- 2628 IF twoPhase THEN
|
|
|
|
|
- 2629 astIsLit := TRUE;
|
|
|
|
|
- 2630 astCur := AST.MakeLeaf(
|
|
|
|
|
- 2631 AST.NkRealLit, s)
|
|
|
|
|
- 2632 END;
|
|
|
|
|
- 2633 t := SymTab.RealType(); .)
|
|
|
|
|
- 2634 | string (. LexString(s);
|
|
|
|
|
- 2635 IF twoPhase THEN
|
|
|
|
|
- 2636 astIsLit := TRUE;
|
|
|
|
|
- 2637 astCur := AST.MakeLeaf(
|
|
|
|
|
- 2638 AST.NkStrLit, s)
|
|
|
|
|
- 2639 END;
|
|
|
|
|
- 2640 IF SymTab.StrLen(s) = 3 THEN
|
|
|
|
|
- 2641 t := SymTab.CharType();
|
|
|
|
|
- 2642 QbeGen.IntStr(
|
|
|
|
|
- 2643 QbeGen.CharVal(s), q)
|
|
|
|
|
- 2644 ELSE t := SymTab.NewStr();
|
|
|
|
|
- 2645 QbeGen.DeclStr(s, q);
|
|
|
|
|
- 2646 (* a literal's value IS its
|
|
|
|
|
- 2647 static descriptor address *)
|
|
|
|
|
- 2648 QbeGen.NoteAddr(q, q)
|
|
|
|
|
- 2649 END; .)
|
|
|
|
|
- 2650 | ustring (. LexString(s);
|
|
|
|
|
- 2651 IF twoPhase THEN
|
|
|
|
|
- 2652 astIsLit := TRUE;
|
|
|
|
|
- 2653 astCur := AST.MakeLeaf(
|
|
|
|
|
- 2654 AST.NkStrLit, s)
|
|
|
|
|
- 2655 END;
|
|
|
|
|
- 2656 QbeGen.DeclUStr(s, q, isU, ucp,
|
|
|
|
|
- 2657 uok);
|
|
|
|
|
- 2658 IF NOT uok THEN
|
|
|
|
|
- 2659 SemError(234);
|
|
|
|
|
- 2660 t := SymTab.InvalidType
|
|
|
|
|
- 2661 ELSIF isU THEN
|
|
|
|
|
- 2662 t := SymTab.UCharType();
|
|
|
|
|
- 2663 QbeGen.IntStr(ucp, q)
|
|
|
|
|
- 2664 ELSE
|
|
|
|
|
- 2665 t := SymTab.NewUStr();
|
|
|
|
|
- 2666 QbeGen.NoteAddr(q, q)
|
|
|
|
|
- 2667 END; .)
|
|
|
|
|
- 2668 | Design<dt, dk, qd, qn, sfx> (. astD := astCur; astCall := FALSE; called := FALSE;
|
|
|
|
|
- 2669 t := dt;
|
|
|
|
|
- 2670 IF sfx THEN
|
|
|
|
|
- 2671 IF dt =
|
|
|
|
|
- 2672 SymTab.InvalidType THEN
|
|
|
|
|
- 2673 QbeGen.CopyOp("0", q)
|
|
|
|
|
- 2674 ELSIF (SymTab.ClassOf(dt) =
|
|
|
|
|
- 2675 SymTab.ClRecord)
|
|
|
|
|
- 2676 OR (SymTab.ClassOf(dt) =
|
|
|
|
|
- 2677 SymTab.ClSet)
|
|
|
|
|
- 2678 OR (SymTab.ClassOf(dt) =
|
|
|
|
|
- 2679 SymTab.ClArray)
|
|
|
|
|
- 2680 OR (SymTab.ClassOf(dt) =
|
|
|
|
|
- 2681 SymTab.ClClass) THEN
|
|
|
|
|
- 2682 QbeGen.CopyOp(qd, q)
|
|
|
|
|
- 2683 ELSE QbeGen.ElemLoad(qd, dt,
|
|
|
|
|
- 2684 q)
|
|
|
|
|
- 2685 END
|
|
|
|
|
- 2686 ELSE QbeGen.CopyOp(qd, q)
|
|
|
|
|
- 2687 END;
|
|
|
|
|
- 2688 IF (dk = SymTab.KindVar)
|
|
|
|
|
- 2689 OR (dk = SymTab.KindParam)
|
|
|
|
|
- 2690 OR (dk =
|
|
|
|
|
- 2691 SymTab.KindField) THEN
|
|
|
|
|
- 2692 IF sfx THEN
|
|
|
|
|
- 2693 QbeGen.NoteAddr(q, qd)
|
|
|
|
|
- 2694 ELSE
|
|
|
|
|
- 2695 QbeGen.AddrOf(qn, qa);
|
|
|
|
|
- 2696 QbeGen.NoteAddr(q, qa)
|
|
|
|
|
|
|
+ 2585 ELSE
|
|
|
|
|
+ 2586 QbeGen.NewTemp(qt);
|
|
|
|
|
+ 2587 IF op = SymTab.OpTimes THEN
|
|
|
|
|
+ 2588 QbeGen.Op3("mul", qt, q, q2, isR)
|
|
|
|
|
+ 2589 ELSIF (op = SymTab.OpDiv)
|
|
|
|
|
+ 2590 OR (op = SymTab.OpSlash) THEN
|
|
|
|
|
+ 2591 QbeGen.Op3("div", qt, q, q2, isR)
|
|
|
|
|
+ 2592 ELSE
|
|
|
|
|
+ 2593 QbeGen.Op3("rem", qt, q, q2, isR)
|
|
|
|
|
+ 2594 END
|
|
|
|
|
+ 2595 END;
|
|
|
|
|
+ 2596 QbeGen.CopyOp(qt, q)
|
|
|
|
|
+ 2597 END
|
|
|
|
|
+ 2598 ELSE QbeGen.CopyOp("0", q)
|
|
|
|
|
+ 2599 END
|
|
|
|
|
+ 2600 END; .) } .
|
|
|
|
|
+ 2601 MulOp<VAR op: INTEGER>
|
|
|
|
|
+ 2602 = "*" (. op := SymTab.OpTimes; .)
|
|
|
|
|
+ 2603 | "/" (. op := SymTab.OpSlash; .)
|
|
|
|
|
+ 2604 | "DIV" (. op := SymTab.OpDiv; .)
|
|
|
|
|
+ 2605 | "MOD" (. op := SymTab.OpMod; .)
|
|
|
|
|
+ 2606 | ( "AND" | "&" ) (. op := SymTab.OpAnd; .) .
|
|
|
|
|
+ 2607 Fact<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
|
|
+ 2608 (. VAR s: ARRAY [0 .. 255] OF CHAR;
|
|
|
|
|
+ 2609 et, dt, t2, st, ct2, et2:
|
|
|
|
|
+ 2610 SymTab.TypeIndex;
|
|
|
|
|
+ 2611 dk: INTEGER;
|
|
|
|
|
+ 2612 qd, q2, sq, qa, qm0, qr, qt:
|
|
|
|
|
+ 2613 QbeGen.QVal;
|
|
|
|
|
+ 2614 qn, vn: SymTab.Name;
|
|
|
|
|
+ 2615 vt: SymTab.TypeIndex;
|
|
|
|
|
+ 2616 c1, c2: INTEGER;
|
|
|
|
|
+ 2617 lo, hi: INTEGER;
|
|
|
|
|
+ 2618 isMax: BOOLEAN;
|
|
|
|
|
+ 2619 called, isHigh, sfx, isCh,
|
|
|
|
|
+ 2620 isU, uok, isStr: BOOLEAN;
|
|
|
|
|
+ 2621 ucp: INTEGER; astIsLit: BOOLEAN;
|
|
|
|
|
+ 2622 astD: AST.Node;
|
|
|
|
|
+ 2623 astCall: BOOLEAN;
|
|
|
|
|
+ 2624 astNode, astNot: AST.Node;
|
|
|
|
|
+ 2625 j: CARDINAL; .)
|
|
|
|
|
+ 2626 = (. astIsLit := FALSE; .)
|
|
|
|
|
+ 2627 ( integer (. LexString(s);
|
|
|
|
|
+ 2628 QbeGen.NormInt(s, q); IF twoPhase THEN astIsLit := TRUE; astCur := AST.MakeLeaf(AST.NkIntLit, s) END;
|
|
|
|
|
+ 2629 t := SymTab.IntType(); .)
|
|
|
|
|
+ 2630 | charConst (. LexString(s);
|
|
|
|
|
+ 2631 QbeGen.NormLit(s, q, isCh);
|
|
|
|
|
+ 2632 IF twoPhase THEN
|
|
|
|
|
+ 2633 astIsLit := TRUE;
|
|
|
|
|
+ 2634 astCur := AST.MakeLeaf(
|
|
|
|
|
+ 2635 AST.NkCharLit, s)
|
|
|
|
|
+ 2636 END;
|
|
|
|
|
+ 2637 t := SymTab.CharType(); .)
|
|
|
|
|
+ 2638 | real (. LexString(s);
|
|
|
|
|
+ 2639 QbeGen.NormReal(s, q);
|
|
|
|
|
+ 2640 IF twoPhase THEN
|
|
|
|
|
+ 2641 astIsLit := TRUE;
|
|
|
|
|
+ 2642 astCur := AST.MakeLeaf(
|
|
|
|
|
+ 2643 AST.NkRealLit, s)
|
|
|
|
|
+ 2644 END;
|
|
|
|
|
+ 2645 t := SymTab.RealType(); .)
|
|
|
|
|
+ 2646 | string (. LexString(s);
|
|
|
|
|
+ 2647 IF twoPhase THEN
|
|
|
|
|
+ 2648 astIsLit := TRUE;
|
|
|
|
|
+ 2649 astCur := AST.MakeLeaf(
|
|
|
|
|
+ 2650 AST.NkStrLit, s)
|
|
|
|
|
+ 2651 END;
|
|
|
|
|
+ 2652 IF SymTab.StrLen(s) = 3 THEN
|
|
|
|
|
+ 2653 t := SymTab.CharType();
|
|
|
|
|
+ 2654 QbeGen.IntStr(
|
|
|
|
|
+ 2655 QbeGen.CharVal(s), q)
|
|
|
|
|
+ 2656 ELSE t := SymTab.NewStr();
|
|
|
|
|
+ 2657 QbeGen.DeclStr(s, q);
|
|
|
|
|
+ 2658 (* a literal's value IS its
|
|
|
|
|
+ 2659 static descriptor address *)
|
|
|
|
|
+ 2660 QbeGen.NoteAddr(q, q)
|
|
|
|
|
+ 2661 END; .)
|
|
|
|
|
+ 2662 | ustring (. LexString(s);
|
|
|
|
|
+ 2663 IF twoPhase THEN
|
|
|
|
|
+ 2664 astIsLit := TRUE;
|
|
|
|
|
+ 2665 astCur := AST.MakeLeaf(
|
|
|
|
|
+ 2666 AST.NkStrLit, s)
|
|
|
|
|
+ 2667 END;
|
|
|
|
|
+ 2668 QbeGen.DeclUStr(s, q, isU, ucp,
|
|
|
|
|
+ 2669 uok);
|
|
|
|
|
+ 2670 IF NOT uok THEN
|
|
|
|
|
+ 2671 SemError(234);
|
|
|
|
|
+ 2672 t := SymTab.InvalidType
|
|
|
|
|
+ 2673 ELSIF isU THEN
|
|
|
|
|
+ 2674 t := SymTab.UCharType();
|
|
|
|
|
+ 2675 QbeGen.IntStr(ucp, q)
|
|
|
|
|
+ 2676 ELSE
|
|
|
|
|
+ 2677 t := SymTab.NewUStr();
|
|
|
|
|
+ 2678 QbeGen.NoteAddr(q, q)
|
|
|
|
|
+ 2679 END; .)
|
|
|
|
|
+ 2680 | Design<dt, dk, qd, qn, sfx> (. astD := astCur; astCall := FALSE; astNArgs := 0; called := FALSE;
|
|
|
|
|
+ 2681 t := dt;
|
|
|
|
|
+ 2682 IF sfx THEN
|
|
|
|
|
+ 2683 IF dt =
|
|
|
|
|
+ 2684 SymTab.InvalidType THEN
|
|
|
|
|
+ 2685 QbeGen.CopyOp("0", q)
|
|
|
|
|
+ 2686 ELSIF (SymTab.ClassOf(dt) =
|
|
|
|
|
+ 2687 SymTab.ClRecord)
|
|
|
|
|
+ 2688 OR (SymTab.ClassOf(dt) =
|
|
|
|
|
+ 2689 SymTab.ClSet)
|
|
|
|
|
+ 2690 OR (SymTab.ClassOf(dt) =
|
|
|
|
|
+ 2691 SymTab.ClArray)
|
|
|
|
|
+ 2692 OR (SymTab.ClassOf(dt) =
|
|
|
|
|
+ 2693 SymTab.ClClass) THEN
|
|
|
|
|
+ 2694 QbeGen.CopyOp(qd, q)
|
|
|
|
|
+ 2695 ELSE QbeGen.ElemLoad(qd, dt,
|
|
|
|
|
+ 2696 q)
|
|
|
2697 END
|
|
2697 END
|
|
|
- 2698 ELSIF sfx
|
|
|
|
|
- 2699 AND (dt #
|
|
|
|
|
- 2700 SymTab.InvalidType)
|
|
|
|
|
- 2701 AND ((SymTab.ClassOf(dt) =
|
|
|
|
|
- 2702 SymTab.ClArray)
|
|
|
|
|
- 2703 OR (SymTab.ClassOf(dt) =
|
|
|
|
|
- 2704 SymTab.ClSet)
|
|
|
|
|
- 2705 OR (SymTab.ClassOf(dt) =
|
|
|
|
|
- 2706 SymTab.ClRecord)) THEN
|
|
|
|
|
- 2707 QbeGen.NoteAddr(qd, qd)
|
|
|
|
|
- 2708 END; .)
|
|
|
|
|
- 2709 [ TypedBraceLit<dt, q> (. t := dt; astCall := TRUE; .) ]
|
|
|
|
|
- 2710 [ ArgList<qn, dt, qd, TRUE, FALSE, methCls, ct2, q2, called>
|
|
|
|
|
- 2711 (. astCall := TRUE; t := ct2;
|
|
|
|
|
- 2712 QbeGen.CopyOp(q2, q);
|
|
|
|
|
- 2713 sfx := FALSE; .)
|
|
|
|
|
- 2714 { ResultComp<t, q, sfx> }
|
|
|
|
|
- 2715 (. IF sfx THEN
|
|
|
|
|
- 2716 IF t = SymTab.InvalidType THEN
|
|
|
|
|
- 2717 QbeGen.CopyOp("0", q)
|
|
|
|
|
- 2718 ELSIF (SymTab.ClassOf(t) #
|
|
|
|
|
- 2719 SymTab.ClRecord)
|
|
|
|
|
- 2720 AND (SymTab.ClassOf(t) # SymTab.ClSet)
|
|
|
|
|
- 2721 AND (SymTab.ClassOf(t) # SymTab.ClArray)
|
|
|
|
|
- 2722 AND (SymTab.ClassOf(t) # SymTab.ClClass) THEN
|
|
|
|
|
- 2723 QbeGen.ElemLoad(q, t, q2);
|
|
|
|
|
- 2724 QbeGen.CopyOp(q2, q)
|
|
|
|
|
- 2725 END
|
|
|
|
|
- 2726 END; .) ]
|
|
|
|
|
- 2727 (. IF astCall THEN astCur := AST.NoNode ELSE astCur := astD END;
|
|
|
|
|
- 2728 astIsLit := TRUE;
|
|
|
|
|
- 2729 IF NOT called
|
|
|
|
|
- 2730 AND (dk = SymTab.KindProc) THEN
|
|
|
|
|
- 2731 (* bare zero-arg function
|
|
|
|
|
- 2732 call (parentheses may be
|
|
|
|
|
- 2733 omitted); a proper or
|
|
|
|
|
- 2734 parameterised proc here
|
|
|
|
|
- 2735 is 230 *)
|
|
|
|
|
- 2736 IF (SymTab.ProcNPar(qn) = 0)
|
|
|
|
|
- 2737 AND (SymTab.ProcRes(qn) #
|
|
|
|
|
- 2738 SymTab.InvalidType) THEN
|
|
|
|
|
- 2739 QbeGen.Mangled(qn,
|
|
|
|
|
- 2740 SymTab.ProcUid(qn), qm0);
|
|
|
|
|
- 2741 QbeGen.CallBegin(qm0,
|
|
|
|
|
- 2742 SymTab.ProcRes(qn),
|
|
|
|
|
- 2743 SymTab.ProcDepthOf(qn),
|
|
|
|
|
- 2744 SymTab.IsExternal(qn));
|
|
|
|
|
- 2745 QbeGen.CallEnd(TRUE, q);
|
|
|
|
|
- 2746 t := SymTab.ProcRes(qn)
|
|
|
|
|
- 2747 ELSE
|
|
|
|
|
- 2748 (* procedure used as a
|
|
|
|
|
- 2749 value (assign to a
|
|
|
|
|
- 2750 procedure variable):
|
|
|
|
|
- 2751 its code address *)
|
|
|
|
|
- 2752 t := SymTab.ProcTypeOf(qn);
|
|
|
|
|
- 2753 QbeGen.Mangled(qn,
|
|
|
|
|
- 2754 SymTab.ProcUid(qn), qm0);
|
|
|
|
|
- 2755 QbeGen.ProcAddr(qm0, q)
|
|
|
|
|
- 2756 END
|
|
|
|
|
- 2757 END; .)
|
|
|
|
|
- 2758 | ( "HIGH" (. isHigh := TRUE; .)
|
|
|
|
|
- 2759 | ( "LEN" | "LENGTH" ) (. isHigh := FALSE; .) )
|
|
|
|
|
- 2760 "(" ( Design<dt, dk, qd, qn, sfx> (. isStr := FALSE;
|
|
|
|
|
- 2761 isU := FALSE; .)
|
|
|
|
|
- 2762 | string (. LexString(s);
|
|
|
|
|
- 2763 isStr := TRUE;
|
|
|
|
|
- 2764 isU := FALSE;
|
|
|
|
|
- 2765 IF SymTab.StrLen(s) = 3 THEN
|
|
|
|
|
- 2766 dt := SymTab.CharType();
|
|
|
|
|
- 2767 QbeGen.IntStr(QbeGen.CharVal(s),
|
|
|
|
|
- 2768 qd)
|
|
|
|
|
- 2769 ELSE
|
|
|
|
|
- 2770 dt := SymTab.NewStr();
|
|
|
|
|
- 2771 QbeGen.DeclStr(s, qd);
|
|
|
|
|
- 2772 QbeGen.NoteAddr(qd, qd)
|
|
|
|
|
- 2773 END;
|
|
|
|
|
- 2774 dk := -1;
|
|
|
|
|
- 2775 qn[0] := CHR(0); .)
|
|
|
|
|
- 2776 | ustring (. LexString(s);
|
|
|
|
|
- 2777 QbeGen.DeclUStr(s, qd, isU, ucp,
|
|
|
|
|
- 2778 uok);
|
|
|
|
|
- 2779 isStr := FALSE;
|
|
|
|
|
- 2780 IF NOT uok THEN
|
|
|
|
|
- 2781 SemError(234);
|
|
|
|
|
- 2782 dt := SymTab.InvalidType
|
|
|
|
|
- 2783 ELSIF isU THEN
|
|
|
|
|
- 2784 (* one codepoint: a UCHAR;
|
|
|
|
|
- 2785 LEN is 1, HIGH is 0 *)
|
|
|
|
|
- 2786 dt := SymTab.UCharType();
|
|
|
|
|
- 2787 QbeGen.IntStr(ucp, qd)
|
|
|
|
|
- 2788 ELSE
|
|
|
|
|
- 2789 dt := SymTab.NewUStr();
|
|
|
|
|
- 2790 QbeGen.NoteAddr(qd, qd)
|
|
|
|
|
- 2791 END;
|
|
|
|
|
- 2792 dk := -1;
|
|
|
|
|
- 2793 qn[0] := CHR(0); .) )
|
|
|
|
|
- 2794 ")"
|
|
|
|
|
- 2795 (. IF (dt # SymTab.InvalidType)
|
|
|
|
|
- 2796 AND (SymTab.ClassOf(dt) = SymTab.ClUStr) THEN
|
|
|
|
|
- 2797 (* UString: the count is
|
|
|
|
|
- 2798 the descriptor header *)
|
|
|
|
|
- 2799 IF isHigh THEN
|
|
|
|
|
- 2800 QbeGen.UStrLen(qd, qr);
|
|
|
|
|
- 2801 QbeGen.DecQ(qr)
|
|
|
|
|
- 2802 ELSE
|
|
|
|
|
- 2803 QbeGen.UStrLen(qd, qr)
|
|
|
|
|
- 2804 END;
|
|
|
|
|
- 2805 t := SymTab.IntType();
|
|
|
|
|
- 2806 QbeGen.CopyOp(qr, q)
|
|
|
|
|
- 2807 ELSIF (dt # SymTab.InvalidType)
|
|
|
|
|
- 2808 AND (SymTab.ClassOf(dt) = SymTab.ClUChar) THEN
|
|
|
|
|
- 2809 (* single UCHAR codepoint *)
|
|
|
|
|
- 2810 IF isHigh THEN
|
|
|
|
|
- 2811 QbeGen.CopyOp("0", qr)
|
|
|
|
|
- 2812 ELSE
|
|
|
|
|
- 2813 QbeGen.CopyOp("1", qr)
|
|
|
|
|
- 2814 END;
|
|
|
|
|
- 2815 t := SymTab.IntType();
|
|
|
|
|
- 2816 QbeGen.CopyOp(qr, q)
|
|
|
|
|
- 2817 ELSIF isStr THEN
|
|
|
|
|
- 2818 (* fold: content length at
|
|
|
|
|
- 2819 compile time *)
|
|
|
|
|
- 2820 IF SymTab.StrLen(s) = 3 THEN
|
|
|
|
|
- 2821 c1 := 1
|
|
|
|
|
- 2822 ELSE
|
|
|
|
|
- 2823 c1 :=
|
|
|
|
|
- 2824 SymTab.StrLen(s) - 2
|
|
|
|
|
- 2825 END;
|
|
|
|
|
|
|
+ 2698 ELSE QbeGen.CopyOp(qd, q)
|
|
|
|
|
+ 2699 END;
|
|
|
|
|
+ 2700 IF (dk = SymTab.KindVar)
|
|
|
|
|
+ 2701 OR (dk = SymTab.KindParam)
|
|
|
|
|
+ 2702 OR (dk =
|
|
|
|
|
+ 2703 SymTab.KindField) THEN
|
|
|
|
|
+ 2704 IF sfx THEN
|
|
|
|
|
+ 2705 QbeGen.NoteAddr(q, qd)
|
|
|
|
|
+ 2706 ELSE
|
|
|
|
|
+ 2707 QbeGen.AddrOf(qn, qa);
|
|
|
|
|
+ 2708 QbeGen.NoteAddr(q, qa)
|
|
|
|
|
+ 2709 END
|
|
|
|
|
+ 2710 ELSIF sfx
|
|
|
|
|
+ 2711 AND (dt #
|
|
|
|
|
+ 2712 SymTab.InvalidType)
|
|
|
|
|
+ 2713 AND ((SymTab.ClassOf(dt) =
|
|
|
|
|
+ 2714 SymTab.ClArray)
|
|
|
|
|
+ 2715 OR (SymTab.ClassOf(dt) =
|
|
|
|
|
+ 2716 SymTab.ClSet)
|
|
|
|
|
+ 2717 OR (SymTab.ClassOf(dt) =
|
|
|
|
|
+ 2718 SymTab.ClRecord)) THEN
|
|
|
|
|
+ 2719 QbeGen.NoteAddr(qd, qd)
|
|
|
|
|
+ 2720 END; .)
|
|
|
|
|
+ 2721 [ TypedBraceLit<dt, q> (. t := dt; astCall := TRUE; .) ]
|
|
|
|
|
+ 2722 [ ArgList<qn, dt, qd, TRUE, FALSE, methCls, ct2, q2, called>
|
|
|
|
|
+ 2723 (. astCall := TRUE; t := ct2;
|
|
|
|
|
+ 2724 QbeGen.CopyOp(q2, q);
|
|
|
|
|
+ 2725 sfx := FALSE; .)
|
|
|
|
|
+ 2726 { ResultComp<t, q, sfx> }
|
|
|
|
|
+ 2727 (. IF sfx THEN
|
|
|
|
|
+ 2728 IF t = SymTab.InvalidType THEN
|
|
|
|
|
+ 2729 QbeGen.CopyOp("0", q)
|
|
|
|
|
+ 2730 ELSIF (SymTab.ClassOf(t) #
|
|
|
|
|
+ 2731 SymTab.ClRecord)
|
|
|
|
|
+ 2732 AND (SymTab.ClassOf(t) # SymTab.ClSet)
|
|
|
|
|
+ 2733 AND (SymTab.ClassOf(t) # SymTab.ClArray)
|
|
|
|
|
+ 2734 AND (SymTab.ClassOf(t) # SymTab.ClClass) THEN
|
|
|
|
|
+ 2735 QbeGen.ElemLoad(q, t, q2);
|
|
|
|
|
+ 2736 QbeGen.CopyOp(q2, q)
|
|
|
|
|
+ 2737 END
|
|
|
|
|
+ 2738 END; .) ]
|
|
|
|
|
+ 2739 (. IF called THEN
|
|
|
|
|
+ 2740 astNode := AST.MakeNode(AST.NkCall);
|
|
|
|
|
+ 2741 AST.SetChild(astNode, 0, astD);
|
|
|
|
|
+ 2742 j := 0;
|
|
|
|
|
+ 2743 WHILE (j < astNArgs)
|
|
|
|
|
+ 2744 AND (AST.NChild(astNode) <
|
|
|
|
|
+ 2745 AST.MaxChild) DO
|
|
|
|
|
+ 2746 AST.SetChild(astNode,
|
|
|
|
|
+ 2747 AST.NChild(astNode), astArgs[j]);
|
|
|
|
|
+ 2748 INC(j)
|
|
|
|
|
+ 2749 END;
|
|
|
|
|
+ 2750 astCur := astNode
|
|
|
|
|
+ 2751 ELSIF astCall THEN
|
|
|
|
|
+ 2752 astCur := AST.NoNode
|
|
|
|
|
+ 2753 ELSE astCur := astD
|
|
|
|
|
+ 2754 END;
|
|
|
|
|
+ 2755 astIsLit := TRUE;
|
|
|
|
|
+ 2756 IF NOT called
|
|
|
|
|
+ 2757 AND (dk = SymTab.KindProc) THEN
|
|
|
|
|
+ 2758 (* bare zero-arg function
|
|
|
|
|
+ 2759 call (parentheses may be
|
|
|
|
|
+ 2760 omitted); a proper or
|
|
|
|
|
+ 2761 parameterised proc here
|
|
|
|
|
+ 2762 is 230 *)
|
|
|
|
|
+ 2763 IF (SymTab.ProcNPar(qn) = 0)
|
|
|
|
|
+ 2764 AND (SymTab.ProcRes(qn) #
|
|
|
|
|
+ 2765 SymTab.InvalidType) THEN
|
|
|
|
|
+ 2766 QbeGen.Mangled(qn,
|
|
|
|
|
+ 2767 SymTab.ProcUid(qn), qm0);
|
|
|
|
|
+ 2768 QbeGen.CallBegin(qm0,
|
|
|
|
|
+ 2769 SymTab.ProcRes(qn),
|
|
|
|
|
+ 2770 SymTab.ProcDepthOf(qn),
|
|
|
|
|
+ 2771 SymTab.IsExternal(qn));
|
|
|
|
|
+ 2772 QbeGen.CallEnd(TRUE, q);
|
|
|
|
|
+ 2773 t := SymTab.ProcRes(qn)
|
|
|
|
|
+ 2774 ELSE
|
|
|
|
|
+ 2775 (* procedure used as a
|
|
|
|
|
+ 2776 value (assign to a
|
|
|
|
|
+ 2777 procedure variable):
|
|
|
|
|
+ 2778 its code address *)
|
|
|
|
|
+ 2779 t := SymTab.ProcTypeOf(qn);
|
|
|
|
|
+ 2780 QbeGen.Mangled(qn,
|
|
|
|
|
+ 2781 SymTab.ProcUid(qn), qm0);
|
|
|
|
|
+ 2782 QbeGen.ProcAddr(qm0, q)
|
|
|
|
|
+ 2783 END
|
|
|
|
|
+ 2784 END; .)
|
|
|
|
|
+ 2785 | ( "HIGH" (. isHigh := TRUE; .)
|
|
|
|
|
+ 2786 | ( "LEN" | "LENGTH" ) (. isHigh := FALSE; .) )
|
|
|
|
|
+ 2787 "(" ( Design<dt, dk, qd, qn, sfx> (. isStr := FALSE;
|
|
|
|
|
+ 2788 isU := FALSE; .)
|
|
|
|
|
+ 2789 | string (. LexString(s);
|
|
|
|
|
+ 2790 isStr := TRUE;
|
|
|
|
|
+ 2791 isU := FALSE;
|
|
|
|
|
+ 2792 IF SymTab.StrLen(s) = 3 THEN
|
|
|
|
|
+ 2793 dt := SymTab.CharType();
|
|
|
|
|
+ 2794 QbeGen.IntStr(QbeGen.CharVal(s),
|
|
|
|
|
+ 2795 qd)
|
|
|
|
|
+ 2796 ELSE
|
|
|
|
|
+ 2797 dt := SymTab.NewStr();
|
|
|
|
|
+ 2798 QbeGen.DeclStr(s, qd);
|
|
|
|
|
+ 2799 QbeGen.NoteAddr(qd, qd)
|
|
|
|
|
+ 2800 END;
|
|
|
|
|
+ 2801 dk := -1;
|
|
|
|
|
+ 2802 qn[0] := CHR(0); .)
|
|
|
|
|
+ 2803 | ustring (. LexString(s);
|
|
|
|
|
+ 2804 QbeGen.DeclUStr(s, qd, isU, ucp,
|
|
|
|
|
+ 2805 uok);
|
|
|
|
|
+ 2806 isStr := FALSE;
|
|
|
|
|
+ 2807 IF NOT uok THEN
|
|
|
|
|
+ 2808 SemError(234);
|
|
|
|
|
+ 2809 dt := SymTab.InvalidType
|
|
|
|
|
+ 2810 ELSIF isU THEN
|
|
|
|
|
+ 2811 (* one codepoint: a UCHAR;
|
|
|
|
|
+ 2812 LEN is 1, HIGH is 0 *)
|
|
|
|
|
+ 2813 dt := SymTab.UCharType();
|
|
|
|
|
+ 2814 QbeGen.IntStr(ucp, qd)
|
|
|
|
|
+ 2815 ELSE
|
|
|
|
|
+ 2816 dt := SymTab.NewUStr();
|
|
|
|
|
+ 2817 QbeGen.NoteAddr(qd, qd)
|
|
|
|
|
+ 2818 END;
|
|
|
|
|
+ 2819 dk := -1;
|
|
|
|
|
+ 2820 qn[0] := CHR(0); .) )
|
|
|
|
|
+ 2821 ")"
|
|
|
|
|
+ 2822 (. IF (dt # SymTab.InvalidType)
|
|
|
|
|
+ 2823 AND (SymTab.ClassOf(dt) = SymTab.ClUStr) THEN
|
|
|
|
|
+ 2824 (* UString: the count is
|
|
|
|
|
+ 2825 the descriptor header *)
|
|
|
2826 IF isHigh THEN
|
|
2826 IF isHigh THEN
|
|
|
- 2827 DEC(c1)
|
|
|
|
|
- 2828 END;
|
|
|
|
|
- 2829 QbeGen.IntStr(c1, qr);
|
|
|
|
|
- 2830 t := SymTab.IntType();
|
|
|
|
|
- 2831 QbeGen.CopyOp(qr, q)
|
|
|
|
|
- 2832 ELSIF dt = SymTab.InvalidType THEN
|
|
|
|
|
- 2833 t := SymTab.InvalidType;
|
|
|
|
|
- 2834 QbeGen.CopyOp("0", q)
|
|
|
|
|
- 2835 ELSIF SymTab.ClassOf(dt) #
|
|
|
|
|
- 2836 SymTab.ClArray THEN
|
|
|
|
|
- 2837 SemError(217);
|
|
|
|
|
- 2838 t := SymTab.InvalidType;
|
|
|
|
|
- 2839 QbeGen.CopyOp("0", q)
|
|
|
|
|
- 2840 ELSE
|
|
|
|
|
- 2841 IF isHigh THEN
|
|
|
|
|
- 2842 IF SymTab.IsOpenArray(dt) THEN
|
|
|
|
|
- 2843 QbeGen.OpenHi(qd, qr)
|
|
|
|
|
- 2844 ELSE
|
|
|
|
|
- 2845 QbeGen.IntStr(
|
|
|
|
|
- 2846 SymTab.ArrayHi(dt), qr)
|
|
|
|
|
- 2847 END
|
|
|
|
|
- 2848 ELSE
|
|
|
|
|
- 2849 IF SymTab.IsOpenArray(dt) THEN
|
|
|
|
|
- 2850 QbeGen.LoadCount(qd, qr)
|
|
|
|
|
- 2851 ELSE
|
|
|
|
|
- 2852 QbeGen.IntStr(VAL(
|
|
|
|
|
- 2853 INTEGER,
|
|
|
|
|
- 2854 SymTab.ArrayLen(dt)),
|
|
|
|
|
- 2855 qr)
|
|
|
|
|
- 2856 END
|
|
|
|
|
- 2857 END;
|
|
|
|
|
- 2858 t := SymTab.IntType();
|
|
|
|
|
- 2859 QbeGen.CopyOp(qr, q)
|
|
|
|
|
- 2860 END; .)
|
|
|
|
|
- 2861 | ( "SIZE" | "TSIZE" ) "(" Design<dt, dk, qd, qn, sfx> ")"
|
|
|
|
|
- 2862 (. IF dt = SymTab.InvalidType THEN
|
|
|
|
|
- 2863 t := SymTab.InvalidType;
|
|
|
|
|
- 2864 QbeGen.CopyOp("0", q)
|
|
|
|
|
- 2865 ELSE
|
|
|
|
|
- 2866 QbeGen.IntStr(VAL(INTEGER,
|
|
|
|
|
- 2867 SymTab.ObjectSize(dt)), q);
|
|
|
|
|
- 2868 t := SymTab.IntType()
|
|
|
|
|
- 2869 END; .)
|
|
|
|
|
- 2870 | ( "SHIFT" (. isMax := FALSE; .)
|
|
|
|
|
- 2871 | "ROTATE" (. isMax := TRUE; .) )
|
|
|
|
|
- 2872 "(" Expr<et, q> "," Expr<et2, q2> ")"
|
|
|
|
|
- 2873 (. (* set shift/rotate: isMax
|
|
|
|
|
- 2874 doubles as "rotate" *)
|
|
|
|
|
- 2875 IF (et # SymTab.InvalidType)
|
|
|
|
|
- 2876 AND (SymTab.ClassOf(et) =
|
|
|
|
|
- 2877 SymTab.ClSet) THEN
|
|
|
|
|
- 2878 QbeGen.SetShift(q, q2,
|
|
|
|
|
- 2879 SymTab.SetWords(et),
|
|
|
|
|
- 2880 SymTab.SetCount(et), isMax,
|
|
|
|
|
- 2881 qt);
|
|
|
|
|
- 2882 t := et;
|
|
|
|
|
- 2883 QbeGen.CopyOp(qt, q)
|
|
|
|
|
- 2884 ELSE SemError(230);
|
|
|
|
|
- 2885 t := SymTab.InvalidType;
|
|
|
|
|
- 2886 QbeGen.CopyOp("0", q)
|
|
|
|
|
- 2887 END; .)
|
|
|
|
|
- 2888 | ( "MIN" (. isMax := FALSE; .)
|
|
|
|
|
- 2889 | "MAX" (. isMax := TRUE; .) )
|
|
|
|
|
- 2890 "(" Design<dt, dk, qd, qn, sfx> ")"
|
|
|
|
|
- 2891 (. IF (dt # SymTab.InvalidType)
|
|
|
|
|
- 2892 AND (SymTab.ClassOf(dt) = SymTab.ClReal) THEN
|
|
|
|
|
- 2893 (* REAL/LONGREAL: the
|
|
|
|
|
- 2894 implementation bounds *)
|
|
|
|
|
- 2895 IF isMax THEN
|
|
|
|
|
- 2896 QbeGen.NormReal(
|
|
|
|
|
- 2897 "3.402823e38", q)
|
|
|
|
|
- 2898 ELSE QbeGen.NormReal(
|
|
|
|
|
- 2899 "-3.402823e38", q)
|
|
|
|
|
- 2900 END;
|
|
|
|
|
- 2901 t := SymTab.RealType()
|
|
|
|
|
- 2902 ELSIF (dt #
|
|
|
|
|
- 2903 SymTab.InvalidType)
|
|
|
|
|
- 2904 AND (SymTab.ClassOf(dt) =
|
|
|
|
|
- 2905 SymTab.ClLong) THEN
|
|
|
|
|
- 2906 IF isMax THEN
|
|
|
|
|
- 2907 QbeGen.CopyOp(
|
|
|
|
|
- 2908 "9223372036854775807", q)
|
|
|
|
|
- 2909 ELSE QbeGen.CopyOp(
|
|
|
|
|
- 2910 "-9223372036854775808", q)
|
|
|
|
|
- 2911 END;
|
|
|
|
|
- 2912 t := SymTab.LongType()
|
|
|
|
|
- 2913 ELSIF SymTab.TypeBounds(dt, lo,
|
|
|
|
|
- 2914 hi) THEN
|
|
|
|
|
- 2915 IF isMax THEN
|
|
|
|
|
- 2916 QbeGen.IntStr(hi, q)
|
|
|
|
|
- 2917 ELSE QbeGen.IntStr(lo, q)
|
|
|
|
|
- 2918 END;
|
|
|
|
|
- 2919 t := SymTab.IntType()
|
|
|
|
|
- 2920 ELSE SemError(230);
|
|
|
|
|
- 2921 t := SymTab.InvalidType;
|
|
|
|
|
- 2922 QbeGen.CopyOp("0", q)
|
|
|
|
|
- 2923 END; .)
|
|
|
|
|
- 2924 | "ADR" "(" Design<dt, dk, qd, qn, sfx> ")"
|
|
|
|
|
- 2925 (. IF dt = SymTab.InvalidType THEN
|
|
|
|
|
- 2926 t := SymTab.InvalidType;
|
|
|
|
|
- 2927 QbeGen.CopyOp("0", q)
|
|
|
|
|
- 2928 ELSE
|
|
|
|
|
- 2929 IF sfx THEN
|
|
|
|
|
- 2930 QbeGen.CopyOp(qd, q)
|
|
|
|
|
- 2931 ELSIF (dk = SymTab.KindVar)
|
|
|
|
|
- 2932 OR (dk = SymTab.KindParam) THEN
|
|
|
|
|
- 2933 QbeGen.AddrOf(qn, q)
|
|
|
|
|
- 2934 ELSE SemError(230);
|
|
|
|
|
- 2935 QbeGen.CopyOp("0", q)
|
|
|
|
|
- 2936 END;
|
|
|
|
|
- 2937 t := SymTab.AddrType()
|
|
|
|
|
- 2938 END; .)
|
|
|
|
|
- 2939 | "CHR" "(" Expr<et, q> ")"
|
|
|
|
|
- 2940 (. IF (et # SymTab.InvalidType)
|
|
|
|
|
- 2941 AND NOT SymTab.IsIntFamily(et) THEN
|
|
|
|
|
- 2942 SemError(211) END;
|
|
|
|
|
- 2943 t := SymTab.CharType(); .)
|
|
|
|
|
- 2944 | ( "ORD" | "ORDL" ) "(" Expr<et, q> ")"
|
|
|
|
|
- 2945 (. IF et # SymTab.InvalidType THEN
|
|
|
|
|
- 2946 IF (SymTab.ClassOf(et) #
|
|
|
|
|
- 2947 SymTab.ClChar)
|
|
|
|
|
- 2948 AND (SymTab.ClassOf(et) #
|
|
|
|
|
- 2949 SymTab.ClBool)
|
|
|
|
|
- 2950 AND (SymTab.ClassOf(et) #
|
|
|
|
|
- 2951 SymTab.ClEnum)
|
|
|
|
|
- 2952 AND NOT SymTab.IsIntFamily(et) THEN
|
|
|
|
|
- 2953 SemError(211) END
|
|
|
|
|
- 2954 END;
|
|
|
|
|
- 2955 t := SymTab.IntType(); .)
|
|
|
|
|
- 2956 | "CAP" "(" Expr<et, q> ")"
|
|
|
|
|
- 2957 (. QbeGen.CapQ(q, qa);
|
|
|
|
|
- 2958 QbeGen.CopyOp(qa, q);
|
|
|
|
|
- 2959 t := SymTab.CharType(); .)
|
|
|
|
|
- 2960 | "UCHR" "(" Expr<et, q> ")"
|
|
|
|
|
- 2961 (. (* UCHR: the UCHAR constructor.
|
|
|
|
|
- 2962 CHAR -> UCHAR (identity);
|
|
|
|
|
- 2963 INTEGER familly -> UCHAR
|
|
|
|
|
- 2964 (codepoint value). *)
|
|
|
|
|
- 2965 IF (et # SymTab.InvalidType)
|
|
|
|
|
- 2966 AND (SymTab.ClassOf(et) # SymTab.ClChar)
|
|
|
|
|
- 2967 AND NOT SymTab.IsIntFamily(et) THEN
|
|
|
|
|
- 2968 SemError(211) END;
|
|
|
|
|
- 2969 t := SymTab.UCharType(); .)
|
|
|
|
|
- 2970 | "CHR8" "(" Expr<et, q> ")"
|
|
|
|
|
- 2971 (. IF (et # SymTab.InvalidType)
|
|
|
|
|
- 2972 AND (SymTab.ClassOf(et) # SymTab.ClUChar) THEN
|
|
|
|
|
- 2973 SemError(211) END;
|
|
|
|
|
- 2974 QbeGen.WidenLong(q, qa);
|
|
|
|
|
- 2975 QbeGen.CheckRange(qa, "0", "255");
|
|
|
|
|
- 2976 t := SymTab.CharType(); .)
|
|
|
|
|
- 2977 | "UORD" "(" Expr<et, q> ")"
|
|
|
|
|
- 2978 (. (* UORD(u): the codepoint as a
|
|
|
|
|
- 2979 32-bit ordinal (INTEGER),
|
|
|
|
|
- 2980 cf. ORD for CHAR. *)
|
|
|
|
|
- 2981 IF (et # SymTab.InvalidType)
|
|
|
|
|
- 2982 AND (SymTab.ClassOf(et) # SymTab.ClUChar) THEN
|
|
|
|
|
- 2983 SemError(211) END;
|
|
|
|
|
- 2984 t := SymTab.IntType(); .)
|
|
|
|
|
- 2985 | "ABS" "(" Expr<et, q> ")"
|
|
|
|
|
- 2986 (. IF (et # SymTab.InvalidType)
|
|
|
|
|
- 2987 AND NOT SymTab.IsIntFamily(et)
|
|
|
|
|
- 2988 AND (SymTab.ClassOf(et) #
|
|
|
|
|
- 2989 SymTab.ClReal) THEN
|
|
|
|
|
- 2990 SemError(211)
|
|
|
|
|
- 2991 ELSE QbeGen.AbsQ(q, qa,
|
|
|
|
|
- 2992 SymTab.ClassOf(et) =
|
|
|
|
|
- 2993 SymTab.ClReal);
|
|
|
|
|
- 2994 QbeGen.CopyOp(qa, q)
|
|
|
|
|
- 2995 END;
|
|
|
|
|
- 2996 t := et; .)
|
|
|
|
|
- 2997 | "VAL" "(" GetIdent<vn> "," Expr<et, q> ")"
|
|
|
|
|
- 2998 (. IF NOT SymTab.Lookup(vn) THEN
|
|
|
|
|
- 2999 SemError(201);
|
|
|
|
|
- 3000 t := SymTab.InvalidType
|
|
|
|
|
- 3001 ELSE vt := SymTab.SymType(vn);
|
|
|
|
|
- 3002 IF vt = SymTab.InvalidType THEN
|
|
|
|
|
- 3003 t := SymTab.InvalidType
|
|
|
|
|
- 3004 ELSIF et =
|
|
|
|
|
- 3005 SymTab.InvalidType THEN
|
|
|
|
|
- 3006 t := vt
|
|
|
|
|
- 3007 ELSE
|
|
|
|
|
- 3008 c1 := SymTab.ClassOf(et);
|
|
|
|
|
- 3009 c2 := SymTab.ClassOf(vt);
|
|
|
|
|
- 3010 IF (c1 = SymTab.ClInt)
|
|
|
|
|
- 3011 AND (c2 = SymTab.ClLong) THEN
|
|
|
|
|
- 3012 QbeGen.WidenLong(q, qa);
|
|
|
|
|
- 3013 QbeGen.CopyOp(qa, q);
|
|
|
|
|
- 3014 t := vt
|
|
|
|
|
- 3015 ELSIF (c1 = SymTab.ClLong)
|
|
|
|
|
- 3016 AND (c2 = SymTab.ClInt) THEN
|
|
|
|
|
- 3017 QbeGen.NarrowLong(q, qa);
|
|
|
|
|
- 3018 QbeGen.CopyOp(qa, q);
|
|
|
|
|
- 3019 t := vt
|
|
|
|
|
- 3020 ELSIF (c1 = SymTab.ClInt)
|
|
|
|
|
- 3021 AND (c2 = SymTab.ClReal) THEN
|
|
|
|
|
- 3022 QbeGen.ConvIR(q, qa);
|
|
|
|
|
- 3023 QbeGen.CopyOp(qa, q);
|
|
|
|
|
- 3024 t := vt
|
|
|
|
|
- 3025 ELSIF (c1 = SymTab.ClLong)
|
|
|
|
|
- 3026 AND (c2 = SymTab.ClReal) THEN
|
|
|
|
|
- 3027 QbeGen.ConvLR(q, qa);
|
|
|
|
|
- 3028 QbeGen.CopyOp(qa, q);
|
|
|
|
|
- 3029 t := vt
|
|
|
|
|
- 3030 ELSIF (c1 = SymTab.ClReal)
|
|
|
|
|
- 3031 AND (c2 = SymTab.ClInt) THEN
|
|
|
|
|
- 3032 QbeGen.ConvRI(q, qa);
|
|
|
|
|
- 3033 QbeGen.CopyOp(qa, q);
|
|
|
|
|
- 3034 t := vt
|
|
|
|
|
- 3035 ELSIF (c1 = SymTab.ClReal)
|
|
|
|
|
- 3036 AND (c2 = SymTab.ClLong) THEN
|
|
|
|
|
- 3037 QbeGen.ConvRL(q, qa);
|
|
|
|
|
- 3038 QbeGen.CopyOp(qa, q);
|
|
|
|
|
- 3039 t := vt
|
|
|
|
|
- 3040 ELSIF ((c1 = SymTab.ClInt)
|
|
|
|
|
- 3041 OR (c1 =
|
|
|
|
|
- 3042 SymTab.ClChar)
|
|
|
|
|
- 3043 OR (c1 =
|
|
|
|
|
- 3044 SymTab.ClBool)
|
|
|
|
|
- 3045 OR (c1 =
|
|
|
|
|
- 3046 SymTab.ClEnum))
|
|
|
|
|
- 3047 AND ((c2 = SymTab.ClInt)
|
|
|
|
|
- 3048 OR (c2 =
|
|
|
|
|
- 3049 SymTab.ClChar)
|
|
|
|
|
- 3050 OR (c2 =
|
|
|
|
|
- 3051 SymTab.ClBool)
|
|
|
|
|
- 3052 OR (c2 =
|
|
|
|
|
- 3053 SymTab.ClEnum)) THEN
|
|
|
|
|
- 3054 t := vt
|
|
|
|
|
- 3055 ELSIF (c1 = SymTab.ClPtr)
|
|
|
|
|
- 3056 AND (c2 = SymTab.ClPtr) THEN
|
|
|
|
|
- 3057 t := vt
|
|
|
|
|
- 3058 ELSIF (c1 = SymTab.ClReal)
|
|
|
|
|
- 3059 AND (c2 = SymTab.ClReal) THEN
|
|
|
|
|
- 3060 t := vt
|
|
|
|
|
- 3061 ELSE SemError(230);
|
|
|
|
|
- 3062 t := SymTab.InvalidType
|
|
|
|
|
- 3063 END
|
|
|
|
|
- 3064 END
|
|
|
|
|
- 3065 END; .)
|
|
|
|
|
- 3066 | "(" Expr<et, q> ")" (. t := et; astIsLit := TRUE; .)
|
|
|
|
|
- 3067 | SetLit<st, sq> (. t := st;
|
|
|
|
|
- 3068 QbeGen.CopyOp(sq, q); .)
|
|
|
|
|
- 3069 | ( "NOT" | "~" ) Fact<t2, q2> (. IF SymTab.BoolCheck(t2) THEN
|
|
|
|
|
- 3070 t := SymTab.BoolType()
|
|
|
|
|
- 3071 ELSE SemError(212);
|
|
|
|
|
- 3072 t := SymTab.InvalidType END;
|
|
|
|
|
- 3073 IF t # SymTab.InvalidType THEN
|
|
|
|
|
- 3074 QbeGen.NotQ(q2, q)
|
|
|
|
|
- 3075 ELSE QbeGen.CopyOp("0", q)
|
|
|
|
|
- 3076 END; .)
|
|
|
|
|
- 3077 )
|
|
|
|
|
- 3078 (. IF NOT astIsLit THEN astCur := AST.NoNode END; .) .
|
|
|
|
|
- 3079 (* Set literals are SET OF [0..255] (8 words); elements validated
|
|
|
|
|
- 3080 0..255 statically when foldable (222 otherwise), runtime trap
|
|
|
|
|
- 3081 for computed elements. Ranges always lower via SetRange. *)
|
|
|
|
|
- 3082 SetLit<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
|
|
- 3083 = "{" (. t := SymTab.NewSet(
|
|
|
|
|
- 3084 SymTab.NewSubR(0, 255));
|
|
|
|
|
- 3085 QbeGen.NewSetTemp(8, q);
|
|
|
|
|
- 3086 QbeGen.SetZero(q, 8); .)
|
|
|
|
|
- 3087 [ SetElem<t, q> { "," SetElem<t, q> } ]
|
|
|
|
|
- 3088 "}" .
|
|
|
|
|
- 3089 (* Typed brace constructor: TypeName{ elems } — BITSET{0} (a set)
|
|
|
|
|
- 3090 or ArrayName{...} (an array constructor, GNU Modula-2). The
|
|
|
|
|
- 3091 declared type sets the width (set) or element type (array). *)
|
|
|
|
|
- 3092 TypedBraceLit<vt: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
|
|
- 3093 (. VAR nw: CARDINAL;
|
|
|
|
|
- 3094 savedCls: INTEGER; .)
|
|
|
|
|
- 3095 = "{" (. savedCls := braceCls;
|
|
|
|
|
- 3096 IF vt = SymTab.InvalidType THEN
|
|
|
|
|
- 3097 braceCls := -1
|
|
|
|
|
- 3098 ELSE braceCls :=
|
|
|
|
|
- 3099 SymTab.ClassOf(vt)
|
|
|
|
|
- 3100 END;
|
|
|
|
|
- 3101 IF braceCls = SymTab.ClSet THEN
|
|
|
|
|
- 3102 IF vt = SymTab.InvalidType THEN
|
|
|
|
|
- 3103 nw := 8
|
|
|
|
|
- 3104 ELSE nw := SymTab.SetWords(vt);
|
|
|
|
|
- 3105 IF nw = 0 THEN nw := 8 END
|
|
|
|
|
- 3106 END;
|
|
|
|
|
- 3107 QbeGen.NewSetTemp(nw, q);
|
|
|
|
|
- 3108 QbeGen.SetZero(q, nw)
|
|
|
|
|
- 3109 ELSIF (braceCls =
|
|
|
|
|
- 3110 SymTab.ClArray)
|
|
|
|
|
- 3111 OR (braceCls =
|
|
|
|
|
- 3112 SymTab.ClRecord)
|
|
|
|
|
- 3113 OR (braceCls =
|
|
|
|
|
- 3114 SymTab.ClClass) THEN
|
|
|
|
|
- 3115 QbeGen.CtorBegin(vt)
|
|
|
|
|
- 3116 ELSE
|
|
|
|
|
- 3117 IF vt # SymTab.InvalidType THEN
|
|
|
|
|
- 3118 SemError(230) END;
|
|
|
|
|
- 3119 braceCls := -1
|
|
|
|
|
- 3120 END; .)
|
|
|
|
|
- 3121 [ BraceElem<vt, q> { "," BraceElem<vt, q> } ]
|
|
|
|
|
- 3122 "}" (. IF (braceCls = SymTab.ClArray)
|
|
|
|
|
- 3123 OR (braceCls =
|
|
|
|
|
- 3124 SymTab.ClRecord)
|
|
|
|
|
- 3125 OR (braceCls =
|
|
|
|
|
- 3126 SymTab.ClClass) THEN
|
|
|
|
|
- 3127 QbeGen.CtorEnd(q)
|
|
|
|
|
- 3128 ELSIF braceCls # SymTab.ClSet THEN
|
|
|
|
|
- 3129 QbeGen.CopyOp("0", q)
|
|
|
|
|
- 3130 END;
|
|
|
|
|
- 3131 braceCls := savedCls; .) .
|
|
|
|
|
- 3132 BraceElem<vt: SymTab.TypeIndex; VAR sq: QbeGen.QVal>
|
|
|
|
|
- 3133 (. VAR et, et2: SymTab.TypeIndex;
|
|
|
|
|
- 3134 qe, q2: QbeGen.QVal;
|
|
|
|
|
- 3135 v, v2, reps, k: INTEGER;
|
|
|
|
|
- 3136 elem: SymTab.TypeIndex;
|
|
|
|
|
- 3137 lo: INTEGER;
|
|
|
|
|
- 3138 span: CARDINAL;
|
|
|
|
|
- 3139 cl, cl2: INTEGER;
|
|
|
|
|
- 3140 hasR, hasB: BOOLEAN; .)
|
|
|
|
|
- 3141 = (. hasR := FALSE; hasB := FALSE; .)
|
|
|
|
|
- 3142 Expr<et, qe>
|
|
|
|
|
- 3143 [ ".." Expr<et2, q2> (. hasR := TRUE; .) ]
|
|
|
|
|
- 3144 [ "BY" Expr<et2, q2> (. hasB := TRUE; .) ]
|
|
|
|
|
- 3145 (. IF braceCls = SymTab.ClSet THEN
|
|
|
|
|
- 3146 IF hasB THEN SemError(230) END;
|
|
|
|
|
- 3147 lo := SymTab.SetBaseLo(vt);
|
|
|
|
|
- 3148 span := SymTab.SetCount(vt);
|
|
|
|
|
- 3149 IF (et = SymTab.InvalidType)
|
|
|
|
|
- 3150 OR (hasR AND (et2 =
|
|
|
|
|
- 3151 SymTab.InvalidType)) THEN
|
|
|
|
|
- 3152 ELSE cl :=
|
|
|
|
|
- 3153 SymTab.ClassOf(et);
|
|
|
|
|
- 3154 IF hasR THEN
|
|
|
|
|
- 3155 cl2 :=
|
|
|
|
|
- 3156 SymTab.ClassOf(et2)
|
|
|
|
|
- 3157 ELSE cl2 := SymTab.ClInt
|
|
|
|
|
- 3158 END;
|
|
|
|
|
- 3159 IF NOT SymTab.SetElemClassOk(cl)
|
|
|
|
|
- 3160 OR (hasR AND NOT
|
|
|
|
|
- 3161 SymTab.SetElemClassOk(cl2))
|
|
|
|
|
- 3162 THEN
|
|
|
|
|
- 3163 SemError(222)
|
|
|
|
|
- 3164 ELSIF hasR
|
|
|
|
|
- 3165 AND SymTab.ConstInt(qe, v)
|
|
|
|
|
- 3166 AND SymTab.ConstInt(q2,
|
|
|
|
|
- 3167 v2)
|
|
|
|
|
- 3168 AND ((v < lo)
|
|
|
|
|
- 3169 OR (v2 < lo)
|
|
|
|
|
- 3170 OR (v >= lo +
|
|
|
|
|
- 3171 VAL(INTEGER, span))
|
|
|
|
|
- 3172 OR (v2 >= lo +
|
|
|
|
|
- 3173 VAL(INTEGER, span))
|
|
|
|
|
- 3174 OR (v > v2)) THEN
|
|
|
|
|
- 3175 SemError(222)
|
|
|
|
|
- 3176 ELSIF hasR THEN
|
|
|
|
|
- 3177 QbeGen.SetRange(sq, qe, q2,
|
|
|
|
|
- 3178 lo, span)
|
|
|
|
|
- 3179 ELSIF SymTab.ConstInt(qe,
|
|
|
|
|
- 3180 v)
|
|
|
|
|
- 3181 AND ((v < lo)
|
|
|
|
|
- 3182 OR (v >= lo +
|
|
|
|
|
- 3183 VAL(INTEGER,
|
|
|
|
|
- 3184 span))) THEN
|
|
|
|
|
- 3185 SemError(222)
|
|
|
|
|
- 3186 ELSE QbeGen.SetBit(sq, qe,
|
|
|
|
|
- 3187 lo, span)
|
|
|
|
|
- 3188 END
|
|
|
|
|
- 3189 END
|
|
|
|
|
- 3190 ELSIF (braceCls = SymTab.ClArray)
|
|
|
|
|
- 3191 OR (braceCls =
|
|
|
|
|
- 3192 SymTab.ClRecord)
|
|
|
|
|
- 3193 OR (braceCls =
|
|
|
|
|
- 3194 SymTab.ClClass) THEN
|
|
|
|
|
- 3195 IF hasR THEN SemError(230) END;
|
|
|
|
|
- 3196 reps := 1;
|
|
|
|
|
- 3197 IF hasB THEN
|
|
|
|
|
- 3198 IF SymTab.ConstInt(q2, v2)
|
|
|
|
|
- 3199 AND (v2 >= 1) THEN
|
|
|
|
|
- 3200 reps := v2
|
|
|
|
|
- 3201 ELSE SemError(230)
|
|
|
|
|
- 3202 END
|
|
|
|
|
- 3203 END;
|
|
|
|
|
- 3204 k := 0;
|
|
|
|
|
- 3205 WHILE k < reps DO
|
|
|
|
|
- 3206 QbeGen.CtorElem(qe);
|
|
|
|
|
- 3207 INC(k)
|
|
|
|
|
- 3208 END
|
|
|
|
|
- 3209 END; .) .
|
|
|
|
|
- 3210 SetElem<st: SymTab.TypeIndex; sq: QbeGen.QVal> (. VAR et, et2: SymTab.TypeIndex;
|
|
|
|
|
- 3211 qe, q2: QbeGen.QVal;
|
|
|
|
|
- 3212 v, v2: INTEGER;
|
|
|
|
|
- 3213 lo: INTEGER;
|
|
|
|
|
- 3214 span: CARDINAL;
|
|
|
|
|
- 3215 cl, cl2: INTEGER;
|
|
|
|
|
- 3216 hasR: BOOLEAN; .)
|
|
|
|
|
- 3217 = (. hasR := FALSE; .)
|
|
|
|
|
- 3218 Expr<et, qe>
|
|
|
|
|
- 3219 [ ".." Expr<et2, q2> (. hasR := TRUE; .) ]
|
|
|
|
|
- 3220 (. lo := SymTab.SetBaseLo(st);
|
|
|
|
|
- 3221 span := SymTab.SetCount(st);
|
|
|
|
|
- 3222 IF (et = SymTab.InvalidType)
|
|
|
|
|
- 3223 OR (hasR AND (et2 =
|
|
|
|
|
- 3224 SymTab.InvalidType)) THEN
|
|
|
|
|
- 3225 ELSE cl :=
|
|
|
|
|
- 3226 SymTab.ClassOf(et);
|
|
|
|
|
- 3227 IF hasR THEN
|
|
|
|
|
- 3228 cl2 :=
|
|
|
|
|
- 3229 SymTab.ClassOf(et2)
|
|
|
|
|
- 3230 ELSE cl2 := SymTab.ClInt
|
|
|
|
|
- 3231 END;
|
|
|
|
|
- 3232 IF NOT SymTab.SetElemClassOk(cl)
|
|
|
|
|
- 3233 OR (hasR AND NOT
|
|
|
|
|
- 3234 SymTab.SetElemClassOk(cl2))
|
|
|
|
|
- 3235 THEN
|
|
|
|
|
- 3236 SemError(222)
|
|
|
|
|
- 3237 ELSIF hasR
|
|
|
|
|
- 3238 AND SymTab.ConstInt(qe, v)
|
|
|
|
|
- 3239 AND SymTab.ConstInt(q2,
|
|
|
|
|
- 3240 v2)
|
|
|
|
|
- 3241 AND ((v < lo)
|
|
|
|
|
- 3242 OR (v2 < lo)
|
|
|
|
|
- 3243 OR (v >= lo +
|
|
|
|
|
- 3244 VAL(INTEGER, span))
|
|
|
|
|
- 3245 OR (v2 >= lo +
|
|
|
|
|
- 3246 VAL(INTEGER, span))
|
|
|
|
|
- 3247 OR (v > v2)) THEN
|
|
|
|
|
- 3248 SemError(222)
|
|
|
|
|
- 3249 ELSIF hasR THEN
|
|
|
|
|
- 3250 QbeGen.SetRange(sq, qe, q2,
|
|
|
|
|
- 3251 lo, span)
|
|
|
|
|
- 3252 ELSIF SymTab.ConstInt(qe,
|
|
|
|
|
- 3253 v)
|
|
|
|
|
- 3254 AND ((v < lo)
|
|
|
|
|
- 3255 OR (v >= lo +
|
|
|
|
|
- 3256 VAL(INTEGER,
|
|
|
|
|
- 3257 span))) THEN
|
|
|
|
|
- 3258 SemError(222)
|
|
|
|
|
- 3259 ELSE QbeGen.SetBit(sq, qe,
|
|
|
|
|
- 3260 lo, span)
|
|
|
|
|
- 3261 END
|
|
|
|
|
- 3262 END; .) .
|
|
|
|
|
- 3263 GetIdent<VAR n: SymTab.Name>
|
|
|
|
|
- 3264 = ident (. LexName(n); .) .
|
|
|
|
|
- 3265
|
|
|
|
|
- 3266 END M2.
|
|
|
|
|
|
|
+ 2827 QbeGen.UStrLen(qd, qr);
|
|
|
|
|
+ 2828 QbeGen.DecQ(qr)
|
|
|
|
|
+ 2829 ELSE
|
|
|
|
|
+ 2830 QbeGen.UStrLen(qd, qr)
|
|
|
|
|
+ 2831 END;
|
|
|
|
|
+ 2832 t := SymTab.IntType();
|
|
|
|
|
+ 2833 QbeGen.CopyOp(qr, q)
|
|
|
|
|
+ 2834 ELSIF (dt # SymTab.InvalidType)
|
|
|
|
|
+ 2835 AND (SymTab.ClassOf(dt) = SymTab.ClUChar) THEN
|
|
|
|
|
+ 2836 (* single UCHAR codepoint *)
|
|
|
|
|
+ 2837 IF isHigh THEN
|
|
|
|
|
+ 2838 QbeGen.CopyOp("0", qr)
|
|
|
|
|
+ 2839 ELSE
|
|
|
|
|
+ 2840 QbeGen.CopyOp("1", qr)
|
|
|
|
|
+ 2841 END;
|
|
|
|
|
+ 2842 t := SymTab.IntType();
|
|
|
|
|
+ 2843 QbeGen.CopyOp(qr, q)
|
|
|
|
|
+ 2844 ELSIF isStr THEN
|
|
|
|
|
+ 2845 (* fold: content length at
|
|
|
|
|
+ 2846 compile time *)
|
|
|
|
|
+ 2847 IF SymTab.StrLen(s) = 3 THEN
|
|
|
|
|
+ 2848 c1 := 1
|
|
|
|
|
+ 2849 ELSE
|
|
|
|
|
+ 2850 c1 :=
|
|
|
|
|
+ 2851 SymTab.StrLen(s) - 2
|
|
|
|
|
+ 2852 END;
|
|
|
|
|
+ 2853 IF isHigh THEN
|
|
|
|
|
+ 2854 DEC(c1)
|
|
|
|
|
+ 2855 END;
|
|
|
|
|
+ 2856 QbeGen.IntStr(c1, qr);
|
|
|
|
|
+ 2857 t := SymTab.IntType();
|
|
|
|
|
+ 2858 QbeGen.CopyOp(qr, q)
|
|
|
|
|
+ 2859 ELSIF dt = SymTab.InvalidType THEN
|
|
|
|
|
+ 2860 t := SymTab.InvalidType;
|
|
|
|
|
+ 2861 QbeGen.CopyOp("0", q)
|
|
|
|
|
+ 2862 ELSIF SymTab.ClassOf(dt) #
|
|
|
|
|
+ 2863 SymTab.ClArray THEN
|
|
|
|
|
+ 2864 SemError(217);
|
|
|
|
|
+ 2865 t := SymTab.InvalidType;
|
|
|
|
|
+ 2866 QbeGen.CopyOp("0", q)
|
|
|
|
|
+ 2867 ELSE
|
|
|
|
|
+ 2868 IF isHigh THEN
|
|
|
|
|
+ 2869 IF SymTab.IsOpenArray(dt) THEN
|
|
|
|
|
+ 2870 QbeGen.OpenHi(qd, qr)
|
|
|
|
|
+ 2871 ELSE
|
|
|
|
|
+ 2872 QbeGen.IntStr(
|
|
|
|
|
+ 2873 SymTab.ArrayHi(dt), qr)
|
|
|
|
|
+ 2874 END
|
|
|
|
|
+ 2875 ELSE
|
|
|
|
|
+ 2876 IF SymTab.IsOpenArray(dt) THEN
|
|
|
|
|
+ 2877 QbeGen.LoadCount(qd, qr)
|
|
|
|
|
+ 2878 ELSE
|
|
|
|
|
+ 2879 QbeGen.IntStr(VAL(
|
|
|
|
|
+ 2880 INTEGER,
|
|
|
|
|
+ 2881 SymTab.ArrayLen(dt)),
|
|
|
|
|
+ 2882 qr)
|
|
|
|
|
+ 2883 END
|
|
|
|
|
+ 2884 END;
|
|
|
|
|
+ 2885 t := SymTab.IntType();
|
|
|
|
|
+ 2886 QbeGen.CopyOp(qr, q)
|
|
|
|
|
+ 2887 END; .)
|
|
|
|
|
+ 2888 | ( "SIZE" | "TSIZE" ) "(" Design<dt, dk, qd, qn, sfx> ")"
|
|
|
|
|
+ 2889 (. IF dt = SymTab.InvalidType THEN
|
|
|
|
|
+ 2890 t := SymTab.InvalidType;
|
|
|
|
|
+ 2891 QbeGen.CopyOp("0", q)
|
|
|
|
|
+ 2892 ELSE
|
|
|
|
|
+ 2893 QbeGen.IntStr(VAL(INTEGER,
|
|
|
|
|
+ 2894 SymTab.ObjectSize(dt)), q);
|
|
|
|
|
+ 2895 t := SymTab.IntType()
|
|
|
|
|
+ 2896 END; .)
|
|
|
|
|
+ 2897 | ( "SHIFT" (. isMax := FALSE; .)
|
|
|
|
|
+ 2898 | "ROTATE" (. isMax := TRUE; .) )
|
|
|
|
|
+ 2899 "(" Expr<et, q> "," Expr<et2, q2> ")"
|
|
|
|
|
+ 2900 (. (* set shift/rotate: isMax
|
|
|
|
|
+ 2901 doubles as "rotate" *)
|
|
|
|
|
+ 2902 IF (et # SymTab.InvalidType)
|
|
|
|
|
+ 2903 AND (SymTab.ClassOf(et) =
|
|
|
|
|
+ 2904 SymTab.ClSet) THEN
|
|
|
|
|
+ 2905 QbeGen.SetShift(q, q2,
|
|
|
|
|
+ 2906 SymTab.SetWords(et),
|
|
|
|
|
+ 2907 SymTab.SetCount(et), isMax,
|
|
|
|
|
+ 2908 qt);
|
|
|
|
|
+ 2909 t := et;
|
|
|
|
|
+ 2910 QbeGen.CopyOp(qt, q)
|
|
|
|
|
+ 2911 ELSE SemError(230);
|
|
|
|
|
+ 2912 t := SymTab.InvalidType;
|
|
|
|
|
+ 2913 QbeGen.CopyOp("0", q)
|
|
|
|
|
+ 2914 END; .)
|
|
|
|
|
+ 2915 | ( "MIN" (. isMax := FALSE; .)
|
|
|
|
|
+ 2916 | "MAX" (. isMax := TRUE; .) )
|
|
|
|
|
+ 2917 "(" Design<dt, dk, qd, qn, sfx> ")"
|
|
|
|
|
+ 2918 (. IF (dt # SymTab.InvalidType)
|
|
|
|
|
+ 2919 AND (SymTab.ClassOf(dt) = SymTab.ClReal) THEN
|
|
|
|
|
+ 2920 (* REAL/LONGREAL: the
|
|
|
|
|
+ 2921 implementation bounds *)
|
|
|
|
|
+ 2922 IF isMax THEN
|
|
|
|
|
+ 2923 QbeGen.NormReal(
|
|
|
|
|
+ 2924 "3.402823e38", q)
|
|
|
|
|
+ 2925 ELSE QbeGen.NormReal(
|
|
|
|
|
+ 2926 "-3.402823e38", q)
|
|
|
|
|
+ 2927 END;
|
|
|
|
|
+ 2928 t := SymTab.RealType()
|
|
|
|
|
+ 2929 ELSIF (dt #
|
|
|
|
|
+ 2930 SymTab.InvalidType)
|
|
|
|
|
+ 2931 AND (SymTab.ClassOf(dt) =
|
|
|
|
|
+ 2932 SymTab.ClLong) THEN
|
|
|
|
|
+ 2933 IF isMax THEN
|
|
|
|
|
+ 2934 QbeGen.CopyOp(
|
|
|
|
|
+ 2935 "9223372036854775807", q)
|
|
|
|
|
+ 2936 ELSE QbeGen.CopyOp(
|
|
|
|
|
+ 2937 "-9223372036854775808", q)
|
|
|
|
|
+ 2938 END;
|
|
|
|
|
+ 2939 t := SymTab.LongType()
|
|
|
|
|
+ 2940 ELSIF SymTab.TypeBounds(dt, lo,
|
|
|
|
|
+ 2941 hi) THEN
|
|
|
|
|
+ 2942 IF isMax THEN
|
|
|
|
|
+ 2943 QbeGen.IntStr(hi, q)
|
|
|
|
|
+ 2944 ELSE QbeGen.IntStr(lo, q)
|
|
|
|
|
+ 2945 END;
|
|
|
|
|
+ 2946 t := SymTab.IntType()
|
|
|
|
|
+ 2947 ELSE SemError(230);
|
|
|
|
|
+ 2948 t := SymTab.InvalidType;
|
|
|
|
|
+ 2949 QbeGen.CopyOp("0", q)
|
|
|
|
|
+ 2950 END; .)
|
|
|
|
|
+ 2951 | "ADR" "(" Design<dt, dk, qd, qn, sfx> ")"
|
|
|
|
|
+ 2952 (. IF dt = SymTab.InvalidType THEN
|
|
|
|
|
+ 2953 t := SymTab.InvalidType;
|
|
|
|
|
+ 2954 QbeGen.CopyOp("0", q)
|
|
|
|
|
+ 2955 ELSE
|
|
|
|
|
+ 2956 IF sfx THEN
|
|
|
|
|
+ 2957 QbeGen.CopyOp(qd, q)
|
|
|
|
|
+ 2958 ELSIF (dk = SymTab.KindVar)
|
|
|
|
|
+ 2959 OR (dk = SymTab.KindParam) THEN
|
|
|
|
|
+ 2960 QbeGen.AddrOf(qn, q)
|
|
|
|
|
+ 2961 ELSE SemError(230);
|
|
|
|
|
+ 2962 QbeGen.CopyOp("0", q)
|
|
|
|
|
+ 2963 END;
|
|
|
|
|
+ 2964 t := SymTab.AddrType()
|
|
|
|
|
+ 2965 END; .)
|
|
|
|
|
+ 2966 | "CHR" "(" Expr<et, q> ")"
|
|
|
|
|
+ 2967 (. IF (et # SymTab.InvalidType)
|
|
|
|
|
+ 2968 AND NOT SymTab.IsIntFamily(et) THEN
|
|
|
|
|
+ 2969 SemError(211) END;
|
|
|
|
|
+ 2970 t := SymTab.CharType(); .)
|
|
|
|
|
+ 2971 | ( "ORD" | "ORDL" ) "(" Expr<et, q> ")"
|
|
|
|
|
+ 2972 (. IF et # SymTab.InvalidType THEN
|
|
|
|
|
+ 2973 IF (SymTab.ClassOf(et) #
|
|
|
|
|
+ 2974 SymTab.ClChar)
|
|
|
|
|
+ 2975 AND (SymTab.ClassOf(et) #
|
|
|
|
|
+ 2976 SymTab.ClBool)
|
|
|
|
|
+ 2977 AND (SymTab.ClassOf(et) #
|
|
|
|
|
+ 2978 SymTab.ClEnum)
|
|
|
|
|
+ 2979 AND NOT SymTab.IsIntFamily(et) THEN
|
|
|
|
|
+ 2980 SemError(211) END
|
|
|
|
|
+ 2981 END;
|
|
|
|
|
+ 2982 t := SymTab.IntType(); .)
|
|
|
|
|
+ 2983 | "CAP" "(" Expr<et, q> ")"
|
|
|
|
|
+ 2984 (. QbeGen.CapQ(q, qa);
|
|
|
|
|
+ 2985 QbeGen.CopyOp(qa, q);
|
|
|
|
|
+ 2986 t := SymTab.CharType(); .)
|
|
|
|
|
+ 2987 | "UCHR" "(" Expr<et, q> ")"
|
|
|
|
|
+ 2988 (. (* UCHR: the UCHAR constructor.
|
|
|
|
|
+ 2989 CHAR -> UCHAR (identity);
|
|
|
|
|
+ 2990 INTEGER familly -> UCHAR
|
|
|
|
|
+ 2991 (codepoint value). *)
|
|
|
|
|
+ 2992 IF (et # SymTab.InvalidType)
|
|
|
|
|
+ 2993 AND (SymTab.ClassOf(et) # SymTab.ClChar)
|
|
|
|
|
+ 2994 AND NOT SymTab.IsIntFamily(et) THEN
|
|
|
|
|
+ 2995 SemError(211) END;
|
|
|
|
|
+ 2996 t := SymTab.UCharType(); .)
|
|
|
|
|
+ 2997 | "CHR8" "(" Expr<et, q> ")"
|
|
|
|
|
+ 2998 (. IF (et # SymTab.InvalidType)
|
|
|
|
|
+ 2999 AND (SymTab.ClassOf(et) # SymTab.ClUChar) THEN
|
|
|
|
|
+ 3000 SemError(211) END;
|
|
|
|
|
+ 3001 QbeGen.WidenLong(q, qa);
|
|
|
|
|
+ 3002 QbeGen.CheckRange(qa, "0", "255");
|
|
|
|
|
+ 3003 t := SymTab.CharType(); .)
|
|
|
|
|
+ 3004 | "UORD" "(" Expr<et, q> ")"
|
|
|
|
|
+ 3005 (. (* UORD(u): the codepoint as a
|
|
|
|
|
+ 3006 32-bit ordinal (INTEGER),
|
|
|
|
|
+ 3007 cf. ORD for CHAR. *)
|
|
|
|
|
+ 3008 IF (et # SymTab.InvalidType)
|
|
|
|
|
+ 3009 AND (SymTab.ClassOf(et) # SymTab.ClUChar) THEN
|
|
|
|
|
+ 3010 SemError(211) END;
|
|
|
|
|
+ 3011 t := SymTab.IntType(); .)
|
|
|
|
|
+ 3012 | "ABS" "(" Expr<et, q> ")"
|
|
|
|
|
+ 3013 (. IF (et # SymTab.InvalidType)
|
|
|
|
|
+ 3014 AND NOT SymTab.IsIntFamily(et)
|
|
|
|
|
+ 3015 AND (SymTab.ClassOf(et) #
|
|
|
|
|
+ 3016 SymTab.ClReal) THEN
|
|
|
|
|
+ 3017 SemError(211)
|
|
|
|
|
+ 3018 ELSE QbeGen.AbsQ(q, qa,
|
|
|
|
|
+ 3019 SymTab.ClassOf(et) =
|
|
|
|
|
+ 3020 SymTab.ClReal);
|
|
|
|
|
+ 3021 QbeGen.CopyOp(qa, q)
|
|
|
|
|
+ 3022 END;
|
|
|
|
|
+ 3023 t := et; .)
|
|
|
|
|
+ 3024 | "VAL" "(" GetIdent<vn> "," Expr<et, q> ")"
|
|
|
|
|
+ 3025 (. IF NOT SymTab.Lookup(vn) THEN
|
|
|
|
|
+ 3026 SemError(201);
|
|
|
|
|
+ 3027 t := SymTab.InvalidType
|
|
|
|
|
+ 3028 ELSE vt := SymTab.SymType(vn);
|
|
|
|
|
+ 3029 IF vt = SymTab.InvalidType THEN
|
|
|
|
|
+ 3030 t := SymTab.InvalidType
|
|
|
|
|
+ 3031 ELSIF et =
|
|
|
|
|
+ 3032 SymTab.InvalidType THEN
|
|
|
|
|
+ 3033 t := vt
|
|
|
|
|
+ 3034 ELSE
|
|
|
|
|
+ 3035 c1 := SymTab.ClassOf(et);
|
|
|
|
|
+ 3036 c2 := SymTab.ClassOf(vt);
|
|
|
|
|
+ 3037 IF (c1 = SymTab.ClInt)
|
|
|
|
|
+ 3038 AND (c2 = SymTab.ClLong) THEN
|
|
|
|
|
+ 3039 QbeGen.WidenLong(q, qa);
|
|
|
|
|
+ 3040 QbeGen.CopyOp(qa, q);
|
|
|
|
|
+ 3041 t := vt
|
|
|
|
|
+ 3042 ELSIF (c1 = SymTab.ClLong)
|
|
|
|
|
+ 3043 AND (c2 = SymTab.ClInt) THEN
|
|
|
|
|
+ 3044 QbeGen.NarrowLong(q, qa);
|
|
|
|
|
+ 3045 QbeGen.CopyOp(qa, q);
|
|
|
|
|
+ 3046 t := vt
|
|
|
|
|
+ 3047 ELSIF (c1 = SymTab.ClInt)
|
|
|
|
|
+ 3048 AND (c2 = SymTab.ClReal) THEN
|
|
|
|
|
+ 3049 QbeGen.ConvIR(q, qa);
|
|
|
|
|
+ 3050 QbeGen.CopyOp(qa, q);
|
|
|
|
|
+ 3051 t := vt
|
|
|
|
|
+ 3052 ELSIF (c1 = SymTab.ClLong)
|
|
|
|
|
+ 3053 AND (c2 = SymTab.ClReal) THEN
|
|
|
|
|
+ 3054 QbeGen.ConvLR(q, qa);
|
|
|
|
|
+ 3055 QbeGen.CopyOp(qa, q);
|
|
|
|
|
+ 3056 t := vt
|
|
|
|
|
+ 3057 ELSIF (c1 = SymTab.ClReal)
|
|
|
|
|
+ 3058 AND (c2 = SymTab.ClInt) THEN
|
|
|
|
|
+ 3059 QbeGen.ConvRI(q, qa);
|
|
|
|
|
+ 3060 QbeGen.CopyOp(qa, q);
|
|
|
|
|
+ 3061 t := vt
|
|
|
|
|
+ 3062 ELSIF (c1 = SymTab.ClReal)
|
|
|
|
|
+ 3063 AND (c2 = SymTab.ClLong) THEN
|
|
|
|
|
+ 3064 QbeGen.ConvRL(q, qa);
|
|
|
|
|
+ 3065 QbeGen.CopyOp(qa, q);
|
|
|
|
|
+ 3066 t := vt
|
|
|
|
|
+ 3067 ELSIF ((c1 = SymTab.ClInt)
|
|
|
|
|
+ 3068 OR (c1 =
|
|
|
|
|
+ 3069 SymTab.ClChar)
|
|
|
|
|
+ 3070 OR (c1 =
|
|
|
|
|
+ 3071 SymTab.ClBool)
|
|
|
|
|
+ 3072 OR (c1 =
|
|
|
|
|
+ 3073 SymTab.ClEnum))
|
|
|
|
|
+ 3074 AND ((c2 = SymTab.ClInt)
|
|
|
|
|
+ 3075 OR (c2 =
|
|
|
|
|
+ 3076 SymTab.ClChar)
|
|
|
|
|
+ 3077 OR (c2 =
|
|
|
|
|
+ 3078 SymTab.ClBool)
|
|
|
|
|
+ 3079 OR (c2 =
|
|
|
|
|
+ 3080 SymTab.ClEnum)) THEN
|
|
|
|
|
+ 3081 t := vt
|
|
|
|
|
+ 3082 ELSIF (c1 = SymTab.ClPtr)
|
|
|
|
|
+ 3083 AND (c2 = SymTab.ClPtr) THEN
|
|
|
|
|
+ 3084 t := vt
|
|
|
|
|
+ 3085 ELSIF (c1 = SymTab.ClReal)
|
|
|
|
|
+ 3086 AND (c2 = SymTab.ClReal) THEN
|
|
|
|
|
+ 3087 t := vt
|
|
|
|
|
+ 3088 ELSE SemError(230);
|
|
|
|
|
+ 3089 t := SymTab.InvalidType
|
|
|
|
|
+ 3090 END
|
|
|
|
|
+ 3091 END
|
|
|
|
|
+ 3092 END; .)
|
|
|
|
|
+ 3093 | "(" Expr<et, q> ")" (. t := et; astIsLit := TRUE; .)
|
|
|
|
|
+ 3094 | SetLit<st, sq> (. t := st;
|
|
|
|
|
+ 3095 QbeGen.CopyOp(sq, q); .)
|
|
|
|
|
+ 3096 | ( "NOT" | "~" ) Fact<t2, q2> (. astNot := astCur;
|
|
|
|
|
+ 3097 IF SymTab.BoolCheck(t2) THEN
|
|
|
|
|
+ 3098 t := SymTab.BoolType()
|
|
|
|
|
+ 3099 ELSE SemError(212);
|
|
|
|
|
+ 3100 t := SymTab.InvalidType END;
|
|
|
|
|
+ 3101 IF t # SymTab.InvalidType THEN
|
|
|
|
|
+ 3102 QbeGen.NotQ(q2, q)
|
|
|
|
|
+ 3103 ELSE QbeGen.CopyOp("0", q)
|
|
|
|
|
+ 3104 END;
|
|
|
|
|
+ 3105 astIsLit := TRUE;
|
|
|
|
|
+ 3106 astCur := AST.MakeUn(
|
|
|
|
|
+ 3107 AST.NkUnary, AST.OpNot, astNot); .)
|
|
|
|
|
+ 3108 )
|
|
|
|
|
+ 3109 (. IF NOT astIsLit THEN astCur := AST.NoNode END; .) .
|
|
|
|
|
+ 3110 (* Set literals are SET OF [0..255] (8 words); elements validated
|
|
|
|
|
+ 3111 0..255 statically when foldable (222 otherwise), runtime trap
|
|
|
|
|
+ 3112 for computed elements. Ranges always lower via SetRange. *)
|
|
|
|
|
+ 3113 SetLit<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
|
|
+ 3114 = "{" (. t := SymTab.NewSet(
|
|
|
|
|
+ 3115 SymTab.NewSubR(0, 255));
|
|
|
|
|
+ 3116 QbeGen.NewSetTemp(8, q);
|
|
|
|
|
+ 3117 QbeGen.SetZero(q, 8); .)
|
|
|
|
|
+ 3118 [ SetElem<t, q> { "," SetElem<t, q> } ]
|
|
|
|
|
+ 3119 "}" .
|
|
|
|
|
+ 3120 (* Typed brace constructor: TypeName{ elems } — BITSET{0} (a set)
|
|
|
|
|
+ 3121 or ArrayName{...} (an array constructor, GNU Modula-2). The
|
|
|
|
|
+ 3122 declared type sets the width (set) or element type (array). *)
|
|
|
|
|
+ 3123 TypedBraceLit<vt: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
|
|
+ 3124 (. VAR nw: CARDINAL;
|
|
|
|
|
+ 3125 savedCls: INTEGER; .)
|
|
|
|
|
+ 3126 = "{" (. savedCls := braceCls;
|
|
|
|
|
+ 3127 IF vt = SymTab.InvalidType THEN
|
|
|
|
|
+ 3128 braceCls := -1
|
|
|
|
|
+ 3129 ELSE braceCls :=
|
|
|
|
|
+ 3130 SymTab.ClassOf(vt)
|
|
|
|
|
+ 3131 END;
|
|
|
|
|
+ 3132 IF braceCls = SymTab.ClSet THEN
|
|
|
|
|
+ 3133 IF vt = SymTab.InvalidType THEN
|
|
|
|
|
+ 3134 nw := 8
|
|
|
|
|
+ 3135 ELSE nw := SymTab.SetWords(vt);
|
|
|
|
|
+ 3136 IF nw = 0 THEN nw := 8 END
|
|
|
|
|
+ 3137 END;
|
|
|
|
|
+ 3138 QbeGen.NewSetTemp(nw, q);
|
|
|
|
|
+ 3139 QbeGen.SetZero(q, nw)
|
|
|
|
|
+ 3140 ELSIF (braceCls =
|
|
|
|
|
+ 3141 SymTab.ClArray)
|
|
|
|
|
+ 3142 OR (braceCls =
|
|
|
|
|
+ 3143 SymTab.ClRecord)
|
|
|
|
|
+ 3144 OR (braceCls =
|
|
|
|
|
+ 3145 SymTab.ClClass) THEN
|
|
|
|
|
+ 3146 QbeGen.CtorBegin(vt)
|
|
|
|
|
+ 3147 ELSE
|
|
|
|
|
+ 3148 IF vt # SymTab.InvalidType THEN
|
|
|
|
|
+ 3149 SemError(230) END;
|
|
|
|
|
+ 3150 braceCls := -1
|
|
|
|
|
+ 3151 END; .)
|
|
|
|
|
+ 3152 [ BraceElem<vt, q> { "," BraceElem<vt, q> } ]
|
|
|
|
|
+ 3153 "}" (. IF (braceCls = SymTab.ClArray)
|
|
|
|
|
+ 3154 OR (braceCls =
|
|
|
|
|
+ 3155 SymTab.ClRecord)
|
|
|
|
|
+ 3156 OR (braceCls =
|
|
|
|
|
+ 3157 SymTab.ClClass) THEN
|
|
|
|
|
+ 3158 QbeGen.CtorEnd(q)
|
|
|
|
|
+ 3159 ELSIF braceCls # SymTab.ClSet THEN
|
|
|
|
|
+ 3160 QbeGen.CopyOp("0", q)
|
|
|
|
|
+ 3161 END;
|
|
|
|
|
+ 3162 braceCls := savedCls; .) .
|
|
|
|
|
+ 3163 BraceElem<vt: SymTab.TypeIndex; VAR sq: QbeGen.QVal>
|
|
|
|
|
+ 3164 (. VAR et, et2: SymTab.TypeIndex;
|
|
|
|
|
+ 3165 qe, q2: QbeGen.QVal;
|
|
|
|
|
+ 3166 v, v2, reps, k: INTEGER;
|
|
|
|
|
+ 3167 elem: SymTab.TypeIndex;
|
|
|
|
|
+ 3168 lo: INTEGER;
|
|
|
|
|
+ 3169 span: CARDINAL;
|
|
|
|
|
+ 3170 cl, cl2: INTEGER;
|
|
|
|
|
+ 3171 hasR, hasB: BOOLEAN; .)
|
|
|
|
|
+ 3172 = (. hasR := FALSE; hasB := FALSE; .)
|
|
|
|
|
+ 3173 Expr<et, qe>
|
|
|
|
|
+ 3174 [ ".." Expr<et2, q2> (. hasR := TRUE; .) ]
|
|
|
|
|
+ 3175 [ "BY" Expr<et2, q2> (. hasB := TRUE; .) ]
|
|
|
|
|
+ 3176 (. IF braceCls = SymTab.ClSet THEN
|
|
|
|
|
+ 3177 IF hasB THEN SemError(230) END;
|
|
|
|
|
+ 3178 lo := SymTab.SetBaseLo(vt);
|
|
|
|
|
+ 3179 span := SymTab.SetCount(vt);
|
|
|
|
|
+ 3180 IF (et = SymTab.InvalidType)
|
|
|
|
|
+ 3181 OR (hasR AND (et2 =
|
|
|
|
|
+ 3182 SymTab.InvalidType)) THEN
|
|
|
|
|
+ 3183 ELSE cl :=
|
|
|
|
|
+ 3184 SymTab.ClassOf(et);
|
|
|
|
|
+ 3185 IF hasR THEN
|
|
|
|
|
+ 3186 cl2 :=
|
|
|
|
|
+ 3187 SymTab.ClassOf(et2)
|
|
|
|
|
+ 3188 ELSE cl2 := SymTab.ClInt
|
|
|
|
|
+ 3189 END;
|
|
|
|
|
+ 3190 IF NOT SymTab.SetElemClassOk(cl)
|
|
|
|
|
+ 3191 OR (hasR AND NOT
|
|
|
|
|
+ 3192 SymTab.SetElemClassOk(cl2))
|
|
|
|
|
+ 3193 THEN
|
|
|
|
|
+ 3194 SemError(222)
|
|
|
|
|
+ 3195 ELSIF hasR
|
|
|
|
|
+ 3196 AND SymTab.ConstInt(qe, v)
|
|
|
|
|
+ 3197 AND SymTab.ConstInt(q2,
|
|
|
|
|
+ 3198 v2)
|
|
|
|
|
+ 3199 AND ((v < lo)
|
|
|
|
|
+ 3200 OR (v2 < lo)
|
|
|
|
|
+ 3201 OR (v >= lo +
|
|
|
|
|
+ 3202 VAL(INTEGER, span))
|
|
|
|
|
+ 3203 OR (v2 >= lo +
|
|
|
|
|
+ 3204 VAL(INTEGER, span))
|
|
|
|
|
+ 3205 OR (v > v2)) THEN
|
|
|
|
|
+ 3206 SemError(222)
|
|
|
|
|
+ 3207 ELSIF hasR THEN
|
|
|
|
|
+ 3208 QbeGen.SetRange(sq, qe, q2,
|
|
|
|
|
+ 3209 lo, span)
|
|
|
|
|
+ 3210 ELSIF SymTab.ConstInt(qe,
|
|
|
|
|
+ 3211 v)
|
|
|
|
|
+ 3212 AND ((v < lo)
|
|
|
|
|
+ 3213 OR (v >= lo +
|
|
|
|
|
+ 3214 VAL(INTEGER,
|
|
|
|
|
+ 3215 span))) THEN
|
|
|
|
|
+ 3216 SemError(222)
|
|
|
|
|
+ 3217 ELSE QbeGen.SetBit(sq, qe,
|
|
|
|
|
+ 3218 lo, span)
|
|
|
|
|
+ 3219 END
|
|
|
|
|
+ 3220 END
|
|
|
|
|
+ 3221 ELSIF (braceCls = SymTab.ClArray)
|
|
|
|
|
+ 3222 OR (braceCls =
|
|
|
|
|
+ 3223 SymTab.ClRecord)
|
|
|
|
|
+ 3224 OR (braceCls =
|
|
|
|
|
+ 3225 SymTab.ClClass) THEN
|
|
|
|
|
+ 3226 IF hasR THEN SemError(230) END;
|
|
|
|
|
+ 3227 reps := 1;
|
|
|
|
|
+ 3228 IF hasB THEN
|
|
|
|
|
+ 3229 IF SymTab.ConstInt(q2, v2)
|
|
|
|
|
+ 3230 AND (v2 >= 1) THEN
|
|
|
|
|
+ 3231 reps := v2
|
|
|
|
|
+ 3232 ELSE SemError(230)
|
|
|
|
|
+ 3233 END
|
|
|
|
|
+ 3234 END;
|
|
|
|
|
+ 3235 k := 0;
|
|
|
|
|
+ 3236 WHILE k < reps DO
|
|
|
|
|
+ 3237 QbeGen.CtorElem(qe);
|
|
|
|
|
+ 3238 INC(k)
|
|
|
|
|
+ 3239 END
|
|
|
|
|
+ 3240 END; .) .
|
|
|
|
|
+ 3241 SetElem<st: SymTab.TypeIndex; sq: QbeGen.QVal> (. VAR et, et2: SymTab.TypeIndex;
|
|
|
|
|
+ 3242 qe, q2: QbeGen.QVal;
|
|
|
|
|
+ 3243 v, v2: INTEGER;
|
|
|
|
|
+ 3244 lo: INTEGER;
|
|
|
|
|
+ 3245 span: CARDINAL;
|
|
|
|
|
+ 3246 cl, cl2: INTEGER;
|
|
|
|
|
+ 3247 hasR: BOOLEAN; .)
|
|
|
|
|
+ 3248 = (. hasR := FALSE; .)
|
|
|
|
|
+ 3249 Expr<et, qe>
|
|
|
|
|
+ 3250 [ ".." Expr<et2, q2> (. hasR := TRUE; .) ]
|
|
|
|
|
+ 3251 (. lo := SymTab.SetBaseLo(st);
|
|
|
|
|
+ 3252 span := SymTab.SetCount(st);
|
|
|
|
|
+ 3253 IF (et = SymTab.InvalidType)
|
|
|
|
|
+ 3254 OR (hasR AND (et2 =
|
|
|
|
|
+ 3255 SymTab.InvalidType)) THEN
|
|
|
|
|
+ 3256 ELSE cl :=
|
|
|
|
|
+ 3257 SymTab.ClassOf(et);
|
|
|
|
|
+ 3258 IF hasR THEN
|
|
|
|
|
+ 3259 cl2 :=
|
|
|
|
|
+ 3260 SymTab.ClassOf(et2)
|
|
|
|
|
+ 3261 ELSE cl2 := SymTab.ClInt
|
|
|
|
|
+ 3262 END;
|
|
|
|
|
+ 3263 IF NOT SymTab.SetElemClassOk(cl)
|
|
|
|
|
+ 3264 OR (hasR AND NOT
|
|
|
|
|
+ 3265 SymTab.SetElemClassOk(cl2))
|
|
|
|
|
+ 3266 THEN
|
|
|
|
|
+ 3267 SemError(222)
|
|
|
|
|
+ 3268 ELSIF hasR
|
|
|
|
|
+ 3269 AND SymTab.ConstInt(qe, v)
|
|
|
|
|
+ 3270 AND SymTab.ConstInt(q2,
|
|
|
|
|
+ 3271 v2)
|
|
|
|
|
+ 3272 AND ((v < lo)
|
|
|
|
|
+ 3273 OR (v2 < lo)
|
|
|
|
|
+ 3274 OR (v >= lo +
|
|
|
|
|
+ 3275 VAL(INTEGER, span))
|
|
|
|
|
+ 3276 OR (v2 >= lo +
|
|
|
|
|
+ 3277 VAL(INTEGER, span))
|
|
|
|
|
+ 3278 OR (v > v2)) THEN
|
|
|
|
|
+ 3279 SemError(222)
|
|
|
|
|
+ 3280 ELSIF hasR THEN
|
|
|
|
|
+ 3281 QbeGen.SetRange(sq, qe, q2,
|
|
|
|
|
+ 3282 lo, span)
|
|
|
|
|
+ 3283 ELSIF SymTab.ConstInt(qe,
|
|
|
|
|
+ 3284 v)
|
|
|
|
|
+ 3285 AND ((v < lo)
|
|
|
|
|
+ 3286 OR (v >= lo +
|
|
|
|
|
+ 3287 VAL(INTEGER,
|
|
|
|
|
+ 3288 span))) THEN
|
|
|
|
|
+ 3289 SemError(222)
|
|
|
|
|
+ 3290 ELSE QbeGen.SetBit(sq, qe,
|
|
|
|
|
+ 3291 lo, span)
|
|
|
|
|
+ 3292 END
|
|
|
|
|
+ 3293 END; .) .
|
|
|
|
|
+ 3294 GetIdent<VAR n: SymTab.Name>
|
|
|
|
|
+ 3295 = ident (. LexName(n); .) .
|
|
|
|
|
+ 3296
|
|
|
|
|
+ 3297 END M2.
|
|
|
|
|
|
|
|
0 errors
|
|
0 errors
|
|
|
|
|
|