|
@@ -268,1244 +268,1245 @@ Listing:
|
|
|
251 OR ~SymTab.ConstInt(qhi, hi)
|
|
251 OR ~SymTab.ConstInt(qhi, hi)
|
|
|
252 OR (lo > hi) THEN
|
|
252 OR (lo > hi) THEN
|
|
|
253 SemError(230); ok := FALSE
|
|
253 SemError(230); ok := FALSE
|
|
|
- 254 ELSIF ~SymTab.BoundAdd(lo, hi) THEN
|
|
|
|
|
- 255 SemError(230); ok := FALSE
|
|
|
|
|
- 256 END; .) .
|
|
|
|
|
- 257 (* Sets: multi-word masks over bases ≤ 256 values (bool, char,
|
|
|
|
|
- 258 bounded subranges; enums wait for ordinals, INTEGER is
|
|
|
|
|
- 259 unbounded). Literals are SET OF [0..255]; assignment and
|
|
|
|
|
- 260 comparison across suitable bases are lenient (masks over min
|
|
|
|
|
- 261 words + zero-check extras), out-of-span literals are 222. *)
|
|
|
|
|
- 262 SetType<VAR t: SymTab.TypeIndex> (. VAR base: SymTab.TypeIndex;
|
|
|
|
|
- 263 blo, bhi, bspan: INTEGER;
|
|
|
|
|
- 264 bcls: INTEGER; .)
|
|
|
|
|
- 265 = "SET" "OF" Type<base, FALSE>
|
|
|
|
|
- 266 (. IF base = SymTab.InvalidType THEN
|
|
|
|
|
- 267 t := SymTab.InvalidType
|
|
|
|
|
- 268 ELSE bcls :=
|
|
|
|
|
- 269 SymTab.ClassOf(base);
|
|
|
|
|
- 270 IF bcls = SymTab.ClBool THEN
|
|
|
|
|
- 271 blo := 0; bspan := 2
|
|
|
|
|
- 272 ELSIF bcls = SymTab.ClChar THEN
|
|
|
|
|
- 273 blo := 0; bspan := 256
|
|
|
|
|
- 274 ELSIF SymTab.SubBounds(base,
|
|
|
|
|
- 275 blo, bhi) THEN
|
|
|
|
|
- 276 bspan := bhi - blo + 1
|
|
|
|
|
- 277 ELSE bspan := 0 END;
|
|
|
|
|
- 278 IF (bspan <= 0)
|
|
|
|
|
- 279 OR (bspan > 256) THEN
|
|
|
|
|
- 280 SemError(230);
|
|
|
|
|
- 281 t := SymTab.InvalidType
|
|
|
|
|
- 282 ELSE t := SymTab.NewSet(base)
|
|
|
|
|
- 283 END
|
|
|
|
|
- 284 END; .) .
|
|
|
|
|
- 285 (* Records: flat blobs; array fields are pointers to static
|
|
|
|
|
- 286 descriptors (locked amendment), nested records inline. Field
|
|
|
|
|
- 287 offsets static and declaration-ordered. *)
|
|
|
|
|
- 288 RecordType<VAR t: SymTab.TypeIndex> (. VAR t2: SymTab.TypeIndex; .)
|
|
|
|
|
- 289 = "RECORD" (. t := SymTab.NewRecord(); .)
|
|
|
|
|
- 290 [ RecField<t> { ";" RecField<t> } ]
|
|
|
|
|
- 291 "END" .
|
|
|
|
|
- 292 RecField<rec: SymTab.TypeIndex> (. VAR n: SymTab.Name;
|
|
|
|
|
- 293 t2: SymTab.TypeIndex; .)
|
|
|
|
|
- 294 = RecIdents<rec> ":" Type<t2, FALSE>(. SymTab.FixPendingF(rec, t2); .) .
|
|
|
|
|
- 295 RecIdents<rec: SymTab.TypeIndex> (. VAR n: SymTab.Name; .)
|
|
|
|
|
- 296 = GetIdent<n> (. IF ~SymTab.FieldPending(rec,
|
|
|
|
|
- 297 n) THEN
|
|
|
|
|
- 298 SemError(200) END; .)
|
|
|
|
|
- 299 { "," GetIdent<n> (. IF ~SymTab.FieldPending(rec,
|
|
|
|
|
- 300 n) THEN
|
|
|
|
|
- 301 SemError(200) END; .) } .
|
|
|
|
|
- 302 TypeIdent<VAR t: SymTab.TypeIndex> (. VAR n: SymTab.Name;
|
|
|
|
|
- 303 k: INTEGER; .)
|
|
|
|
|
- 304 = GetIdent<n> (. IF ~SymTab.Lookup(n) THEN
|
|
|
|
|
- 305 SemError(201);
|
|
|
|
|
- 306 t := SymTab.InvalidType
|
|
|
|
|
- 307 ELSE k := SymTab.SymKind(n);
|
|
|
|
|
- 308 IF (k = SymTab.KindType)
|
|
|
|
|
- 309 OR (k = SymTab.KindPredef) THEN
|
|
|
|
|
- 310 t := SymTab.SymType(n)
|
|
|
|
|
- 311 ELSIF k = SymTab.KindImport THEN
|
|
|
|
|
- 312 t := SymTab.InvalidType
|
|
|
|
|
- 313 ELSE SemError(221);
|
|
|
|
|
- 314 t := SymTab.InvalidType
|
|
|
|
|
- 315 END
|
|
|
|
|
- 316 END; .) .
|
|
|
|
|
- 317 Subrange<VAR t: SymTab.TypeIndex> (. VAR tlo, thi: SymTab.TypeIndex;
|
|
|
|
|
- 318 qlo, qhi: QbeGen.QVal;
|
|
|
|
|
- 319 lo, hi: INTEGER; .)
|
|
|
|
|
- 320 = "[" Expr<tlo, qlo> ".." Expr<thi, qhi>
|
|
|
|
|
- 321 (. IF (tlo = SymTab.InvalidType)
|
|
|
|
|
- 322 OR (thi = SymTab.InvalidType) THEN
|
|
|
|
|
- 323 t := SymTab.InvalidType
|
|
|
|
|
- 324 ELSIF (SymTab.ClassOf(tlo) #
|
|
|
|
|
- 325 SymTab.ClInt)
|
|
|
|
|
- 326 OR (SymTab.ClassOf(thi) #
|
|
|
|
|
- 327 SymTab.ClInt) THEN
|
|
|
|
|
- 328 SemError(230);
|
|
|
|
|
- 329 t := SymTab.InvalidType
|
|
|
|
|
- 330 ELSIF ~SymTab.ConstInt(qlo, lo)
|
|
|
|
|
- 331 OR ~SymTab.ConstInt(qhi, hi)
|
|
|
|
|
- 332 OR (lo > hi) THEN
|
|
|
|
|
- 333 SemError(230);
|
|
|
|
|
- 334 t := SymTab.InvalidType
|
|
|
|
|
- 335 ELSE t := SymTab.NewSubR(lo, hi)
|
|
|
|
|
- 336 END; .)
|
|
|
|
|
- 337 "]" .
|
|
|
|
|
- 338 Enum<VAR t: SymTab.TypeIndex> (. VAR n: SymTab.Name; .)
|
|
|
|
|
- 339 = "(" (. t := SymTab.NewEnum(); .)
|
|
|
|
|
- 340 GetIdent<n> (. IF ~SymTab.Enter(n,
|
|
|
|
|
- 341 SymTab.KindConst) THEN
|
|
|
|
|
- 342 SemError(200) END;
|
|
|
|
|
- 343 SymTab.SetSymType(n, t); .)
|
|
|
|
|
- 344 { "," GetIdent<n> (. IF ~SymTab.Enter(n,
|
|
|
|
|
- 345 SymTab.KindConst) THEN
|
|
|
|
|
- 346 SemError(200) END;
|
|
|
|
|
- 347 SymTab.SetSymType(n, t); .) }
|
|
|
|
|
- 348 ")" .
|
|
|
|
|
- 349 (* Clarion-form classes (docs/OOP.txt): declaration + single
|
|
|
|
|
- 350 inheritance + IMPLEMENTATION blocks. Scopes and member checks
|
|
|
|
|
- 351 now; lowering (vtable, dispatch, THIS) later — one 230 per
|
|
|
|
|
- 352 class/impl block. Methods end with ";" per the Table example
|
|
|
|
|
- 353 (not "," as in the sketch). No underscores in identifiers. *)
|
|
|
|
|
- 354 (* Single CLASS item in both loops: separating declaration from
|
|
|
|
|
- 355 IMPLEMENTATION at the loop level needs 2-token lookahead
|
|
|
|
|
- 356 (CLASS ident vs CLASS IMPLEMENTATION), which LL(1) cannot do.
|
|
|
|
|
- 357 The second token decides after CLASS is consumed. A misplaced
|
|
|
|
|
- 358 CLASS IMPLEMENTATION inside TYPE still parses (harmless: the
|
|
|
|
|
- 359 whole unit ends 230 until lowering). *)
|
|
|
|
|
- 360 ClassItem
|
|
|
|
|
- 361 = "CLASS" ( "IMPLEMENTATION" ClassImplRest | ClassRest ) .
|
|
|
|
|
- 362 ClassRest (. VAR cn, m2, pn: SymTab.Name;
|
|
|
|
|
- 363 ct: SymTab.TypeIndex; .)
|
|
|
|
|
- 364 = GetIdent<cn> (. IF ~SymTab.Enter(cn,
|
|
|
|
|
- 365 SymTab.KindType) THEN
|
|
|
|
|
- 366 SemError(200) END;
|
|
|
|
|
- 367 ct := SymTab.NewClass();
|
|
|
|
|
- 368 SymTab.SetSymType(cn, ct);
|
|
|
|
|
- 369 SymTab.PushClassScope(ct); .)
|
|
|
|
|
- 370 [ Parents<ct> ]
|
|
|
|
|
- 371 ";"
|
|
|
|
|
- 372 { ClassField<ct> ";" }
|
|
|
|
|
- 373 { MethodHeading<pn> ";" (. SymTab.CloseProc; .) }
|
|
|
|
|
- 374 "END"
|
|
|
|
|
- 375 GetIdent<m2> (. IF ~SymTab.Equal(cn, m2) THEN
|
|
|
|
|
- 376 SemError(202) END;
|
|
|
|
|
- 377 SymTab.PopScope;
|
|
|
|
|
- 378 SemError(230); .) .
|
|
|
|
|
- 379 Parents<ct: SymTab.TypeIndex> (. VAR p: SymTab.Name; .)
|
|
|
|
|
- 380 = "(" Parent1<ct>
|
|
|
|
|
- 381 { "," GetIdent<p> (. SemError(230); .) }
|
|
|
|
|
- 382 ")" .
|
|
|
|
|
- 383 Parent1<ct: SymTab.TypeIndex> (. VAR p: SymTab.Name;
|
|
|
|
|
- 384 pt: SymTab.TypeIndex; .)
|
|
|
|
|
- 385 = GetIdent<p> (. IF ~SymTab.Lookup(p) THEN
|
|
|
|
|
- 386 SemError(201)
|
|
|
|
|
- 387 ELSE pt := SymTab.SymType(p);
|
|
|
|
|
- 388 IF SymTab.ClassOf(pt) #
|
|
|
|
|
- 389 SymTab.ClClass THEN
|
|
|
|
|
- 390 SemError(230)
|
|
|
|
|
- 391 ELSE SymTab.SetParent(ct, pt)
|
|
|
|
|
- 392 END
|
|
|
|
|
- 393 END; .) .
|
|
|
|
|
- 394 ClassField<ct: SymTab.TypeIndex> (. VAR n, rhs: SymTab.Name;
|
|
|
|
|
- 395 t: SymTab.TypeIndex; .)
|
|
|
|
|
- 396 = GetIdent<n>
|
|
|
|
|
- 397 ( "=" GetIdent<rhs> (. IF ~SymTab.Enter(n,
|
|
|
|
|
- 398 SymTab.KindConst) THEN
|
|
|
|
|
- 399 SemError(200) END;
|
|
|
|
|
- 400 IF SymTab.Lookup(rhs) THEN
|
|
|
|
|
- 401 SymTab.SetSymType(n,
|
|
|
|
|
- 402 SymTab.SymType(rhs))
|
|
|
|
|
- 403 END; .)
|
|
|
|
|
- 404 | (. IF ~SymTab.FieldPending(ct,
|
|
|
|
|
- 405 n) THEN
|
|
|
|
|
- 406 SemError(200) END; .)
|
|
|
|
|
- 407 { "," GetIdent<n> (. IF ~SymTab.FieldPending(ct,
|
|
|
|
|
- 408 n) THEN
|
|
|
|
|
- 409 SemError(200) END; .) }
|
|
|
|
|
- 410 ":" Type<t, FALSE> (. SymTab.FixPendingF(ct, t); .) ) .
|
|
|
|
|
- 411 MethodHeading<VAR pn: SymTab.Name> (. VAR wantVirt: BOOLEAN; .)
|
|
|
|
|
- 412 = (. wantVirt := FALSE; .)
|
|
|
|
|
- 413 [ "VIRTUAL" (. wantVirt := TRUE; .) ]
|
|
|
|
|
- 414 ProcHeading<pn> (. IF wantVirt THEN
|
|
|
|
|
- 415 SymTab.MarkVirtual END; .) .
|
|
|
|
|
- 416 ClassImplRest (. VAR cn, m2: SymTab.Name;
|
|
|
|
|
- 417 ct: SymTab.TypeIndex; .)
|
|
|
|
|
- 418 = GetIdent<cn> (. IF ~SymTab.Lookup(cn) THEN
|
|
|
|
|
- 419 SemError(201);
|
|
|
|
|
- 420 ct := SymTab.InvalidType
|
|
|
|
|
- 421 ELSE ct := SymTab.SymType(cn);
|
|
|
|
|
- 422 IF SymTab.ClassOf(ct) #
|
|
|
|
|
- 423 SymTab.ClClass THEN
|
|
|
|
|
- 424 SemError(230);
|
|
|
|
|
- 425 ct := SymTab.InvalidType
|
|
|
|
|
- 426 END
|
|
|
|
|
- 427 END;
|
|
|
|
|
- 428 IF ct #
|
|
|
|
|
- 429 SymTab.InvalidType THEN
|
|
|
|
|
- 430 IF ~SymTab.PushClassMembers(
|
|
|
|
|
- 431 ct) THEN
|
|
|
|
|
- 432 SemError(230) END
|
|
|
|
|
- 433 END; .)
|
|
|
|
|
- 434 ";" { MethodImpl<ct> ";" }
|
|
|
|
|
- 435 [ "BEGIN"
|
|
|
|
|
- 436 [ StatSeq ] ]
|
|
|
|
|
- 437 "END"
|
|
|
|
|
- 438 GetIdent<m2> (. IF ~SymTab.Equal(cn, m2) THEN
|
|
|
|
|
- 439 SemError(202) END;
|
|
|
|
|
- 440 SymTab.PopScope;
|
|
|
|
|
- 441 SemError(230); .) .
|
|
|
|
|
- 442 MethodImpl<ct: SymTab.TypeIndex> (. VAR pn: SymTab.Name; .)
|
|
|
|
|
- 443 = MethodHeading<pn> ";"
|
|
|
|
|
- 444 (. IF (ct #
|
|
|
|
|
- 445 SymTab.InvalidType)
|
|
|
|
|
- 446 & ~SymTab.MethodExists(ct,
|
|
|
|
|
- 447 pn) THEN
|
|
|
|
|
- 448 SemError(201) END; .)
|
|
|
|
|
- 449 ( "FORWARD" (. SymTab.MarkFwd;
|
|
|
|
|
- 450 SymTab.CloseProc; .)
|
|
|
|
|
- 451 | Block<pn> (. SymTab.CloseProc;
|
|
|
|
|
- 452 SemError(230); .) ) .
|
|
|
|
|
- 453 ConstBlock
|
|
|
|
|
- 454 = "CONST" { ConstDecl ";" } .
|
|
|
|
|
- 455 ConstDecl (. VAR n: SymTab.Name;
|
|
|
|
|
- 456 t: SymTab.TypeIndex;
|
|
|
|
|
- 457 qv: QbeGen.QVal;
|
|
|
|
|
- 458 cls: INTEGER; .)
|
|
|
|
|
- 459 = GetIdent<n> (. IF ~SymTab.Enter(n,
|
|
|
|
|
- 460 SymTab.KindConst) THEN
|
|
|
|
|
- 461 SemError(200) END; .)
|
|
|
|
|
- 462 "="
|
|
|
|
|
- 463 Expr<t, qv> (. SymTab.SetSymType(n, t);
|
|
|
|
|
- 464 cls := SymTab.ClassOf(t);
|
|
|
|
|
- 465 IF cls = SymTab.ClStr THEN
|
|
|
|
|
- 466 SemError(230)
|
|
|
|
|
- 467 ELSIF ~QbeGen.IsImm(qv) THEN
|
|
|
|
|
- 468 SemError(230) END;
|
|
|
|
|
- 469 QbeGen.DeclConst(n, qv, t); .) .
|
|
|
|
|
- 470 VarBlock
|
|
|
|
|
- 471 = "VAR" { VarDecl ";" } .
|
|
|
|
|
- 472 VarDecl (. VAR nm: SymTab.Name;
|
|
|
|
|
- 473 t: SymTab.TypeIndex;
|
|
|
|
|
- 474 i: CARDINAL;
|
|
|
|
|
- 475 cls: INTEGER; .)
|
|
|
|
|
- 476 = VarIdents ":"
|
|
|
|
|
- 477 Type<t, FALSE> (. cls := SymTab.ClassOf(t);
|
|
|
|
|
- 478 IF (t # SymTab.InvalidType)
|
|
|
|
|
- 479 & (cls # SymTab.ClInt)
|
|
|
|
|
- 480 & (cls # SymTab.ClBool)
|
|
|
|
|
- 481 & (cls # SymTab.ClChar)
|
|
|
|
|
- 482 & (cls # SymTab.ClReal)
|
|
|
|
|
- 483 & (cls # SymTab.ClArray)
|
|
|
|
|
- 484 & (cls # SymTab.ClSet)
|
|
|
|
|
- 485 & (cls # SymTab.ClRecord)
|
|
|
|
|
- 486 & (cls # SymTab.ClPtr) THEN
|
|
|
|
|
- 487 SemError(230) END;
|
|
|
|
|
- 488 i := 0;
|
|
|
|
|
- 489 WHILE i < SymTab.PendCount() DO
|
|
|
|
|
- 490 SymTab.PendName(i, nm);
|
|
|
|
|
- 491 QbeGen.DeclVar(nm, t);
|
|
|
|
|
- 492 INC(i)
|
|
|
|
|
- 493 END;
|
|
|
|
|
- 494 SymTab.FixPending(t); .) .
|
|
|
|
|
- 495 VarIdents (. VAR n: SymTab.Name; .)
|
|
|
|
|
- 496 = GetIdent<n> (. IF ~SymTab.EnterPending(n,
|
|
|
|
|
- 497 SymTab.KindVar) THEN
|
|
|
|
|
- 498 SemError(200) END; .)
|
|
|
|
|
- 499 { ","
|
|
|
|
|
- 500 GetIdent<n> (. IF ~SymTab.EnterPending(n,
|
|
|
|
|
- 501 SymTab.KindVar) THEN
|
|
|
|
|
- 502 SemError(200) END; .) } .
|
|
|
|
|
- 503 ParIdents<isV: BOOLEAN> (. VAR n: SymTab.Name; .)
|
|
|
|
|
- 504 = GetIdent<n> (. IF ~SymTab.EnterParam(n, isV) THEN
|
|
|
|
|
- 505 SemError(200) END; .)
|
|
|
|
|
- 506 { "," GetIdent<n> (. IF ~SymTab.EnterParam(n, isV) THEN
|
|
|
|
|
- 507 SemError(200) END; .) } .
|
|
|
|
|
- 508 (* Procedure headings enter now (scopes, params, result); bodies
|
|
|
|
|
- 509 parse + check with one 230 at END (lowering = step 4).
|
|
|
|
|
- 510 FORWARD marks; the body heading re-enters (signature compare
|
|
|
|
|
- 511 tightens in step 4). *)
|
|
|
|
|
- 512 ProcHeading<VAR pn: SymTab.Name> (. VAR t: SymTab.TypeIndex; .)
|
|
|
|
|
- 513 = "PROCEDURE"
|
|
|
|
|
- 514 GetIdent<pn> (. IF ~SymTab.EnterProc(pn) THEN
|
|
|
|
|
- 515 IF ~SymTab.ReenterProc(pn) THEN
|
|
|
|
|
- 516 SemError(200) END
|
|
|
|
|
- 517 END; .)
|
|
|
|
|
- 518 [ FormalParams ]
|
|
|
|
|
- 519 [ ":" TypeIdent<t> (. SymTab.SetProcRes(t);
|
|
|
|
|
- 520 IF (t #
|
|
|
|
|
- 521 SymTab.InvalidType)
|
|
|
|
|
- 522 & (SymTab.ClassOf(t)
|
|
|
|
|
- 523 = SymTab.ClArray) THEN
|
|
|
|
|
- 524 SemError(230) END; .) ] .
|
|
|
|
|
- 525 FormalParams
|
|
|
|
|
- 526 = "(" [ ParamSection { ";" ParamSection } ] ")" .
|
|
|
|
|
- 527 ParamSection (. VAR t: SymTab.TypeIndex;
|
|
|
|
|
- 528 isV: BOOLEAN; .)
|
|
|
|
|
- 529 = (. isV := FALSE; .)
|
|
|
|
|
- 530 [ "VAR" (. isV := TRUE; .) ]
|
|
|
|
|
- 531 ParIdents<isV> ":" Type<t, TRUE> (. SymTab.FixPending(t); .) .
|
|
|
|
|
- 532 ProcDecl (. VAR pn, m2: SymTab.Name; .)
|
|
|
|
|
- 533 = ProcHeading<pn> ";"
|
|
|
|
|
- 534 ( "FORWARD" (. SymTab.MarkFwd;
|
|
|
|
|
- 535 SymTab.CloseProc; .)
|
|
|
|
|
- 536 | Block<pn> (. SymTab.CloseProc;
|
|
|
|
|
- 537 SemError(230); .) ) .
|
|
|
|
|
- 538 Block<pn: SymTab.Name> (. VAR m2: SymTab.Name; .)
|
|
|
|
|
- 539 = DeclSeq
|
|
|
|
|
- 540 [ "BEGIN"
|
|
|
|
|
- 541 [ StatSeq ] ]
|
|
|
|
|
- 542 "END"
|
|
|
|
|
- 543 GetIdent<m2> (. IF ~SymTab.Equal(pn, m2) THEN
|
|
|
|
|
- 544 SemError(202) END; .) .
|
|
|
|
|
- 545 StatSeq
|
|
|
|
|
- 546 = Statement { ";" Statement } .
|
|
|
|
|
- 547 Statement (. VAR lx: QbeGen.QVal; .)
|
|
|
|
|
- 548 = Assign
|
|
|
|
|
- 549 | IfStat
|
|
|
|
|
- 550 | WhileStat
|
|
|
|
|
- 551 | RepeatStat
|
|
|
|
|
- 552 | LoopStat
|
|
|
|
|
- 553 | ForStat
|
|
|
|
|
- 554 | CaseStat
|
|
|
|
|
- 555 | WithStat
|
|
|
|
|
- 556 | ReturnStat
|
|
|
|
|
- 557 | NewStat
|
|
|
|
|
- 558 | DisposeStat
|
|
|
|
|
- 559 | "EXIT" (. IF QbeGen.TopLoop(lx) THEN
|
|
|
|
|
- 560 QbeGen.Jmp(lx)
|
|
|
|
|
- 561 ELSE SemError(230) END; .) .
|
|
|
|
|
- 562 (* NEW/DISPOSE as builtin statements (no call syntax until step 4).
|
|
|
|
|
- 563 Targets are pointer designators; DISPOSE nils afterwards (safer
|
|
|
|
|
- 564 than Wirth-undefined; documented). DISPOSE is shallow. *)
|
|
|
|
|
- 565 NewStat (. VAR dt: SymTab.TypeIndex;
|
|
|
|
|
- 566 dk: INTEGER;
|
|
|
|
|
- 567 qd, qm: QbeGen.QVal;
|
|
|
|
|
- 568 qn: SymTab.Name;
|
|
|
|
|
- 569 sfx: BOOLEAN;
|
|
|
|
|
- 570 bt: SymTab.TypeIndex; .)
|
|
|
|
|
- 571 = "NEW" "(" Design<dt, dk, qd, qn, sfx> ")"
|
|
|
|
|
- 572 (. IF dt = SymTab.InvalidType THEN
|
|
|
|
|
- 573 ELSIF (dk # SymTab.KindVar)
|
|
|
|
|
- 574 & (dk # SymTab.KindParam)
|
|
|
|
|
- 575 & (dk # SymTab.KindField) THEN
|
|
|
|
|
- 576 SemError(210)
|
|
|
|
|
- 577 ELSIF SymTab.ClassOf(dt) #
|
|
|
|
|
- 578 SymTab.ClPtr THEN
|
|
|
|
|
- 579 SemError(219)
|
|
|
|
|
- 580 ELSE bt := SymTab.PtrBase(dt);
|
|
|
|
|
- 581 IF bt #
|
|
|
|
|
- 582 SymTab.InvalidType THEN
|
|
|
|
|
- 583 QbeGen.NewHeap(bt, qm);
|
|
|
|
|
- 584 QbeGen.InitHeap(qm, bt);
|
|
|
|
|
- 585 IF sfx
|
|
|
|
|
- 586 OR (dk =
|
|
|
|
|
- 587 SymTab.KindField) THEN
|
|
|
|
|
- 588 QbeGen.ElemStore(qd, qm,
|
|
|
|
|
- 589 dt)
|
|
|
|
|
- 590 ELSE QbeGen.StorePtr(qn,
|
|
|
|
|
- 591 qm)
|
|
|
|
|
- 592 END
|
|
|
|
|
- 593 END
|
|
|
|
|
- 594 END; .) .
|
|
|
|
|
- 595 DisposeStat (. VAR dt: SymTab.TypeIndex;
|
|
|
|
|
- 596 dk: INTEGER;
|
|
|
|
|
- 597 qd, qv: QbeGen.QVal;
|
|
|
|
|
- 598 qn: SymTab.Name;
|
|
|
|
|
- 599 sfx: BOOLEAN; .)
|
|
|
|
|
- 600 = "DISPOSE" "(" Design<dt, dk, qd, qn, sfx> ")"
|
|
|
|
|
- 601 (. IF dt = SymTab.InvalidType THEN
|
|
|
|
|
- 602 ELSIF (dk # SymTab.KindVar)
|
|
|
|
|
- 603 & (dk # SymTab.KindParam)
|
|
|
|
|
- 604 & (dk # SymTab.KindField) THEN
|
|
|
|
|
- 605 SemError(210)
|
|
|
|
|
- 606 ELSIF SymTab.ClassOf(dt) #
|
|
|
|
|
- 607 SymTab.ClPtr THEN
|
|
|
|
|
- 608 SemError(219)
|
|
|
|
|
- 609 ELSE
|
|
|
|
|
- 610 IF sfx
|
|
|
|
|
- 611 OR (dk =
|
|
|
|
|
- 612 SymTab.KindField) THEN
|
|
|
|
|
- 613 QbeGen.ElemLoad(qd, dt,
|
|
|
|
|
- 614 qv)
|
|
|
|
|
- 615 ELSE QbeGen.LoadPtr(qn, qv)
|
|
|
|
|
- 616 END;
|
|
|
|
|
- 617 QbeGen.FreeHeap(qv);
|
|
|
|
|
- 618 IF sfx
|
|
|
|
|
- 619 OR (dk =
|
|
|
|
|
- 620 SymTab.KindField) THEN
|
|
|
|
|
- 621 QbeGen.ElemStore(qd, "0",
|
|
|
|
|
- 622 dt)
|
|
|
|
|
- 623 ELSE QbeGen.StorePtr(qn,
|
|
|
|
|
- 624 "0")
|
|
|
|
|
- 625 END
|
|
|
|
|
- 626 END; .) .
|
|
|
|
|
- 627 (* WITH pushes each record's fields (inner wins) plus its base
|
|
|
|
|
- 628 address; field designators resolve through both stacks. *)
|
|
|
|
|
- 629 WithStat (. VAR nW: CARDINAL; .)
|
|
|
|
|
- 630 = "WITH" (. nW := 0; .)
|
|
|
|
|
- 631 WithItem<nW> { "," WithItem<nW> }
|
|
|
|
|
- 632 "DO" StatSeq "END"
|
|
|
|
|
- 633 (. WHILE nW > 0 DO
|
|
|
|
|
- 634 SymTab.PopScope;
|
|
|
|
|
- 635 QbeGen.PopWith;
|
|
|
|
|
- 636 DEC(nW)
|
|
|
|
|
- 637 END; .) .
|
|
|
|
|
- 638 WithItem<VAR nW: CARDINAL> (. VAR dt: SymTab.TypeIndex;
|
|
|
|
|
- 639 dk: INTEGER;
|
|
|
|
|
- 640 qd, qe: QbeGen.QVal;
|
|
|
|
|
- 641 qn: SymTab.Name;
|
|
|
|
|
- 642 sfx: BOOLEAN; .)
|
|
|
|
|
- 643 = Design<dt, dk, qd, qn, sfx>
|
|
|
|
|
- 644 (. IF dt = SymTab.InvalidType THEN
|
|
|
|
|
- 645 ELSIF (SymTab.ClassOf(dt) #
|
|
|
|
|
- 646 SymTab.ClRecord)
|
|
|
|
|
- 647 & (SymTab.ClassOf(dt) #
|
|
|
|
|
- 648 SymTab.ClClass) THEN
|
|
|
|
|
- 649 SemError(215)
|
|
|
|
|
- 650 ELSIF SymTab.PushRecord(dt) THEN
|
|
|
|
|
- 651 QbeGen.PushWith(qd);
|
|
|
|
|
- 652 INC(nW)
|
|
|
|
|
- 653 END; .) .
|
|
|
|
|
- 654 Assign (. VAR dt, et: SymTab.TypeIndex;
|
|
|
|
|
- 655 dk: INTEGER;
|
|
|
|
|
- 656 qd, qe, qt: QbeGen.QVal;
|
|
|
|
|
- 657 qn: SymTab.Name;
|
|
|
|
|
- 658 isR, conv: BOOLEAN;
|
|
|
|
|
- 659 sfx: BOOLEAN; .)
|
|
|
|
|
- 660 = Design<dt, dk, qd, qn, sfx> ":="
|
|
|
|
|
- 661 Expr<et, qe> (. IF (dt # SymTab.InvalidType)
|
|
|
|
|
- 662 & (dk # SymTab.KindVar)
|
|
|
|
|
- 663 & (dk # SymTab.KindParam)
|
|
|
|
|
- 664 & (dk # SymTab.KindField) THEN
|
|
|
|
|
- 665 SemError(210)
|
|
|
|
|
- 666 ELSIF ~SymTab.Assignable(et,
|
|
|
|
|
- 667 dt) THEN
|
|
|
|
|
- 668 SemError(210)
|
|
|
|
|
- 669 ELSIF (dt # SymTab.InvalidType)
|
|
|
|
|
- 670 & (SymTab.ClassOf(dt) =
|
|
|
|
|
- 671 SymTab.ClClass) THEN
|
|
|
|
|
- 672 SemError(230) END;
|
|
|
|
|
- 673 isR := (dt #
|
|
|
|
|
- 674 SymTab.InvalidType)
|
|
|
|
|
- 675 & (SymTab.ClassOf(dt)
|
|
|
|
|
- 676 = SymTab.ClReal);
|
|
|
|
|
- 677 conv := isR
|
|
|
|
|
- 678 & SymTab.IsIntFamily(et);
|
|
|
|
|
- 679 IF ((dk = SymTab.KindVar)
|
|
|
|
|
- 680 OR (dk = SymTab.KindParam)
|
|
|
|
|
- 681 OR (dk = SymTab.KindField))
|
|
|
|
|
- 682 & (dt # SymTab.InvalidType)
|
|
|
|
|
- 683 & (et # SymTab.InvalidType)
|
|
|
|
|
- 684 & (SymTab.ClassOf(dt) #
|
|
|
|
|
- 685 SymTab.ClClass) THEN
|
|
|
|
|
- 686 IF sfx
|
|
|
|
|
- 687 OR (dk = SymTab.KindField) THEN
|
|
|
|
|
- 688 IF SymTab.ClassOf(dt) =
|
|
|
|
|
- 689 SymTab.ClArray THEN
|
|
|
|
|
- 690 QbeGen.CopyArray(qd, qe,
|
|
|
|
|
- 691 dt)
|
|
|
|
|
- 692 ELSIF SymTab.ClassOf(dt) =
|
|
|
|
|
- 693 SymTab.ClSet THEN
|
|
|
|
|
- 694 QbeGen.CopySet(qd, qe,
|
|
|
|
|
- 695 SymTab.SetWords(dt),
|
|
|
|
|
- 696 SymTab.SetWords(et))
|
|
|
|
|
- 697 ELSIF SymTab.ClassOf(dt) =
|
|
|
|
|
- 698 SymTab.ClRecord THEN
|
|
|
|
|
- 699 QbeGen.CopyRecord(qd, qe,
|
|
|
|
|
- 700 dt)
|
|
|
|
|
- 701 ELSIF conv THEN
|
|
|
|
|
- 702 QbeGen.ConvIR(qe, qt);
|
|
|
|
|
- 703 QbeGen.ElemStore(qd, qt,
|
|
|
|
|
- 704 dt)
|
|
|
|
|
- 705 ELSE QbeGen.ElemStore(qd, qe,
|
|
|
|
|
- 706 dt)
|
|
|
|
|
- 707 END
|
|
|
|
|
- 708 ELSIF SymTab.ClassOf(dt) =
|
|
|
|
|
- 709 SymTab.ClArray THEN
|
|
|
|
|
- 710 QbeGen.CopyArray(qd, qe, dt)
|
|
|
|
|
- 711 ELSIF SymTab.ClassOf(dt) =
|
|
|
|
|
- 712 SymTab.ClSet THEN
|
|
|
|
|
- 713 QbeGen.CopySet(qd, qe,
|
|
|
|
|
- 714 SymTab.SetWords(dt),
|
|
|
|
|
- 715 SymTab.SetWords(et))
|
|
|
|
|
- 716 ELSIF SymTab.ClassOf(dt) =
|
|
|
|
|
- 717 SymTab.ClRecord THEN
|
|
|
|
|
- 718 QbeGen.CopyRecord(qd, qe, dt)
|
|
|
|
|
- 719 ELSIF SymTab.ClassOf(dt) =
|
|
|
|
|
- 720 SymTab.ClPtr THEN
|
|
|
|
|
- 721 QbeGen.StorePtr(qn, qe)
|
|
|
|
|
- 722 ELSIF conv THEN
|
|
|
|
|
- 723 QbeGen.ConvIR(qe, qt);
|
|
|
|
|
- 724 QbeGen.StoreVar(qn, qt, TRUE)
|
|
|
|
|
- 725 ELSE
|
|
|
|
|
- 726 QbeGen.StoreVar(qn, qe, isR)
|
|
|
|
|
- 727 END
|
|
|
|
|
- 728 END; .) .
|
|
|
|
|
- 729 IfStat (. VAR t: SymTab.TypeIndex;
|
|
|
|
|
- 730 q, lThen, lElse, lEnd:
|
|
|
|
|
- 731 QbeGen.QVal;
|
|
|
|
|
- 732 hasElse: BOOLEAN; .)
|
|
|
|
|
- 733 = "IF" (. hasElse := FALSE; .)
|
|
|
|
|
- 734 Expr<t, q> (. IF ~SymTab.BoolCheck(t) THEN
|
|
|
|
|
- 735 SemError(214) END;
|
|
|
|
|
- 736 QbeGen.NewLabel(lThen);
|
|
|
|
|
- 737 QbeGen.NewLabel(lElse);
|
|
|
|
|
- 738 QbeGen.NewLabel(lEnd);
|
|
|
|
|
- 739 QbeGen.Jnz(q, lThen, lElse);
|
|
|
|
|
- 740 QbeGen.EmitLabel(lThen); .)
|
|
|
|
|
- 741 "THEN" StatSeq (. QbeGen.Jmp(lEnd); .)
|
|
|
|
|
- 742 { "ELSIF" (. QbeGen.EmitLabel(lElse);
|
|
|
|
|
- 743 QbeGen.NewLabel(lElse); .)
|
|
|
|
|
- 744 Expr<t, q> (. IF ~SymTab.BoolCheck(t) THEN
|
|
|
|
|
- 745 SemError(214) END;
|
|
|
|
|
- 746 QbeGen.NewLabel(lThen);
|
|
|
|
|
- 747 QbeGen.Jnz(q, lThen, lElse);
|
|
|
|
|
- 748 QbeGen.EmitLabel(lThen); .)
|
|
|
|
|
- 749 "THEN" StatSeq (. QbeGen.Jmp(lEnd); .) }
|
|
|
|
|
- 750 [ "ELSE" (. QbeGen.EmitLabel(lElse);
|
|
|
|
|
- 751 hasElse := TRUE; .)
|
|
|
|
|
- 752 StatSeq ]
|
|
|
|
|
- 753 "END" (. IF hasElse THEN
|
|
|
|
|
- 754 QbeGen.EmitLabel(lEnd)
|
|
|
|
|
- 755 ELSE QbeGen.EmitLabel(lElse);
|
|
|
|
|
- 756 QbeGen.EmitLabel(lEnd)
|
|
|
|
|
- 757 END; .) .
|
|
|
|
|
- 758 WhileStat (. VAR t: SymTab.TypeIndex;
|
|
|
|
|
- 759 q, lTop, lBody, lEnd:
|
|
|
|
|
- 760 QbeGen.QVal; .)
|
|
|
|
|
- 761 = "WHILE" (. QbeGen.NewLabel(lTop);
|
|
|
|
|
- 762 QbeGen.NewLabel(lBody);
|
|
|
|
|
- 763 QbeGen.NewLabel(lEnd);
|
|
|
|
|
- 764 QbeGen.EmitLabel(lTop); .)
|
|
|
|
|
- 765 Expr<t, q> (. IF ~SymTab.BoolCheck(t) THEN
|
|
|
|
|
- 766 SemError(214) END;
|
|
|
|
|
- 767 QbeGen.Jnz(q, lBody, lEnd);
|
|
|
|
|
- 768 QbeGen.EmitLabel(lBody); .)
|
|
|
|
|
- 769 "DO" StatSeq (. QbeGen.Jmp(lTop); .)
|
|
|
|
|
- 770 "END" (. QbeGen.EmitLabel(lEnd); .) .
|
|
|
|
|
- 771 RepeatStat (. VAR t: SymTab.TypeIndex;
|
|
|
|
|
- 772 q, lTop, lEnd: QbeGen.QVal; .)
|
|
|
|
|
- 773 = "REPEAT" (. QbeGen.NewLabel(lTop);
|
|
|
|
|
- 774 QbeGen.NewLabel(lEnd);
|
|
|
|
|
- 775 QbeGen.EmitLabel(lTop); .)
|
|
|
|
|
- 776 StatSeq
|
|
|
|
|
- 777 "UNTIL" Expr<t, q> (. IF ~SymTab.BoolCheck(t) THEN
|
|
|
|
|
- 778 SemError(214) END;
|
|
|
|
|
- 779 QbeGen.Jnz(q, lEnd, lTop);
|
|
|
|
|
- 780 QbeGen.EmitLabel(lEnd); .) .
|
|
|
|
|
- 781 LoopStat (. VAR lTop, lEnd: QbeGen.QVal; .)
|
|
|
|
|
- 782 = "LOOP" (. QbeGen.NewLabel(lTop);
|
|
|
|
|
- 783 QbeGen.NewLabel(lEnd);
|
|
|
|
|
- 784 QbeGen.PushLoop(lEnd);
|
|
|
|
|
- 785 QbeGen.EmitLabel(lTop); .)
|
|
|
|
|
- 786 StatSeq
|
|
|
|
|
- 787 "END" (. QbeGen.Jmp(lTop);
|
|
|
|
|
- 788 QbeGen.PopLoop;
|
|
|
|
|
- 789 QbeGen.EmitLabel(lEnd); .) .
|
|
|
|
|
- 790 (* FOR with static-sign BY (literal, non-zero; 220 otherwise).
|
|
|
|
|
- 791 Runtime direction would need a compare-select; the literal
|
|
|
|
|
- 792 sign picks cslew/csegew at "DO" time. *)
|
|
|
|
|
- 793 ForStat (. VAR lv: SymTab.Name;
|
|
|
|
|
- 794 tlo, thi, tby:
|
|
|
|
|
- 795 SymTab.TypeIndex;
|
|
|
|
|
- 796 qlo, qhi, qby, qt, qk, qb:
|
|
|
|
|
- 797 QbeGen.QVal;
|
|
|
|
|
- 798 lTop, lBody, lEnd:
|
|
|
|
|
- 799 QbeGen.QVal;
|
|
|
|
|
- 800 by: INTEGER;
|
|
|
|
|
- 801 ok: BOOLEAN; .)
|
|
|
|
|
- 802 = "FOR" (. by := 1; .)
|
|
|
|
|
- 803 GetIdent<lv> (. ok := SymTab.Lookup(lv);
|
|
|
|
|
- 804 IF ~ok THEN
|
|
|
|
|
- 805 SemError(201)
|
|
|
|
|
- 806 ELSIF (SymTab.SymKind(lv) #
|
|
|
|
|
- 807 SymTab.KindVar)
|
|
|
|
|
- 808 & (SymTab.SymKind(lv) #
|
|
|
|
|
- 809 SymTab.KindParam) THEN
|
|
|
|
|
- 810 SemError(220); ok := FALSE
|
|
|
|
|
- 811 ELSIF ~SymTab.IsIntFamily(
|
|
|
|
|
- 812 SymTab.SymType(lv)) THEN
|
|
|
|
|
- 813 SemError(220); ok := FALSE
|
|
|
|
|
- 814 END; .)
|
|
|
|
|
- 815 ":=" Expr<tlo, qlo> (. IF ~SymTab.IsIntFamily(tlo) THEN
|
|
|
|
|
- 816 SemError(220); ok := FALSE
|
|
|
|
|
- 817 END; .)
|
|
|
|
|
- 818 "TO" Expr<thi, qhi> (. IF ~SymTab.IsIntFamily(thi) THEN
|
|
|
|
|
- 819 SemError(220); ok := FALSE
|
|
|
|
|
- 820 END; .)
|
|
|
|
|
- 821 [ "BY" Expr<tby, qby> (. IF (tby #
|
|
|
|
|
- 822 SymTab.InvalidType)
|
|
|
|
|
- 823 & ~SymTab.IsIntFamily(tby) THEN
|
|
|
|
|
- 824 SemError(220); ok := FALSE
|
|
|
|
|
- 825 END;
|
|
|
|
|
- 826 IF ~SymTab.ConstInt(qby, by) THEN
|
|
|
|
|
- 827 SemError(230); by := 1
|
|
|
|
|
- 828 ELSIF by = 0 THEN
|
|
|
|
|
- 829 SemError(220); by := 1
|
|
|
|
|
- 830 END; .) ]
|
|
|
|
|
- 831 "DO" (. IF ok THEN
|
|
|
|
|
- 832 QbeGen.StoreVar(lv, qlo,
|
|
|
|
|
- 833 FALSE) END;
|
|
|
|
|
- 834 QbeGen.NewLabel(lTop);
|
|
|
|
|
- 835 QbeGen.NewLabel(lBody);
|
|
|
|
|
- 836 QbeGen.NewLabel(lEnd);
|
|
|
|
|
- 837 QbeGen.EmitLabel(lTop);
|
|
|
|
|
- 838 QbeGen.LoadVar(lv, FALSE, qt);
|
|
|
|
|
- 839 QbeGen.NewTemp(qk);
|
|
|
|
|
- 840 IF by > 0 THEN
|
|
|
|
|
- 841 QbeGen.Op3("cslew", qk,
|
|
|
|
|
- 842 qt, qhi, FALSE)
|
|
|
|
|
- 843 ELSE QbeGen.Op3("csgew", qk,
|
|
|
|
|
- 844 qt, qhi, FALSE)
|
|
|
|
|
- 845 END;
|
|
|
|
|
- 846 QbeGen.Jnz(qk, lBody, lEnd);
|
|
|
|
|
- 847 QbeGen.EmitLabel(lBody); .)
|
|
|
|
|
- 848 StatSeq
|
|
|
|
|
- 849 "END" (. IF ok THEN
|
|
|
|
|
- 850 QbeGen.LoadVar(lv, FALSE,
|
|
|
|
|
- 851 qt);
|
|
|
|
|
- 852 QbeGen.IntStr(by, qb);
|
|
|
|
|
- 853 QbeGen.NewTemp(qk);
|
|
|
|
|
- 854 QbeGen.Op3("add", qk,
|
|
|
|
|
- 855 qt, qb, FALSE);
|
|
|
|
|
- 856 QbeGen.StoreVar(lv, qk,
|
|
|
|
|
- 857 FALSE) END;
|
|
|
|
|
- 858 QbeGen.Jmp(lTop);
|
|
|
|
|
- 859 QbeGen.EmitLabel(lEnd); .) .
|
|
|
|
|
- 860 CaseStat (. VAR tsel: SymTab.TypeIndex;
|
|
|
|
|
- 861 qsel, lEnd: QbeGen.QVal; .)
|
|
|
|
|
- 862 = "CASE" Expr<tsel, qsel> (. QbeGen.NewLabel(lEnd); .)
|
|
|
|
|
- 863 "OF" CaseAlt<tsel, qsel, lEnd>
|
|
|
|
|
- 864 { "|" CaseAlt<tsel, qsel, lEnd> }
|
|
|
|
|
- 865 [ "ELSE" StatSeq ]
|
|
|
|
|
- 866 "END" (. QbeGen.EmitLabel(lEnd); .) .
|
|
|
|
|
- 867 (* Compare-chain lowering: each alternative ends its match-tests
|
|
|
|
|
- 868 with "jmp lAfter", so the no-match fallthrough skips the body:
|
|
|
|
|
- 869 "cmp; jnz(lBody,lF); lF: ... ; jmp lAfter; lBody: S; jmp lEnd;
|
|
|
|
|
- 870 lAfter:". Falls into the next alternative, ELSE, or END. *)
|
|
|
|
|
- 871 CaseAlt<tsel: SymTab.TypeIndex; qsel: QbeGen.QVal;
|
|
|
|
|
- 872 lEnd: QbeGen.QVal> (. VAR lBody, lAfter: QbeGen.QVal; .)
|
|
|
|
|
- 873 = (. QbeGen.NewLabel(lBody);
|
|
|
|
|
- 874 QbeGen.NewLabel(lAfter); .)
|
|
|
|
|
- 875 CaseLabel<tsel, qsel, lBody>
|
|
|
|
|
- 876 { "," CaseLabel<tsel, qsel, lBody> }
|
|
|
|
|
- 877 ":" (. QbeGen.Jmp(lAfter);
|
|
|
|
|
- 878 QbeGen.EmitLabel(lBody); .)
|
|
|
|
|
- 879 StatSeq (. QbeGen.Jmp(lEnd);
|
|
|
|
|
- 880 QbeGen.EmitLabel(lAfter); .) .
|
|
|
|
|
- 881 CaseLabel<tsel: SymTab.TypeIndex; qsel: QbeGen.QVal;
|
|
|
|
|
- 882 lBody: QbeGen.QVal> (. VAR t2, t3: SymTab.TypeIndex;
|
|
|
|
|
- 883 q2, q3, qc, qd, qe:
|
|
|
|
|
- 884 QbeGen.QVal;
|
|
|
|
|
- 885 lNext: QbeGen.QVal; .)
|
|
|
|
|
- 886 = Expr<t2, q2> (. IF (t2 #
|
|
|
|
|
- 887 SymTab.InvalidType)
|
|
|
|
|
- 888 & (tsel #
|
|
|
|
|
- 889 SymTab.InvalidType)
|
|
|
|
|
- 890 & ((SymTab.ClassOf(t2) =
|
|
|
|
|
- 891 SymTab.ClSet)
|
|
|
|
|
- 892 OR (SymTab.ClassOf(tsel) =
|
|
|
|
|
- 893 SymTab.ClSet)) THEN
|
|
|
|
|
- 894 SemError(230)
|
|
|
|
|
- 895 ELSIF (t2 #
|
|
|
|
|
- 896 SymTab.InvalidType)
|
|
|
|
|
- 897 & (tsel #
|
|
|
|
|
- 898 SymTab.InvalidType)
|
|
|
|
|
- 899 & ~SymTab.EqCheck(t2,
|
|
|
|
|
- 900 tsel) THEN
|
|
|
|
|
- 901 SemError(213) END;
|
|
|
|
|
- 902 IF ~QbeGen.IsImm(q2) THEN
|
|
|
|
|
- 903 SemError(230);
|
|
|
|
|
- 904 QbeGen.CopyOp("0", q2)
|
|
|
|
|
- 905 END;
|
|
|
|
|
- 906 QbeGen.NewLabel(lNext);
|
|
|
|
|
- 907 QbeGen.Cmp(SymTab.OpEq,
|
|
|
|
|
- 908 qsel, q2, qc, FALSE);
|
|
|
|
|
- 909 QbeGen.Jnz(qc, lBody, lNext);
|
|
|
|
|
- 910 QbeGen.EmitLabel(lNext); .)
|
|
|
|
|
- 911 [ ".." Expr<t3, q3> (. IF (t3 #
|
|
|
|
|
- 912 SymTab.InvalidType)
|
|
|
|
|
- 913 & (tsel #
|
|
|
|
|
- 914 SymTab.InvalidType)
|
|
|
|
|
- 915 & ~SymTab.EqCheck(t3,
|
|
|
|
|
- 916 tsel) THEN
|
|
|
|
|
- 917 SemError(213) END;
|
|
|
|
|
- 918 IF ~QbeGen.IsImm(q3) THEN
|
|
|
|
|
- 919 SemError(230);
|
|
|
|
|
- 920 QbeGen.CopyOp("0", q3)
|
|
|
|
|
- 921 END;
|
|
|
|
|
- 922 QbeGen.Cmp(SymTab.OpGe,
|
|
|
|
|
- 923 qsel, q2, qc, FALSE);
|
|
|
|
|
- 924 QbeGen.Cmp(SymTab.OpLe,
|
|
|
|
|
- 925 qsel, q3, qd, FALSE);
|
|
|
|
|
- 926 QbeGen.NewTemp(qe);
|
|
|
|
|
- 927 QbeGen.Op3("and", qe, qc, qd,
|
|
|
|
|
- 928 FALSE);
|
|
|
|
|
- 929 QbeGen.NewLabel(lNext);
|
|
|
|
|
- 930 QbeGen.Jnz(qe, lBody, lNext);
|
|
|
|
|
- 931 QbeGen.EmitLabel(lNext); .) ] .
|
|
|
|
|
- 932 ReturnStat (. VAR t: SymTab.TypeIndex;
|
|
|
|
|
- 933 q: QbeGen.QVal;
|
|
|
|
|
- 934 res: SymTab.TypeIndex;
|
|
|
|
|
- 935 hadE: BOOLEAN; .)
|
|
|
|
|
- 936 = "RETURN" (. hadE := FALSE; .)
|
|
|
|
|
- 937 [ Expr<t, q> (. hadE := TRUE; .) ]
|
|
|
|
|
- 938 (. IF ~SymTab.InProc() THEN
|
|
|
|
|
- 939 SemError(232)
|
|
|
|
|
- 940 ELSE res := SymTab.CurRes();
|
|
|
|
|
- 941 IF ~hadE THEN
|
|
|
|
|
- 942 IF res #
|
|
|
|
|
- 943 SymTab.InvalidType THEN
|
|
|
|
|
- 944 SemError(232) END
|
|
|
|
|
- 945 ELSIF (res =
|
|
|
|
|
- 946 SymTab.InvalidType)
|
|
|
|
|
- 947 OR (t #
|
|
|
|
|
- 948 SymTab.InvalidType)
|
|
|
|
|
- 949 & ~SymTab.Assignable(t,
|
|
|
|
|
- 950 res) THEN
|
|
|
|
|
- 951 SemError(232)
|
|
|
|
|
- 952 END
|
|
|
|
|
- 953 END; .) .
|
|
|
|
|
- 954 (* Designator: scalar loads, array addresses, and index suffixes.
|
|
|
|
|
- 955 Each index descends one level (bounds-checked, trap on breach);
|
|
|
|
|
- 956 nested levels reload the inner descriptor address. q ends as the
|
|
|
|
|
- 957 value (scalars), the descriptor address (plain arrays), or the
|
|
|
|
|
- 958 element address (indexed); sfx marks the indexed form. *)
|
|
|
|
|
- 959 Design<VAR t: SymTab.TypeIndex; VAR k: INTEGER;
|
|
|
|
|
- 960 VAR q: QbeGen.QVal; VAR qn: SymTab.Name; VAR sfx: BOOLEAN>
|
|
|
|
|
- 961 (. VAR n, fn: SymTab.Name;
|
|
|
|
|
- 962 cls: INTEGER;
|
|
|
|
|
- 963 curT, it, eT, bt:
|
|
|
|
|
- 964 SymTab.TypeIndex;
|
|
|
|
|
- 965 iq, ql, qlo, qhi, qe:
|
|
|
|
|
- 966 QbeGen.QVal;
|
|
|
|
|
- 967 lo, hi: INTEGER;
|
|
|
|
|
- 968 fo: INTEGER;
|
|
|
|
|
- 969 isOpen: BOOLEAN;
|
|
|
|
|
- 970 qb: QbeGen.QVal; .)
|
|
|
|
|
- 971 = GetIdent<n> (. QbeGen.CopyOp(n, qn);
|
|
|
|
|
- 972 sfx := FALSE;
|
|
|
|
|
- 973 IF ~SymTab.Lookup(n) THEN
|
|
|
|
|
- 974 SemError(201);
|
|
|
|
|
- 975 t := SymTab.InvalidType;
|
|
|
|
|
- 976 k := -1;
|
|
|
|
|
- 977 QbeGen.CopyOp("0", q)
|
|
|
|
|
- 978 ELSE
|
|
|
|
|
- 979 t := SymTab.SymType(n);
|
|
|
|
|
- 980 k := SymTab.SymKind(n);
|
|
|
|
|
- 981 IF k = SymTab.KindConst THEN
|
|
|
|
|
- 982 IF SymTab.Equal(n,
|
|
|
|
|
- 983 "TRUE") THEN
|
|
|
|
|
- 984 t := SymTab.BoolType();
|
|
|
|
|
- 985 QbeGen.CopyOp("1", q)
|
|
|
|
|
- 986 ELSIF SymTab.Equal(n,
|
|
|
|
|
- 987 "FALSE") THEN
|
|
|
|
|
- 988 t := SymTab.BoolType();
|
|
|
|
|
- 989 QbeGen.CopyOp("0", q)
|
|
|
|
|
- 990 ELSIF SymTab.Equal(n,
|
|
|
|
|
- 991 "NIL") THEN
|
|
|
|
|
- 992 QbeGen.CopyOp("0", q)
|
|
|
|
|
- 993 ELSE
|
|
|
|
|
- 994 cls :=
|
|
|
|
|
- 995 SymTab.ClassOf(t);
|
|
|
|
|
- 996 IF (t #
|
|
|
|
|
- 997 SymTab.InvalidType)
|
|
|
|
|
- 998 & ((cls = SymTab.ClInt)
|
|
|
|
|
- 999 OR (cls
|
|
|
|
|
- 1000 = SymTab.ClChar)
|
|
|
|
|
- 1001 OR (cls
|
|
|
|
|
- 1002 = SymTab.ClReal)
|
|
|
|
|
- 1003 OR (cls
|
|
|
|
|
- 1004 = SymTab.ClNil)) THEN
|
|
|
|
|
- 1005 IF cls = SymTab.ClNil THEN
|
|
|
|
|
- 1006 QbeGen.CopyOp("0", q)
|
|
|
|
|
- 1007 ELSE
|
|
|
|
|
- 1008 QbeGen.LoadVar(n,
|
|
|
|
|
- 1009 cls = SymTab.ClReal,
|
|
|
|
|
- 1010 q)
|
|
|
|
|
- 1011 END
|
|
|
|
|
- 1012 ELSE
|
|
|
|
|
- 1013 IF t #
|
|
|
|
|
- 1014 SymTab.InvalidType THEN
|
|
|
|
|
- 1015 SemError(230)
|
|
|
|
|
- 1016 END;
|
|
|
|
|
- 1017 QbeGen.CopyOp("0", q)
|
|
|
|
|
- 1018 END
|
|
|
|
|
- 1019 END
|
|
|
|
|
- 1020 ELSIF (k = SymTab.KindVar)
|
|
|
|
|
- 1021 OR (k = SymTab.KindParam) THEN
|
|
|
|
|
- 1022 cls :=
|
|
|
|
|
- 1023 SymTab.ClassOf(t);
|
|
|
|
|
- 1024 IF (cls = SymTab.ClInt)
|
|
|
|
|
- 1025 OR (cls = SymTab.ClBool)
|
|
|
|
|
- 1026 OR (cls = SymTab.ClChar)
|
|
|
|
|
- 1027 OR (cls
|
|
|
|
|
- 1028 = SymTab.ClReal) THEN
|
|
|
|
|
- 1029 QbeGen.LoadVar(n,
|
|
|
|
|
- 1030 cls = SymTab.ClReal, q)
|
|
|
|
|
- 1031 ELSIF cls = SymTab.ClPtr THEN
|
|
|
|
|
- 1032 QbeGen.LoadPtr(n, q)
|
|
|
|
|
- 1033 ELSIF (cls
|
|
|
|
|
- 1034 = SymTab.ClArray)
|
|
|
|
|
- 1035 OR (cls
|
|
|
|
|
- 1036 = SymTab.ClSet)
|
|
|
|
|
- 1037 OR (cls
|
|
|
|
|
- 1038 = SymTab.ClRecord)
|
|
|
|
|
- 1039 OR (cls
|
|
|
|
|
- 1040 = SymTab.ClClass) THEN
|
|
|
|
|
- 1041 QbeGen.AddrOf(n, q)
|
|
|
|
|
- 1042 ELSE SemError(230);
|
|
|
|
|
- 1043 QbeGen.CopyOp("0", q)
|
|
|
|
|
- 1044 END
|
|
|
|
|
- 1045 ELSE QbeGen.CopyOp("0", q);
|
|
|
|
|
- 1046 IF (k = SymTab.KindImport)
|
|
|
|
|
- 1047 OR (k = SymTab.KindProc) THEN
|
|
|
|
|
- 1048 SemError(230)
|
|
|
|
|
- 1049 ELSE
|
|
|
|
|
- 1050 IF k = SymTab.KindField THEN
|
|
|
|
|
- 1051 IF QbeGen.TopWith(qb) THEN
|
|
|
|
|
- 1052 fo :=
|
|
|
|
|
- 1053 SymTab.FieldOffset(
|
|
|
|
|
- 1054 SymTab.FieldOwner(n),
|
|
|
|
|
- 1055 n);
|
|
|
|
|
- 1056 QbeGen.FieldAddr(qb,
|
|
|
|
|
- 1057 fo, q);
|
|
|
|
|
- 1058 sfx := TRUE
|
|
|
|
|
- 1059 ELSE SemError(230);
|
|
|
|
|
- 1060 QbeGen.CopyOp("0", q)
|
|
|
|
|
- 1061 END
|
|
|
|
|
- 1062 END
|
|
|
|
|
- 1063 END
|
|
|
|
|
- 1064 END
|
|
|
|
|
- 1065 END; .)
|
|
|
|
|
- 1066 { "[" Expr<it, iq>
|
|
|
|
|
- 1067 (. IF t = SymTab.InvalidType THEN
|
|
|
|
|
- 1068 ELSIF SymTab.ClassOf(t) #
|
|
|
|
|
- 1069 SymTab.ClArray THEN
|
|
|
|
|
- 1070 SemError(217);
|
|
|
|
|
- 1071 t := SymTab.InvalidType
|
|
|
|
|
- 1072 ELSIF ~SymTab.IsIntFamily(it)
|
|
|
|
|
- 1073 & (SymTab.ClassOf(it) #
|
|
|
|
|
- 1074 SymTab.ClChar) THEN
|
|
|
|
|
- 1075 SemError(218);
|
|
|
|
|
- 1076 t := SymTab.InvalidType
|
|
|
|
|
- 1077 ELSE
|
|
|
|
|
- 1078 QbeGen.WidenIndex(iq, ql);
|
|
|
|
|
- 1079 isOpen :=
|
|
|
|
|
- 1080 SymTab.IsOpenArray(t);
|
|
|
|
|
- 1081 IF isOpen THEN
|
|
|
|
|
- 1082 QbeGen.CopyOp("0", qlo);
|
|
|
|
|
- 1083 QbeGen.OpenHi(q, qhi)
|
|
|
|
|
- 1084 ELSE
|
|
|
|
|
- 1085 lo := SymTab.ArrayLo(t);
|
|
|
|
|
- 1086 hi := SymTab.ArrayHi(t);
|
|
|
|
|
- 1087 QbeGen.IntStr(lo, qlo);
|
|
|
|
|
- 1088 QbeGen.IntStr(hi, qhi)
|
|
|
|
|
- 1089 END;
|
|
|
|
|
- 1090 QbeGen.CheckRange(ql, qlo,
|
|
|
|
|
- 1091 qhi);
|
|
|
|
|
- 1092 eT := SymTab.ArrayElem(t);
|
|
|
|
|
- 1093 QbeGen.ElemAddr(q, ql, qlo,
|
|
|
|
|
- 1094 t, qe);
|
|
|
|
|
- 1095 IF SymTab.ClassOf(eT) =
|
|
|
|
|
- 1096 SymTab.ClArray THEN
|
|
|
|
|
- 1097 QbeGen.ElemLoad(qe, eT, q)
|
|
|
|
|
- 1098 ELSE QbeGen.CopyOp(qe, q)
|
|
|
|
|
- 1099 END;
|
|
|
|
|
- 1100 t := eT; sfx := TRUE
|
|
|
|
|
- 1101 END; .)
|
|
|
|
|
- 1102 { "," Expr<it, iq>
|
|
|
|
|
- 1103 (. IF t = SymTab.InvalidType THEN
|
|
|
|
|
- 1104 ELSIF SymTab.ClassOf(t) #
|
|
|
|
|
- 1105 SymTab.ClArray THEN
|
|
|
|
|
- 1106 SemError(217);
|
|
|
|
|
- 1107 t := SymTab.InvalidType
|
|
|
|
|
- 1108 ELSIF ~SymTab.IsIntFamily(it)
|
|
|
|
|
- 1109 & (SymTab.ClassOf(it) #
|
|
|
|
|
- 1110 SymTab.ClChar) THEN
|
|
|
|
|
- 1111 SemError(218);
|
|
|
|
|
- 1112 t := SymTab.InvalidType
|
|
|
|
|
- 1113 ELSE
|
|
|
|
|
- 1114 QbeGen.WidenIndex(iq, ql);
|
|
|
|
|
- 1115 isOpen :=
|
|
|
|
|
- 1116 SymTab.IsOpenArray(t);
|
|
|
|
|
- 1117 IF isOpen THEN
|
|
|
|
|
- 1118 QbeGen.CopyOp("0", qlo);
|
|
|
|
|
- 1119 QbeGen.OpenHi(q, qhi)
|
|
|
|
|
- 1120 ELSE
|
|
|
|
|
- 1121 lo := SymTab.ArrayLo(t);
|
|
|
|
|
- 1122 hi := SymTab.ArrayHi(t);
|
|
|
|
|
- 1123 QbeGen.IntStr(lo, qlo);
|
|
|
|
|
- 1124 QbeGen.IntStr(hi, qhi)
|
|
|
|
|
- 1125 END;
|
|
|
|
|
- 1126 QbeGen.CheckRange(ql, qlo,
|
|
|
|
|
- 1127 qhi);
|
|
|
|
|
- 1128 eT := SymTab.ArrayElem(t);
|
|
|
|
|
- 1129 QbeGen.ElemAddr(q, ql, qlo,
|
|
|
|
|
- 1130 t, qe);
|
|
|
|
|
- 1131 IF SymTab.ClassOf(eT) =
|
|
|
|
|
- 1132 SymTab.ClArray THEN
|
|
|
|
|
- 1133 QbeGen.ElemLoad(qe, eT, q)
|
|
|
|
|
- 1134 ELSE QbeGen.CopyOp(qe, q)
|
|
|
|
|
- 1135 END;
|
|
|
|
|
- 1136 t := eT; sfx := TRUE
|
|
|
|
|
- 1137 END; .) }
|
|
|
|
|
- 1138 "]"
|
|
|
|
|
- 1139 | "." GetIdent<fn>
|
|
|
|
|
- 1140 (. IF t = SymTab.InvalidType THEN
|
|
|
|
|
- 1141 ELSIF (SymTab.ClassOf(t) #
|
|
|
|
|
- 1142 SymTab.ClRecord)
|
|
|
|
|
- 1143 & (SymTab.ClassOf(t) #
|
|
|
|
|
- 1144 SymTab.ClClass) THEN
|
|
|
|
|
- 1145 SemError(215);
|
|
|
|
|
- 1146 t := SymTab.InvalidType
|
|
|
|
|
- 1147 ELSIF ~SymTab.FieldExists(t,
|
|
|
|
|
- 1148 fn) THEN
|
|
|
|
|
- 1149 SemError(216);
|
|
|
|
|
- 1150 t := SymTab.InvalidType
|
|
|
|
|
- 1151 ELSE
|
|
|
|
|
- 1152 fo := SymTab.FieldOffset(t,
|
|
|
|
|
- 1153 fn);
|
|
|
|
|
- 1154 t := SymTab.FieldType(t, fn);
|
|
|
|
|
- 1155 QbeGen.FieldAddr(q, fo, qe);
|
|
|
|
|
- 1156 IF SymTab.ClassOf(t) =
|
|
|
|
|
- 1157 SymTab.ClArray THEN
|
|
|
|
|
- 1158 QbeGen.ElemLoad(qe, t, q)
|
|
|
|
|
- 1159 ELSE QbeGen.CopyOp(qe, q)
|
|
|
|
|
- 1160 END;
|
|
|
|
|
- 1161 sfx := TRUE
|
|
|
|
|
- 1162 END; .)
|
|
|
|
|
- 1163 | "^"
|
|
|
|
|
- 1164 (. IF t = SymTab.InvalidType THEN
|
|
|
|
|
- 1165 ELSIF SymTab.ClassOf(t) #
|
|
|
|
|
- 1166 SymTab.ClPtr THEN
|
|
|
|
|
- 1167 SemError(219);
|
|
|
|
|
- 1168 t := SymTab.InvalidType
|
|
|
|
|
- 1169 ELSE
|
|
|
|
|
- 1170 bt := SymTab.PtrBase(t);
|
|
|
|
|
- 1171 IF bt = SymTab.InvalidType THEN
|
|
|
|
|
- 1172 ELSE
|
|
|
|
|
- 1173 IF sfx THEN
|
|
|
|
|
- 1174 QbeGen.ElemLoad(q, t,
|
|
|
|
|
- 1175 qb);
|
|
|
|
|
- 1176 QbeGen.CopyOp(qb, q)
|
|
|
|
|
- 1177 END;
|
|
|
|
|
- 1178 t := bt;
|
|
|
|
|
- 1179 IF (SymTab.ClassOf(bt) =
|
|
|
|
|
- 1180 SymTab.ClInt)
|
|
|
|
|
- 1181 OR (SymTab.ClassOf(bt) =
|
|
|
|
|
- 1182 SymTab.ClBool)
|
|
|
|
|
- 1183 OR (SymTab.ClassOf(bt) =
|
|
|
|
|
- 1184 SymTab.ClChar)
|
|
|
|
|
- 1185 OR (SymTab.ClassOf(bt) =
|
|
|
|
|
- 1186 SymTab.ClReal) THEN
|
|
|
|
|
- 1187 sfx := TRUE
|
|
|
|
|
- 1188 ELSE sfx := FALSE
|
|
|
|
|
- 1189 END
|
|
|
|
|
- 1190 END
|
|
|
|
|
- 1191 END; .) } .
|
|
|
|
|
- 1192 Expr<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
|
|
- 1193 (. VAR t2: SymTab.TypeIndex;
|
|
|
|
|
- 1194 op: INTEGER;
|
|
|
|
|
- 1195 q2, qt: QbeGen.QVal;
|
|
|
|
|
- 1196 isR: BOOLEAN; .)
|
|
|
|
|
- 1197 = SimExpr<t, q>
|
|
|
|
|
- 1198 [ Rel<op> SimExpr<t2, q2>
|
|
|
|
|
- 1199 (. IF op = SymTab.OpIn THEN
|
|
|
|
|
- 1200 IF SymTab.InCheck(t, t2) THEN
|
|
|
|
|
- 1201 IF (t = SymTab.InvalidType)
|
|
|
|
|
- 1202 OR (t2 = SymTab.InvalidType) THEN
|
|
|
|
|
- 1203 t := SymTab.BoolType(); QbeGen.CopyOp("0", q)
|
|
|
|
|
- 1204 ELSE
|
|
|
|
|
- 1205 QbeGen.InSet(q, q2, SymTab.SetBaseLo(t2),
|
|
|
|
|
- 1206 SymTab.SetCount(t2), qt);
|
|
|
|
|
- 1207 t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
|
|
|
|
|
- 1208 END
|
|
|
|
|
- 1209 ELSE SemError(222); t := SymTab.InvalidType;
|
|
|
|
|
- 1210 QbeGen.CopyOp("0", q)
|
|
|
|
|
- 1211 END
|
|
|
|
|
- 1212 ELSIF SymTab.RelCheck(t, t2, op) THEN
|
|
|
|
|
- 1213 IF (t = SymTab.InvalidType)
|
|
|
|
|
- 1214 OR (t2 = SymTab.InvalidType) THEN
|
|
|
|
|
- 1215 t := SymTab.BoolType(); QbeGen.CopyOp("0", q)
|
|
|
|
|
- 1216 ELSIF (SymTab.ClassOf(t) = SymTab.ClPtr)
|
|
|
|
|
- 1217 OR (SymTab.ClassOf(t2) = SymTab.ClPtr) THEN
|
|
|
|
|
- 1218 IF (op # SymTab.OpEq) & (op # SymTab.OpNeq1)
|
|
|
|
|
- 1219 & (op # SymTab.OpNeq2) THEN
|
|
|
|
|
- 1220 SemError(213); t := SymTab.InvalidType;
|
|
|
|
|
- 1221 QbeGen.CopyOp("0", q)
|
|
|
|
|
- 1222 ELSE
|
|
|
|
|
- 1223 QbeGen.CmpL(op, q, q2, qt);
|
|
|
|
|
- 1224 t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
|
|
|
|
|
- 1225 END
|
|
|
|
|
- 1226 ELSIF (SymTab.ClassOf(t) = SymTab.ClSet)
|
|
|
|
|
- 1227 OR (SymTab.ClassOf(t2) = SymTab.ClSet) THEN
|
|
|
|
|
- 1228 QbeGen.CmpSet(op, q, q2,
|
|
|
|
|
- 1229 SymTab.SetWords(t), SymTab.SetWords(t2), qt);
|
|
|
|
|
- 1230 t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
|
|
|
|
|
- 1231 ELSE
|
|
|
|
|
- 1232 isR := SymTab.ClassOf(t) = SymTab.ClReal;
|
|
|
|
|
- 1233 t := SymTab.BoolType();
|
|
|
|
|
- 1234 QbeGen.Cmp(op, q, q2, qt, isR);
|
|
|
|
|
- 1235 QbeGen.CopyOp(qt, q)
|
|
|
|
|
- 1236 END
|
|
|
|
|
- 1237 ELSE SemError(213); t := SymTab.InvalidType;
|
|
|
|
|
- 1238 QbeGen.CopyOp("0", q)
|
|
|
|
|
- 1239 END; .) ] .
|
|
|
|
|
- 1240 Rel<VAR op: INTEGER>
|
|
|
|
|
- 1241 = "=" (. op := SymTab.OpEq; .)
|
|
|
|
|
- 1242 | "#" (. op := SymTab.OpNeq1; .)
|
|
|
|
|
- 1243 | "<" (. op := SymTab.OpLt; .)
|
|
|
|
|
- 1244 | "<=" (. op := SymTab.OpLe; .)
|
|
|
|
|
- 1245 | ">" (. op := SymTab.OpGt; .)
|
|
|
|
|
- 1246 | ">=" (. op := SymTab.OpGe; .)
|
|
|
|
|
- 1247 | "IN" (. op := SymTab.OpIn; .) .
|
|
|
|
|
- 1248 SimExpr<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
|
|
- 1249 (. VAR t2, res2: SymTab.TypeIndex;
|
|
|
|
|
- 1250 op: INTEGER;
|
|
|
|
|
- 1251 q2, qt: QbeGen.QVal;
|
|
|
|
|
- 1252 neg, isR: BOOLEAN;
|
|
|
|
|
- 1253 lw, rw, mw: CARDINAL; .)
|
|
|
|
|
- 1254 = (. neg := FALSE; .)
|
|
|
|
|
- 1255 [ "+" | "-" (. neg := TRUE; .) ]
|
|
|
|
|
- 1256 Term<t, q> (. IF neg THEN
|
|
|
|
|
- 1257 IF QbeGen.IsImm(q) THEN
|
|
|
|
|
- 1258 QbeGen.NegFold(q, q)
|
|
|
|
|
- 1259 ELSE QbeGen.NewTemp(qt);
|
|
|
|
|
- 1260 QbeGen.NegQ(q, qt,
|
|
|
|
|
- 1261 SymTab.ClassOf(t)
|
|
|
|
|
- 1262 = SymTab.ClReal);
|
|
|
|
|
- 1263 QbeGen.CopyOp(qt, q)
|
|
|
|
|
- 1264 END
|
|
|
|
|
- 1265 END; .)
|
|
|
|
|
- 1266 { AddOp<op> Term<t2, q2>
|
|
|
|
|
- 1267 (. IF op = SymTab.OpOr THEN
|
|
|
|
|
- 1268 IF SymTab.BoolCheck(t) & SymTab.BoolCheck(t2) THEN
|
|
|
|
|
- 1269 t := SymTab.BoolType()
|
|
|
|
|
- 1270 ELSE SemError(212); t := SymTab.InvalidType END;
|
|
|
|
|
- 1271 IF t # SymTab.InvalidType THEN
|
|
|
|
|
- 1272 QbeGen.NewTemp(qt);
|
|
|
|
|
- 1273 QbeGen.Op3("or", qt, q, q2, FALSE);
|
|
|
|
|
- 1274 QbeGen.CopyOp(qt, q)
|
|
|
|
|
- 1275 ELSE QbeGen.CopyOp("0", q)
|
|
|
|
|
- 1276 END
|
|
|
|
|
- 1277 ELSIF (t # SymTab.InvalidType) & (t2 # SymTab.InvalidType)
|
|
|
|
|
- 1278 & (SymTab.ClassOf(t) = SymTab.ClSet)
|
|
|
|
|
- 1279 & (SymTab.ClassOf(t2) = SymTab.ClSet) THEN
|
|
|
|
|
- 1280 lw := SymTab.SetWords(t); rw := SymTab.SetWords(t2);
|
|
|
|
|
- 1281 mw := lw;
|
|
|
|
|
- 1282 IF rw > mw THEN mw := rw END;
|
|
|
|
|
- 1283 IF op = SymTab.OpAdd THEN
|
|
|
|
|
- 1284 QbeGen.SetBinOp(0, q, q2, lw, rw, qt)
|
|
|
|
|
- 1285 ELSE
|
|
|
|
|
- 1286 QbeGen.SetBinOp(2, q, q2, lw, rw, qt)
|
|
|
|
|
- 1287 END;
|
|
|
|
|
- 1288 t := SymTab.NewSet(
|
|
|
|
|
- 1289 SymTab.NewSubR(0,
|
|
|
|
|
- 1290 VAL(INTEGER, mw) * 32 - 1));
|
|
|
|
|
- 1291 QbeGen.CopyOp(qt, q)
|
|
|
|
|
- 1292 ELSE
|
|
|
|
|
- 1293 IF SymTab.ArithCheck(t, t2, FALSE, res2) THEN
|
|
|
|
|
- 1294 t := res2
|
|
|
|
|
- 1295 ELSE SemError(211); t := SymTab.InvalidType END;
|
|
|
|
|
- 1296 isR := SymTab.ClassOf(t) = SymTab.ClReal;
|
|
|
|
|
- 1297 IF t # SymTab.InvalidType THEN
|
|
|
|
|
- 1298 QbeGen.NewTemp(qt);
|
|
|
|
|
- 1299 IF op = SymTab.OpAdd THEN
|
|
|
|
|
- 1300 QbeGen.Op3("add", qt, q, q2, isR)
|
|
|
|
|
- 1301 ELSE
|
|
|
|
|
- 1302 QbeGen.Op3("sub", qt, q, q2, isR)
|
|
|
|
|
- 1303 END;
|
|
|
|
|
- 1304 QbeGen.CopyOp(qt, q)
|
|
|
|
|
- 1305 ELSE QbeGen.CopyOp("0", q)
|
|
|
|
|
- 1306 END
|
|
|
|
|
- 1307 END; .) } .
|
|
|
|
|
- 1308 AddOp<VAR op: INTEGER>
|
|
|
|
|
- 1309 = "+" (. op := SymTab.OpAdd; .)
|
|
|
|
|
- 1310 | "-" (. op := SymTab.OpSub; .)
|
|
|
|
|
- 1311 | "OR" (. op := SymTab.OpOr; .) .
|
|
|
|
|
- 1312 Term<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
|
|
- 1313 (. VAR t2, res2: SymTab.TypeIndex;
|
|
|
|
|
- 1314 op: INTEGER;
|
|
|
|
|
- 1315 q2, qt: QbeGen.QVal;
|
|
|
|
|
- 1316 isR: BOOLEAN;
|
|
|
|
|
- 1317 lw, rw, mw: CARDINAL; .)
|
|
|
|
|
- 1318 = Fact<t, q> { MulOp<op> Fact<t2, q2>
|
|
|
|
|
- 1319 (. IF op = SymTab.OpAnd THEN
|
|
|
|
|
- 1320 IF SymTab.BoolCheck(t) & SymTab.BoolCheck(t2) THEN
|
|
|
|
|
- 1321 t := SymTab.BoolType()
|
|
|
|
|
- 1322 ELSE SemError(212); t := SymTab.InvalidType END;
|
|
|
|
|
- 1323 IF t # SymTab.InvalidType THEN
|
|
|
|
|
- 1324 QbeGen.NewTemp(qt);
|
|
|
|
|
- 1325 QbeGen.Op3("and", qt, q, q2, FALSE);
|
|
|
|
|
- 1326 QbeGen.CopyOp(qt, q)
|
|
|
|
|
- 1327 ELSE QbeGen.CopyOp("0", q)
|
|
|
|
|
- 1328 END
|
|
|
|
|
- 1329 ELSIF (t # SymTab.InvalidType) & (t2 # SymTab.InvalidType)
|
|
|
|
|
- 1330 & (SymTab.ClassOf(t) = SymTab.ClSet)
|
|
|
|
|
- 1331 & (SymTab.ClassOf(t2) = SymTab.ClSet) THEN
|
|
|
|
|
- 1332 lw := SymTab.SetWords(t); rw := SymTab.SetWords(t2);
|
|
|
|
|
- 1333 mw := lw;
|
|
|
|
|
- 1334 IF rw > mw THEN mw := rw END;
|
|
|
|
|
- 1335 IF op = SymTab.OpTimes THEN
|
|
|
|
|
- 1336 QbeGen.SetBinOp(1, q, q2, lw, rw, qt)
|
|
|
|
|
- 1337 ELSE
|
|
|
|
|
- 1338 QbeGen.SetBinOp(3, q, q2, lw, rw, qt)
|
|
|
|
|
- 1339 END;
|
|
|
|
|
- 1340 t := SymTab.NewSet(
|
|
|
|
|
- 1341 SymTab.NewSubR(0,
|
|
|
|
|
- 1342 VAL(INTEGER, mw) * 32 - 1));
|
|
|
|
|
- 1343 QbeGen.CopyOp(qt, q)
|
|
|
|
|
- 1344 ELSE
|
|
|
|
|
- 1345 IF SymTab.ArithCheck(t, t2,
|
|
|
|
|
- 1346 (op = SymTab.OpDiv) OR (op = SymTab.OpMod),
|
|
|
|
|
- 1347 res2) THEN t := res2
|
|
|
|
|
- 1348 ELSE SemError(211); t := SymTab.InvalidType END;
|
|
|
|
|
- 1349 isR := SymTab.ClassOf(t) = SymTab.ClReal;
|
|
|
|
|
- 1350 IF t # SymTab.InvalidType THEN
|
|
|
|
|
- 1351 QbeGen.NewTemp(qt);
|
|
|
|
|
- 1352 IF op = SymTab.OpTimes THEN
|
|
|
|
|
- 1353 QbeGen.Op3("mul", qt, q, q2, isR)
|
|
|
|
|
- 1354 ELSIF (op = SymTab.OpDiv)
|
|
|
|
|
- 1355 OR (op = SymTab.OpSlash) THEN
|
|
|
|
|
- 1356 QbeGen.Op3("div", qt, q, q2, isR)
|
|
|
|
|
- 1357 ELSE
|
|
|
|
|
- 1358 QbeGen.Op3("rem", qt, q, q2, isR)
|
|
|
|
|
- 1359 END;
|
|
|
|
|
- 1360 QbeGen.CopyOp(qt, q)
|
|
|
|
|
- 1361 ELSE QbeGen.CopyOp("0", q)
|
|
|
|
|
- 1362 END
|
|
|
|
|
- 1363 END; .) } .
|
|
|
|
|
- 1364 MulOp<VAR op: INTEGER>
|
|
|
|
|
- 1365 = "*" (. op := SymTab.OpTimes; .)
|
|
|
|
|
- 1366 | "/" (. op := SymTab.OpSlash; .)
|
|
|
|
|
- 1367 | "DIV" (. op := SymTab.OpDiv; .)
|
|
|
|
|
- 1368 | "MOD" (. op := SymTab.OpMod; .)
|
|
|
|
|
- 1369 | "AND" (. op := SymTab.OpAnd; .) .
|
|
|
|
|
- 1370 Fact<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
|
|
- 1371 (. VAR s: ARRAY [0 .. 255] OF CHAR;
|
|
|
|
|
- 1372 et, dt, t2, st: SymTab.TypeIndex;
|
|
|
|
|
- 1373 dk: INTEGER;
|
|
|
|
|
- 1374 qd, q2, sq: QbeGen.QVal;
|
|
|
|
|
- 1375 qn: SymTab.Name;
|
|
|
|
|
- 1376 sfx: BOOLEAN; .)
|
|
|
|
|
- 1377 = integer (. LexString(s);
|
|
|
|
|
- 1378 QbeGen.NormInt(s, q);
|
|
|
|
|
- 1379 t := SymTab.IntType(); .)
|
|
|
|
|
- 1380 | real (. LexString(s);
|
|
|
|
|
- 1381 QbeGen.NormReal(s, q);
|
|
|
|
|
- 1382 t := SymTab.RealType(); .)
|
|
|
|
|
- 1383 | string (. LexString(s);
|
|
|
|
|
- 1384 IF SymTab.StrLen(s) = 3 THEN
|
|
|
|
|
- 1385 t := SymTab.CharType();
|
|
|
|
|
- 1386 QbeGen.IntStr(
|
|
|
|
|
- 1387 QbeGen.CharVal(s), q)
|
|
|
|
|
- 1388 ELSE t := SymTab.NewStr();
|
|
|
|
|
- 1389 QbeGen.DeclStr(s, q)
|
|
|
|
|
- 1390 END; .)
|
|
|
|
|
- 1391 | Design<dt, dk, qd, qn, sfx> (. t := dt;
|
|
|
|
|
- 1392 IF sfx THEN
|
|
|
|
|
- 1393 IF dt =
|
|
|
|
|
- 1394 SymTab.InvalidType THEN
|
|
|
|
|
- 1395 QbeGen.CopyOp("0", q)
|
|
|
|
|
- 1396 ELSIF (SymTab.ClassOf(dt) =
|
|
|
|
|
- 1397 SymTab.ClRecord)
|
|
|
|
|
- 1398 OR (SymTab.ClassOf(dt) =
|
|
|
|
|
- 1399 SymTab.ClSet)
|
|
|
|
|
- 1400 OR (SymTab.ClassOf(dt) =
|
|
|
|
|
- 1401 SymTab.ClClass) THEN
|
|
|
|
|
- 1402 QbeGen.CopyOp(qd, q)
|
|
|
|
|
- 1403 ELSE QbeGen.ElemLoad(qd, dt,
|
|
|
|
|
- 1404 q)
|
|
|
|
|
- 1405 END
|
|
|
|
|
- 1406 ELSE QbeGen.CopyOp(qd, q)
|
|
|
|
|
- 1407 END; .)
|
|
|
|
|
- 1408 | "(" Expr<et, q> ")" (. t := et; .)
|
|
|
|
|
- 1409 | SetLit<st, sq> (. t := st;
|
|
|
|
|
- 1410 QbeGen.CopyOp(sq, q); .)
|
|
|
|
|
- 1411 | "NOT" Fact<t2, q2> (. IF SymTab.BoolCheck(t2) THEN
|
|
|
|
|
- 1412 t := SymTab.BoolType()
|
|
|
|
|
- 1413 ELSE SemError(212);
|
|
|
|
|
- 1414 t := SymTab.InvalidType END;
|
|
|
|
|
- 1415 IF t # SymTab.InvalidType THEN
|
|
|
|
|
- 1416 QbeGen.NotQ(q2, q)
|
|
|
|
|
- 1417 ELSE QbeGen.CopyOp("0", q)
|
|
|
|
|
- 1418 END; .) .
|
|
|
|
|
- 1419 (* Set literals are SET OF [0..255] (8 words); elements validated
|
|
|
|
|
- 1420 0..255 statically when foldable (222 otherwise), runtime trap
|
|
|
|
|
- 1421 for computed elements. Ranges always lower via SetRange. *)
|
|
|
|
|
- 1422 SetLit<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
|
|
- 1423 = "{" (. t := SymTab.NewSet(
|
|
|
|
|
- 1424 SymTab.NewSubR(0, 255));
|
|
|
|
|
- 1425 QbeGen.NewSetTemp(8, q);
|
|
|
|
|
- 1426 QbeGen.SetZero(q, 8); .)
|
|
|
|
|
- 1427 [ SetElem<t, q> { "," SetElem<t, q> } ]
|
|
|
|
|
- 1428 "}" .
|
|
|
|
|
- 1429 SetElem<st: SymTab.TypeIndex; sq: QbeGen.QVal> (. VAR et, et2: SymTab.TypeIndex;
|
|
|
|
|
- 1430 qe, q2: QbeGen.QVal;
|
|
|
|
|
- 1431 v, v2: INTEGER;
|
|
|
|
|
- 1432 lo: INTEGER;
|
|
|
|
|
- 1433 span: CARDINAL;
|
|
|
|
|
- 1434 cl, cl2: INTEGER;
|
|
|
|
|
- 1435 hasR: BOOLEAN; .)
|
|
|
|
|
- 1436 = (. hasR := FALSE; .)
|
|
|
|
|
- 1437 Expr<et, qe>
|
|
|
|
|
- 1438 [ ".." Expr<et2, q2> (. hasR := TRUE; .) ]
|
|
|
|
|
- 1439 (. lo := SymTab.SetBaseLo(st);
|
|
|
|
|
- 1440 span := SymTab.SetCount(st);
|
|
|
|
|
- 1441 IF (et = SymTab.InvalidType)
|
|
|
|
|
- 1442 OR (hasR & (et2 =
|
|
|
|
|
- 1443 SymTab.InvalidType)) THEN
|
|
|
|
|
- 1444 ELSE cl :=
|
|
|
|
|
- 1445 SymTab.ClassOf(et);
|
|
|
|
|
- 1446 IF hasR THEN
|
|
|
|
|
- 1447 cl2 :=
|
|
|
|
|
- 1448 SymTab.ClassOf(et2)
|
|
|
|
|
- 1449 ELSE cl2 := SymTab.ClInt
|
|
|
|
|
- 1450 END;
|
|
|
|
|
- 1451 IF ((cl # SymTab.ClInt)
|
|
|
|
|
- 1452 & (cl # SymTab.ClChar)
|
|
|
|
|
- 1453 & (cl # SymTab.ClBool))
|
|
|
|
|
- 1454 OR (hasR &
|
|
|
|
|
- 1455 ((cl2
|
|
|
|
|
- 1456 # SymTab.ClInt)
|
|
|
|
|
- 1457 & (cl2
|
|
|
|
|
- 1458 # SymTab.ClChar)
|
|
|
|
|
- 1459 & (cl2
|
|
|
|
|
- 1460 # SymTab.ClBool))) THEN
|
|
|
|
|
- 1461 SemError(222)
|
|
|
|
|
- 1462 ELSIF hasR
|
|
|
|
|
- 1463 & SymTab.ConstInt(qe, v)
|
|
|
|
|
- 1464 & SymTab.ConstInt(q2,
|
|
|
|
|
- 1465 v2)
|
|
|
|
|
- 1466 & ((v < lo)
|
|
|
|
|
- 1467 OR (v2 < lo)
|
|
|
|
|
- 1468 OR (v >= lo +
|
|
|
|
|
- 1469 VAL(INTEGER, span))
|
|
|
|
|
- 1470 OR (v2 >= lo +
|
|
|
|
|
- 1471 VAL(INTEGER, span))
|
|
|
|
|
- 1472 OR (v > v2)) THEN
|
|
|
|
|
- 1473 SemError(222)
|
|
|
|
|
- 1474 ELSIF hasR THEN
|
|
|
|
|
- 1475 QbeGen.SetRange(sq, qe, q2,
|
|
|
|
|
- 1476 lo, span)
|
|
|
|
|
- 1477 ELSIF SymTab.ConstInt(qe,
|
|
|
|
|
- 1478 v)
|
|
|
|
|
- 1479 & ((v < lo)
|
|
|
|
|
- 1480 OR (v >= lo +
|
|
|
|
|
- 1481 VAL(INTEGER,
|
|
|
|
|
- 1482 span))) THEN
|
|
|
|
|
- 1483 SemError(222)
|
|
|
|
|
- 1484 ELSE QbeGen.SetBit(sq, qe,
|
|
|
|
|
- 1485 lo, span)
|
|
|
|
|
- 1486 END
|
|
|
|
|
- 1487 END; .) .
|
|
|
|
|
- 1488 GetIdent<VAR n: SymTab.Name>
|
|
|
|
|
- 1489 = ident (. LexName(n); .) .
|
|
|
|
|
- 1490
|
|
|
|
|
- 1491 END M2.
|
|
|
|
|
|
|
+ 254 ELSIF ~SymTab.BoundAdd(lo, hi) THEN
|
|
|
|
|
+ 255 SemError(230); ok := FALSE
|
|
|
|
|
+ 256 END;
|
|
|
|
|
+ 257 END; .) .
|
|
|
|
|
+ 258 (* Sets: multi-word masks over bases ≤ 256 values (bool, char,
|
|
|
|
|
+ 259 bounded subranges; enums wait for ordinals, INTEGER is
|
|
|
|
|
+ 260 unbounded). Literals are SET OF [0..255]; assignment and
|
|
|
|
|
+ 261 comparison across suitable bases are lenient (masks over min
|
|
|
|
|
+ 262 words + zero-check extras), out-of-span literals are 222. *)
|
|
|
|
|
+ 263 SetType<VAR t: SymTab.TypeIndex> (. VAR base: SymTab.TypeIndex;
|
|
|
|
|
+ 264 blo, bhi, bspan: INTEGER;
|
|
|
|
|
+ 265 bcls: INTEGER; .)
|
|
|
|
|
+ 266 = "SET" "OF" Type<base, FALSE>
|
|
|
|
|
+ 267 (. IF base = SymTab.InvalidType THEN
|
|
|
|
|
+ 268 t := SymTab.InvalidType
|
|
|
|
|
+ 269 ELSE bcls :=
|
|
|
|
|
+ 270 SymTab.ClassOf(base);
|
|
|
|
|
+ 271 IF bcls = SymTab.ClBool THEN
|
|
|
|
|
+ 272 blo := 0; bspan := 2
|
|
|
|
|
+ 273 ELSIF bcls = SymTab.ClChar THEN
|
|
|
|
|
+ 274 blo := 0; bspan := 256
|
|
|
|
|
+ 275 ELSIF SymTab.SubBounds(base,
|
|
|
|
|
+ 276 blo, bhi) THEN
|
|
|
|
|
+ 277 bspan := bhi - blo + 1
|
|
|
|
|
+ 278 ELSE bspan := 0 END;
|
|
|
|
|
+ 279 IF (bspan <= 0)
|
|
|
|
|
+ 280 OR (bspan > 256) THEN
|
|
|
|
|
+ 281 SemError(230);
|
|
|
|
|
+ 282 t := SymTab.InvalidType
|
|
|
|
|
+ 283 ELSE t := SymTab.NewSet(base)
|
|
|
|
|
+ 284 END
|
|
|
|
|
+ 285 END; .) .
|
|
|
|
|
+ 286 (* Records: flat blobs; array fields are pointers to static
|
|
|
|
|
+ 287 descriptors (locked amendment), nested records inline. Field
|
|
|
|
|
+ 288 offsets static and declaration-ordered. *)
|
|
|
|
|
+ 289 RecordType<VAR t: SymTab.TypeIndex> (. VAR t2: SymTab.TypeIndex; .)
|
|
|
|
|
+ 290 = "RECORD" (. t := SymTab.NewRecord(); .)
|
|
|
|
|
+ 291 [ RecField<t> { ";" RecField<t> } ]
|
|
|
|
|
+ 292 "END" .
|
|
|
|
|
+ 293 RecField<rec: SymTab.TypeIndex> (. VAR n: SymTab.Name;
|
|
|
|
|
+ 294 t2: SymTab.TypeIndex; .)
|
|
|
|
|
+ 295 = RecIdents<rec> ":" Type<t2, FALSE>(. SymTab.FixPendingF(rec, t2); .) .
|
|
|
|
|
+ 296 RecIdents<rec: SymTab.TypeIndex> (. VAR n: SymTab.Name; .)
|
|
|
|
|
+ 297 = GetIdent<n> (. IF ~SymTab.FieldPending(rec,
|
|
|
|
|
+ 298 n) THEN
|
|
|
|
|
+ 299 SemError(200) END; .)
|
|
|
|
|
+ 300 { "," GetIdent<n> (. IF ~SymTab.FieldPending(rec,
|
|
|
|
|
+ 301 n) THEN
|
|
|
|
|
+ 302 SemError(200) END; .) } .
|
|
|
|
|
+ 303 TypeIdent<VAR t: SymTab.TypeIndex> (. VAR n: SymTab.Name;
|
|
|
|
|
+ 304 k: INTEGER; .)
|
|
|
|
|
+ 305 = GetIdent<n> (. IF ~SymTab.Lookup(n) THEN
|
|
|
|
|
+ 306 SemError(201);
|
|
|
|
|
+ 307 t := SymTab.InvalidType
|
|
|
|
|
+ 308 ELSE k := SymTab.SymKind(n);
|
|
|
|
|
+ 309 IF (k = SymTab.KindType)
|
|
|
|
|
+ 310 OR (k = SymTab.KindPredef) THEN
|
|
|
|
|
+ 311 t := SymTab.SymType(n)
|
|
|
|
|
+ 312 ELSIF k = SymTab.KindImport THEN
|
|
|
|
|
+ 313 t := SymTab.InvalidType
|
|
|
|
|
+ 314 ELSE SemError(221);
|
|
|
|
|
+ 315 t := SymTab.InvalidType
|
|
|
|
|
+ 316 END
|
|
|
|
|
+ 317 END; .) .
|
|
|
|
|
+ 318 Subrange<VAR t: SymTab.TypeIndex> (. VAR tlo, thi: SymTab.TypeIndex;
|
|
|
|
|
+ 319 qlo, qhi: QbeGen.QVal;
|
|
|
|
|
+ 320 lo, hi: INTEGER; .)
|
|
|
|
|
+ 321 = "[" Expr<tlo, qlo> ".." Expr<thi, qhi>
|
|
|
|
|
+ 322 (. IF (tlo = SymTab.InvalidType)
|
|
|
|
|
+ 323 OR (thi = SymTab.InvalidType) THEN
|
|
|
|
|
+ 324 t := SymTab.InvalidType
|
|
|
|
|
+ 325 ELSIF (SymTab.ClassOf(tlo) #
|
|
|
|
|
+ 326 SymTab.ClInt)
|
|
|
|
|
+ 327 OR (SymTab.ClassOf(thi) #
|
|
|
|
|
+ 328 SymTab.ClInt) THEN
|
|
|
|
|
+ 329 SemError(230);
|
|
|
|
|
+ 330 t := SymTab.InvalidType
|
|
|
|
|
+ 331 ELSIF ~SymTab.ConstInt(qlo, lo)
|
|
|
|
|
+ 332 OR ~SymTab.ConstInt(qhi, hi)
|
|
|
|
|
+ 333 OR (lo > hi) THEN
|
|
|
|
|
+ 334 SemError(230);
|
|
|
|
|
+ 335 t := SymTab.InvalidType
|
|
|
|
|
+ 336 ELSE t := SymTab.NewSubR(lo, hi)
|
|
|
|
|
+ 337 END; .)
|
|
|
|
|
+ 338 "]" .
|
|
|
|
|
+ 339 Enum<VAR t: SymTab.TypeIndex> (. VAR n: SymTab.Name; .)
|
|
|
|
|
+ 340 = "(" (. t := SymTab.NewEnum(); .)
|
|
|
|
|
+ 341 GetIdent<n> (. IF ~SymTab.Enter(n,
|
|
|
|
|
+ 342 SymTab.KindConst) THEN
|
|
|
|
|
+ 343 SemError(200) END;
|
|
|
|
|
+ 344 SymTab.SetSymType(n, t); .)
|
|
|
|
|
+ 345 { "," GetIdent<n> (. IF ~SymTab.Enter(n,
|
|
|
|
|
+ 346 SymTab.KindConst) THEN
|
|
|
|
|
+ 347 SemError(200) END;
|
|
|
|
|
+ 348 SymTab.SetSymType(n, t); .) }
|
|
|
|
|
+ 349 ")" .
|
|
|
|
|
+ 350 (* Clarion-form classes (docs/OOP.txt): declaration + single
|
|
|
|
|
+ 351 inheritance + IMPLEMENTATION blocks. Scopes and member checks
|
|
|
|
|
+ 352 now; lowering (vtable, dispatch, THIS) later — one 230 per
|
|
|
|
|
+ 353 class/impl block. Methods end with ";" per the Table example
|
|
|
|
|
+ 354 (not "," as in the sketch). No underscores in identifiers. *)
|
|
|
|
|
+ 355 (* Single CLASS item in both loops: separating declaration from
|
|
|
|
|
+ 356 IMPLEMENTATION at the loop level needs 2-token lookahead
|
|
|
|
|
+ 357 (CLASS ident vs CLASS IMPLEMENTATION), which LL(1) cannot do.
|
|
|
|
|
+ 358 The second token decides after CLASS is consumed. A misplaced
|
|
|
|
|
+ 359 CLASS IMPLEMENTATION inside TYPE still parses (harmless: the
|
|
|
|
|
+ 360 whole unit ends 230 until lowering). *)
|
|
|
|
|
+ 361 ClassItem
|
|
|
|
|
+ 362 = "CLASS" ( "IMPLEMENTATION" ClassImplRest | ClassRest ) .
|
|
|
|
|
+ 363 ClassRest (. VAR cn, m2, pn: SymTab.Name;
|
|
|
|
|
+ 364 ct: SymTab.TypeIndex; .)
|
|
|
|
|
+ 365 = GetIdent<cn> (. IF ~SymTab.Enter(cn,
|
|
|
|
|
+ 366 SymTab.KindType) THEN
|
|
|
|
|
+ 367 SemError(200) END;
|
|
|
|
|
+ 368 ct := SymTab.NewClass();
|
|
|
|
|
+ 369 SymTab.SetSymType(cn, ct);
|
|
|
|
|
+ 370 SymTab.PushClassScope(ct); .)
|
|
|
|
|
+ 371 [ Parents<ct> ]
|
|
|
|
|
+ 372 ";"
|
|
|
|
|
+ 373 { ClassField<ct> ";" }
|
|
|
|
|
+ 374 { MethodHeading<pn> ";" (. SymTab.CloseProc; .) }
|
|
|
|
|
+ 375 "END"
|
|
|
|
|
+ 376 GetIdent<m2> (. IF ~SymTab.Equal(cn, m2) THEN
|
|
|
|
|
+ 377 SemError(202) END;
|
|
|
|
|
+ 378 SymTab.PopScope;
|
|
|
|
|
+ 379 SemError(230); .) .
|
|
|
|
|
+ 380 Parents<ct: SymTab.TypeIndex> (. VAR p: SymTab.Name; .)
|
|
|
|
|
+ 381 = "(" Parent1<ct>
|
|
|
|
|
+ 382 { "," GetIdent<p> (. SemError(230); .) }
|
|
|
|
|
+ 383 ")" .
|
|
|
|
|
+ 384 Parent1<ct: SymTab.TypeIndex> (. VAR p: SymTab.Name;
|
|
|
|
|
+ 385 pt: SymTab.TypeIndex; .)
|
|
|
|
|
+ 386 = GetIdent<p> (. IF ~SymTab.Lookup(p) THEN
|
|
|
|
|
+ 387 SemError(201)
|
|
|
|
|
+ 388 ELSE pt := SymTab.SymType(p);
|
|
|
|
|
+ 389 IF SymTab.ClassOf(pt) #
|
|
|
|
|
+ 390 SymTab.ClClass THEN
|
|
|
|
|
+ 391 SemError(230)
|
|
|
|
|
+ 392 ELSE SymTab.SetParent(ct, pt)
|
|
|
|
|
+ 393 END
|
|
|
|
|
+ 394 END; .) .
|
|
|
|
|
+ 395 ClassField<ct: SymTab.TypeIndex> (. VAR n, rhs: SymTab.Name;
|
|
|
|
|
+ 396 t: SymTab.TypeIndex; .)
|
|
|
|
|
+ 397 = GetIdent<n>
|
|
|
|
|
+ 398 ( "=" GetIdent<rhs> (. IF ~SymTab.Enter(n,
|
|
|
|
|
+ 399 SymTab.KindConst) THEN
|
|
|
|
|
+ 400 SemError(200) END;
|
|
|
|
|
+ 401 IF SymTab.Lookup(rhs) THEN
|
|
|
|
|
+ 402 SymTab.SetSymType(n,
|
|
|
|
|
+ 403 SymTab.SymType(rhs))
|
|
|
|
|
+ 404 END; .)
|
|
|
|
|
+ 405 | (. IF ~SymTab.FieldPending(ct,
|
|
|
|
|
+ 406 n) THEN
|
|
|
|
|
+ 407 SemError(200) END; .)
|
|
|
|
|
+ 408 { "," GetIdent<n> (. IF ~SymTab.FieldPending(ct,
|
|
|
|
|
+ 409 n) THEN
|
|
|
|
|
+ 410 SemError(200) END; .) }
|
|
|
|
|
+ 411 ":" Type<t, FALSE> (. SymTab.FixPendingF(ct, t); .) ) .
|
|
|
|
|
+ 412 MethodHeading<VAR pn: SymTab.Name> (. VAR wantVirt: BOOLEAN; .)
|
|
|
|
|
+ 413 = (. wantVirt := FALSE; .)
|
|
|
|
|
+ 414 [ "VIRTUAL" (. wantVirt := TRUE; .) ]
|
|
|
|
|
+ 415 ProcHeading<pn> (. IF wantVirt THEN
|
|
|
|
|
+ 416 SymTab.MarkVirtual END; .) .
|
|
|
|
|
+ 417 ClassImplRest (. VAR cn, m2: SymTab.Name;
|
|
|
|
|
+ 418 ct: SymTab.TypeIndex; .)
|
|
|
|
|
+ 419 = GetIdent<cn> (. IF ~SymTab.Lookup(cn) THEN
|
|
|
|
|
+ 420 SemError(201);
|
|
|
|
|
+ 421 ct := SymTab.InvalidType
|
|
|
|
|
+ 422 ELSE ct := SymTab.SymType(cn);
|
|
|
|
|
+ 423 IF SymTab.ClassOf(ct) #
|
|
|
|
|
+ 424 SymTab.ClClass THEN
|
|
|
|
|
+ 425 SemError(230);
|
|
|
|
|
+ 426 ct := SymTab.InvalidType
|
|
|
|
|
+ 427 END
|
|
|
|
|
+ 428 END;
|
|
|
|
|
+ 429 IF ct #
|
|
|
|
|
+ 430 SymTab.InvalidType THEN
|
|
|
|
|
+ 431 IF ~SymTab.PushClassMembers(
|
|
|
|
|
+ 432 ct) THEN
|
|
|
|
|
+ 433 SemError(230) END
|
|
|
|
|
+ 434 END; .)
|
|
|
|
|
+ 435 ";" { MethodImpl<ct> ";" }
|
|
|
|
|
+ 436 [ "BEGIN"
|
|
|
|
|
+ 437 [ StatSeq ] ]
|
|
|
|
|
+ 438 "END"
|
|
|
|
|
+ 439 GetIdent<m2> (. IF ~SymTab.Equal(cn, m2) THEN
|
|
|
|
|
+ 440 SemError(202) END;
|
|
|
|
|
+ 441 SymTab.PopScope;
|
|
|
|
|
+ 442 SemError(230); .) .
|
|
|
|
|
+ 443 MethodImpl<ct: SymTab.TypeIndex> (. VAR pn: SymTab.Name; .)
|
|
|
|
|
+ 444 = MethodHeading<pn> ";"
|
|
|
|
|
+ 445 (. IF (ct #
|
|
|
|
|
+ 446 SymTab.InvalidType)
|
|
|
|
|
+ 447 & ~SymTab.MethodExists(ct,
|
|
|
|
|
+ 448 pn) THEN
|
|
|
|
|
+ 449 SemError(201) END; .)
|
|
|
|
|
+ 450 ( "FORWARD" (. SymTab.MarkFwd;
|
|
|
|
|
+ 451 SymTab.CloseProc; .)
|
|
|
|
|
+ 452 | Block<pn> (. SymTab.CloseProc;
|
|
|
|
|
+ 453 SemError(230); .) ) .
|
|
|
|
|
+ 454 ConstBlock
|
|
|
|
|
+ 455 = "CONST" { ConstDecl ";" } .
|
|
|
|
|
+ 456 ConstDecl (. VAR n: SymTab.Name;
|
|
|
|
|
+ 457 t: SymTab.TypeIndex;
|
|
|
|
|
+ 458 qv: QbeGen.QVal;
|
|
|
|
|
+ 459 cls: INTEGER; .)
|
|
|
|
|
+ 460 = GetIdent<n> (. IF ~SymTab.Enter(n,
|
|
|
|
|
+ 461 SymTab.KindConst) THEN
|
|
|
|
|
+ 462 SemError(200) END; .)
|
|
|
|
|
+ 463 "="
|
|
|
|
|
+ 464 Expr<t, qv> (. SymTab.SetSymType(n, t);
|
|
|
|
|
+ 465 cls := SymTab.ClassOf(t);
|
|
|
|
|
+ 466 IF cls = SymTab.ClStr THEN
|
|
|
|
|
+ 467 SemError(230)
|
|
|
|
|
+ 468 ELSIF ~QbeGen.IsImm(qv) THEN
|
|
|
|
|
+ 469 SemError(230) END;
|
|
|
|
|
+ 470 QbeGen.DeclConst(n, qv, t); .) .
|
|
|
|
|
+ 471 VarBlock
|
|
|
|
|
+ 472 = "VAR" { VarDecl ";" } .
|
|
|
|
|
+ 473 VarDecl (. VAR nm: SymTab.Name;
|
|
|
|
|
+ 474 t: SymTab.TypeIndex;
|
|
|
|
|
+ 475 i: CARDINAL;
|
|
|
|
|
+ 476 cls: INTEGER; .)
|
|
|
|
|
+ 477 = VarIdents ":"
|
|
|
|
|
+ 478 Type<t, FALSE> (. cls := SymTab.ClassOf(t);
|
|
|
|
|
+ 479 IF (t # SymTab.InvalidType)
|
|
|
|
|
+ 480 & (cls # SymTab.ClInt)
|
|
|
|
|
+ 481 & (cls # SymTab.ClBool)
|
|
|
|
|
+ 482 & (cls # SymTab.ClChar)
|
|
|
|
|
+ 483 & (cls # SymTab.ClReal)
|
|
|
|
|
+ 484 & (cls # SymTab.ClArray)
|
|
|
|
|
+ 485 & (cls # SymTab.ClSet)
|
|
|
|
|
+ 486 & (cls # SymTab.ClRecord)
|
|
|
|
|
+ 487 & (cls # SymTab.ClPtr) THEN
|
|
|
|
|
+ 488 SemError(230) END;
|
|
|
|
|
+ 489 i := 0;
|
|
|
|
|
+ 490 WHILE i < SymTab.PendCount() DO
|
|
|
|
|
+ 491 SymTab.PendName(i, nm);
|
|
|
|
|
+ 492 QbeGen.DeclVar(nm, t);
|
|
|
|
|
+ 493 INC(i)
|
|
|
|
|
+ 494 END;
|
|
|
|
|
+ 495 SymTab.FixPending(t); .) .
|
|
|
|
|
+ 496 VarIdents (. VAR n: SymTab.Name; .)
|
|
|
|
|
+ 497 = GetIdent<n> (. IF ~SymTab.EnterPending(n,
|
|
|
|
|
+ 498 SymTab.KindVar) THEN
|
|
|
|
|
+ 499 SemError(200) END; .)
|
|
|
|
|
+ 500 { ","
|
|
|
|
|
+ 501 GetIdent<n> (. IF ~SymTab.EnterPending(n,
|
|
|
|
|
+ 502 SymTab.KindVar) THEN
|
|
|
|
|
+ 503 SemError(200) END; .) } .
|
|
|
|
|
+ 504 ParIdents<isV: BOOLEAN> (. VAR n: SymTab.Name; .)
|
|
|
|
|
+ 505 = GetIdent<n> (. IF ~SymTab.EnterParam(n, isV) THEN
|
|
|
|
|
+ 506 SemError(200) END; .)
|
|
|
|
|
+ 507 { "," GetIdent<n> (. IF ~SymTab.EnterParam(n, isV) THEN
|
|
|
|
|
+ 508 SemError(200) END; .) } .
|
|
|
|
|
+ 509 (* Procedure headings enter now (scopes, params, result); bodies
|
|
|
|
|
+ 510 parse + check with one 230 at END (lowering = step 4).
|
|
|
|
|
+ 511 FORWARD marks; the body heading re-enters (signature compare
|
|
|
|
|
+ 512 tightens in step 4). *)
|
|
|
|
|
+ 513 ProcHeading<VAR pn: SymTab.Name> (. VAR t: SymTab.TypeIndex; .)
|
|
|
|
|
+ 514 = "PROCEDURE"
|
|
|
|
|
+ 515 GetIdent<pn> (. IF ~SymTab.EnterProc(pn) THEN
|
|
|
|
|
+ 516 IF ~SymTab.ReenterProc(pn) THEN
|
|
|
|
|
+ 517 SemError(200) END
|
|
|
|
|
+ 518 END; .)
|
|
|
|
|
+ 519 [ FormalParams ]
|
|
|
|
|
+ 520 [ ":" TypeIdent<t> (. SymTab.SetProcRes(t);
|
|
|
|
|
+ 521 IF (t #
|
|
|
|
|
+ 522 SymTab.InvalidType)
|
|
|
|
|
+ 523 & (SymTab.ClassOf(t)
|
|
|
|
|
+ 524 = SymTab.ClArray) THEN
|
|
|
|
|
+ 525 SemError(230) END; .) ] .
|
|
|
|
|
+ 526 FormalParams
|
|
|
|
|
+ 527 = "(" [ ParamSection { ";" ParamSection } ] ")" .
|
|
|
|
|
+ 528 ParamSection (. VAR t: SymTab.TypeIndex;
|
|
|
|
|
+ 529 isV: BOOLEAN; .)
|
|
|
|
|
+ 530 = (. isV := FALSE; .)
|
|
|
|
|
+ 531 [ "VAR" (. isV := TRUE; .) ]
|
|
|
|
|
+ 532 ParIdents<isV> ":" Type<t, TRUE> (. SymTab.FixPending(t); .) .
|
|
|
|
|
+ 533 ProcDecl (. VAR pn, m2: SymTab.Name; .)
|
|
|
|
|
+ 534 = ProcHeading<pn> ";"
|
|
|
|
|
+ 535 ( "FORWARD" (. SymTab.MarkFwd;
|
|
|
|
|
+ 536 SymTab.CloseProc; .)
|
|
|
|
|
+ 537 | Block<pn> (. SymTab.CloseProc;
|
|
|
|
|
+ 538 SemError(230); .) ) .
|
|
|
|
|
+ 539 Block<pn: SymTab.Name> (. VAR m2: SymTab.Name; .)
|
|
|
|
|
+ 540 = DeclSeq
|
|
|
|
|
+ 541 [ "BEGIN"
|
|
|
|
|
+ 542 [ StatSeq ] ]
|
|
|
|
|
+ 543 "END"
|
|
|
|
|
+ 544 GetIdent<m2> (. IF ~SymTab.Equal(pn, m2) THEN
|
|
|
|
|
+ 545 SemError(202) END; .) .
|
|
|
|
|
+ 546 StatSeq
|
|
|
|
|
+ 547 = Statement { ";" Statement } .
|
|
|
|
|
+ 548 Statement (. VAR lx: QbeGen.QVal; .)
|
|
|
|
|
+ 549 = Assign
|
|
|
|
|
+ 550 | IfStat
|
|
|
|
|
+ 551 | WhileStat
|
|
|
|
|
+ 552 | RepeatStat
|
|
|
|
|
+ 553 | LoopStat
|
|
|
|
|
+ 554 | ForStat
|
|
|
|
|
+ 555 | CaseStat
|
|
|
|
|
+ 556 | WithStat
|
|
|
|
|
+ 557 | ReturnStat
|
|
|
|
|
+ 558 | NewStat
|
|
|
|
|
+ 559 | DisposeStat
|
|
|
|
|
+ 560 | "EXIT" (. IF QbeGen.TopLoop(lx) THEN
|
|
|
|
|
+ 561 QbeGen.Jmp(lx)
|
|
|
|
|
+ 562 ELSE SemError(230) END; .) .
|
|
|
|
|
+ 563 (* NEW/DISPOSE as builtin statements (no call syntax until step 4).
|
|
|
|
|
+ 564 Targets are pointer designators; DISPOSE nils afterwards (safer
|
|
|
|
|
+ 565 than Wirth-undefined; documented). DISPOSE is shallow. *)
|
|
|
|
|
+ 566 NewStat (. VAR dt: SymTab.TypeIndex;
|
|
|
|
|
+ 567 dk: INTEGER;
|
|
|
|
|
+ 568 qd, qm: QbeGen.QVal;
|
|
|
|
|
+ 569 qn: SymTab.Name;
|
|
|
|
|
+ 570 sfx: BOOLEAN;
|
|
|
|
|
+ 571 bt: SymTab.TypeIndex; .)
|
|
|
|
|
+ 572 = "NEW" "(" Design<dt, dk, qd, qn, sfx> ")"
|
|
|
|
|
+ 573 (. IF dt = SymTab.InvalidType THEN
|
|
|
|
|
+ 574 ELSIF (dk # SymTab.KindVar)
|
|
|
|
|
+ 575 & (dk # SymTab.KindParam)
|
|
|
|
|
+ 576 & (dk # SymTab.KindField) THEN
|
|
|
|
|
+ 577 SemError(210)
|
|
|
|
|
+ 578 ELSIF SymTab.ClassOf(dt) #
|
|
|
|
|
+ 579 SymTab.ClPtr THEN
|
|
|
|
|
+ 580 SemError(219)
|
|
|
|
|
+ 581 ELSE bt := SymTab.PtrBase(dt);
|
|
|
|
|
+ 582 IF bt #
|
|
|
|
|
+ 583 SymTab.InvalidType THEN
|
|
|
|
|
+ 584 QbeGen.NewHeap(bt, qm);
|
|
|
|
|
+ 585 QbeGen.InitHeap(qm, bt);
|
|
|
|
|
+ 586 IF sfx
|
|
|
|
|
+ 587 OR (dk =
|
|
|
|
|
+ 588 SymTab.KindField) THEN
|
|
|
|
|
+ 589 QbeGen.ElemStore(qd, qm,
|
|
|
|
|
+ 590 dt)
|
|
|
|
|
+ 591 ELSE QbeGen.StorePtr(qn,
|
|
|
|
|
+ 592 qm)
|
|
|
|
|
+ 593 END
|
|
|
|
|
+ 594 END
|
|
|
|
|
+ 595 END; .) .
|
|
|
|
|
+ 596 DisposeStat (. VAR dt: SymTab.TypeIndex;
|
|
|
|
|
+ 597 dk: INTEGER;
|
|
|
|
|
+ 598 qd, qv: QbeGen.QVal;
|
|
|
|
|
+ 599 qn: SymTab.Name;
|
|
|
|
|
+ 600 sfx: BOOLEAN; .)
|
|
|
|
|
+ 601 = "DISPOSE" "(" Design<dt, dk, qd, qn, sfx> ")"
|
|
|
|
|
+ 602 (. IF dt = SymTab.InvalidType THEN
|
|
|
|
|
+ 603 ELSIF (dk # SymTab.KindVar)
|
|
|
|
|
+ 604 & (dk # SymTab.KindParam)
|
|
|
|
|
+ 605 & (dk # SymTab.KindField) THEN
|
|
|
|
|
+ 606 SemError(210)
|
|
|
|
|
+ 607 ELSIF SymTab.ClassOf(dt) #
|
|
|
|
|
+ 608 SymTab.ClPtr THEN
|
|
|
|
|
+ 609 SemError(219)
|
|
|
|
|
+ 610 ELSE
|
|
|
|
|
+ 611 IF sfx
|
|
|
|
|
+ 612 OR (dk =
|
|
|
|
|
+ 613 SymTab.KindField) THEN
|
|
|
|
|
+ 614 QbeGen.ElemLoad(qd, dt,
|
|
|
|
|
+ 615 qv)
|
|
|
|
|
+ 616 ELSE QbeGen.LoadPtr(qn, qv)
|
|
|
|
|
+ 617 END;
|
|
|
|
|
+ 618 QbeGen.FreeHeap(qv);
|
|
|
|
|
+ 619 IF sfx
|
|
|
|
|
+ 620 OR (dk =
|
|
|
|
|
+ 621 SymTab.KindField) THEN
|
|
|
|
|
+ 622 QbeGen.ElemStore(qd, "0",
|
|
|
|
|
+ 623 dt)
|
|
|
|
|
+ 624 ELSE QbeGen.StorePtr(qn,
|
|
|
|
|
+ 625 "0")
|
|
|
|
|
+ 626 END
|
|
|
|
|
+ 627 END; .) .
|
|
|
|
|
+ 628 (* WITH pushes each record's fields (inner wins) plus its base
|
|
|
|
|
+ 629 address; field designators resolve through both stacks. *)
|
|
|
|
|
+ 630 WithStat (. VAR nW: CARDINAL; .)
|
|
|
|
|
+ 631 = "WITH" (. nW := 0; .)
|
|
|
|
|
+ 632 WithItem<nW> { "," WithItem<nW> }
|
|
|
|
|
+ 633 "DO" StatSeq "END"
|
|
|
|
|
+ 634 (. WHILE nW > 0 DO
|
|
|
|
|
+ 635 SymTab.PopScope;
|
|
|
|
|
+ 636 QbeGen.PopWith;
|
|
|
|
|
+ 637 DEC(nW)
|
|
|
|
|
+ 638 END; .) .
|
|
|
|
|
+ 639 WithItem<VAR nW: CARDINAL> (. VAR dt: SymTab.TypeIndex;
|
|
|
|
|
+ 640 dk: INTEGER;
|
|
|
|
|
+ 641 qd, qe: QbeGen.QVal;
|
|
|
|
|
+ 642 qn: SymTab.Name;
|
|
|
|
|
+ 643 sfx: BOOLEAN; .)
|
|
|
|
|
+ 644 = Design<dt, dk, qd, qn, sfx>
|
|
|
|
|
+ 645 (. IF dt = SymTab.InvalidType THEN
|
|
|
|
|
+ 646 ELSIF (SymTab.ClassOf(dt) #
|
|
|
|
|
+ 647 SymTab.ClRecord)
|
|
|
|
|
+ 648 & (SymTab.ClassOf(dt) #
|
|
|
|
|
+ 649 SymTab.ClClass) THEN
|
|
|
|
|
+ 650 SemError(215)
|
|
|
|
|
+ 651 ELSIF SymTab.PushRecord(dt) THEN
|
|
|
|
|
+ 652 QbeGen.PushWith(qd);
|
|
|
|
|
+ 653 INC(nW)
|
|
|
|
|
+ 654 END; .) .
|
|
|
|
|
+ 655 Assign (. VAR dt, et: SymTab.TypeIndex;
|
|
|
|
|
+ 656 dk: INTEGER;
|
|
|
|
|
+ 657 qd, qe, qt: QbeGen.QVal;
|
|
|
|
|
+ 658 qn: SymTab.Name;
|
|
|
|
|
+ 659 isR, conv: BOOLEAN;
|
|
|
|
|
+ 660 sfx: BOOLEAN; .)
|
|
|
|
|
+ 661 = Design<dt, dk, qd, qn, sfx> ":="
|
|
|
|
|
+ 662 Expr<et, qe> (. IF (dt # SymTab.InvalidType)
|
|
|
|
|
+ 663 & (dk # SymTab.KindVar)
|
|
|
|
|
+ 664 & (dk # SymTab.KindParam)
|
|
|
|
|
+ 665 & (dk # SymTab.KindField) THEN
|
|
|
|
|
+ 666 SemError(210)
|
|
|
|
|
+ 667 ELSIF ~SymTab.Assignable(et,
|
|
|
|
|
+ 668 dt) THEN
|
|
|
|
|
+ 669 SemError(210)
|
|
|
|
|
+ 670 ELSIF (dt # SymTab.InvalidType)
|
|
|
|
|
+ 671 & (SymTab.ClassOf(dt) =
|
|
|
|
|
+ 672 SymTab.ClClass) THEN
|
|
|
|
|
+ 673 SemError(230) END;
|
|
|
|
|
+ 674 isR := (dt #
|
|
|
|
|
+ 675 SymTab.InvalidType)
|
|
|
|
|
+ 676 & (SymTab.ClassOf(dt)
|
|
|
|
|
+ 677 = SymTab.ClReal);
|
|
|
|
|
+ 678 conv := isR
|
|
|
|
|
+ 679 & SymTab.IsIntFamily(et);
|
|
|
|
|
+ 680 IF ((dk = SymTab.KindVar)
|
|
|
|
|
+ 681 OR (dk = SymTab.KindParam)
|
|
|
|
|
+ 682 OR (dk = SymTab.KindField))
|
|
|
|
|
+ 683 & (dt # SymTab.InvalidType)
|
|
|
|
|
+ 684 & (et # SymTab.InvalidType)
|
|
|
|
|
+ 685 & (SymTab.ClassOf(dt) #
|
|
|
|
|
+ 686 SymTab.ClClass) THEN
|
|
|
|
|
+ 687 IF sfx
|
|
|
|
|
+ 688 OR (dk = SymTab.KindField) THEN
|
|
|
|
|
+ 689 IF SymTab.ClassOf(dt) =
|
|
|
|
|
+ 690 SymTab.ClArray THEN
|
|
|
|
|
+ 691 QbeGen.CopyArray(qd, qe,
|
|
|
|
|
+ 692 dt)
|
|
|
|
|
+ 693 ELSIF SymTab.ClassOf(dt) =
|
|
|
|
|
+ 694 SymTab.ClSet THEN
|
|
|
|
|
+ 695 QbeGen.CopySet(qd, qe,
|
|
|
|
|
+ 696 SymTab.SetWords(dt),
|
|
|
|
|
+ 697 SymTab.SetWords(et))
|
|
|
|
|
+ 698 ELSIF SymTab.ClassOf(dt) =
|
|
|
|
|
+ 699 SymTab.ClRecord THEN
|
|
|
|
|
+ 700 QbeGen.CopyRecord(qd, qe,
|
|
|
|
|
+ 701 dt)
|
|
|
|
|
+ 702 ELSIF conv THEN
|
|
|
|
|
+ 703 QbeGen.ConvIR(qe, qt);
|
|
|
|
|
+ 704 QbeGen.ElemStore(qd, qt,
|
|
|
|
|
+ 705 dt)
|
|
|
|
|
+ 706 ELSE QbeGen.ElemStore(qd, qe,
|
|
|
|
|
+ 707 dt)
|
|
|
|
|
+ 708 END
|
|
|
|
|
+ 709 ELSIF SymTab.ClassOf(dt) =
|
|
|
|
|
+ 710 SymTab.ClArray THEN
|
|
|
|
|
+ 711 QbeGen.CopyArray(qd, qe, dt)
|
|
|
|
|
+ 712 ELSIF SymTab.ClassOf(dt) =
|
|
|
|
|
+ 713 SymTab.ClSet THEN
|
|
|
|
|
+ 714 QbeGen.CopySet(qd, qe,
|
|
|
|
|
+ 715 SymTab.SetWords(dt),
|
|
|
|
|
+ 716 SymTab.SetWords(et))
|
|
|
|
|
+ 717 ELSIF SymTab.ClassOf(dt) =
|
|
|
|
|
+ 718 SymTab.ClRecord THEN
|
|
|
|
|
+ 719 QbeGen.CopyRecord(qd, qe, dt)
|
|
|
|
|
+ 720 ELSIF SymTab.ClassOf(dt) =
|
|
|
|
|
+ 721 SymTab.ClPtr THEN
|
|
|
|
|
+ 722 QbeGen.StorePtr(qn, qe)
|
|
|
|
|
+ 723 ELSIF conv THEN
|
|
|
|
|
+ 724 QbeGen.ConvIR(qe, qt);
|
|
|
|
|
+ 725 QbeGen.StoreVar(qn, qt, TRUE)
|
|
|
|
|
+ 726 ELSE
|
|
|
|
|
+ 727 QbeGen.StoreVar(qn, qe, isR)
|
|
|
|
|
+ 728 END
|
|
|
|
|
+ 729 END; .) .
|
|
|
|
|
+ 730 IfStat (. VAR t: SymTab.TypeIndex;
|
|
|
|
|
+ 731 q, lThen, lElse, lEnd:
|
|
|
|
|
+ 732 QbeGen.QVal;
|
|
|
|
|
+ 733 hasElse: BOOLEAN; .)
|
|
|
|
|
+ 734 = "IF" (. hasElse := FALSE; .)
|
|
|
|
|
+ 735 Expr<t, q> (. IF ~SymTab.BoolCheck(t) THEN
|
|
|
|
|
+ 736 SemError(214) END;
|
|
|
|
|
+ 737 QbeGen.NewLabel(lThen);
|
|
|
|
|
+ 738 QbeGen.NewLabel(lElse);
|
|
|
|
|
+ 739 QbeGen.NewLabel(lEnd);
|
|
|
|
|
+ 740 QbeGen.Jnz(q, lThen, lElse);
|
|
|
|
|
+ 741 QbeGen.EmitLabel(lThen); .)
|
|
|
|
|
+ 742 "THEN" StatSeq (. QbeGen.Jmp(lEnd); .)
|
|
|
|
|
+ 743 { "ELSIF" (. QbeGen.EmitLabel(lElse);
|
|
|
|
|
+ 744 QbeGen.NewLabel(lElse); .)
|
|
|
|
|
+ 745 Expr<t, q> (. IF ~SymTab.BoolCheck(t) THEN
|
|
|
|
|
+ 746 SemError(214) END;
|
|
|
|
|
+ 747 QbeGen.NewLabel(lThen);
|
|
|
|
|
+ 748 QbeGen.Jnz(q, lThen, lElse);
|
|
|
|
|
+ 749 QbeGen.EmitLabel(lThen); .)
|
|
|
|
|
+ 750 "THEN" StatSeq (. QbeGen.Jmp(lEnd); .) }
|
|
|
|
|
+ 751 [ "ELSE" (. QbeGen.EmitLabel(lElse);
|
|
|
|
|
+ 752 hasElse := TRUE; .)
|
|
|
|
|
+ 753 StatSeq ]
|
|
|
|
|
+ 754 "END" (. IF hasElse THEN
|
|
|
|
|
+ 755 QbeGen.EmitLabel(lEnd)
|
|
|
|
|
+ 756 ELSE QbeGen.EmitLabel(lElse);
|
|
|
|
|
+ 757 QbeGen.EmitLabel(lEnd)
|
|
|
|
|
+ 758 END; .) .
|
|
|
|
|
+ 759 WhileStat (. VAR t: SymTab.TypeIndex;
|
|
|
|
|
+ 760 q, lTop, lBody, lEnd:
|
|
|
|
|
+ 761 QbeGen.QVal; .)
|
|
|
|
|
+ 762 = "WHILE" (. QbeGen.NewLabel(lTop);
|
|
|
|
|
+ 763 QbeGen.NewLabel(lBody);
|
|
|
|
|
+ 764 QbeGen.NewLabel(lEnd);
|
|
|
|
|
+ 765 QbeGen.EmitLabel(lTop); .)
|
|
|
|
|
+ 766 Expr<t, q> (. IF ~SymTab.BoolCheck(t) THEN
|
|
|
|
|
+ 767 SemError(214) END;
|
|
|
|
|
+ 768 QbeGen.Jnz(q, lBody, lEnd);
|
|
|
|
|
+ 769 QbeGen.EmitLabel(lBody); .)
|
|
|
|
|
+ 770 "DO" StatSeq (. QbeGen.Jmp(lTop); .)
|
|
|
|
|
+ 771 "END" (. QbeGen.EmitLabel(lEnd); .) .
|
|
|
|
|
+ 772 RepeatStat (. VAR t: SymTab.TypeIndex;
|
|
|
|
|
+ 773 q, lTop, lEnd: QbeGen.QVal; .)
|
|
|
|
|
+ 774 = "REPEAT" (. QbeGen.NewLabel(lTop);
|
|
|
|
|
+ 775 QbeGen.NewLabel(lEnd);
|
|
|
|
|
+ 776 QbeGen.EmitLabel(lTop); .)
|
|
|
|
|
+ 777 StatSeq
|
|
|
|
|
+ 778 "UNTIL" Expr<t, q> (. IF ~SymTab.BoolCheck(t) THEN
|
|
|
|
|
+ 779 SemError(214) END;
|
|
|
|
|
+ 780 QbeGen.Jnz(q, lEnd, lTop);
|
|
|
|
|
+ 781 QbeGen.EmitLabel(lEnd); .) .
|
|
|
|
|
+ 782 LoopStat (. VAR lTop, lEnd: QbeGen.QVal; .)
|
|
|
|
|
+ 783 = "LOOP" (. QbeGen.NewLabel(lTop);
|
|
|
|
|
+ 784 QbeGen.NewLabel(lEnd);
|
|
|
|
|
+ 785 QbeGen.PushLoop(lEnd);
|
|
|
|
|
+ 786 QbeGen.EmitLabel(lTop); .)
|
|
|
|
|
+ 787 StatSeq
|
|
|
|
|
+ 788 "END" (. QbeGen.Jmp(lTop);
|
|
|
|
|
+ 789 QbeGen.PopLoop;
|
|
|
|
|
+ 790 QbeGen.EmitLabel(lEnd); .) .
|
|
|
|
|
+ 791 (* FOR with static-sign BY (literal, non-zero; 220 otherwise).
|
|
|
|
|
+ 792 Runtime direction would need a compare-select; the literal
|
|
|
|
|
+ 793 sign picks cslew/csegew at "DO" time. *)
|
|
|
|
|
+ 794 ForStat (. VAR lv: SymTab.Name;
|
|
|
|
|
+ 795 tlo, thi, tby:
|
|
|
|
|
+ 796 SymTab.TypeIndex;
|
|
|
|
|
+ 797 qlo, qhi, qby, qt, qk, qb:
|
|
|
|
|
+ 798 QbeGen.QVal;
|
|
|
|
|
+ 799 lTop, lBody, lEnd:
|
|
|
|
|
+ 800 QbeGen.QVal;
|
|
|
|
|
+ 801 by: INTEGER;
|
|
|
|
|
+ 802 ok: BOOLEAN; .)
|
|
|
|
|
+ 803 = "FOR" (. by := 1; .)
|
|
|
|
|
+ 804 GetIdent<lv> (. ok := SymTab.Lookup(lv);
|
|
|
|
|
+ 805 IF ~ok THEN
|
|
|
|
|
+ 806 SemError(201)
|
|
|
|
|
+ 807 ELSIF (SymTab.SymKind(lv) #
|
|
|
|
|
+ 808 SymTab.KindVar)
|
|
|
|
|
+ 809 & (SymTab.SymKind(lv) #
|
|
|
|
|
+ 810 SymTab.KindParam) THEN
|
|
|
|
|
+ 811 SemError(220); ok := FALSE
|
|
|
|
|
+ 812 ELSIF ~SymTab.IsIntFamily(
|
|
|
|
|
+ 813 SymTab.SymType(lv)) THEN
|
|
|
|
|
+ 814 SemError(220); ok := FALSE
|
|
|
|
|
+ 815 END; .)
|
|
|
|
|
+ 816 ":=" Expr<tlo, qlo> (. IF ~SymTab.IsIntFamily(tlo) THEN
|
|
|
|
|
+ 817 SemError(220); ok := FALSE
|
|
|
|
|
+ 818 END; .)
|
|
|
|
|
+ 819 "TO" Expr<thi, qhi> (. IF ~SymTab.IsIntFamily(thi) THEN
|
|
|
|
|
+ 820 SemError(220); ok := FALSE
|
|
|
|
|
+ 821 END; .)
|
|
|
|
|
+ 822 [ "BY" Expr<tby, qby> (. IF (tby #
|
|
|
|
|
+ 823 SymTab.InvalidType)
|
|
|
|
|
+ 824 & ~SymTab.IsIntFamily(tby) THEN
|
|
|
|
|
+ 825 SemError(220); ok := FALSE
|
|
|
|
|
+ 826 END;
|
|
|
|
|
+ 827 IF ~SymTab.ConstInt(qby, by) THEN
|
|
|
|
|
+ 828 SemError(230); by := 1
|
|
|
|
|
+ 829 ELSIF by = 0 THEN
|
|
|
|
|
+ 830 SemError(220); by := 1
|
|
|
|
|
+ 831 END; .) ]
|
|
|
|
|
+ 832 "DO" (. IF ok THEN
|
|
|
|
|
+ 833 QbeGen.StoreVar(lv, qlo,
|
|
|
|
|
+ 834 FALSE) END;
|
|
|
|
|
+ 835 QbeGen.NewLabel(lTop);
|
|
|
|
|
+ 836 QbeGen.NewLabel(lBody);
|
|
|
|
|
+ 837 QbeGen.NewLabel(lEnd);
|
|
|
|
|
+ 838 QbeGen.EmitLabel(lTop);
|
|
|
|
|
+ 839 QbeGen.LoadVar(lv, FALSE, qt);
|
|
|
|
|
+ 840 QbeGen.NewTemp(qk);
|
|
|
|
|
+ 841 IF by > 0 THEN
|
|
|
|
|
+ 842 QbeGen.Op3("cslew", qk,
|
|
|
|
|
+ 843 qt, qhi, FALSE)
|
|
|
|
|
+ 844 ELSE QbeGen.Op3("csgew", qk,
|
|
|
|
|
+ 845 qt, qhi, FALSE)
|
|
|
|
|
+ 846 END;
|
|
|
|
|
+ 847 QbeGen.Jnz(qk, lBody, lEnd);
|
|
|
|
|
+ 848 QbeGen.EmitLabel(lBody); .)
|
|
|
|
|
+ 849 StatSeq
|
|
|
|
|
+ 850 "END" (. IF ok THEN
|
|
|
|
|
+ 851 QbeGen.LoadVar(lv, FALSE,
|
|
|
|
|
+ 852 qt);
|
|
|
|
|
+ 853 QbeGen.IntStr(by, qb);
|
|
|
|
|
+ 854 QbeGen.NewTemp(qk);
|
|
|
|
|
+ 855 QbeGen.Op3("add", qk,
|
|
|
|
|
+ 856 qt, qb, FALSE);
|
|
|
|
|
+ 857 QbeGen.StoreVar(lv, qk,
|
|
|
|
|
+ 858 FALSE) END;
|
|
|
|
|
+ 859 QbeGen.Jmp(lTop);
|
|
|
|
|
+ 860 QbeGen.EmitLabel(lEnd); .) .
|
|
|
|
|
+ 861 CaseStat (. VAR tsel: SymTab.TypeIndex;
|
|
|
|
|
+ 862 qsel, lEnd: QbeGen.QVal; .)
|
|
|
|
|
+ 863 = "CASE" Expr<tsel, qsel> (. QbeGen.NewLabel(lEnd); .)
|
|
|
|
|
+ 864 "OF" CaseAlt<tsel, qsel, lEnd>
|
|
|
|
|
+ 865 { "|" CaseAlt<tsel, qsel, lEnd> }
|
|
|
|
|
+ 866 [ "ELSE" StatSeq ]
|
|
|
|
|
+ 867 "END" (. QbeGen.EmitLabel(lEnd); .) .
|
|
|
|
|
+ 868 (* Compare-chain lowering: each alternative ends its match-tests
|
|
|
|
|
+ 869 with "jmp lAfter", so the no-match fallthrough skips the body:
|
|
|
|
|
+ 870 "cmp; jnz(lBody,lF); lF: ... ; jmp lAfter; lBody: S; jmp lEnd;
|
|
|
|
|
+ 871 lAfter:". Falls into the next alternative, ELSE, or END. *)
|
|
|
|
|
+ 872 CaseAlt<tsel: SymTab.TypeIndex; qsel: QbeGen.QVal;
|
|
|
|
|
+ 873 lEnd: QbeGen.QVal> (. VAR lBody, lAfter: QbeGen.QVal; .)
|
|
|
|
|
+ 874 = (. QbeGen.NewLabel(lBody);
|
|
|
|
|
+ 875 QbeGen.NewLabel(lAfter); .)
|
|
|
|
|
+ 876 CaseLabel<tsel, qsel, lBody>
|
|
|
|
|
+ 877 { "," CaseLabel<tsel, qsel, lBody> }
|
|
|
|
|
+ 878 ":" (. QbeGen.Jmp(lAfter);
|
|
|
|
|
+ 879 QbeGen.EmitLabel(lBody); .)
|
|
|
|
|
+ 880 StatSeq (. QbeGen.Jmp(lEnd);
|
|
|
|
|
+ 881 QbeGen.EmitLabel(lAfter); .) .
|
|
|
|
|
+ 882 CaseLabel<tsel: SymTab.TypeIndex; qsel: QbeGen.QVal;
|
|
|
|
|
+ 883 lBody: QbeGen.QVal> (. VAR t2, t3: SymTab.TypeIndex;
|
|
|
|
|
+ 884 q2, q3, qc, qd, qe:
|
|
|
|
|
+ 885 QbeGen.QVal;
|
|
|
|
|
+ 886 lNext: QbeGen.QVal; .)
|
|
|
|
|
+ 887 = Expr<t2, q2> (. IF (t2 #
|
|
|
|
|
+ 888 SymTab.InvalidType)
|
|
|
|
|
+ 889 & (tsel #
|
|
|
|
|
+ 890 SymTab.InvalidType)
|
|
|
|
|
+ 891 & ((SymTab.ClassOf(t2) =
|
|
|
|
|
+ 892 SymTab.ClSet)
|
|
|
|
|
+ 893 OR (SymTab.ClassOf(tsel) =
|
|
|
|
|
+ 894 SymTab.ClSet)) THEN
|
|
|
|
|
+ 895 SemError(230)
|
|
|
|
|
+ 896 ELSIF (t2 #
|
|
|
|
|
+ 897 SymTab.InvalidType)
|
|
|
|
|
+ 898 & (tsel #
|
|
|
|
|
+ 899 SymTab.InvalidType)
|
|
|
|
|
+ 900 & ~SymTab.EqCheck(t2,
|
|
|
|
|
+ 901 tsel) THEN
|
|
|
|
|
+ 902 SemError(213) END;
|
|
|
|
|
+ 903 IF ~QbeGen.IsImm(q2) THEN
|
|
|
|
|
+ 904 SemError(230);
|
|
|
|
|
+ 905 QbeGen.CopyOp("0", q2)
|
|
|
|
|
+ 906 END;
|
|
|
|
|
+ 907 QbeGen.NewLabel(lNext);
|
|
|
|
|
+ 908 QbeGen.Cmp(SymTab.OpEq,
|
|
|
|
|
+ 909 qsel, q2, qc, FALSE);
|
|
|
|
|
+ 910 QbeGen.Jnz(qc, lBody, lNext);
|
|
|
|
|
+ 911 QbeGen.EmitLabel(lNext); .)
|
|
|
|
|
+ 912 [ ".." Expr<t3, q3> (. IF (t3 #
|
|
|
|
|
+ 913 SymTab.InvalidType)
|
|
|
|
|
+ 914 & (tsel #
|
|
|
|
|
+ 915 SymTab.InvalidType)
|
|
|
|
|
+ 916 & ~SymTab.EqCheck(t3,
|
|
|
|
|
+ 917 tsel) THEN
|
|
|
|
|
+ 918 SemError(213) END;
|
|
|
|
|
+ 919 IF ~QbeGen.IsImm(q3) THEN
|
|
|
|
|
+ 920 SemError(230);
|
|
|
|
|
+ 921 QbeGen.CopyOp("0", q3)
|
|
|
|
|
+ 922 END;
|
|
|
|
|
+ 923 QbeGen.Cmp(SymTab.OpGe,
|
|
|
|
|
+ 924 qsel, q2, qc, FALSE);
|
|
|
|
|
+ 925 QbeGen.Cmp(SymTab.OpLe,
|
|
|
|
|
+ 926 qsel, q3, qd, FALSE);
|
|
|
|
|
+ 927 QbeGen.NewTemp(qe);
|
|
|
|
|
+ 928 QbeGen.Op3("and", qe, qc, qd,
|
|
|
|
|
+ 929 FALSE);
|
|
|
|
|
+ 930 QbeGen.NewLabel(lNext);
|
|
|
|
|
+ 931 QbeGen.Jnz(qe, lBody, lNext);
|
|
|
|
|
+ 932 QbeGen.EmitLabel(lNext); .) ] .
|
|
|
|
|
+ 933 ReturnStat (. VAR t: SymTab.TypeIndex;
|
|
|
|
|
+ 934 q: QbeGen.QVal;
|
|
|
|
|
+ 935 res: SymTab.TypeIndex;
|
|
|
|
|
+ 936 hadE: BOOLEAN; .)
|
|
|
|
|
+ 937 = "RETURN" (. hadE := FALSE; .)
|
|
|
|
|
+ 938 [ Expr<t, q> (. hadE := TRUE; .) ]
|
|
|
|
|
+ 939 (. IF ~SymTab.InProc() THEN
|
|
|
|
|
+ 940 SemError(232)
|
|
|
|
|
+ 941 ELSE res := SymTab.CurRes();
|
|
|
|
|
+ 942 IF ~hadE THEN
|
|
|
|
|
+ 943 IF res #
|
|
|
|
|
+ 944 SymTab.InvalidType THEN
|
|
|
|
|
+ 945 SemError(232) END
|
|
|
|
|
+ 946 ELSIF (res =
|
|
|
|
|
+ 947 SymTab.InvalidType)
|
|
|
|
|
+ 948 OR (t #
|
|
|
|
|
+ 949 SymTab.InvalidType)
|
|
|
|
|
+ 950 & ~SymTab.Assignable(t,
|
|
|
|
|
+ 951 res) THEN
|
|
|
|
|
+ 952 SemError(232)
|
|
|
|
|
+ 953 END
|
|
|
|
|
+ 954 END; .) .
|
|
|
|
|
+ 955 (* Designator: scalar loads, array addresses, and index suffixes.
|
|
|
|
|
+ 956 Each index descends one level (bounds-checked, trap on breach);
|
|
|
|
|
+ 957 nested levels reload the inner descriptor address. q ends as the
|
|
|
|
|
+ 958 value (scalars), the descriptor address (plain arrays), or the
|
|
|
|
|
+ 959 element address (indexed); sfx marks the indexed form. *)
|
|
|
|
|
+ 960 Design<VAR t: SymTab.TypeIndex; VAR k: INTEGER;
|
|
|
|
|
+ 961 VAR q: QbeGen.QVal; VAR qn: SymTab.Name; VAR sfx: BOOLEAN>
|
|
|
|
|
+ 962 (. VAR n, fn: SymTab.Name;
|
|
|
|
|
+ 963 cls: INTEGER;
|
|
|
|
|
+ 964 curT, it, eT, bt:
|
|
|
|
|
+ 965 SymTab.TypeIndex;
|
|
|
|
|
+ 966 iq, ql, qlo, qhi, qe:
|
|
|
|
|
+ 967 QbeGen.QVal;
|
|
|
|
|
+ 968 lo, hi: INTEGER;
|
|
|
|
|
+ 969 fo: INTEGER;
|
|
|
|
|
+ 970 isOpen: BOOLEAN;
|
|
|
|
|
+ 971 qb: QbeGen.QVal; .)
|
|
|
|
|
+ 972 = GetIdent<n> (. QbeGen.CopyOp(n, qn);
|
|
|
|
|
+ 973 sfx := FALSE;
|
|
|
|
|
+ 974 IF ~SymTab.Lookup(n) THEN
|
|
|
|
|
+ 975 SemError(201);
|
|
|
|
|
+ 976 t := SymTab.InvalidType;
|
|
|
|
|
+ 977 k := -1;
|
|
|
|
|
+ 978 QbeGen.CopyOp("0", q)
|
|
|
|
|
+ 979 ELSE
|
|
|
|
|
+ 980 t := SymTab.SymType(n);
|
|
|
|
|
+ 981 k := SymTab.SymKind(n);
|
|
|
|
|
+ 982 IF k = SymTab.KindConst THEN
|
|
|
|
|
+ 983 IF SymTab.Equal(n,
|
|
|
|
|
+ 984 "TRUE") THEN
|
|
|
|
|
+ 985 t := SymTab.BoolType();
|
|
|
|
|
+ 986 QbeGen.CopyOp("1", q)
|
|
|
|
|
+ 987 ELSIF SymTab.Equal(n,
|
|
|
|
|
+ 988 "FALSE") THEN
|
|
|
|
|
+ 989 t := SymTab.BoolType();
|
|
|
|
|
+ 990 QbeGen.CopyOp("0", q)
|
|
|
|
|
+ 991 ELSIF SymTab.Equal(n,
|
|
|
|
|
+ 992 "NIL") THEN
|
|
|
|
|
+ 993 QbeGen.CopyOp("0", q)
|
|
|
|
|
+ 994 ELSE
|
|
|
|
|
+ 995 cls :=
|
|
|
|
|
+ 996 SymTab.ClassOf(t);
|
|
|
|
|
+ 997 IF (t #
|
|
|
|
|
+ 998 SymTab.InvalidType)
|
|
|
|
|
+ 999 & ((cls = SymTab.ClInt)
|
|
|
|
|
+ 1000 OR (cls
|
|
|
|
|
+ 1001 = SymTab.ClChar)
|
|
|
|
|
+ 1002 OR (cls
|
|
|
|
|
+ 1003 = SymTab.ClReal)
|
|
|
|
|
+ 1004 OR (cls
|
|
|
|
|
+ 1005 = SymTab.ClNil)) THEN
|
|
|
|
|
+ 1006 IF cls = SymTab.ClNil THEN
|
|
|
|
|
+ 1007 QbeGen.CopyOp("0", q)
|
|
|
|
|
+ 1008 ELSE
|
|
|
|
|
+ 1009 QbeGen.LoadVar(n,
|
|
|
|
|
+ 1010 cls = SymTab.ClReal,
|
|
|
|
|
+ 1011 q)
|
|
|
|
|
+ 1012 END
|
|
|
|
|
+ 1013 ELSE
|
|
|
|
|
+ 1014 IF t #
|
|
|
|
|
+ 1015 SymTab.InvalidType THEN
|
|
|
|
|
+ 1016 SemError(230)
|
|
|
|
|
+ 1017 END;
|
|
|
|
|
+ 1018 QbeGen.CopyOp("0", q)
|
|
|
|
|
+ 1019 END
|
|
|
|
|
+ 1020 END
|
|
|
|
|
+ 1021 ELSIF (k = SymTab.KindVar)
|
|
|
|
|
+ 1022 OR (k = SymTab.KindParam) THEN
|
|
|
|
|
+ 1023 cls :=
|
|
|
|
|
+ 1024 SymTab.ClassOf(t);
|
|
|
|
|
+ 1025 IF (cls = SymTab.ClInt)
|
|
|
|
|
+ 1026 OR (cls = SymTab.ClBool)
|
|
|
|
|
+ 1027 OR (cls = SymTab.ClChar)
|
|
|
|
|
+ 1028 OR (cls
|
|
|
|
|
+ 1029 = SymTab.ClReal) THEN
|
|
|
|
|
+ 1030 QbeGen.LoadVar(n,
|
|
|
|
|
+ 1031 cls = SymTab.ClReal, q)
|
|
|
|
|
+ 1032 ELSIF cls = SymTab.ClPtr THEN
|
|
|
|
|
+ 1033 QbeGen.LoadPtr(n, q)
|
|
|
|
|
+ 1034 ELSIF (cls
|
|
|
|
|
+ 1035 = SymTab.ClArray)
|
|
|
|
|
+ 1036 OR (cls
|
|
|
|
|
+ 1037 = SymTab.ClSet)
|
|
|
|
|
+ 1038 OR (cls
|
|
|
|
|
+ 1039 = SymTab.ClRecord)
|
|
|
|
|
+ 1040 OR (cls
|
|
|
|
|
+ 1041 = SymTab.ClClass) THEN
|
|
|
|
|
+ 1042 QbeGen.AddrOf(n, q)
|
|
|
|
|
+ 1043 ELSE SemError(230);
|
|
|
|
|
+ 1044 QbeGen.CopyOp("0", q)
|
|
|
|
|
+ 1045 END
|
|
|
|
|
+ 1046 ELSE QbeGen.CopyOp("0", q);
|
|
|
|
|
+ 1047 IF (k = SymTab.KindImport)
|
|
|
|
|
+ 1048 OR (k = SymTab.KindProc) THEN
|
|
|
|
|
+ 1049 SemError(230)
|
|
|
|
|
+ 1050 ELSE
|
|
|
|
|
+ 1051 IF k = SymTab.KindField THEN
|
|
|
|
|
+ 1052 IF QbeGen.TopWith(qb) THEN
|
|
|
|
|
+ 1053 fo :=
|
|
|
|
|
+ 1054 SymTab.FieldOffset(
|
|
|
|
|
+ 1055 SymTab.FieldOwner(n),
|
|
|
|
|
+ 1056 n);
|
|
|
|
|
+ 1057 QbeGen.FieldAddr(qb,
|
|
|
|
|
+ 1058 fo, q);
|
|
|
|
|
+ 1059 sfx := TRUE
|
|
|
|
|
+ 1060 ELSE SemError(230);
|
|
|
|
|
+ 1061 QbeGen.CopyOp("0", q)
|
|
|
|
|
+ 1062 END
|
|
|
|
|
+ 1063 END
|
|
|
|
|
+ 1064 END
|
|
|
|
|
+ 1065 END
|
|
|
|
|
+ 1066 END; .)
|
|
|
|
|
+ 1067 { "[" Expr<it, iq>
|
|
|
|
|
+ 1068 (. IF t = SymTab.InvalidType THEN
|
|
|
|
|
+ 1069 ELSIF SymTab.ClassOf(t) #
|
|
|
|
|
+ 1070 SymTab.ClArray THEN
|
|
|
|
|
+ 1071 SemError(217);
|
|
|
|
|
+ 1072 t := SymTab.InvalidType
|
|
|
|
|
+ 1073 ELSIF ~SymTab.IsIntFamily(it)
|
|
|
|
|
+ 1074 & (SymTab.ClassOf(it) #
|
|
|
|
|
+ 1075 SymTab.ClChar) THEN
|
|
|
|
|
+ 1076 SemError(218);
|
|
|
|
|
+ 1077 t := SymTab.InvalidType
|
|
|
|
|
+ 1078 ELSE
|
|
|
|
|
+ 1079 QbeGen.WidenIndex(iq, ql);
|
|
|
|
|
+ 1080 isOpen :=
|
|
|
|
|
+ 1081 SymTab.IsOpenArray(t);
|
|
|
|
|
+ 1082 IF isOpen THEN
|
|
|
|
|
+ 1083 QbeGen.CopyOp("0", qlo);
|
|
|
|
|
+ 1084 QbeGen.OpenHi(q, qhi)
|
|
|
|
|
+ 1085 ELSE
|
|
|
|
|
+ 1086 lo := SymTab.ArrayLo(t);
|
|
|
|
|
+ 1087 hi := SymTab.ArrayHi(t);
|
|
|
|
|
+ 1088 QbeGen.IntStr(lo, qlo);
|
|
|
|
|
+ 1089 QbeGen.IntStr(hi, qhi)
|
|
|
|
|
+ 1090 END;
|
|
|
|
|
+ 1091 QbeGen.CheckRange(ql, qlo,
|
|
|
|
|
+ 1092 qhi);
|
|
|
|
|
+ 1093 eT := SymTab.ArrayElem(t);
|
|
|
|
|
+ 1094 QbeGen.ElemAddr(q, ql, qlo,
|
|
|
|
|
+ 1095 t, qe);
|
|
|
|
|
+ 1096 IF SymTab.ClassOf(eT) =
|
|
|
|
|
+ 1097 SymTab.ClArray THEN
|
|
|
|
|
+ 1098 QbeGen.ElemLoad(qe, eT, q)
|
|
|
|
|
+ 1099 ELSE QbeGen.CopyOp(qe, q)
|
|
|
|
|
+ 1100 END;
|
|
|
|
|
+ 1101 t := eT; sfx := TRUE
|
|
|
|
|
+ 1102 END; .)
|
|
|
|
|
+ 1103 { "," Expr<it, iq>
|
|
|
|
|
+ 1104 (. IF t = SymTab.InvalidType THEN
|
|
|
|
|
+ 1105 ELSIF SymTab.ClassOf(t) #
|
|
|
|
|
+ 1106 SymTab.ClArray THEN
|
|
|
|
|
+ 1107 SemError(217);
|
|
|
|
|
+ 1108 t := SymTab.InvalidType
|
|
|
|
|
+ 1109 ELSIF ~SymTab.IsIntFamily(it)
|
|
|
|
|
+ 1110 & (SymTab.ClassOf(it) #
|
|
|
|
|
+ 1111 SymTab.ClChar) THEN
|
|
|
|
|
+ 1112 SemError(218);
|
|
|
|
|
+ 1113 t := SymTab.InvalidType
|
|
|
|
|
+ 1114 ELSE
|
|
|
|
|
+ 1115 QbeGen.WidenIndex(iq, ql);
|
|
|
|
|
+ 1116 isOpen :=
|
|
|
|
|
+ 1117 SymTab.IsOpenArray(t);
|
|
|
|
|
+ 1118 IF isOpen THEN
|
|
|
|
|
+ 1119 QbeGen.CopyOp("0", qlo);
|
|
|
|
|
+ 1120 QbeGen.OpenHi(q, qhi)
|
|
|
|
|
+ 1121 ELSE
|
|
|
|
|
+ 1122 lo := SymTab.ArrayLo(t);
|
|
|
|
|
+ 1123 hi := SymTab.ArrayHi(t);
|
|
|
|
|
+ 1124 QbeGen.IntStr(lo, qlo);
|
|
|
|
|
+ 1125 QbeGen.IntStr(hi, qhi)
|
|
|
|
|
+ 1126 END;
|
|
|
|
|
+ 1127 QbeGen.CheckRange(ql, qlo,
|
|
|
|
|
+ 1128 qhi);
|
|
|
|
|
+ 1129 eT := SymTab.ArrayElem(t);
|
|
|
|
|
+ 1130 QbeGen.ElemAddr(q, ql, qlo,
|
|
|
|
|
+ 1131 t, qe);
|
|
|
|
|
+ 1132 IF SymTab.ClassOf(eT) =
|
|
|
|
|
+ 1133 SymTab.ClArray THEN
|
|
|
|
|
+ 1134 QbeGen.ElemLoad(qe, eT, q)
|
|
|
|
|
+ 1135 ELSE QbeGen.CopyOp(qe, q)
|
|
|
|
|
+ 1136 END;
|
|
|
|
|
+ 1137 t := eT; sfx := TRUE
|
|
|
|
|
+ 1138 END; .) }
|
|
|
|
|
+ 1139 "]"
|
|
|
|
|
+ 1140 | "." GetIdent<fn>
|
|
|
|
|
+ 1141 (. IF t = SymTab.InvalidType THEN
|
|
|
|
|
+ 1142 ELSIF (SymTab.ClassOf(t) #
|
|
|
|
|
+ 1143 SymTab.ClRecord)
|
|
|
|
|
+ 1144 & (SymTab.ClassOf(t) #
|
|
|
|
|
+ 1145 SymTab.ClClass) THEN
|
|
|
|
|
+ 1146 SemError(215);
|
|
|
|
|
+ 1147 t := SymTab.InvalidType
|
|
|
|
|
+ 1148 ELSIF ~SymTab.FieldExists(t,
|
|
|
|
|
+ 1149 fn) THEN
|
|
|
|
|
+ 1150 SemError(216);
|
|
|
|
|
+ 1151 t := SymTab.InvalidType
|
|
|
|
|
+ 1152 ELSE
|
|
|
|
|
+ 1153 fo := SymTab.FieldOffset(t,
|
|
|
|
|
+ 1154 fn);
|
|
|
|
|
+ 1155 t := SymTab.FieldType(t, fn);
|
|
|
|
|
+ 1156 QbeGen.FieldAddr(q, fo, qe);
|
|
|
|
|
+ 1157 IF SymTab.ClassOf(t) =
|
|
|
|
|
+ 1158 SymTab.ClArray THEN
|
|
|
|
|
+ 1159 QbeGen.ElemLoad(qe, t, q)
|
|
|
|
|
+ 1160 ELSE QbeGen.CopyOp(qe, q)
|
|
|
|
|
+ 1161 END;
|
|
|
|
|
+ 1162 sfx := TRUE
|
|
|
|
|
+ 1163 END; .)
|
|
|
|
|
+ 1164 | "^"
|
|
|
|
|
+ 1165 (. IF t = SymTab.InvalidType THEN
|
|
|
|
|
+ 1166 ELSIF SymTab.ClassOf(t) #
|
|
|
|
|
+ 1167 SymTab.ClPtr THEN
|
|
|
|
|
+ 1168 SemError(219);
|
|
|
|
|
+ 1169 t := SymTab.InvalidType
|
|
|
|
|
+ 1170 ELSE
|
|
|
|
|
+ 1171 bt := SymTab.PtrBase(t);
|
|
|
|
|
+ 1172 IF bt = SymTab.InvalidType THEN
|
|
|
|
|
+ 1173 ELSE
|
|
|
|
|
+ 1174 IF sfx THEN
|
|
|
|
|
+ 1175 QbeGen.ElemLoad(q, t,
|
|
|
|
|
+ 1176 qb);
|
|
|
|
|
+ 1177 QbeGen.CopyOp(qb, q)
|
|
|
|
|
+ 1178 END;
|
|
|
|
|
+ 1179 t := bt;
|
|
|
|
|
+ 1180 IF (SymTab.ClassOf(bt) =
|
|
|
|
|
+ 1181 SymTab.ClInt)
|
|
|
|
|
+ 1182 OR (SymTab.ClassOf(bt) =
|
|
|
|
|
+ 1183 SymTab.ClBool)
|
|
|
|
|
+ 1184 OR (SymTab.ClassOf(bt) =
|
|
|
|
|
+ 1185 SymTab.ClChar)
|
|
|
|
|
+ 1186 OR (SymTab.ClassOf(bt) =
|
|
|
|
|
+ 1187 SymTab.ClReal) THEN
|
|
|
|
|
+ 1188 sfx := TRUE
|
|
|
|
|
+ 1189 ELSE sfx := FALSE
|
|
|
|
|
+ 1190 END
|
|
|
|
|
+ 1191 END
|
|
|
|
|
+ 1192 END; .) } .
|
|
|
|
|
+ 1193 Expr<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
|
|
+ 1194 (. VAR t2: SymTab.TypeIndex;
|
|
|
|
|
+ 1195 op: INTEGER;
|
|
|
|
|
+ 1196 q2, qt: QbeGen.QVal;
|
|
|
|
|
+ 1197 isR: BOOLEAN; .)
|
|
|
|
|
+ 1198 = SimExpr<t, q>
|
|
|
|
|
+ 1199 [ Rel<op> SimExpr<t2, q2>
|
|
|
|
|
+ 1200 (. IF op = SymTab.OpIn THEN
|
|
|
|
|
+ 1201 IF SymTab.InCheck(t, t2) THEN
|
|
|
|
|
+ 1202 IF (t = SymTab.InvalidType)
|
|
|
|
|
+ 1203 OR (t2 = SymTab.InvalidType) THEN
|
|
|
|
|
+ 1204 t := SymTab.BoolType(); QbeGen.CopyOp("0", q)
|
|
|
|
|
+ 1205 ELSE
|
|
|
|
|
+ 1206 QbeGen.InSet(q, q2, SymTab.SetBaseLo(t2),
|
|
|
|
|
+ 1207 SymTab.SetCount(t2), qt);
|
|
|
|
|
+ 1208 t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
|
|
|
|
|
+ 1209 END
|
|
|
|
|
+ 1210 ELSE SemError(222); t := SymTab.InvalidType;
|
|
|
|
|
+ 1211 QbeGen.CopyOp("0", q)
|
|
|
|
|
+ 1212 END
|
|
|
|
|
+ 1213 ELSIF SymTab.RelCheck(t, t2, op) THEN
|
|
|
|
|
+ 1214 IF (t = SymTab.InvalidType)
|
|
|
|
|
+ 1215 OR (t2 = SymTab.InvalidType) THEN
|
|
|
|
|
+ 1216 t := SymTab.BoolType(); QbeGen.CopyOp("0", q)
|
|
|
|
|
+ 1217 ELSIF (SymTab.ClassOf(t) = SymTab.ClPtr)
|
|
|
|
|
+ 1218 OR (SymTab.ClassOf(t2) = SymTab.ClPtr) THEN
|
|
|
|
|
+ 1219 IF (op # SymTab.OpEq) & (op # SymTab.OpNeq1)
|
|
|
|
|
+ 1220 & (op # SymTab.OpNeq2) THEN
|
|
|
|
|
+ 1221 SemError(213); t := SymTab.InvalidType;
|
|
|
|
|
+ 1222 QbeGen.CopyOp("0", q)
|
|
|
|
|
+ 1223 ELSE
|
|
|
|
|
+ 1224 QbeGen.CmpL(op, q, q2, qt);
|
|
|
|
|
+ 1225 t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
|
|
|
|
|
+ 1226 END
|
|
|
|
|
+ 1227 ELSIF (SymTab.ClassOf(t) = SymTab.ClSet)
|
|
|
|
|
+ 1228 OR (SymTab.ClassOf(t2) = SymTab.ClSet) THEN
|
|
|
|
|
+ 1229 QbeGen.CmpSet(op, q, q2,
|
|
|
|
|
+ 1230 SymTab.SetWords(t), SymTab.SetWords(t2), qt);
|
|
|
|
|
+ 1231 t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
|
|
|
|
|
+ 1232 ELSE
|
|
|
|
|
+ 1233 isR := SymTab.ClassOf(t) = SymTab.ClReal;
|
|
|
|
|
+ 1234 t := SymTab.BoolType();
|
|
|
|
|
+ 1235 QbeGen.Cmp(op, q, q2, qt, isR);
|
|
|
|
|
+ 1236 QbeGen.CopyOp(qt, q)
|
|
|
|
|
+ 1237 END
|
|
|
|
|
+ 1238 ELSE SemError(213); t := SymTab.InvalidType;
|
|
|
|
|
+ 1239 QbeGen.CopyOp("0", q)
|
|
|
|
|
+ 1240 END; .) ] .
|
|
|
|
|
+ 1241 Rel<VAR op: INTEGER>
|
|
|
|
|
+ 1242 = "=" (. op := SymTab.OpEq; .)
|
|
|
|
|
+ 1243 | "#" (. op := SymTab.OpNeq1; .)
|
|
|
|
|
+ 1244 | "<" (. op := SymTab.OpLt; .)
|
|
|
|
|
+ 1245 | "<=" (. op := SymTab.OpLe; .)
|
|
|
|
|
+ 1246 | ">" (. op := SymTab.OpGt; .)
|
|
|
|
|
+ 1247 | ">=" (. op := SymTab.OpGe; .)
|
|
|
|
|
+ 1248 | "IN" (. op := SymTab.OpIn; .) .
|
|
|
|
|
+ 1249 SimExpr<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
|
|
+ 1250 (. VAR t2, res2: SymTab.TypeIndex;
|
|
|
|
|
+ 1251 op: INTEGER;
|
|
|
|
|
+ 1252 q2, qt: QbeGen.QVal;
|
|
|
|
|
+ 1253 neg, isR: BOOLEAN;
|
|
|
|
|
+ 1254 lw, rw, mw: CARDINAL; .)
|
|
|
|
|
+ 1255 = (. neg := FALSE; .)
|
|
|
|
|
+ 1256 [ "+" | "-" (. neg := TRUE; .) ]
|
|
|
|
|
+ 1257 Term<t, q> (. IF neg THEN
|
|
|
|
|
+ 1258 IF QbeGen.IsImm(q) THEN
|
|
|
|
|
+ 1259 QbeGen.NegFold(q, q)
|
|
|
|
|
+ 1260 ELSE QbeGen.NewTemp(qt);
|
|
|
|
|
+ 1261 QbeGen.NegQ(q, qt,
|
|
|
|
|
+ 1262 SymTab.ClassOf(t)
|
|
|
|
|
+ 1263 = SymTab.ClReal);
|
|
|
|
|
+ 1264 QbeGen.CopyOp(qt, q)
|
|
|
|
|
+ 1265 END
|
|
|
|
|
+ 1266 END; .)
|
|
|
|
|
+ 1267 { AddOp<op> Term<t2, q2>
|
|
|
|
|
+ 1268 (. IF op = SymTab.OpOr THEN
|
|
|
|
|
+ 1269 IF SymTab.BoolCheck(t) & SymTab.BoolCheck(t2) THEN
|
|
|
|
|
+ 1270 t := SymTab.BoolType()
|
|
|
|
|
+ 1271 ELSE SemError(212); t := SymTab.InvalidType END;
|
|
|
|
|
+ 1272 IF t # SymTab.InvalidType THEN
|
|
|
|
|
+ 1273 QbeGen.NewTemp(qt);
|
|
|
|
|
+ 1274 QbeGen.Op3("or", qt, q, q2, FALSE);
|
|
|
|
|
+ 1275 QbeGen.CopyOp(qt, q)
|
|
|
|
|
+ 1276 ELSE QbeGen.CopyOp("0", q)
|
|
|
|
|
+ 1277 END
|
|
|
|
|
+ 1278 ELSIF (t # SymTab.InvalidType) & (t2 # SymTab.InvalidType)
|
|
|
|
|
+ 1279 & (SymTab.ClassOf(t) = SymTab.ClSet)
|
|
|
|
|
+ 1280 & (SymTab.ClassOf(t2) = SymTab.ClSet) THEN
|
|
|
|
|
+ 1281 lw := SymTab.SetWords(t); rw := SymTab.SetWords(t2);
|
|
|
|
|
+ 1282 mw := lw;
|
|
|
|
|
+ 1283 IF rw > mw THEN mw := rw END;
|
|
|
|
|
+ 1284 IF op = SymTab.OpAdd THEN
|
|
|
|
|
+ 1285 QbeGen.SetBinOp(0, q, q2, lw, rw, qt)
|
|
|
|
|
+ 1286 ELSE
|
|
|
|
|
+ 1287 QbeGen.SetBinOp(2, q, q2, lw, rw, qt)
|
|
|
|
|
+ 1288 END;
|
|
|
|
|
+ 1289 t := SymTab.NewSet(
|
|
|
|
|
+ 1290 SymTab.NewSubR(0,
|
|
|
|
|
+ 1291 VAL(INTEGER, mw) * 32 - 1));
|
|
|
|
|
+ 1292 QbeGen.CopyOp(qt, q)
|
|
|
|
|
+ 1293 ELSE
|
|
|
|
|
+ 1294 IF SymTab.ArithCheck(t, t2, FALSE, res2) THEN
|
|
|
|
|
+ 1295 t := res2
|
|
|
|
|
+ 1296 ELSE SemError(211); t := SymTab.InvalidType END;
|
|
|
|
|
+ 1297 isR := SymTab.ClassOf(t) = SymTab.ClReal;
|
|
|
|
|
+ 1298 IF t # SymTab.InvalidType THEN
|
|
|
|
|
+ 1299 QbeGen.NewTemp(qt);
|
|
|
|
|
+ 1300 IF op = SymTab.OpAdd THEN
|
|
|
|
|
+ 1301 QbeGen.Op3("add", qt, q, q2, isR)
|
|
|
|
|
+ 1302 ELSE
|
|
|
|
|
+ 1303 QbeGen.Op3("sub", qt, q, q2, isR)
|
|
|
|
|
+ 1304 END;
|
|
|
|
|
+ 1305 QbeGen.CopyOp(qt, q)
|
|
|
|
|
+ 1306 ELSE QbeGen.CopyOp("0", q)
|
|
|
|
|
+ 1307 END
|
|
|
|
|
+ 1308 END; .) } .
|
|
|
|
|
+ 1309 AddOp<VAR op: INTEGER>
|
|
|
|
|
+ 1310 = "+" (. op := SymTab.OpAdd; .)
|
|
|
|
|
+ 1311 | "-" (. op := SymTab.OpSub; .)
|
|
|
|
|
+ 1312 | "OR" (. op := SymTab.OpOr; .) .
|
|
|
|
|
+ 1313 Term<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
|
|
+ 1314 (. VAR t2, res2: SymTab.TypeIndex;
|
|
|
|
|
+ 1315 op: INTEGER;
|
|
|
|
|
+ 1316 q2, qt: QbeGen.QVal;
|
|
|
|
|
+ 1317 isR: BOOLEAN;
|
|
|
|
|
+ 1318 lw, rw, mw: CARDINAL; .)
|
|
|
|
|
+ 1319 = Fact<t, q> { MulOp<op> Fact<t2, q2>
|
|
|
|
|
+ 1320 (. IF op = SymTab.OpAnd THEN
|
|
|
|
|
+ 1321 IF SymTab.BoolCheck(t) & SymTab.BoolCheck(t2) THEN
|
|
|
|
|
+ 1322 t := SymTab.BoolType()
|
|
|
|
|
+ 1323 ELSE SemError(212); t := SymTab.InvalidType END;
|
|
|
|
|
+ 1324 IF t # SymTab.InvalidType THEN
|
|
|
|
|
+ 1325 QbeGen.NewTemp(qt);
|
|
|
|
|
+ 1326 QbeGen.Op3("and", qt, q, q2, FALSE);
|
|
|
|
|
+ 1327 QbeGen.CopyOp(qt, q)
|
|
|
|
|
+ 1328 ELSE QbeGen.CopyOp("0", q)
|
|
|
|
|
+ 1329 END
|
|
|
|
|
+ 1330 ELSIF (t # SymTab.InvalidType) & (t2 # SymTab.InvalidType)
|
|
|
|
|
+ 1331 & (SymTab.ClassOf(t) = SymTab.ClSet)
|
|
|
|
|
+ 1332 & (SymTab.ClassOf(t2) = SymTab.ClSet) THEN
|
|
|
|
|
+ 1333 lw := SymTab.SetWords(t); rw := SymTab.SetWords(t2);
|
|
|
|
|
+ 1334 mw := lw;
|
|
|
|
|
+ 1335 IF rw > mw THEN mw := rw END;
|
|
|
|
|
+ 1336 IF op = SymTab.OpTimes THEN
|
|
|
|
|
+ 1337 QbeGen.SetBinOp(1, q, q2, lw, rw, qt)
|
|
|
|
|
+ 1338 ELSE
|
|
|
|
|
+ 1339 QbeGen.SetBinOp(3, q, q2, lw, rw, qt)
|
|
|
|
|
+ 1340 END;
|
|
|
|
|
+ 1341 t := SymTab.NewSet(
|
|
|
|
|
+ 1342 SymTab.NewSubR(0,
|
|
|
|
|
+ 1343 VAL(INTEGER, mw) * 32 - 1));
|
|
|
|
|
+ 1344 QbeGen.CopyOp(qt, q)
|
|
|
|
|
+ 1345 ELSE
|
|
|
|
|
+ 1346 IF SymTab.ArithCheck(t, t2,
|
|
|
|
|
+ 1347 (op = SymTab.OpDiv) OR (op = SymTab.OpMod),
|
|
|
|
|
+ 1348 res2) THEN t := res2
|
|
|
|
|
+ 1349 ELSE SemError(211); t := SymTab.InvalidType END;
|
|
|
|
|
+ 1350 isR := SymTab.ClassOf(t) = SymTab.ClReal;
|
|
|
|
|
+ 1351 IF t # SymTab.InvalidType THEN
|
|
|
|
|
+ 1352 QbeGen.NewTemp(qt);
|
|
|
|
|
+ 1353 IF op = SymTab.OpTimes THEN
|
|
|
|
|
+ 1354 QbeGen.Op3("mul", qt, q, q2, isR)
|
|
|
|
|
+ 1355 ELSIF (op = SymTab.OpDiv)
|
|
|
|
|
+ 1356 OR (op = SymTab.OpSlash) THEN
|
|
|
|
|
+ 1357 QbeGen.Op3("div", qt, q, q2, isR)
|
|
|
|
|
+ 1358 ELSE
|
|
|
|
|
+ 1359 QbeGen.Op3("rem", qt, q, q2, isR)
|
|
|
|
|
+ 1360 END;
|
|
|
|
|
+ 1361 QbeGen.CopyOp(qt, q)
|
|
|
|
|
+ 1362 ELSE QbeGen.CopyOp("0", q)
|
|
|
|
|
+ 1363 END
|
|
|
|
|
+ 1364 END; .) } .
|
|
|
|
|
+ 1365 MulOp<VAR op: INTEGER>
|
|
|
|
|
+ 1366 = "*" (. op := SymTab.OpTimes; .)
|
|
|
|
|
+ 1367 | "/" (. op := SymTab.OpSlash; .)
|
|
|
|
|
+ 1368 | "DIV" (. op := SymTab.OpDiv; .)
|
|
|
|
|
+ 1369 | "MOD" (. op := SymTab.OpMod; .)
|
|
|
|
|
+ 1370 | "AND" (. op := SymTab.OpAnd; .) .
|
|
|
|
|
+ 1371 Fact<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
|
|
+ 1372 (. VAR s: ARRAY [0 .. 255] OF CHAR;
|
|
|
|
|
+ 1373 et, dt, t2, st: SymTab.TypeIndex;
|
|
|
|
|
+ 1374 dk: INTEGER;
|
|
|
|
|
+ 1375 qd, q2, sq: QbeGen.QVal;
|
|
|
|
|
+ 1376 qn: SymTab.Name;
|
|
|
|
|
+ 1377 sfx: BOOLEAN; .)
|
|
|
|
|
+ 1378 = integer (. LexString(s);
|
|
|
|
|
+ 1379 QbeGen.NormInt(s, q);
|
|
|
|
|
+ 1380 t := SymTab.IntType(); .)
|
|
|
|
|
+ 1381 | real (. LexString(s);
|
|
|
|
|
+ 1382 QbeGen.NormReal(s, q);
|
|
|
|
|
+ 1383 t := SymTab.RealType(); .)
|
|
|
|
|
+ 1384 | string (. LexString(s);
|
|
|
|
|
+ 1385 IF SymTab.StrLen(s) = 3 THEN
|
|
|
|
|
+ 1386 t := SymTab.CharType();
|
|
|
|
|
+ 1387 QbeGen.IntStr(
|
|
|
|
|
+ 1388 QbeGen.CharVal(s), q)
|
|
|
|
|
+ 1389 ELSE t := SymTab.NewStr();
|
|
|
|
|
+ 1390 QbeGen.DeclStr(s, q)
|
|
|
|
|
+ 1391 END; .)
|
|
|
|
|
+ 1392 | Design<dt, dk, qd, qn, sfx> (. t := dt;
|
|
|
|
|
+ 1393 IF sfx THEN
|
|
|
|
|
+ 1394 IF dt =
|
|
|
|
|
+ 1395 SymTab.InvalidType THEN
|
|
|
|
|
+ 1396 QbeGen.CopyOp("0", q)
|
|
|
|
|
+ 1397 ELSIF (SymTab.ClassOf(dt) =
|
|
|
|
|
+ 1398 SymTab.ClRecord)
|
|
|
|
|
+ 1399 OR (SymTab.ClassOf(dt) =
|
|
|
|
|
+ 1400 SymTab.ClSet)
|
|
|
|
|
+ 1401 OR (SymTab.ClassOf(dt) =
|
|
|
|
|
+ 1402 SymTab.ClClass) THEN
|
|
|
|
|
+ 1403 QbeGen.CopyOp(qd, q)
|
|
|
|
|
+ 1404 ELSE QbeGen.ElemLoad(qd, dt,
|
|
|
|
|
+ 1405 q)
|
|
|
|
|
+ 1406 END
|
|
|
|
|
+ 1407 ELSE QbeGen.CopyOp(qd, q)
|
|
|
|
|
+ 1408 END; .)
|
|
|
|
|
+ 1409 | "(" Expr<et, q> ")" (. t := et; .)
|
|
|
|
|
+ 1410 | SetLit<st, sq> (. t := st;
|
|
|
|
|
+ 1411 QbeGen.CopyOp(sq, q); .)
|
|
|
|
|
+ 1412 | "NOT" Fact<t2, q2> (. IF SymTab.BoolCheck(t2) THEN
|
|
|
|
|
+ 1413 t := SymTab.BoolType()
|
|
|
|
|
+ 1414 ELSE SemError(212);
|
|
|
|
|
+ 1415 t := SymTab.InvalidType END;
|
|
|
|
|
+ 1416 IF t # SymTab.InvalidType THEN
|
|
|
|
|
+ 1417 QbeGen.NotQ(q2, q)
|
|
|
|
|
+ 1418 ELSE QbeGen.CopyOp("0", q)
|
|
|
|
|
+ 1419 END; .) .
|
|
|
|
|
+ 1420 (* Set literals are SET OF [0..255] (8 words); elements validated
|
|
|
|
|
+ 1421 0..255 statically when foldable (222 otherwise), runtime trap
|
|
|
|
|
+ 1422 for computed elements. Ranges always lower via SetRange. *)
|
|
|
|
|
+ 1423 SetLit<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
|
|
+ 1424 = "{" (. t := SymTab.NewSet(
|
|
|
|
|
+ 1425 SymTab.NewSubR(0, 255));
|
|
|
|
|
+ 1426 QbeGen.NewSetTemp(8, q);
|
|
|
|
|
+ 1427 QbeGen.SetZero(q, 8); .)
|
|
|
|
|
+ 1428 [ SetElem<t, q> { "," SetElem<t, q> } ]
|
|
|
|
|
+ 1429 "}" .
|
|
|
|
|
+ 1430 SetElem<st: SymTab.TypeIndex; sq: QbeGen.QVal> (. VAR et, et2: SymTab.TypeIndex;
|
|
|
|
|
+ 1431 qe, q2: QbeGen.QVal;
|
|
|
|
|
+ 1432 v, v2: INTEGER;
|
|
|
|
|
+ 1433 lo: INTEGER;
|
|
|
|
|
+ 1434 span: CARDINAL;
|
|
|
|
|
+ 1435 cl, cl2: INTEGER;
|
|
|
|
|
+ 1436 hasR: BOOLEAN; .)
|
|
|
|
|
+ 1437 = (. hasR := FALSE; .)
|
|
|
|
|
+ 1438 Expr<et, qe>
|
|
|
|
|
+ 1439 [ ".." Expr<et2, q2> (. hasR := TRUE; .) ]
|
|
|
|
|
+ 1440 (. lo := SymTab.SetBaseLo(st);
|
|
|
|
|
+ 1441 span := SymTab.SetCount(st);
|
|
|
|
|
+ 1442 IF (et = SymTab.InvalidType)
|
|
|
|
|
+ 1443 OR (hasR & (et2 =
|
|
|
|
|
+ 1444 SymTab.InvalidType)) THEN
|
|
|
|
|
+ 1445 ELSE cl :=
|
|
|
|
|
+ 1446 SymTab.ClassOf(et);
|
|
|
|
|
+ 1447 IF hasR THEN
|
|
|
|
|
+ 1448 cl2 :=
|
|
|
|
|
+ 1449 SymTab.ClassOf(et2)
|
|
|
|
|
+ 1450 ELSE cl2 := SymTab.ClInt
|
|
|
|
|
+ 1451 END;
|
|
|
|
|
+ 1452 IF ((cl # SymTab.ClInt)
|
|
|
|
|
+ 1453 & (cl # SymTab.ClChar)
|
|
|
|
|
+ 1454 & (cl # SymTab.ClBool))
|
|
|
|
|
+ 1455 OR (hasR &
|
|
|
|
|
+ 1456 ((cl2
|
|
|
|
|
+ 1457 # SymTab.ClInt)
|
|
|
|
|
+ 1458 & (cl2
|
|
|
|
|
+ 1459 # SymTab.ClChar)
|
|
|
|
|
+ 1460 & (cl2
|
|
|
|
|
+ 1461 # SymTab.ClBool))) THEN
|
|
|
|
|
+ 1462 SemError(222)
|
|
|
|
|
+ 1463 ELSIF hasR
|
|
|
|
|
+ 1464 & SymTab.ConstInt(qe, v)
|
|
|
|
|
+ 1465 & SymTab.ConstInt(q2,
|
|
|
|
|
+ 1466 v2)
|
|
|
|
|
+ 1467 & ((v < lo)
|
|
|
|
|
+ 1468 OR (v2 < lo)
|
|
|
|
|
+ 1469 OR (v >= lo +
|
|
|
|
|
+ 1470 VAL(INTEGER, span))
|
|
|
|
|
+ 1471 OR (v2 >= lo +
|
|
|
|
|
+ 1472 VAL(INTEGER, span))
|
|
|
|
|
+ 1473 OR (v > v2)) THEN
|
|
|
|
|
+ 1474 SemError(222)
|
|
|
|
|
+ 1475 ELSIF hasR THEN
|
|
|
|
|
+ 1476 QbeGen.SetRange(sq, qe, q2,
|
|
|
|
|
+ 1477 lo, span)
|
|
|
|
|
+ 1478 ELSIF SymTab.ConstInt(qe,
|
|
|
|
|
+ 1479 v)
|
|
|
|
|
+ 1480 & ((v < lo)
|
|
|
|
|
+ 1481 OR (v >= lo +
|
|
|
|
|
+ 1482 VAL(INTEGER,
|
|
|
|
|
+ 1483 span))) THEN
|
|
|
|
|
+ 1484 SemError(222)
|
|
|
|
|
+ 1485 ELSE QbeGen.SetBit(sq, qe,
|
|
|
|
|
+ 1486 lo, span)
|
|
|
|
|
+ 1487 END
|
|
|
|
|
+ 1488 END; .) .
|
|
|
|
|
+ 1489 GetIdent<VAR n: SymTab.Name>
|
|
|
|
|
+ 1490 = ident (. LexName(n); .) .
|
|
|
|
|
+ 1491
|
|
|
|
|
+ 1492 END M2.
|
|
|
|
|
|
|
|
0 errors
|
|
0 errors
|
|
|
|
|
|