|
|
@@ -2401,1328 +2401,1324 @@ Listing:
|
|
|
2382 fo: INTEGER;
|
|
|
2383 isOpen: BOOLEAN;
|
|
|
2384 qb, cv: QbeGen.QVal;
|
|
|
- 2385 fid, fref: INTEGER;
|
|
|
- 2386 r: BOOLEAN;
|
|
|
- 2387 astDes, astSel: AST.Node;
|
|
|
- 2388 fwd: BOOLEAN; .)
|
|
|
- 2389 = (. methCls := SymTab.InvalidType;
|
|
|
- 2390 QbeGen.CopyOp(n, qn);
|
|
|
- 2391 sfx := FALSE; fwd := FALSE;
|
|
|
- 2392 fid := 0; fref := 0;
|
|
|
- 2393 IF NOT SymTab.Lookup(n) THEN
|
|
|
- 2394 (* a bare method name inside
|
|
|
- 2395 a CLASS IMPLEMENTATION
|
|
|
- 2396 is a sibling call on
|
|
|
- 2397 THIS *)
|
|
|
- 2398 ic := SymTab.CurImplClass();
|
|
|
- 2399 IF (ic #
|
|
|
- 2400 SymTab.InvalidType)
|
|
|
- 2401 AND SymTab.MethodExists(ic, n) THEN
|
|
|
- 2402 sfx := FALSE;
|
|
|
- 2403 QbeGen.CopyOp("@", q);
|
|
|
- 2404 methCls := ic;
|
|
|
- 2405 k := SymTab.KindProc;
|
|
|
- 2406 t := SymTab.InvalidType
|
|
|
- 2407 ELSIF SymTab.InProc() THEN
|
|
|
- 2408 (* not declared yet: a
|
|
|
- 2409 forward reference to a
|
|
|
- 2410 module-level variable
|
|
|
- 2411 declared further down. *)
|
|
|
- 2412 k := SymTab.KindVar;
|
|
|
- 2413 r := SymTab.FwdVarRef(n, k,
|
|
|
- 2414 fref, t);
|
|
|
- 2415 QbeGen.CopyOp("@", q);
|
|
|
- 2416 sfx := TRUE; fwd := TRUE
|
|
|
- 2417 ELSE
|
|
|
- 2418 SemError(201);
|
|
|
- 2419 t :=
|
|
|
- 2420 SymTab.InvalidType;
|
|
|
- 2421 k := -1;
|
|
|
- 2422 QbeGen.CopyOp("0", q)
|
|
|
- 2423 END
|
|
|
- 2424 ELSE
|
|
|
- 2425 t := SymTab.SymType(n);
|
|
|
- 2426 k := SymTab.SymKind(n);
|
|
|
- 2427 IF k = SymTab.KindConst THEN
|
|
|
- 2428 IF SymTab.Equal(n,
|
|
|
- 2429 "TRUE") THEN
|
|
|
- 2430 t := SymTab.BoolType();
|
|
|
- 2431 QbeGen.CopyOp("1", q)
|
|
|
- 2432 ELSIF SymTab.Equal(n,
|
|
|
- 2433 "FALSE") THEN
|
|
|
- 2434 t := SymTab.BoolType();
|
|
|
- 2435 QbeGen.CopyOp("0", q)
|
|
|
- 2436 ELSIF SymTab.Equal(n,
|
|
|
- 2437 "NIL") THEN
|
|
|
- 2438 QbeGen.CopyOp("0", q)
|
|
|
- 2439 ELSE
|
|
|
- 2440 cls :=
|
|
|
- 2441 SymTab.ClassOf(t);
|
|
|
- 2442 IF (t #
|
|
|
- 2443 SymTab.InvalidType)
|
|
|
- 2444 AND ((cls = SymTab.ClInt)
|
|
|
+ 2385 r: BOOLEAN;
|
|
|
+ 2386 astDes, astSel: AST.Node; .)
|
|
|
+ 2387 = (. methCls := SymTab.InvalidType;
|
|
|
+ 2388 QbeGen.CopyOp(n, qn);
|
|
|
+ 2389 sfx := FALSE;
|
|
|
+ 2390 IF NOT SymTab.Lookup(n) THEN
|
|
|
+ 2391 (* a bare method name inside
|
|
|
+ 2392 a CLASS IMPLEMENTATION
|
|
|
+ 2393 is a sibling call on
|
|
|
+ 2394 THIS *)
|
|
|
+ 2395 ic := SymTab.CurImplClass();
|
|
|
+ 2396 IF (ic #
|
|
|
+ 2397 SymTab.InvalidType)
|
|
|
+ 2398 AND SymTab.MethodExists(ic, n) THEN
|
|
|
+ 2399 sfx := FALSE;
|
|
|
+ 2400 QbeGen.CopyOp("@", q);
|
|
|
+ 2401 methCls := ic;
|
|
|
+ 2402 k := SymTab.KindProc;
|
|
|
+ 2403 t := SymTab.InvalidType
|
|
|
+ 2404 ELSIF SymTab.InProc() THEN
|
|
|
+ 2405 (* not declared anywhere
|
|
|
+ 2406 in scope: with bodies
|
|
|
+ 2407 parsed at unit end this
|
|
|
+ 2408 is a genuine 201 (a
|
|
|
+ 2409 nested-local forward is
|
|
|
+ 2410 no longer tolerated). *)
|
|
|
+ 2411 SemError(201);
|
|
|
+ 2412 t := SymTab.InvalidType;
|
|
|
+ 2413 k := -1;
|
|
|
+ 2414 QbeGen.CopyOp("0", q)
|
|
|
+ 2415 ELSE
|
|
|
+ 2416 SemError(201);
|
|
|
+ 2417 t :=
|
|
|
+ 2418 SymTab.InvalidType;
|
|
|
+ 2419 k := -1;
|
|
|
+ 2420 QbeGen.CopyOp("0", q)
|
|
|
+ 2421 END
|
|
|
+ 2422 ELSE
|
|
|
+ 2423 t := SymTab.SymType(n);
|
|
|
+ 2424 k := SymTab.SymKind(n);
|
|
|
+ 2425 IF k = SymTab.KindConst THEN
|
|
|
+ 2426 IF SymTab.Equal(n,
|
|
|
+ 2427 "TRUE") THEN
|
|
|
+ 2428 t := SymTab.BoolType();
|
|
|
+ 2429 QbeGen.CopyOp("1", q)
|
|
|
+ 2430 ELSIF SymTab.Equal(n,
|
|
|
+ 2431 "FALSE") THEN
|
|
|
+ 2432 t := SymTab.BoolType();
|
|
|
+ 2433 QbeGen.CopyOp("0", q)
|
|
|
+ 2434 ELSIF SymTab.Equal(n,
|
|
|
+ 2435 "NIL") THEN
|
|
|
+ 2436 QbeGen.CopyOp("0", q)
|
|
|
+ 2437 ELSE
|
|
|
+ 2438 cls :=
|
|
|
+ 2439 SymTab.ClassOf(t);
|
|
|
+ 2440 IF (t #
|
|
|
+ 2441 SymTab.InvalidType)
|
|
|
+ 2442 AND ((cls = SymTab.ClInt)
|
|
|
+ 2443 OR (cls
|
|
|
+ 2444 = SymTab.ClChar)
|
|
|
2445 OR (cls
|
|
|
- 2446 = SymTab.ClChar)
|
|
|
+ 2446 = SymTab.ClEnum)
|
|
|
2447 OR (cls
|
|
|
- 2448 = SymTab.ClEnum)
|
|
|
+ 2448 = SymTab.ClReal)
|
|
|
2449 OR (cls
|
|
|
- 2450 = SymTab.ClReal)
|
|
|
+ 2450 = SymTab.ClLong)
|
|
|
2451 OR (cls
|
|
|
- 2452 = SymTab.ClLong)
|
|
|
- 2453 OR (cls
|
|
|
- 2454 = SymTab.ClNil)) THEN
|
|
|
- 2455 IF cls = SymTab.ClNil THEN
|
|
|
- 2456 QbeGen.CopyOp("0", q)
|
|
|
- 2457 ELSIF ((cls
|
|
|
- 2458 = SymTab.ClInt)
|
|
|
+ 2452 = SymTab.ClNil)) THEN
|
|
|
+ 2453 IF cls = SymTab.ClNil THEN
|
|
|
+ 2454 QbeGen.CopyOp("0", q)
|
|
|
+ 2455 ELSIF ((cls
|
|
|
+ 2456 = SymTab.ClInt)
|
|
|
+ 2457 OR (cls
|
|
|
+ 2458 = SymTab.ClChar)
|
|
|
2459 OR (cls
|
|
|
- 2460 = SymTab.ClChar)
|
|
|
+ 2460 = SymTab.ClEnum)
|
|
|
2461 OR (cls
|
|
|
- 2462 = SymTab.ClEnum)
|
|
|
- 2463 OR (cls
|
|
|
- 2464 = SymTab.ClLong))
|
|
|
- 2465 AND SymTab.GetSymVal(n, cv)
|
|
|
- 2466 AND QbeGen.IsImm(cv) THEN
|
|
|
- 2467 QbeGen.CopyOp(cv, q)
|
|
|
- 2468 ELSE
|
|
|
- 2469 QbeGen.LoadVar(n,
|
|
|
- 2470 cls = SymTab.ClReal,
|
|
|
- 2471 q)
|
|
|
- 2472 END
|
|
|
- 2473 ELSIF (cls = SymTab.ClArray)
|
|
|
- 2474 OR (cls = SymTab.ClRecord)
|
|
|
- 2475 OR (cls = SymTab.ClClass)
|
|
|
- 2476 OR (cls = SymTab.ClStr)
|
|
|
- 2477 OR (cls = SymTab.ClUStr) THEN
|
|
|
- 2478 (* aggregate constant:
|
|
|
- 2479 its value IS the
|
|
|
- 2480 descriptor address *)
|
|
|
- 2481 IF SymTab.GetSymVal(n, cv) THEN
|
|
|
- 2482 QbeGen.CopyOp(cv, q)
|
|
|
- 2483 ELSE
|
|
|
- 2484 QbeGen.CopyOp("0", q)
|
|
|
- 2485 END
|
|
|
- 2486 ELSE
|
|
|
- 2487 IF t #
|
|
|
- 2488 SymTab.InvalidType THEN
|
|
|
- 2489 SemError(230)
|
|
|
- 2490 END;
|
|
|
- 2491 QbeGen.CopyOp("0", q)
|
|
|
- 2492 END
|
|
|
- 2493 END
|
|
|
- 2494 ELSIF (k = SymTab.KindVar)
|
|
|
- 2495 OR (k = SymTab.KindParam) THEN
|
|
|
- 2496 cls := SymTab.ClassOf(t);
|
|
|
- 2497 IF (cls # SymTab.ClInt)
|
|
|
- 2498 AND (cls # SymTab.ClBool)
|
|
|
- 2499 AND (cls # SymTab.ClChar)
|
|
|
- 2500 AND (cls # SymTab.ClUChar)
|
|
|
- 2501 AND (cls # SymTab.ClEnum)
|
|
|
- 2502 AND (cls # SymTab.ClReal)
|
|
|
- 2503 AND (cls # SymTab.ClPtr)
|
|
|
- 2504 AND (cls # SymTab.ClProc)
|
|
|
- 2505 AND (cls # SymTab.ClLong)
|
|
|
- 2506 AND (cls # SymTab.ClArray)
|
|
|
- 2507 AND (cls # SymTab.ClSet)
|
|
|
- 2508 AND (cls # SymTab.ClRecord)
|
|
|
- 2509 AND (cls # SymTab.ClUStr)
|
|
|
- 2510 AND (cls # SymTab.ClClass) THEN
|
|
|
- 2511 SemError(230);
|
|
|
- 2512 QbeGen.CopyOp("0", q)
|
|
|
- 2513 ELSE QbeGen.CopyOp("@", q)
|
|
|
- 2514 END
|
|
|
- 2515 ELSE QbeGen.CopyOp("0", q);
|
|
|
- 2516 IF k = SymTab.KindImport THEN
|
|
|
- 2517 SemError(230)
|
|
|
- 2518 ELSIF k =
|
|
|
- 2519 SymTab.KindProc THEN
|
|
|
- 2520 (* bare procedure name:
|
|
|
- 2521 a following ArgList
|
|
|
- 2522 makes it a call;
|
|
|
- 2523 otherwise Fact
|
|
|
- 2524 reports 230 *)
|
|
|
- 2525 ELSE
|
|
|
- 2526 IF k = SymTab.KindField THEN
|
|
|
- 2527 IF QbeGen.TopWith(qb) THEN
|
|
|
- 2528 sfx := TRUE
|
|
|
- 2529 ELSE SemError(230);
|
|
|
- 2530 QbeGen.CopyOp("0", q)
|
|
|
- 2531 END
|
|
|
- 2532 END
|
|
|
- 2533 END
|
|
|
- 2534 END
|
|
|
- 2535 END; .)
|
|
|
- 2536 (. astDes := AST.MakeNode(AST.NkDesignator);
|
|
|
- 2537 AST.SetChild(astDes, AST.NChild(astDes), AST.MakeLeaf(AST.NkIdent, n));
|
|
|
- 2538 IF fwd THEN AST.SetOp(astDes, 1) END;
|
|
|
- 2539 IF fwd THEN Check.NoteForward(fref, astDes) END; .)
|
|
|
- 2540 { "[" Expr<it, iq>
|
|
|
- 2541 (. AST.SetChild(astDes, AST.NChild(astDes),
|
|
|
- 2542 AST.MakeUn(AST.NkSelector, AST.SelIndex, astCur)); IF t = SymTab.InvalidType THEN
|
|
|
- 2543 ELSIF SymTab.ClassOf(t) #
|
|
|
- 2544 SymTab.ClArray THEN
|
|
|
- 2545 SemError(217);
|
|
|
- 2546 t := SymTab.InvalidType
|
|
|
- 2547 ELSIF NOT SymTab.IsIntFamily(it)
|
|
|
- 2548 AND (SymTab.ClassOf(it) #
|
|
|
- 2549 SymTab.ClChar)
|
|
|
- 2550 AND (SymTab.ClassOf(it) #
|
|
|
- 2551 SymTab.ClEnum) THEN
|
|
|
- 2552 SemError(218);
|
|
|
- 2553 t := SymTab.InvalidType
|
|
|
- 2554 ELSE
|
|
|
- 2555 eT := SymTab.ArrayElem(t);
|
|
|
- 2556 t := eT; sfx := TRUE
|
|
|
- 2557 END; .)
|
|
|
- 2558 { "," Expr<it, iq>
|
|
|
- 2559 (. AST.SetChild(astDes, AST.NChild(astDes),
|
|
|
- 2560 AST.MakeUn(AST.NkSelector, AST.SelIndex, astCur)); IF t = SymTab.InvalidType THEN
|
|
|
- 2561 ELSIF SymTab.ClassOf(t) #
|
|
|
- 2562 SymTab.ClArray THEN
|
|
|
- 2563 SemError(217);
|
|
|
- 2564 t := SymTab.InvalidType
|
|
|
- 2565 ELSIF NOT SymTab.IsIntFamily(it)
|
|
|
- 2566 AND (SymTab.ClassOf(it) #
|
|
|
- 2567 SymTab.ClChar)
|
|
|
- 2568 AND (SymTab.ClassOf(it) #
|
|
|
- 2569 SymTab.ClEnum) THEN
|
|
|
- 2570 SemError(218);
|
|
|
- 2571 t := SymTab.InvalidType
|
|
|
- 2572 ELSE
|
|
|
- 2573 eT := SymTab.ArrayElem(t);
|
|
|
- 2574 t := eT; sfx := TRUE
|
|
|
- 2575 END; .) }
|
|
|
- 2576 "]"
|
|
|
- 2577 | "." GetIdent<fn>
|
|
|
- 2578 (. astSel := AST.MakeNode(AST.NkSelector);
|
|
|
- 2579 AST.SetOp(astSel, AST.SelField);
|
|
|
- 2580 AST.SetChild(astSel, 0, AST.MakeLeaf(AST.NkIdent, fn));
|
|
|
- 2581 AST.SetChild(astDes, AST.NChild(astDes), astSel); IF k = SymTab.KindModule THEN
|
|
|
- 2582 (* qualified L.x: materialize
|
|
|
- 2583 the export, then load it *)
|
|
|
- 2584 IF NOT SymTab.MaterializeAlias(n,
|
|
|
- 2585 fn, mal) THEN
|
|
|
- 2586 SemError(201);
|
|
|
- 2587 t := SymTab.InvalidType;
|
|
|
- 2588 QbeGen.CopyOp("0", q)
|
|
|
- 2589 ELSE
|
|
|
- 2590 QbeGen.CopyOp(mal, qn);
|
|
|
- 2591 t := SymTab.SymType(mal);
|
|
|
- 2592 k := SymTab.SymKind(mal);
|
|
|
- 2593 sfx := FALSE;
|
|
|
- 2594 IF k = SymTab.KindProc THEN
|
|
|
- 2595 (* call: ArgList supplies
|
|
|
- 2596 the value *)
|
|
|
- 2597 QbeGen.CopyOp("0", q)
|
|
|
- 2598 END
|
|
|
- 2599 END
|
|
|
- 2600 ELSIF t = SymTab.InvalidType THEN
|
|
|
- 2601 ELSIF (SymTab.ClassOf(t) #
|
|
|
- 2602 SymTab.ClRecord)
|
|
|
- 2603 AND (SymTab.ClassOf(t) #
|
|
|
- 2604 SymTab.ClClass) THEN
|
|
|
- 2605 SemError(215);
|
|
|
- 2606 t := SymTab.InvalidType
|
|
|
- 2607 ELSIF (SymTab.ClassOf(t) =
|
|
|
- 2608 SymTab.ClClass)
|
|
|
- 2609 AND SymTab.MethodExists(t, fn) THEN
|
|
|
- 2610 (* obj.Method: bind the
|
|
|
- 2611 method and pass obj as
|
|
|
- 2612 the hidden receiver; q
|
|
|
- 2613 already holds the
|
|
|
- 2614 object's address *)
|
|
|
- 2615 QbeGen.CopyOp(fn, n);
|
|
|
- 2616 QbeGen.CopyOp(fn, qn);
|
|
|
- 2617 methCls := t;
|
|
|
- 2618 k := SymTab.KindProc;
|
|
|
+ 2462 = SymTab.ClLong))
|
|
|
+ 2463 AND SymTab.GetSymVal(n, cv)
|
|
|
+ 2464 AND QbeGen.IsImm(cv) THEN
|
|
|
+ 2465 QbeGen.CopyOp(cv, q)
|
|
|
+ 2466 ELSE
|
|
|
+ 2467 QbeGen.LoadVar(n,
|
|
|
+ 2468 cls = SymTab.ClReal,
|
|
|
+ 2469 q)
|
|
|
+ 2470 END
|
|
|
+ 2471 ELSIF (cls = SymTab.ClArray)
|
|
|
+ 2472 OR (cls = SymTab.ClRecord)
|
|
|
+ 2473 OR (cls = SymTab.ClClass)
|
|
|
+ 2474 OR (cls = SymTab.ClStr)
|
|
|
+ 2475 OR (cls = SymTab.ClUStr) THEN
|
|
|
+ 2476 (* aggregate constant:
|
|
|
+ 2477 its value IS the
|
|
|
+ 2478 descriptor address *)
|
|
|
+ 2479 IF SymTab.GetSymVal(n, cv) THEN
|
|
|
+ 2480 QbeGen.CopyOp(cv, q)
|
|
|
+ 2481 ELSE
|
|
|
+ 2482 QbeGen.CopyOp("0", q)
|
|
|
+ 2483 END
|
|
|
+ 2484 ELSE
|
|
|
+ 2485 IF t #
|
|
|
+ 2486 SymTab.InvalidType THEN
|
|
|
+ 2487 SemError(230)
|
|
|
+ 2488 END;
|
|
|
+ 2489 QbeGen.CopyOp("0", q)
|
|
|
+ 2490 END
|
|
|
+ 2491 END
|
|
|
+ 2492 ELSIF (k = SymTab.KindVar)
|
|
|
+ 2493 OR (k = SymTab.KindParam) THEN
|
|
|
+ 2494 cls := SymTab.ClassOf(t);
|
|
|
+ 2495 IF (cls # SymTab.ClInt)
|
|
|
+ 2496 AND (cls # SymTab.ClBool)
|
|
|
+ 2497 AND (cls # SymTab.ClChar)
|
|
|
+ 2498 AND (cls # SymTab.ClUChar)
|
|
|
+ 2499 AND (cls # SymTab.ClEnum)
|
|
|
+ 2500 AND (cls # SymTab.ClReal)
|
|
|
+ 2501 AND (cls # SymTab.ClPtr)
|
|
|
+ 2502 AND (cls # SymTab.ClProc)
|
|
|
+ 2503 AND (cls # SymTab.ClLong)
|
|
|
+ 2504 AND (cls # SymTab.ClArray)
|
|
|
+ 2505 AND (cls # SymTab.ClSet)
|
|
|
+ 2506 AND (cls # SymTab.ClRecord)
|
|
|
+ 2507 AND (cls # SymTab.ClUStr)
|
|
|
+ 2508 AND (cls # SymTab.ClClass) THEN
|
|
|
+ 2509 SemError(230);
|
|
|
+ 2510 QbeGen.CopyOp("0", q)
|
|
|
+ 2511 ELSE QbeGen.CopyOp("@", q)
|
|
|
+ 2512 END
|
|
|
+ 2513 ELSE QbeGen.CopyOp("0", q);
|
|
|
+ 2514 IF k = SymTab.KindImport THEN
|
|
|
+ 2515 SemError(230)
|
|
|
+ 2516 ELSIF k =
|
|
|
+ 2517 SymTab.KindProc THEN
|
|
|
+ 2518 (* bare procedure name:
|
|
|
+ 2519 a following ArgList
|
|
|
+ 2520 makes it a call;
|
|
|
+ 2521 otherwise Fact
|
|
|
+ 2522 reports 230 *)
|
|
|
+ 2523 ELSE
|
|
|
+ 2524 IF k = SymTab.KindField THEN
|
|
|
+ 2525 IF QbeGen.TopWith(qb) THEN
|
|
|
+ 2526 sfx := TRUE
|
|
|
+ 2527 ELSE SemError(230);
|
|
|
+ 2528 QbeGen.CopyOp("0", q)
|
|
|
+ 2529 END
|
|
|
+ 2530 END
|
|
|
+ 2531 END
|
|
|
+ 2532 END
|
|
|
+ 2533 END; .)
|
|
|
+ 2534 (. astDes := AST.MakeNode(AST.NkDesignator);
|
|
|
+ 2535 AST.SetChild(astDes, AST.NChild(astDes), AST.MakeLeaf(AST.NkIdent, n)); .)
|
|
|
+ 2536 { "[" Expr<it, iq>
|
|
|
+ 2537 (. AST.SetChild(astDes, AST.NChild(astDes),
|
|
|
+ 2538 AST.MakeUn(AST.NkSelector, AST.SelIndex, astCur)); IF t = SymTab.InvalidType THEN
|
|
|
+ 2539 ELSIF SymTab.ClassOf(t) #
|
|
|
+ 2540 SymTab.ClArray THEN
|
|
|
+ 2541 SemError(217);
|
|
|
+ 2542 t := SymTab.InvalidType
|
|
|
+ 2543 ELSIF NOT SymTab.IsIntFamily(it)
|
|
|
+ 2544 AND (SymTab.ClassOf(it) #
|
|
|
+ 2545 SymTab.ClChar)
|
|
|
+ 2546 AND (SymTab.ClassOf(it) #
|
|
|
+ 2547 SymTab.ClEnum) THEN
|
|
|
+ 2548 SemError(218);
|
|
|
+ 2549 t := SymTab.InvalidType
|
|
|
+ 2550 ELSE
|
|
|
+ 2551 eT := SymTab.ArrayElem(t);
|
|
|
+ 2552 t := eT; sfx := TRUE
|
|
|
+ 2553 END; .)
|
|
|
+ 2554 { "," Expr<it, iq>
|
|
|
+ 2555 (. AST.SetChild(astDes, AST.NChild(astDes),
|
|
|
+ 2556 AST.MakeUn(AST.NkSelector, AST.SelIndex, astCur)); IF t = SymTab.InvalidType THEN
|
|
|
+ 2557 ELSIF SymTab.ClassOf(t) #
|
|
|
+ 2558 SymTab.ClArray THEN
|
|
|
+ 2559 SemError(217);
|
|
|
+ 2560 t := SymTab.InvalidType
|
|
|
+ 2561 ELSIF NOT SymTab.IsIntFamily(it)
|
|
|
+ 2562 AND (SymTab.ClassOf(it) #
|
|
|
+ 2563 SymTab.ClChar)
|
|
|
+ 2564 AND (SymTab.ClassOf(it) #
|
|
|
+ 2565 SymTab.ClEnum) THEN
|
|
|
+ 2566 SemError(218);
|
|
|
+ 2567 t := SymTab.InvalidType
|
|
|
+ 2568 ELSE
|
|
|
+ 2569 eT := SymTab.ArrayElem(t);
|
|
|
+ 2570 t := eT; sfx := TRUE
|
|
|
+ 2571 END; .) }
|
|
|
+ 2572 "]"
|
|
|
+ 2573 | "." GetIdent<fn>
|
|
|
+ 2574 (. astSel := AST.MakeNode(AST.NkSelector);
|
|
|
+ 2575 AST.SetOp(astSel, AST.SelField);
|
|
|
+ 2576 AST.SetChild(astSel, 0, AST.MakeLeaf(AST.NkIdent, fn));
|
|
|
+ 2577 AST.SetChild(astDes, AST.NChild(astDes), astSel); IF k = SymTab.KindModule THEN
|
|
|
+ 2578 (* qualified L.x: materialize
|
|
|
+ 2579 the export, then load it *)
|
|
|
+ 2580 IF NOT SymTab.MaterializeAlias(n,
|
|
|
+ 2581 fn, mal) THEN
|
|
|
+ 2582 SemError(201);
|
|
|
+ 2583 t := SymTab.InvalidType;
|
|
|
+ 2584 QbeGen.CopyOp("0", q)
|
|
|
+ 2585 ELSE
|
|
|
+ 2586 QbeGen.CopyOp(mal, qn);
|
|
|
+ 2587 t := SymTab.SymType(mal);
|
|
|
+ 2588 k := SymTab.SymKind(mal);
|
|
|
+ 2589 sfx := FALSE;
|
|
|
+ 2590 IF k = SymTab.KindProc THEN
|
|
|
+ 2591 (* call: ArgList supplies
|
|
|
+ 2592 the value *)
|
|
|
+ 2593 QbeGen.CopyOp("0", q)
|
|
|
+ 2594 END
|
|
|
+ 2595 END
|
|
|
+ 2596 ELSIF t = SymTab.InvalidType THEN
|
|
|
+ 2597 ELSIF (SymTab.ClassOf(t) #
|
|
|
+ 2598 SymTab.ClRecord)
|
|
|
+ 2599 AND (SymTab.ClassOf(t) #
|
|
|
+ 2600 SymTab.ClClass) THEN
|
|
|
+ 2601 SemError(215);
|
|
|
+ 2602 t := SymTab.InvalidType
|
|
|
+ 2603 ELSIF (SymTab.ClassOf(t) =
|
|
|
+ 2604 SymTab.ClClass)
|
|
|
+ 2605 AND SymTab.MethodExists(t, fn) THEN
|
|
|
+ 2606 (* obj.Method: bind the
|
|
|
+ 2607 method and pass obj as
|
|
|
+ 2608 the hidden receiver; q
|
|
|
+ 2609 already holds the
|
|
|
+ 2610 object's address *)
|
|
|
+ 2611 QbeGen.CopyOp(fn, n);
|
|
|
+ 2612 QbeGen.CopyOp(fn, qn);
|
|
|
+ 2613 methCls := t;
|
|
|
+ 2614 k := SymTab.KindProc;
|
|
|
+ 2615 t := SymTab.InvalidType
|
|
|
+ 2616 ELSIF NOT SymTab.FieldExists(t,
|
|
|
+ 2617 fn) THEN
|
|
|
+ 2618 SemError(216);
|
|
|
2619 t := SymTab.InvalidType
|
|
|
- 2620 ELSIF NOT SymTab.FieldExists(t,
|
|
|
- 2621 fn) THEN
|
|
|
- 2622 SemError(216);
|
|
|
- 2623 t := SymTab.InvalidType
|
|
|
- 2624 ELSE
|
|
|
- 2625 t := SymTab.FieldType(t, fn);
|
|
|
- 2626 sfx := TRUE
|
|
|
- 2627 END; .)
|
|
|
- 2628 | "^"
|
|
|
- 2629 (. astSel := AST.MakeNode(AST.NkSelector);
|
|
|
- 2630 AST.SetOp(astSel, AST.SelDeref);
|
|
|
- 2631 AST.SetChild(astDes, AST.NChild(astDes), astSel); IF t = SymTab.InvalidType THEN
|
|
|
- 2632 ELSIF SymTab.ClassOf(t) #
|
|
|
- 2633 SymTab.ClPtr THEN
|
|
|
- 2634 SemError(219);
|
|
|
- 2635 t := SymTab.InvalidType
|
|
|
- 2636 ELSE
|
|
|
- 2637 bt := SymTab.PtrBase(t);
|
|
|
- 2638 IF bt = SymTab.InvalidType THEN
|
|
|
- 2639 ELSE
|
|
|
- 2640 t := bt;
|
|
|
- 2641 sfx := TRUE
|
|
|
- 2642 END
|
|
|
- 2643 END; .) } (. astCur := astDes; .) .
|
|
|
- 2644 (* Result suffix (ISO component after a function call): `F()^`,
|
|
|
- 2645 `F()[i]`, `F().field`. The call result is in t/q with sfx FALSE
|
|
|
- 2646 (a value, or a descriptor address for aggregates); each component
|
|
|
- 2647 descends one level exactly like the Design components. *)
|
|
|
- 2648 ResultComp<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal;
|
|
|
- 2649 VAR sfx: BOOLEAN; VAR node: AST.Node;
|
|
|
- 2650 VAR mname: SymTab.Name; VAR methCls: SymTab.TypeIndex;
|
|
|
- 2651 VAR isM: BOOLEAN> (. VAR it, eT, bt: SymTab.TypeIndex;
|
|
|
- 2652 iq, ql, qlo, qhi, qe, qb:
|
|
|
- 2653 QbeGen.QVal;
|
|
|
- 2654 lo, hi, fo: INTEGER;
|
|
|
- 2655 isOpen: BOOLEAN;
|
|
|
- 2656 fname: SymTab.Name;
|
|
|
- 2657 astWrap, astSel: AST.Node; .)
|
|
|
- 2658 = "[" Expr<it, iq>
|
|
|
- 2659 (. isM := FALSE;
|
|
|
- 2660 IF AST.Kind(node) # AST.NkDesignator THEN
|
|
|
- 2661 astWrap := AST.MakeNode(
|
|
|
- 2662 AST.NkDesignator);
|
|
|
- 2663 AST.SetChild(astWrap, 0, node);
|
|
|
- 2664 node := astWrap
|
|
|
- 2665 END;
|
|
|
- 2666 AST.SetChild(node, AST.NChild(node),
|
|
|
- 2667 AST.MakeUn(AST.NkSelector,
|
|
|
- 2668 AST.SelIndex, astCur)); IF t = SymTab.InvalidType THEN
|
|
|
- 2669 ELSIF SymTab.ClassOf(t) #
|
|
|
- 2670 SymTab.ClArray THEN
|
|
|
- 2671 SemError(217);
|
|
|
- 2672 t := SymTab.InvalidType
|
|
|
- 2673 ELSIF NOT SymTab.IsIntFamily(it)
|
|
|
- 2674 AND (SymTab.ClassOf(it) # SymTab.ClChar)
|
|
|
- 2675 AND (SymTab.ClassOf(it) # SymTab.ClEnum) THEN
|
|
|
- 2676 SemError(218);
|
|
|
- 2677 t := SymTab.InvalidType
|
|
|
- 2678 ELSE
|
|
|
- 2679 eT := SymTab.ArrayElem(t);
|
|
|
- 2680 t := eT; sfx := TRUE
|
|
|
- 2681 END; .)
|
|
|
- 2682 "]"
|
|
|
- 2683 | "." GetIdent<fname>
|
|
|
- 2684 (. isM := FALSE;
|
|
|
- 2685 IF AST.Kind(node) # AST.NkDesignator THEN
|
|
|
- 2686 astWrap := AST.MakeNode(
|
|
|
- 2687 AST.NkDesignator);
|
|
|
- 2688 AST.SetChild(astWrap, 0, node);
|
|
|
- 2689 node := astWrap
|
|
|
- 2690 END;
|
|
|
- 2691 AST.SetChild(node, AST.NChild(node),
|
|
|
- 2692 AST.MakeUn(AST.NkSelector,
|
|
|
- 2693 AST.SelField,
|
|
|
- 2694 AST.MakeLeaf(AST.NkIdent,
|
|
|
- 2695 fname))); IF t = SymTab.InvalidType THEN
|
|
|
- 2696 ELSIF (SymTab.ClassOf(t) #
|
|
|
- 2697 SymTab.ClRecord)
|
|
|
- 2698 AND (SymTab.ClassOf(t) # SymTab.ClClass) THEN
|
|
|
- 2699 SemError(215);
|
|
|
- 2700 t := SymTab.InvalidType
|
|
|
- 2701 ELSIF (SymTab.ClassOf(t) =
|
|
|
- 2702 SymTab.ClClass)
|
|
|
- 2703 AND SymTab.MethodExists(t, fname) THEN
|
|
|
- 2704 (* a method on the call result:
|
|
|
- 2705 a following ArgList makes
|
|
|
- 2706 the call *)
|
|
|
- 2707 mname := fname;
|
|
|
- 2708 methCls := t; isM := TRUE;
|
|
|
- 2709 t := SymTab.InvalidType
|
|
|
- 2710 ELSIF NOT SymTab.FieldExists(t,
|
|
|
- 2711 fname) THEN
|
|
|
- 2712 SemError(216);
|
|
|
- 2713 t := SymTab.InvalidType
|
|
|
- 2714 ELSE
|
|
|
- 2715 t := SymTab.FieldType(t, fname);
|
|
|
- 2716 sfx := TRUE
|
|
|
- 2717 END; .)
|
|
|
- 2718 | "^" (. isM := FALSE;
|
|
|
- 2719 IF AST.Kind(node) # AST.NkDesignator THEN
|
|
|
- 2720 astWrap := AST.MakeNode(
|
|
|
- 2721 AST.NkDesignator);
|
|
|
- 2722 AST.SetChild(astWrap, 0, node);
|
|
|
- 2723 node := astWrap
|
|
|
- 2724 END;
|
|
|
- 2725 astSel := AST.MakeNode(AST.NkSelector);
|
|
|
- 2726 AST.SetOp(astSel, AST.SelDeref);
|
|
|
- 2727 AST.SetChild(node,
|
|
|
- 2728 AST.NChild(node), astSel); IF t = SymTab.InvalidType THEN
|
|
|
- 2729 ELSIF SymTab.ClassOf(t) #
|
|
|
- 2730 SymTab.ClPtr THEN
|
|
|
- 2731 SemError(219);
|
|
|
- 2732 t := SymTab.InvalidType
|
|
|
- 2733 ELSE
|
|
|
- 2734 bt := SymTab.PtrBase(t);
|
|
|
- 2735 IF bt # SymTab.InvalidType THEN
|
|
|
- 2736 t := bt; sfx := TRUE
|
|
|
- 2737 END
|
|
|
- 2738 END; .) .
|
|
|
- 2739 Expr<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
- 2740 (. VAR t2: SymTab.TypeIndex;
|
|
|
- 2741 op: INTEGER;
|
|
|
- 2742 q2, qt, wl: QbeGen.QVal;
|
|
|
- 2743 astA, astB: AST.Node;
|
|
|
- 2744 astOp: INTEGER;
|
|
|
- 2745 astMade: BOOLEAN;
|
|
|
- 2746 isR: BOOLEAN; .)
|
|
|
- 2747 = SimExpr<t, q> (. astA := astCur; astMade := FALSE; .)
|
|
|
- 2748 [ Rel<op> SimExpr<t2, q2>
|
|
|
- 2749 (. astB := astCur; astMade := TRUE;
|
|
|
- 2750 astOp := AST.OpEq;
|
|
|
- 2751 IF op = SymTab.OpNeq1 THEN astOp := AST.OpNe
|
|
|
- 2752 ELSIF op = SymTab.OpNeq2 THEN astOp := AST.OpNe
|
|
|
- 2753 ELSIF op = SymTab.OpLt THEN astOp := AST.OpLt
|
|
|
- 2754 ELSIF op = SymTab.OpLe THEN astOp := AST.OpLe
|
|
|
- 2755 ELSIF op = SymTab.OpGt THEN astOp := AST.OpGt
|
|
|
- 2756 ELSIF op = SymTab.OpGe THEN astOp := AST.OpGe
|
|
|
- 2757 ELSIF op = SymTab.OpIn THEN astOp := AST.OpIn
|
|
|
- 2758 END;
|
|
|
- 2759 IF op = SymTab.OpIn THEN
|
|
|
- 2760 IF SymTab.InCheck(t, t2) THEN
|
|
|
- 2761 IF (t = SymTab.InvalidType)
|
|
|
- 2762 OR (t2 = SymTab.InvalidType) THEN
|
|
|
- 2763 t := SymTab.BoolType(); QbeGen.CopyOp("0", q)
|
|
|
- 2764 ELSE
|
|
|
- 2765 t := SymTab.BoolType(); QbeGen.CopyOp("@", q)
|
|
|
- 2766 END
|
|
|
- 2767 ELSE SemError(222); t := SymTab.InvalidType;
|
|
|
- 2768 QbeGen.CopyOp("0", q)
|
|
|
- 2769 END
|
|
|
- 2770 ELSIF SymTab.RelCheck(t, t2, op) THEN
|
|
|
- 2771 IF (t = SymTab.InvalidType)
|
|
|
- 2772 OR (t2 = SymTab.InvalidType) THEN
|
|
|
- 2773 t := SymTab.BoolType(); QbeGen.CopyOp("0", q)
|
|
|
- 2774 ELSIF (SymTab.ClassOf(t) = SymTab.ClPtr)
|
|
|
- 2775 OR (SymTab.ClassOf(t2) = SymTab.ClPtr) THEN
|
|
|
- 2776 IF (op # SymTab.OpEq) AND (op # SymTab.OpNeq1)
|
|
|
- 2777 AND (op # SymTab.OpNeq2) THEN
|
|
|
- 2778 SemError(213); t := SymTab.InvalidType;
|
|
|
- 2779 QbeGen.CopyOp("0", q)
|
|
|
- 2780 ELSE
|
|
|
- 2781 t := SymTab.BoolType(); QbeGen.CopyOp("@", q)
|
|
|
- 2782 END
|
|
|
- 2783 ELSIF (SymTab.ClassOf(t) = SymTab.ClSet)
|
|
|
- 2784 OR (SymTab.ClassOf(t2) = SymTab.ClSet) THEN
|
|
|
- 2785 t := SymTab.BoolType(); QbeGen.CopyOp("@", q)
|
|
|
- 2786 ELSIF SymTab.StrCompat(t, t2) THEN
|
|
|
- 2787 QbeGen.StrEq(op, q, q2, qt);
|
|
|
- 2788 t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
|
|
|
- 2789 ELSIF SymTab.IsLongFamily(t)
|
|
|
- 2790 OR SymTab.IsLongFamily(t2) THEN
|
|
|
- 2791 t := SymTab.BoolType(); QbeGen.CopyOp("@", q)
|
|
|
- 2792 ELSE
|
|
|
- 2793 t := SymTab.BoolType();
|
|
|
- 2794 QbeGen.CopyOp("@", q)
|
|
|
- 2795 END
|
|
|
- 2796 ELSE SemError(213); t := SymTab.InvalidType;
|
|
|
- 2797 QbeGen.CopyOp("0", q)
|
|
|
- 2798 END;
|
|
|
- 2799 astCur := AST.MakeBin(AST.NkBinExpr, astOp, astA, astB); .) ]
|
|
|
- 2800 (. IF NOT astMade THEN astCur := astA END; .)
|
|
|
- 2801 (. IF astCur # AST.NoNode THEN AST.SetTy(astCur, t) END; .) .
|
|
|
- 2802 Rel<VAR op: INTEGER>
|
|
|
- 2803 = "=" (. op := SymTab.OpEq; .)
|
|
|
- 2804 | "#" (. op := SymTab.OpNeq1; .)
|
|
|
- 2805 | "<" (. op := SymTab.OpLt; .)
|
|
|
- 2806 | "<=" (. op := SymTab.OpLe; .)
|
|
|
- 2807 | ">" (. op := SymTab.OpGt; .)
|
|
|
- 2808 | ">=" (. op := SymTab.OpGe; .)
|
|
|
- 2809 | "IN" (. op := SymTab.OpIn; .) .
|
|
|
- 2810 SimExpr<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
- 2811 (. VAR t2, res2, lt, rt:
|
|
|
- 2812 SymTab.TypeIndex;
|
|
|
- 2813 op: INTEGER;
|
|
|
- 2814 q2, qt, wq, qf, q2a, q2b:
|
|
|
- 2815 QbeGen.QVal;
|
|
|
- 2816 neg, isR, isL, folded:
|
|
|
- 2817 BOOLEAN;
|
|
|
- 2818 fok: BOOLEAN;
|
|
|
- 2819 lw, rw, mw: CARDINAL;
|
|
|
- 2820 lTrue, lNext, lDone, qr, qs: QbeGen.QVal;
|
|
|
- 2821 astA, astB: AST.Node;
|
|
|
- 2822 astSign, astOp: INTEGER; .)
|
|
|
- 2823 = (. neg := FALSE; astSign := 0; .)
|
|
|
- 2824 [ "+" (. neg := TRUE; astSign := 1; .)
|
|
|
- 2825 | "-" (. neg := TRUE; astSign := -1; .) ]
|
|
|
- 2826 Term<t, q> (. astA := astCur;
|
|
|
- 2827 IF neg AND QbeGen.IsImm(q) THEN
|
|
|
- 2828 QbeGen.NegFold(q, q)
|
|
|
- 2829 END;
|
|
|
- 2830 IF astSign < 0 THEN
|
|
|
- 2831 astCur := AST.MakeUn(
|
|
|
- 2832 AST.NkUnary, AST.OpSub, astA);
|
|
|
- 2833 astA := astCur
|
|
|
- 2834 END; .)
|
|
|
- 2835 { AddOp<op>
|
|
|
- 2836 Term<t2, q2> (. astB := astCur; .)
|
|
|
- 2837 (. astOp := AST.OpAdd;
|
|
|
- 2838 IF op = SymTab.OpSub THEN astOp := AST.OpSub
|
|
|
- 2839 ELSIF op = SymTab.OpOr THEN astOp := AST.OpOr END;
|
|
|
- 2840 astA := AST.MakeBin(AST.NkBinExpr, astOp, astA, astB);
|
|
|
- 2841 astCur := astA;
|
|
|
- 2842 IF op = SymTab.OpOr THEN
|
|
|
- 2843 (* short-circuit: if q is true the RHS is skipped *)
|
|
|
- 2844 IF SymTab.BoolCheck(t) AND SymTab.BoolCheck(t2) THEN
|
|
|
- 2845 t := SymTab.BoolType()
|
|
|
- 2846 ELSE SemError(212); t := SymTab.InvalidType END;
|
|
|
- 2847 IF t # SymTab.InvalidType THEN
|
|
|
- 2848 QbeGen.CopyOp("@", q)
|
|
|
- 2849 ELSE QbeGen.CopyOp("0", q)
|
|
|
- 2850 END
|
|
|
- 2851 ELSIF (op = SymTab.OpAdd)
|
|
|
- 2852 AND (SymTab.UStrCompat(t, t2)
|
|
|
+ 2620 ELSE
|
|
|
+ 2621 t := SymTab.FieldType(t, fn);
|
|
|
+ 2622 sfx := TRUE
|
|
|
+ 2623 END; .)
|
|
|
+ 2624 | "^"
|
|
|
+ 2625 (. astSel := AST.MakeNode(AST.NkSelector);
|
|
|
+ 2626 AST.SetOp(astSel, AST.SelDeref);
|
|
|
+ 2627 AST.SetChild(astDes, AST.NChild(astDes), astSel); IF t = SymTab.InvalidType THEN
|
|
|
+ 2628 ELSIF SymTab.ClassOf(t) #
|
|
|
+ 2629 SymTab.ClPtr THEN
|
|
|
+ 2630 SemError(219);
|
|
|
+ 2631 t := SymTab.InvalidType
|
|
|
+ 2632 ELSE
|
|
|
+ 2633 bt := SymTab.PtrBase(t);
|
|
|
+ 2634 IF bt = SymTab.InvalidType THEN
|
|
|
+ 2635 ELSE
|
|
|
+ 2636 t := bt;
|
|
|
+ 2637 sfx := TRUE
|
|
|
+ 2638 END
|
|
|
+ 2639 END; .) } (. astCur := astDes; .) .
|
|
|
+ 2640 (* Result suffix (ISO component after a function call): `F()^`,
|
|
|
+ 2641 `F()[i]`, `F().field`. The call result is in t/q with sfx FALSE
|
|
|
+ 2642 (a value, or a descriptor address for aggregates); each component
|
|
|
+ 2643 descends one level exactly like the Design components. *)
|
|
|
+ 2644 ResultComp<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal;
|
|
|
+ 2645 VAR sfx: BOOLEAN; VAR node: AST.Node;
|
|
|
+ 2646 VAR mname: SymTab.Name; VAR methCls: SymTab.TypeIndex;
|
|
|
+ 2647 VAR isM: BOOLEAN> (. VAR it, eT, bt: SymTab.TypeIndex;
|
|
|
+ 2648 iq, ql, qlo, qhi, qe, qb:
|
|
|
+ 2649 QbeGen.QVal;
|
|
|
+ 2650 lo, hi, fo: INTEGER;
|
|
|
+ 2651 isOpen: BOOLEAN;
|
|
|
+ 2652 fname: SymTab.Name;
|
|
|
+ 2653 astWrap, astSel: AST.Node; .)
|
|
|
+ 2654 = "[" Expr<it, iq>
|
|
|
+ 2655 (. isM := FALSE;
|
|
|
+ 2656 IF AST.Kind(node) # AST.NkDesignator THEN
|
|
|
+ 2657 astWrap := AST.MakeNode(
|
|
|
+ 2658 AST.NkDesignator);
|
|
|
+ 2659 AST.SetChild(astWrap, 0, node);
|
|
|
+ 2660 node := astWrap
|
|
|
+ 2661 END;
|
|
|
+ 2662 AST.SetChild(node, AST.NChild(node),
|
|
|
+ 2663 AST.MakeUn(AST.NkSelector,
|
|
|
+ 2664 AST.SelIndex, astCur)); IF t = SymTab.InvalidType THEN
|
|
|
+ 2665 ELSIF SymTab.ClassOf(t) #
|
|
|
+ 2666 SymTab.ClArray THEN
|
|
|
+ 2667 SemError(217);
|
|
|
+ 2668 t := SymTab.InvalidType
|
|
|
+ 2669 ELSIF NOT SymTab.IsIntFamily(it)
|
|
|
+ 2670 AND (SymTab.ClassOf(it) # SymTab.ClChar)
|
|
|
+ 2671 AND (SymTab.ClassOf(it) # SymTab.ClEnum) THEN
|
|
|
+ 2672 SemError(218);
|
|
|
+ 2673 t := SymTab.InvalidType
|
|
|
+ 2674 ELSE
|
|
|
+ 2675 eT := SymTab.ArrayElem(t);
|
|
|
+ 2676 t := eT; sfx := TRUE
|
|
|
+ 2677 END; .)
|
|
|
+ 2678 "]"
|
|
|
+ 2679 | "." GetIdent<fname>
|
|
|
+ 2680 (. isM := FALSE;
|
|
|
+ 2681 IF AST.Kind(node) # AST.NkDesignator THEN
|
|
|
+ 2682 astWrap := AST.MakeNode(
|
|
|
+ 2683 AST.NkDesignator);
|
|
|
+ 2684 AST.SetChild(astWrap, 0, node);
|
|
|
+ 2685 node := astWrap
|
|
|
+ 2686 END;
|
|
|
+ 2687 AST.SetChild(node, AST.NChild(node),
|
|
|
+ 2688 AST.MakeUn(AST.NkSelector,
|
|
|
+ 2689 AST.SelField,
|
|
|
+ 2690 AST.MakeLeaf(AST.NkIdent,
|
|
|
+ 2691 fname))); IF t = SymTab.InvalidType THEN
|
|
|
+ 2692 ELSIF (SymTab.ClassOf(t) #
|
|
|
+ 2693 SymTab.ClRecord)
|
|
|
+ 2694 AND (SymTab.ClassOf(t) # SymTab.ClClass) THEN
|
|
|
+ 2695 SemError(215);
|
|
|
+ 2696 t := SymTab.InvalidType
|
|
|
+ 2697 ELSIF (SymTab.ClassOf(t) =
|
|
|
+ 2698 SymTab.ClClass)
|
|
|
+ 2699 AND SymTab.MethodExists(t, fname) THEN
|
|
|
+ 2700 (* a method on the call result:
|
|
|
+ 2701 a following ArgList makes
|
|
|
+ 2702 the call *)
|
|
|
+ 2703 mname := fname;
|
|
|
+ 2704 methCls := t; isM := TRUE;
|
|
|
+ 2705 t := SymTab.InvalidType
|
|
|
+ 2706 ELSIF NOT SymTab.FieldExists(t,
|
|
|
+ 2707 fname) THEN
|
|
|
+ 2708 SemError(216);
|
|
|
+ 2709 t := SymTab.InvalidType
|
|
|
+ 2710 ELSE
|
|
|
+ 2711 t := SymTab.FieldType(t, fname);
|
|
|
+ 2712 sfx := TRUE
|
|
|
+ 2713 END; .)
|
|
|
+ 2714 | "^" (. isM := FALSE;
|
|
|
+ 2715 IF AST.Kind(node) # AST.NkDesignator THEN
|
|
|
+ 2716 astWrap := AST.MakeNode(
|
|
|
+ 2717 AST.NkDesignator);
|
|
|
+ 2718 AST.SetChild(astWrap, 0, node);
|
|
|
+ 2719 node := astWrap
|
|
|
+ 2720 END;
|
|
|
+ 2721 astSel := AST.MakeNode(AST.NkSelector);
|
|
|
+ 2722 AST.SetOp(astSel, AST.SelDeref);
|
|
|
+ 2723 AST.SetChild(node,
|
|
|
+ 2724 AST.NChild(node), astSel); IF t = SymTab.InvalidType THEN
|
|
|
+ 2725 ELSIF SymTab.ClassOf(t) #
|
|
|
+ 2726 SymTab.ClPtr THEN
|
|
|
+ 2727 SemError(219);
|
|
|
+ 2728 t := SymTab.InvalidType
|
|
|
+ 2729 ELSE
|
|
|
+ 2730 bt := SymTab.PtrBase(t);
|
|
|
+ 2731 IF bt # SymTab.InvalidType THEN
|
|
|
+ 2732 t := bt; sfx := TRUE
|
|
|
+ 2733 END
|
|
|
+ 2734 END; .) .
|
|
|
+ 2735 Expr<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
+ 2736 (. VAR t2: SymTab.TypeIndex;
|
|
|
+ 2737 op: INTEGER;
|
|
|
+ 2738 q2, qt, wl: QbeGen.QVal;
|
|
|
+ 2739 astA, astB: AST.Node;
|
|
|
+ 2740 astOp: INTEGER;
|
|
|
+ 2741 astMade: BOOLEAN;
|
|
|
+ 2742 isR: BOOLEAN; .)
|
|
|
+ 2743 = SimExpr<t, q> (. astA := astCur; astMade := FALSE; .)
|
|
|
+ 2744 [ Rel<op> SimExpr<t2, q2>
|
|
|
+ 2745 (. astB := astCur; astMade := TRUE;
|
|
|
+ 2746 astOp := AST.OpEq;
|
|
|
+ 2747 IF op = SymTab.OpNeq1 THEN astOp := AST.OpNe
|
|
|
+ 2748 ELSIF op = SymTab.OpNeq2 THEN astOp := AST.OpNe
|
|
|
+ 2749 ELSIF op = SymTab.OpLt THEN astOp := AST.OpLt
|
|
|
+ 2750 ELSIF op = SymTab.OpLe THEN astOp := AST.OpLe
|
|
|
+ 2751 ELSIF op = SymTab.OpGt THEN astOp := AST.OpGt
|
|
|
+ 2752 ELSIF op = SymTab.OpGe THEN astOp := AST.OpGe
|
|
|
+ 2753 ELSIF op = SymTab.OpIn THEN astOp := AST.OpIn
|
|
|
+ 2754 END;
|
|
|
+ 2755 IF op = SymTab.OpIn THEN
|
|
|
+ 2756 IF SymTab.InCheck(t, t2) THEN
|
|
|
+ 2757 IF (t = SymTab.InvalidType)
|
|
|
+ 2758 OR (t2 = SymTab.InvalidType) THEN
|
|
|
+ 2759 t := SymTab.BoolType(); QbeGen.CopyOp("0", q)
|
|
|
+ 2760 ELSE
|
|
|
+ 2761 t := SymTab.BoolType(); QbeGen.CopyOp("@", q)
|
|
|
+ 2762 END
|
|
|
+ 2763 ELSE SemError(222); t := SymTab.InvalidType;
|
|
|
+ 2764 QbeGen.CopyOp("0", q)
|
|
|
+ 2765 END
|
|
|
+ 2766 ELSIF SymTab.RelCheck(t, t2, op) THEN
|
|
|
+ 2767 IF (t = SymTab.InvalidType)
|
|
|
+ 2768 OR (t2 = SymTab.InvalidType) THEN
|
|
|
+ 2769 t := SymTab.BoolType(); QbeGen.CopyOp("0", q)
|
|
|
+ 2770 ELSIF (SymTab.ClassOf(t) = SymTab.ClPtr)
|
|
|
+ 2771 OR (SymTab.ClassOf(t2) = SymTab.ClPtr) THEN
|
|
|
+ 2772 IF (op # SymTab.OpEq) AND (op # SymTab.OpNeq1)
|
|
|
+ 2773 AND (op # SymTab.OpNeq2) THEN
|
|
|
+ 2774 SemError(213); t := SymTab.InvalidType;
|
|
|
+ 2775 QbeGen.CopyOp("0", q)
|
|
|
+ 2776 ELSE
|
|
|
+ 2777 t := SymTab.BoolType(); QbeGen.CopyOp("@", q)
|
|
|
+ 2778 END
|
|
|
+ 2779 ELSIF (SymTab.ClassOf(t) = SymTab.ClSet)
|
|
|
+ 2780 OR (SymTab.ClassOf(t2) = SymTab.ClSet) THEN
|
|
|
+ 2781 t := SymTab.BoolType(); QbeGen.CopyOp("@", q)
|
|
|
+ 2782 ELSIF SymTab.StrCompat(t, t2) THEN
|
|
|
+ 2783 QbeGen.StrEq(op, q, q2, qt);
|
|
|
+ 2784 t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
|
|
|
+ 2785 ELSIF SymTab.IsLongFamily(t)
|
|
|
+ 2786 OR SymTab.IsLongFamily(t2) THEN
|
|
|
+ 2787 t := SymTab.BoolType(); QbeGen.CopyOp("@", q)
|
|
|
+ 2788 ELSE
|
|
|
+ 2789 t := SymTab.BoolType();
|
|
|
+ 2790 QbeGen.CopyOp("@", q)
|
|
|
+ 2791 END
|
|
|
+ 2792 ELSE SemError(213); t := SymTab.InvalidType;
|
|
|
+ 2793 QbeGen.CopyOp("0", q)
|
|
|
+ 2794 END;
|
|
|
+ 2795 astCur := AST.MakeBin(AST.NkBinExpr, astOp, astA, astB); .) ]
|
|
|
+ 2796 (. IF NOT astMade THEN astCur := astA END; .)
|
|
|
+ 2797 (. IF astCur # AST.NoNode THEN AST.SetTy(astCur, t) END; .) .
|
|
|
+ 2798 Rel<VAR op: INTEGER>
|
|
|
+ 2799 = "=" (. op := SymTab.OpEq; .)
|
|
|
+ 2800 | "#" (. op := SymTab.OpNeq1; .)
|
|
|
+ 2801 | "<" (. op := SymTab.OpLt; .)
|
|
|
+ 2802 | "<=" (. op := SymTab.OpLe; .)
|
|
|
+ 2803 | ">" (. op := SymTab.OpGt; .)
|
|
|
+ 2804 | ">=" (. op := SymTab.OpGe; .)
|
|
|
+ 2805 | "IN" (. op := SymTab.OpIn; .) .
|
|
|
+ 2806 SimExpr<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
+ 2807 (. VAR t2, res2, lt, rt:
|
|
|
+ 2808 SymTab.TypeIndex;
|
|
|
+ 2809 op: INTEGER;
|
|
|
+ 2810 q2, qt, wq, qf, q2a, q2b:
|
|
|
+ 2811 QbeGen.QVal;
|
|
|
+ 2812 neg, isR, isL, folded:
|
|
|
+ 2813 BOOLEAN;
|
|
|
+ 2814 fok: BOOLEAN;
|
|
|
+ 2815 lw, rw, mw: CARDINAL;
|
|
|
+ 2816 lTrue, lNext, lDone, qr, qs: QbeGen.QVal;
|
|
|
+ 2817 astA, astB: AST.Node;
|
|
|
+ 2818 astSign, astOp: INTEGER; .)
|
|
|
+ 2819 = (. neg := FALSE; astSign := 0; .)
|
|
|
+ 2820 [ "+" (. neg := TRUE; astSign := 1; .)
|
|
|
+ 2821 | "-" (. neg := TRUE; astSign := -1; .) ]
|
|
|
+ 2822 Term<t, q> (. astA := astCur;
|
|
|
+ 2823 IF neg AND QbeGen.IsImm(q) THEN
|
|
|
+ 2824 QbeGen.NegFold(q, q)
|
|
|
+ 2825 END;
|
|
|
+ 2826 IF astSign < 0 THEN
|
|
|
+ 2827 astCur := AST.MakeUn(
|
|
|
+ 2828 AST.NkUnary, AST.OpSub, astA);
|
|
|
+ 2829 astA := astCur
|
|
|
+ 2830 END; .)
|
|
|
+ 2831 { AddOp<op>
|
|
|
+ 2832 Term<t2, q2> (. astB := astCur; .)
|
|
|
+ 2833 (. astOp := AST.OpAdd;
|
|
|
+ 2834 IF op = SymTab.OpSub THEN astOp := AST.OpSub
|
|
|
+ 2835 ELSIF op = SymTab.OpOr THEN astOp := AST.OpOr END;
|
|
|
+ 2836 astA := AST.MakeBin(AST.NkBinExpr, astOp, astA, astB);
|
|
|
+ 2837 astCur := astA;
|
|
|
+ 2838 IF op = SymTab.OpOr THEN
|
|
|
+ 2839 (* short-circuit: if q is true the RHS is skipped *)
|
|
|
+ 2840 IF SymTab.BoolCheck(t) AND SymTab.BoolCheck(t2) THEN
|
|
|
+ 2841 t := SymTab.BoolType()
|
|
|
+ 2842 ELSE SemError(212); t := SymTab.InvalidType END;
|
|
|
+ 2843 IF t # SymTab.InvalidType THEN
|
|
|
+ 2844 QbeGen.CopyOp("@", q)
|
|
|
+ 2845 ELSE QbeGen.CopyOp("0", q)
|
|
|
+ 2846 END
|
|
|
+ 2847 ELSIF (op = SymTab.OpAdd)
|
|
|
+ 2848 AND (SymTab.UStrCompat(t, t2)
|
|
|
+ 2849 OR ((SymTab.ClassOf(t) = SymTab.ClUChar)
|
|
|
+ 2850 AND (SymTab.ClassOf(t2) = SymTab.ClUStr))
|
|
|
+ 2851 OR ((SymTab.ClassOf(t) = SymTab.ClUStr)
|
|
|
+ 2852 AND (SymTab.ClassOf(t2) = SymTab.ClUChar))
|
|
|
2853 OR ((SymTab.ClassOf(t) = SymTab.ClUChar)
|
|
|
- 2854 AND (SymTab.ClassOf(t2) = SymTab.ClUStr))
|
|
|
- 2855 OR ((SymTab.ClassOf(t) = SymTab.ClUStr)
|
|
|
- 2856 AND (SymTab.ClassOf(t2) = SymTab.ClUChar))
|
|
|
- 2857 OR ((SymTab.ClassOf(t) = SymTab.ClUChar)
|
|
|
- 2858 AND (SymTab.ClassOf(t2) = SymTab.ClUChar))) THEN
|
|
|
- 2859 (* UString concatenation: a UCHAR operand becomes a
|
|
|
- 2860 1-codepoint UString; the result is a descriptor in the
|
|
|
- 2861 shim's concat buffer. Work on copies so neither
|
|
|
- 2862 operand is clobbered. *)
|
|
|
- 2863 t := SymTab.NewUStr();
|
|
|
- 2864 QbeGen.CopyOp("@", q)
|
|
|
- 2865 ELSIF (op = SymTab.OpAdd)
|
|
|
- 2866 AND (SymTab.StrCompat(t, t2)
|
|
|
- 2867 OR (SymTab.IsStrType(t)
|
|
|
- 2868 AND (SymTab.ClassOf(t2) = SymTab.ClChar))
|
|
|
- 2869 OR ((SymTab.ClassOf(t) = SymTab.ClChar)
|
|
|
- 2870 AND SymTab.IsStrType(t2))) THEN
|
|
|
- 2871 (* string concatenation; a CHAR operand becomes a
|
|
|
- 2872 1-character string literal. When both operands are
|
|
|
- 2873 constants, fold to a single string literal so a
|
|
|
- 2874 constructor element stays compile-time. *)
|
|
|
- 2875 QbeGen.StrFold(q, q2, SymTab.ClassOf(t), SymTab.ClassOf(t2),
|
|
|
- 2876 qt, fok);
|
|
|
- 2877 IF fok THEN QbeGen.CopyOp(qt, q)
|
|
|
- 2878 ELSE QbeGen.CopyOp("@", q)
|
|
|
- 2879 END;
|
|
|
- 2880 t := SymTab.NewStr()
|
|
|
- 2881 ELSIF (t # SymTab.InvalidType) AND (t2 # SymTab.InvalidType)
|
|
|
- 2882 AND (SymTab.ClassOf(t) = SymTab.ClSet)
|
|
|
- 2883 AND (SymTab.ClassOf(t2) = SymTab.ClSet) THEN
|
|
|
- 2884 lw := SymTab.SetWords(t); rw := SymTab.SetWords(t2);
|
|
|
- 2885 mw := lw;
|
|
|
- 2886 IF rw > mw THEN mw := rw END;
|
|
|
- 2887 t := SymTab.NewSet(
|
|
|
- 2888 SymTab.NewSubR(0,
|
|
|
- 2889 VAL(INTEGER, mw) * 32 - 1));
|
|
|
- 2890 QbeGen.CopyOp("@", q)
|
|
|
- 2891 ELSE
|
|
|
- 2892 IF SymTab.ArithCheck(t, t2, FALSE, res2) THEN
|
|
|
- 2893 lt := t; rt := t2; t := res2
|
|
|
- 2894 ELSE SemError(211); t := SymTab.InvalidType END;
|
|
|
- 2895 IF t # SymTab.InvalidType THEN
|
|
|
- 2896 isL := SymTab.IsLongFamily(t);
|
|
|
- 2897 isR := SymTab.ClassOf(t) = SymTab.ClReal;
|
|
|
- 2898 folded := FALSE;
|
|
|
- 2899 IF (NOT isL) AND (NOT isR)
|
|
|
- 2900 AND QbeGen.IsImm(q) AND QbeGen.IsImm(q2) THEN
|
|
|
- 2901 IF op = SymTab.OpAdd THEN
|
|
|
- 2902 folded := QbeGen.Fold2(0, q, q2, qf)
|
|
|
- 2903 ELSE
|
|
|
- 2904 folded := QbeGen.Fold2(1, q, q2, qf)
|
|
|
- 2905 END
|
|
|
- 2906 END;
|
|
|
- 2907 IF folded THEN QbeGen.CopyOp(qf, q)
|
|
|
- 2908 ELSE
|
|
|
- 2909 QbeGen.CopyOp("@", q)
|
|
|
- 2910 END
|
|
|
- 2911 ELSE QbeGen.CopyOp("0", q)
|
|
|
- 2912 END
|
|
|
- 2913 END; .) }
|
|
|
- 2914 (. IF astCur # AST.NoNode THEN AST.SetTy(astCur, t) END; .) .
|
|
|
- 2915 AddOp<VAR op: INTEGER>
|
|
|
- 2916 = "+" (. op := SymTab.OpAdd; .)
|
|
|
- 2917 | "-" (. op := SymTab.OpSub; .)
|
|
|
- 2918 | "OR" (. op := SymTab.OpOr; .) .
|
|
|
- 2919 Term<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
- 2920 (. VAR t2, res2, lt, rt:
|
|
|
- 2921 SymTab.TypeIndex;
|
|
|
- 2922 op: INTEGER;
|
|
|
- 2923 q2, qt, wq, qf:
|
|
|
- 2924 QbeGen.QVal;
|
|
|
- 2925 isR, isL, folded: BOOLEAN;
|
|
|
- 2926 lw, rw, mw: CARDINAL;
|
|
|
- 2927 lNext, lFalse, lDone, qr, qs: QbeGen.QVal;
|
|
|
- 2928 astA, astB: AST.Node;
|
|
|
- 2929 astOp: INTEGER; .)
|
|
|
- 2930 = Fact<t, q> (. astA := astCur; .) { MulOp<op>
|
|
|
- 2931 Fact<t2, q2> (. astB := astCur; .)
|
|
|
- 2932 (. astOp := AST.OpMul;
|
|
|
- 2933 IF op = SymTab.OpSlash THEN astOp := AST.OpDiv
|
|
|
- 2934 ELSIF op = SymTab.OpDiv THEN astOp := AST.OpDiv
|
|
|
- 2935 ELSIF op = SymTab.OpMod THEN astOp := AST.OpMod
|
|
|
- 2936 ELSIF op = SymTab.OpAnd THEN astOp := AST.OpAnd END;
|
|
|
- 2937 astA := AST.MakeBin(AST.NkBinExpr, astOp, astA, astB);
|
|
|
- 2938 astCur := astA;
|
|
|
- 2939 IF op = SymTab.OpAnd THEN
|
|
|
- 2940 (* short-circuit: if q is false the RHS is skipped *)
|
|
|
- 2941 IF SymTab.BoolCheck(t) AND SymTab.BoolCheck(t2) THEN
|
|
|
- 2942 t := SymTab.BoolType()
|
|
|
- 2943 ELSE SemError(212); t := SymTab.InvalidType END;
|
|
|
- 2944 IF t # SymTab.InvalidType THEN QbeGen.CopyOp("@", q)
|
|
|
- 2945 ELSE QbeGen.CopyOp("0", q)
|
|
|
- 2946 END
|
|
|
- 2947 ELSIF (t # SymTab.InvalidType) AND (t2 # SymTab.InvalidType)
|
|
|
- 2948 AND (SymTab.ClassOf(t) = SymTab.ClSet)
|
|
|
- 2949 AND (SymTab.ClassOf(t2) = SymTab.ClSet) THEN
|
|
|
- 2950 lw := SymTab.SetWords(t); rw := SymTab.SetWords(t2);
|
|
|
- 2951 mw := lw;
|
|
|
- 2952 IF rw > mw THEN mw := rw END;
|
|
|
- 2953 t := SymTab.NewSet(
|
|
|
- 2954 SymTab.NewSubR(0,
|
|
|
- 2955 VAL(INTEGER, mw) * 32 - 1));
|
|
|
- 2956 QbeGen.CopyOp("@", q)
|
|
|
- 2957 ELSE
|
|
|
- 2958 IF SymTab.ArithCheck(t, t2,
|
|
|
- 2959 (op = SymTab.OpDiv) OR (op = SymTab.OpMod),
|
|
|
- 2960 res2) THEN
|
|
|
- 2961 lt := t; rt := t2; t := res2
|
|
|
- 2962 ELSE SemError(211); t := SymTab.InvalidType END;
|
|
|
- 2963 IF t # SymTab.InvalidType THEN
|
|
|
- 2964 isL := SymTab.IsLongFamily(t);
|
|
|
- 2965 isR := SymTab.ClassOf(t) = SymTab.ClReal;
|
|
|
- 2966 folded := FALSE;
|
|
|
- 2967 IF (NOT isL) AND (NOT isR)
|
|
|
- 2968 AND QbeGen.IsImm(q) AND QbeGen.IsImm(q2) THEN
|
|
|
- 2969 IF op = SymTab.OpTimes THEN
|
|
|
- 2970 folded := QbeGen.Fold2(2, q, q2, qf)
|
|
|
- 2971 ELSIF op = SymTab.OpDiv THEN
|
|
|
- 2972 folded := QbeGen.Fold2(3, q, q2, qf)
|
|
|
- 2973 ELSIF op = SymTab.OpMod THEN
|
|
|
- 2974 folded := QbeGen.Fold2(4, q, q2, qf)
|
|
|
- 2975 END
|
|
|
- 2976 END;
|
|
|
- 2977 IF folded THEN QbeGen.CopyOp(qf, q)
|
|
|
- 2978 ELSE
|
|
|
- 2979 QbeGen.CopyOp("@", q)
|
|
|
- 2980 END
|
|
|
- 2981 ELSE QbeGen.CopyOp("0", q)
|
|
|
- 2982 END
|
|
|
- 2983 END; .) }
|
|
|
- 2984 (. IF astCur # AST.NoNode THEN AST.SetTy(astCur, t) END; .) .
|
|
|
- 2985 MulOp<VAR op: INTEGER>
|
|
|
- 2986 = "*" (. op := SymTab.OpTimes; .)
|
|
|
- 2987 | "/" (. op := SymTab.OpSlash; .)
|
|
|
- 2988 | "DIV" (. op := SymTab.OpDiv; .)
|
|
|
- 2989 | "MOD" (. op := SymTab.OpMod; .)
|
|
|
- 2990 | ( "AND" | "&" ) (. op := SymTab.OpAnd; .) .
|
|
|
- 2991 Fact<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
- 2992 (. VAR s: ARRAY [0 .. 255] OF CHAR;
|
|
|
- 2993 et, dt, t2, st, ct2, et2:
|
|
|
- 2994 SymTab.TypeIndex;
|
|
|
- 2995 dk: INTEGER;
|
|
|
- 2996 qd, q2, sq, qa, qm0, qr, qt:
|
|
|
- 2997 QbeGen.QVal;
|
|
|
- 2998 qn, vn: SymTab.Name;
|
|
|
- 2999 vt: SymTab.TypeIndex;
|
|
|
- 3000 c1, c2: INTEGER;
|
|
|
- 3001 lo, hi: INTEGER;
|
|
|
- 3002 isMax: BOOLEAN;
|
|
|
- 3003 called, isHigh, sfx, isCh,
|
|
|
- 3004 isU, uok, isStr: BOOLEAN;
|
|
|
- 3005 ucp: INTEGER; astIsLit: BOOLEAN;
|
|
|
- 3006 astD: AST.Node;
|
|
|
- 3007 astCall: BOOLEAN;
|
|
|
- 3008 astNode, astNot: AST.Node;
|
|
|
- 3009 j: CARDINAL;
|
|
|
- 3010 astArg2: AST.Node;
|
|
|
- 3011 astBrace: AST.Node;
|
|
|
- 3012 astRes: AST.Node; mname: SymTab.Name; isM: BOOLEAN; .)
|
|
|
- 3013 = (. astIsLit := FALSE; .)
|
|
|
- 3014 ( integer (. LexString(s);
|
|
|
- 3015 QbeGen.NormInt(s, q); IF twoPhase THEN astIsLit := TRUE; astCur := AST.MakeLeaf(AST.NkIntLit, s) END;
|
|
|
- 3016 t := SymTab.IntType(); .)
|
|
|
- 3017 | charConst (. LexString(s);
|
|
|
- 3018 QbeGen.NormLit(s, q, isCh);
|
|
|
- 3019 IF twoPhase THEN
|
|
|
- 3020 astIsLit := TRUE;
|
|
|
- 3021 astCur := AST.MakeLeaf(
|
|
|
- 3022 AST.NkCharLit, s)
|
|
|
- 3023 END;
|
|
|
- 3024 t := SymTab.CharType(); .)
|
|
|
- 3025 | real (. LexString(s);
|
|
|
- 3026 QbeGen.NormReal(s, q);
|
|
|
- 3027 IF twoPhase THEN
|
|
|
- 3028 astIsLit := TRUE;
|
|
|
- 3029 astCur := AST.MakeLeaf(
|
|
|
- 3030 AST.NkRealLit, s)
|
|
|
- 3031 END;
|
|
|
- 3032 t := SymTab.RealType(); .)
|
|
|
- 3033 | string (. LexString(s);
|
|
|
- 3034 IF twoPhase THEN
|
|
|
- 3035 astIsLit := TRUE;
|
|
|
- 3036 astCur := AST.MakeLeaf(
|
|
|
- 3037 AST.NkStrLit, s)
|
|
|
- 3038 END;
|
|
|
- 3039 IF SymTab.StrLen(s) = 3 THEN
|
|
|
- 3040 t := SymTab.CharType();
|
|
|
- 3041 QbeGen.IntStr(
|
|
|
- 3042 QbeGen.CharVal(s), q)
|
|
|
- 3043 ELSE t := SymTab.NewStr();
|
|
|
- 3044 QbeGen.DeclStr(s, q);
|
|
|
- 3045 (* a literal's value IS its
|
|
|
- 3046 static descriptor address *)
|
|
|
- 3047 END; .)
|
|
|
- 3048 | ustring (. LexString(s);
|
|
|
- 3049 IF twoPhase THEN
|
|
|
- 3050 astIsLit := TRUE;
|
|
|
- 3051 astCur := AST.MakeLeaf(
|
|
|
- 3052 AST.NkStrLit, s)
|
|
|
- 3053 END;
|
|
|
- 3054 QbeGen.DeclUStr(s, q, isU, ucp,
|
|
|
- 3055 uok);
|
|
|
- 3056 IF NOT uok THEN
|
|
|
- 3057 SemError(234);
|
|
|
- 3058 t := SymTab.InvalidType
|
|
|
- 3059 ELSIF isU THEN
|
|
|
- 3060 t := SymTab.UCharType();
|
|
|
- 3061 QbeGen.IntStr(ucp, q)
|
|
|
- 3062 ELSE
|
|
|
- 3063 t := SymTab.NewUStr();
|
|
|
- 3064 END; .)
|
|
|
- 3065 | Design<dt, dk, qd, qn, sfx> (. astD := astCur; astCall := FALSE; astBrace := AST.NoNode;
|
|
|
- 3066 astNArgs := 0; called := FALSE;
|
|
|
- 3067 t := dt;
|
|
|
- 3068 IF dk = SymTab.KindConst THEN
|
|
|
- 3069 QbeGen.CopyOp(qd, q)
|
|
|
- 3070 ELSE QbeGen.CopyOp("@", q)
|
|
|
- 3071 END; .)
|
|
|
- 3072 [ TypedBraceLit<dt, q> (. t := dt; astCall := TRUE;
|
|
|
- 3073 astBrace := astCur; .) ]
|
|
|
- 3074 [ ArgList<qn, dt, qd, TRUE, FALSE, methCls, ct2, q2, called>
|
|
|
- 3075 (. astCall := TRUE;
|
|
|
- 3076 astNode := AstCallNode(astD);
|
|
|
- 3077 astRes := astNode;
|
|
|
- 3078 t := ct2;
|
|
|
- 3079 QbeGen.CopyOp(q2, q);
|
|
|
- 3080 sfx := FALSE; .)
|
|
|
- 3081 { ResultComp<t, q, sfx, astRes, mname, methCls, isM>
|
|
|
- 3082 [ (. astNArgs := 0; .)
|
|
|
- 3083 ArgList<mname, t, q, TRUE, FALSE, methCls, ct2, q2, called>
|
|
|
- 3084 (. astNode := AstCallNode(astRes);
|
|
|
- 3085 astRes := astNode;
|
|
|
- 3086 t := ct2;
|
|
|
- 3087 QbeGen.CopyOp(q2, q);
|
|
|
- 3088 sfx := FALSE; .) ] }
|
|
|
- 3089 (. IF sfx THEN
|
|
|
- 3090 IF t = SymTab.InvalidType THEN
|
|
|
- 3091 QbeGen.CopyOp("0", q)
|
|
|
- 3092 ELSIF (SymTab.ClassOf(t) #
|
|
|
- 3093 SymTab.ClRecord)
|
|
|
- 3094 AND (SymTab.ClassOf(t) # SymTab.ClSet)
|
|
|
- 3095 AND (SymTab.ClassOf(t) # SymTab.ClArray)
|
|
|
- 3096 AND (SymTab.ClassOf(t) # SymTab.ClClass) THEN
|
|
|
- 3097 QbeGen.CopyOp("@", q)
|
|
|
- 3098 END
|
|
|
- 3099 END; .) ]
|
|
|
- 3100 (. IF called THEN
|
|
|
- 3101 astCur := astRes
|
|
|
- 3102 ELSIF astCall THEN
|
|
|
- 3103 astCur := astBrace
|
|
|
- 3104 ELSE astCur := astD
|
|
|
- 3105 END;
|
|
|
- 3106 astIsLit := TRUE;
|
|
|
- 3107 IF NOT called
|
|
|
- 3108 AND (dk = SymTab.KindProc) THEN
|
|
|
- 3109 (* bare zero-arg function
|
|
|
- 3110 call (parentheses may be
|
|
|
- 3111 omitted); a proper or
|
|
|
- 3112 parameterised proc here
|
|
|
- 3113 is 230 *)
|
|
|
- 3114 IF (SymTab.ProcNPar(qn) = 0)
|
|
|
- 3115 AND (SymTab.ProcRes(qn) # SymTab.InvalidType) THEN
|
|
|
- 3116 t := SymTab.ProcRes(qn);
|
|
|
- 3117 QbeGen.CopyOp("@", q);
|
|
|
- 3118 astCur := AST.MakeNode(AST.NkCall);
|
|
|
- 3119 AST.SetChild(astCur, 0, astD)
|
|
|
- 3120 ELSE
|
|
|
- 3121 t := SymTab.ProcTypeOf(qn);
|
|
|
- 3122 QbeGen.CopyOp("@", q)
|
|
|
- 3123 END
|
|
|
- 3124 END; .)
|
|
|
- 3125 | ( "HIGH" (. isHigh := TRUE; .)
|
|
|
- 3126 | ( "LEN" | "LENGTH" ) (. isHigh := FALSE; .) )
|
|
|
- 3127 "(" ( Design<dt, dk, qd, qn, sfx> (. isStr := FALSE;
|
|
|
- 3128 isU := FALSE; .)
|
|
|
- 3129 | string (. LexString(s); astCur := AST.MakeLeaf(AST.NkStrLit, s);
|
|
|
- 3130 isStr := TRUE;
|
|
|
- 3131 isU := FALSE;
|
|
|
- 3132 IF SymTab.StrLen(s) = 3 THEN
|
|
|
- 3133 dt := SymTab.CharType();
|
|
|
- 3134 QbeGen.IntStr(QbeGen.CharVal(s),
|
|
|
- 3135 qd)
|
|
|
- 3136 ELSE
|
|
|
- 3137 dt := SymTab.NewStr();
|
|
|
- 3138 QbeGen.DeclStr(s, qd);
|
|
|
- 3139 END;
|
|
|
- 3140 dk := -1;
|
|
|
- 3141 qn[0] := CHR(0); .)
|
|
|
- 3142 | ustring (. LexString(s); astCur := AST.MakeLeaf(AST.NkStrLit, s);
|
|
|
- 3143 QbeGen.DeclUStr(s, qd, isU, ucp,
|
|
|
- 3144 uok);
|
|
|
- 3145 isStr := FALSE;
|
|
|
- 3146 IF NOT uok THEN
|
|
|
- 3147 SemError(234);
|
|
|
- 3148 dt := SymTab.InvalidType
|
|
|
- 3149 ELSIF isU THEN
|
|
|
- 3150 (* one codepoint: a UCHAR;
|
|
|
- 3151 LEN is 1, HIGH is 0 *)
|
|
|
- 3152 dt := SymTab.UCharType();
|
|
|
- 3153 QbeGen.IntStr(ucp, qd)
|
|
|
- 3154 ELSE
|
|
|
- 3155 dt := SymTab.NewUStr();
|
|
|
- 3156 END;
|
|
|
- 3157 dk := -1;
|
|
|
- 3158 qn[0] := CHR(0); .) )
|
|
|
- 3159 ")"
|
|
|
- 3160 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
- 3161 IF isHigh THEN AST.SetChild(astNode, 0,
|
|
|
- 3162 AST.MakeLeaf(AST.NkIdent, "HIGH"))
|
|
|
- 3163 ELSE AST.SetChild(astNode, 0,
|
|
|
- 3164 AST.MakeLeaf(AST.NkIdent, "LEN")) END;
|
|
|
- 3165 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
- 3166 astCur := astNode; astIsLit := TRUE;
|
|
|
- 3167 IF (dt # SymTab.InvalidType)
|
|
|
- 3168 AND (SymTab.ClassOf(dt) = SymTab.ClUStr) THEN
|
|
|
- 3169 (* UString: the count is
|
|
|
- 3170 the descriptor header *)
|
|
|
- 3171 t := SymTab.IntType();
|
|
|
- 3172 QbeGen.CopyOp("@", q)
|
|
|
- 3173 ELSIF (dt # SymTab.InvalidType)
|
|
|
- 3174 AND (SymTab.ClassOf(dt) = SymTab.ClUChar) THEN
|
|
|
- 3175 (* single UCHAR codepoint *)
|
|
|
- 3176 IF isHigh THEN
|
|
|
- 3177 QbeGen.CopyOp("0", qr)
|
|
|
- 3178 ELSE
|
|
|
- 3179 QbeGen.CopyOp("1", qr)
|
|
|
- 3180 END;
|
|
|
- 3181 t := SymTab.IntType();
|
|
|
- 3182 QbeGen.CopyOp(qr, q)
|
|
|
- 3183 ELSIF isStr THEN
|
|
|
- 3184 (* fold: content length at
|
|
|
- 3185 compile time *)
|
|
|
- 3186 IF SymTab.StrLen(s) = 3 THEN
|
|
|
- 3187 c1 := 1
|
|
|
- 3188 ELSE
|
|
|
- 3189 c1 :=
|
|
|
- 3190 SymTab.StrLen(s) - 2
|
|
|
- 3191 END;
|
|
|
- 3192 IF isHigh THEN
|
|
|
- 3193 DEC(c1)
|
|
|
- 3194 END;
|
|
|
- 3195 QbeGen.IntStr(c1, qr);
|
|
|
- 3196 t := SymTab.IntType();
|
|
|
- 3197 QbeGen.CopyOp(qr, q)
|
|
|
- 3198 ELSIF dt = SymTab.InvalidType THEN
|
|
|
- 3199 t := SymTab.InvalidType;
|
|
|
- 3200 QbeGen.CopyOp("0", q)
|
|
|
- 3201 ELSIF SymTab.ClassOf(dt) #
|
|
|
- 3202 SymTab.ClArray THEN
|
|
|
- 3203 SemError(217);
|
|
|
- 3204 t := SymTab.InvalidType;
|
|
|
- 3205 QbeGen.CopyOp("0", q)
|
|
|
- 3206 ELSE
|
|
|
- 3207 IF SymTab.IsOpenArray(dt) THEN
|
|
|
- 3208 t := SymTab.IntType();
|
|
|
- 3209 QbeGen.CopyOp("@", q)
|
|
|
- 3210 ELSE
|
|
|
- 3211 IF isHigh THEN
|
|
|
- 3212 QbeGen.IntStr(
|
|
|
- 3213 SymTab.ArrayHi(dt), qr)
|
|
|
- 3214 ELSE
|
|
|
- 3215 QbeGen.IntStr(VAL(
|
|
|
- 3216 INTEGER,
|
|
|
- 3217 SymTab.ArrayLen(dt)),
|
|
|
- 3218 qr)
|
|
|
- 3219 END;
|
|
|
- 3220 t := SymTab.IntType();
|
|
|
- 3221 QbeGen.CopyOp(qr, q)
|
|
|
- 3222 END
|
|
|
- 3223 END; .)
|
|
|
- 3224 | ( "SIZE" | "TSIZE" ) "(" Design<dt, dk, qd, qn, sfx> ")"
|
|
|
- 3225 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
- 3226 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "SIZE"));
|
|
|
- 3227 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
- 3228 astCur := astNode; astIsLit := TRUE; .)
|
|
|
- 3229 (. IF dt = SymTab.InvalidType THEN
|
|
|
- 3230 t := SymTab.InvalidType;
|
|
|
- 3231 QbeGen.CopyOp("0", q)
|
|
|
- 3232 ELSE
|
|
|
- 3233 QbeGen.IntStr(VAL(INTEGER,
|
|
|
- 3234 SymTab.ObjectSize(dt)), q);
|
|
|
- 3235 t := SymTab.IntType()
|
|
|
- 3236 END; .)
|
|
|
- 3237 | ( "SHIFT" (. isMax := FALSE; .)
|
|
|
- 3238 | "ROTATE" (. isMax := TRUE; .) )
|
|
|
- 3239 "(" Expr<et, q> (. astArg2 := astCur; .) "," Expr<et2, q2> ")"
|
|
|
- 3240 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
- 3241 IF isMax THEN AST.SetChild(astNode, 0,
|
|
|
- 3242 AST.MakeLeaf(AST.NkIdent, "ROTATE"))
|
|
|
- 3243 ELSE AST.SetChild(astNode, 0,
|
|
|
- 3244 AST.MakeLeaf(AST.NkIdent, "SHIFT")) END;
|
|
|
- 3245 IF astArg2 # AST.NoNode THEN AST.SetChild(astNode, 1, astArg2) END;
|
|
|
- 3246 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 2, astCur) END;
|
|
|
- 3247 astCur := astNode; astIsLit := TRUE;
|
|
|
- 3248 (* set shift/rotate: isMax
|
|
|
- 3249 doubles as "rotate" *)
|
|
|
- 3250 IF (et # SymTab.InvalidType)
|
|
|
- 3251 AND (SymTab.ClassOf(et) =
|
|
|
- 3252 SymTab.ClSet) THEN
|
|
|
- 3253 t := et;
|
|
|
- 3254 QbeGen.CopyOp("@", q)
|
|
|
- 3255 ELSE SemError(230);
|
|
|
- 3256 t := SymTab.InvalidType;
|
|
|
- 3257 QbeGen.CopyOp("0", q)
|
|
|
- 3258 END; .)
|
|
|
- 3259 | ( "MIN" (. isMax := FALSE; .)
|
|
|
- 3260 | "MAX" (. isMax := TRUE; .) )
|
|
|
- 3261 "(" Design<dt, dk, qd, qn, sfx> ")"
|
|
|
- 3262 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
- 3263 IF isMax THEN AST.SetChild(astNode, 0,
|
|
|
- 3264 AST.MakeLeaf(AST.NkIdent, "MAX"))
|
|
|
- 3265 ELSE AST.SetChild(astNode, 0,
|
|
|
- 3266 AST.MakeLeaf(AST.NkIdent, "MIN")) END;
|
|
|
- 3267 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
- 3268 astCur := astNode; astIsLit := TRUE;
|
|
|
- 3269 IF (dt # SymTab.InvalidType)
|
|
|
- 3270 AND (SymTab.ClassOf(dt) = SymTab.ClReal) THEN
|
|
|
- 3271 (* REAL/LONGREAL: the
|
|
|
- 3272 implementation bounds *)
|
|
|
- 3273 IF isMax THEN
|
|
|
- 3274 QbeGen.NormReal(
|
|
|
- 3275 "3.402823e38", q)
|
|
|
- 3276 ELSE QbeGen.NormReal(
|
|
|
- 3277 "-3.402823e38", q)
|
|
|
- 3278 END;
|
|
|
- 3279 t := SymTab.RealType()
|
|
|
- 3280 ELSIF (dt #
|
|
|
- 3281 SymTab.InvalidType)
|
|
|
- 3282 AND (SymTab.ClassOf(dt) =
|
|
|
- 3283 SymTab.ClLong) THEN
|
|
|
- 3284 IF isMax THEN
|
|
|
- 3285 QbeGen.CopyOp(
|
|
|
- 3286 "9223372036854775807", q)
|
|
|
- 3287 ELSE QbeGen.CopyOp(
|
|
|
- 3288 "-9223372036854775808", q)
|
|
|
- 3289 END;
|
|
|
- 3290 t := SymTab.LongType()
|
|
|
- 3291 ELSIF SymTab.TypeBounds(dt, lo,
|
|
|
- 3292 hi) THEN
|
|
|
- 3293 IF isMax THEN
|
|
|
- 3294 QbeGen.IntStr(hi, q)
|
|
|
- 3295 ELSE QbeGen.IntStr(lo, q)
|
|
|
- 3296 END;
|
|
|
- 3297 t := SymTab.IntType()
|
|
|
- 3298 ELSE SemError(230);
|
|
|
- 3299 t := SymTab.InvalidType;
|
|
|
- 3300 QbeGen.CopyOp("0", q)
|
|
|
- 3301 END; .)
|
|
|
- 3302 | "ADR" "(" Design<dt, dk, qd, qn, sfx> ")"
|
|
|
- 3303 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
- 3304 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "ADR"));
|
|
|
- 3305 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
- 3306 astCur := astNode; astIsLit := TRUE; .)
|
|
|
- 3307 (. IF dt = SymTab.InvalidType THEN
|
|
|
- 3308 t := SymTab.InvalidType;
|
|
|
- 3309 QbeGen.CopyOp("0", q)
|
|
|
- 3310 ELSE
|
|
|
- 3311 IF sfx
|
|
|
- 3312 OR (dk = SymTab.KindVar)
|
|
|
- 3313 OR (dk = SymTab.KindParam) THEN
|
|
|
- 3314 QbeGen.CopyOp("@", q)
|
|
|
- 3315 ELSE SemError(230);
|
|
|
- 3316 QbeGen.CopyOp("0", q)
|
|
|
- 3317 END;
|
|
|
- 3318 t := SymTab.AddrType()
|
|
|
- 3319 END; .)
|
|
|
- 3320 | "CHR" "(" Expr<et, q> ")"
|
|
|
- 3321 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
- 3322 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "CHR"));
|
|
|
- 3323 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
- 3324 astCur := astNode; astIsLit := TRUE; .)
|
|
|
- 3325 (. IF (et # SymTab.InvalidType)
|
|
|
- 3326 AND NOT SymTab.IsIntFamily(et) THEN
|
|
|
- 3327 SemError(211) END;
|
|
|
- 3328 t := SymTab.CharType(); .)
|
|
|
- 3329 | ( "ORD" | "ORDL" ) "(" Expr<et, q> ")"
|
|
|
- 3330 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
- 3331 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "ORD"));
|
|
|
- 3332 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
- 3333 astCur := astNode; astIsLit := TRUE; .)
|
|
|
- 3334 (. IF et # SymTab.InvalidType THEN
|
|
|
- 3335 IF (SymTab.ClassOf(et) #
|
|
|
- 3336 SymTab.ClChar)
|
|
|
- 3337 AND (SymTab.ClassOf(et) #
|
|
|
- 3338 SymTab.ClBool)
|
|
|
- 3339 AND (SymTab.ClassOf(et) #
|
|
|
- 3340 SymTab.ClEnum)
|
|
|
- 3341 AND NOT SymTab.IsIntFamily(et) THEN
|
|
|
- 3342 SemError(211) END
|
|
|
- 3343 END;
|
|
|
- 3344 t := SymTab.IntType(); .)
|
|
|
- 3345 | "CAP" "(" Expr<et, q> ")"
|
|
|
- 3346 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
- 3347 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "CAP"));
|
|
|
- 3348 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
- 3349 astCur := astNode; astIsLit := TRUE; .)
|
|
|
- 3350 (. QbeGen.CopyOp("@", q);
|
|
|
- 3351 t := SymTab.CharType(); .)
|
|
|
- 3352 | "UCHR" "(" Expr<et, q> ")"
|
|
|
- 3353 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
- 3354 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "UCHR"));
|
|
|
- 3355 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
- 3356 astCur := astNode; astIsLit := TRUE; .)
|
|
|
- 3357 (. (* UCHR: the UCHAR constructor.
|
|
|
- 3358 CHAR -> UCHAR (identity);
|
|
|
- 3359 INTEGER familly -> UCHAR
|
|
|
- 3360 (codepoint value). *)
|
|
|
- 3361 IF (et # SymTab.InvalidType)
|
|
|
- 3362 AND (SymTab.ClassOf(et) # SymTab.ClChar)
|
|
|
- 3363 AND NOT SymTab.IsIntFamily(et) THEN
|
|
|
- 3364 SemError(211) END;
|
|
|
- 3365 t := SymTab.UCharType(); .)
|
|
|
- 3366 | "CHR8" "(" Expr<et, q> ")"
|
|
|
- 3367 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
- 3368 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "CHR8"));
|
|
|
- 3369 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
- 3370 astCur := astNode; astIsLit := TRUE; .)
|
|
|
- 3371 (. IF (et # SymTab.InvalidType)
|
|
|
- 3372 AND (SymTab.ClassOf(et) # SymTab.ClUChar) THEN
|
|
|
- 3373 SemError(211) END;
|
|
|
- 3374 t := SymTab.CharType(); .)
|
|
|
- 3375 | "UORD" "(" Expr<et, q> ")"
|
|
|
- 3376 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
- 3377 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "UORD"));
|
|
|
- 3378 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
- 3379 astCur := astNode; astIsLit := TRUE; .)
|
|
|
- 3380 (. (* UORD(u): the codepoint as a
|
|
|
- 3381 32-bit ordinal (INTEGER),
|
|
|
- 3382 cf. ORD for CHAR. *)
|
|
|
- 3383 IF (et # SymTab.InvalidType)
|
|
|
- 3384 AND (SymTab.ClassOf(et) # SymTab.ClUChar) THEN
|
|
|
- 3385 SemError(211) END;
|
|
|
- 3386 t := SymTab.IntType(); .)
|
|
|
- 3387 | "ABS" "(" Expr<et, q> ")"
|
|
|
- 3388 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
- 3389 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "ABS"));
|
|
|
- 3390 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
- 3391 astCur := astNode; astIsLit := TRUE; .)
|
|
|
- 3392 (. IF (et # SymTab.InvalidType)
|
|
|
- 3393 AND NOT SymTab.IsIntFamily(et)
|
|
|
- 3394 AND (SymTab.ClassOf(et) #
|
|
|
- 3395 SymTab.ClReal) THEN
|
|
|
- 3396 SemError(211)
|
|
|
- 3397 ELSE QbeGen.CopyOp("@", q)
|
|
|
- 3398 END;
|
|
|
- 3399 t := et; .)
|
|
|
- 3400 | "VAL" "(" GetIdent<vn> (. astArg2 := AST.MakeLeaf(AST.NkIdent, vn); .) "," Expr<et, q> ")"
|
|
|
- 3401 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
- 3402 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "VAL"));
|
|
|
- 3403 IF astArg2 # AST.NoNode THEN AST.SetChild(astNode, 1, astArg2) END;
|
|
|
- 3404 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 2, astCur) END;
|
|
|
- 3405 astCur := astNode; astIsLit := TRUE; .)
|
|
|
- 3406 (. IF NOT SymTab.Lookup(vn) THEN
|
|
|
- 3407 SemError(201);
|
|
|
- 3408 t := SymTab.InvalidType
|
|
|
- 3409 ELSE vt := SymTab.SymType(vn);
|
|
|
- 3410 IF vt = SymTab.InvalidType THEN
|
|
|
- 3411 t := SymTab.InvalidType
|
|
|
- 3412 ELSIF et =
|
|
|
- 3413 SymTab.InvalidType THEN
|
|
|
- 3414 t := vt
|
|
|
- 3415 ELSE
|
|
|
- 3416 c1 := SymTab.ClassOf(et);
|
|
|
- 3417 c2 := SymTab.ClassOf(vt);
|
|
|
- 3418 IF (c1 = SymTab.ClInt)
|
|
|
- 3419 AND (c2 = SymTab.ClLong) THEN
|
|
|
- 3420 QbeGen.WidenLong(q, qa);
|
|
|
- 3421 QbeGen.CopyOp(qa, q);
|
|
|
- 3422 t := vt
|
|
|
- 3423 ELSIF (c1 = SymTab.ClLong)
|
|
|
- 3424 AND (c2 = SymTab.ClInt) THEN
|
|
|
- 3425 QbeGen.NarrowLong(q, qa);
|
|
|
- 3426 QbeGen.CopyOp(qa, q);
|
|
|
- 3427 t := vt
|
|
|
- 3428 ELSIF (c1 = SymTab.ClInt)
|
|
|
- 3429 AND (c2 = SymTab.ClReal) THEN
|
|
|
- 3430 QbeGen.ConvIR(q, qa);
|
|
|
- 3431 QbeGen.CopyOp(qa, q);
|
|
|
- 3432 t := vt
|
|
|
- 3433 ELSIF (c1 = SymTab.ClLong)
|
|
|
- 3434 AND (c2 = SymTab.ClReal) THEN
|
|
|
- 3435 QbeGen.ConvLR(q, qa);
|
|
|
- 3436 QbeGen.CopyOp(qa, q);
|
|
|
- 3437 t := vt
|
|
|
- 3438 ELSIF (c1 = SymTab.ClReal)
|
|
|
- 3439 AND (c2 = SymTab.ClInt) THEN
|
|
|
- 3440 QbeGen.ConvRI(q, qa);
|
|
|
- 3441 QbeGen.CopyOp(qa, q);
|
|
|
- 3442 t := vt
|
|
|
- 3443 ELSIF (c1 = SymTab.ClReal)
|
|
|
- 3444 AND (c2 = SymTab.ClLong) THEN
|
|
|
- 3445 QbeGen.ConvRL(q, qa);
|
|
|
- 3446 QbeGen.CopyOp(qa, q);
|
|
|
- 3447 t := vt
|
|
|
- 3448 ELSIF ((c1 = SymTab.ClInt)
|
|
|
+ 2854 AND (SymTab.ClassOf(t2) = SymTab.ClUChar))) THEN
|
|
|
+ 2855 (* UString concatenation: a UCHAR operand becomes a
|
|
|
+ 2856 1-codepoint UString; the result is a descriptor in the
|
|
|
+ 2857 shim's concat buffer. Work on copies so neither
|
|
|
+ 2858 operand is clobbered. *)
|
|
|
+ 2859 t := SymTab.NewUStr();
|
|
|
+ 2860 QbeGen.CopyOp("@", q)
|
|
|
+ 2861 ELSIF (op = SymTab.OpAdd)
|
|
|
+ 2862 AND (SymTab.StrCompat(t, t2)
|
|
|
+ 2863 OR (SymTab.IsStrType(t)
|
|
|
+ 2864 AND (SymTab.ClassOf(t2) = SymTab.ClChar))
|
|
|
+ 2865 OR ((SymTab.ClassOf(t) = SymTab.ClChar)
|
|
|
+ 2866 AND SymTab.IsStrType(t2))) THEN
|
|
|
+ 2867 (* string concatenation; a CHAR operand becomes a
|
|
|
+ 2868 1-character string literal. When both operands are
|
|
|
+ 2869 constants, fold to a single string literal so a
|
|
|
+ 2870 constructor element stays compile-time. *)
|
|
|
+ 2871 QbeGen.StrFold(q, q2, SymTab.ClassOf(t), SymTab.ClassOf(t2),
|
|
|
+ 2872 qt, fok);
|
|
|
+ 2873 IF fok THEN QbeGen.CopyOp(qt, q)
|
|
|
+ 2874 ELSE QbeGen.CopyOp("@", q)
|
|
|
+ 2875 END;
|
|
|
+ 2876 t := SymTab.NewStr()
|
|
|
+ 2877 ELSIF (t # SymTab.InvalidType) AND (t2 # SymTab.InvalidType)
|
|
|
+ 2878 AND (SymTab.ClassOf(t) = SymTab.ClSet)
|
|
|
+ 2879 AND (SymTab.ClassOf(t2) = SymTab.ClSet) THEN
|
|
|
+ 2880 lw := SymTab.SetWords(t); rw := SymTab.SetWords(t2);
|
|
|
+ 2881 mw := lw;
|
|
|
+ 2882 IF rw > mw THEN mw := rw END;
|
|
|
+ 2883 t := SymTab.NewSet(
|
|
|
+ 2884 SymTab.NewSubR(0,
|
|
|
+ 2885 VAL(INTEGER, mw) * 32 - 1));
|
|
|
+ 2886 QbeGen.CopyOp("@", q)
|
|
|
+ 2887 ELSE
|
|
|
+ 2888 IF SymTab.ArithCheck(t, t2, FALSE, res2) THEN
|
|
|
+ 2889 lt := t; rt := t2; t := res2
|
|
|
+ 2890 ELSE SemError(211); t := SymTab.InvalidType END;
|
|
|
+ 2891 IF t # SymTab.InvalidType THEN
|
|
|
+ 2892 isL := SymTab.IsLongFamily(t);
|
|
|
+ 2893 isR := SymTab.ClassOf(t) = SymTab.ClReal;
|
|
|
+ 2894 folded := FALSE;
|
|
|
+ 2895 IF (NOT isL) AND (NOT isR)
|
|
|
+ 2896 AND QbeGen.IsImm(q) AND QbeGen.IsImm(q2) THEN
|
|
|
+ 2897 IF op = SymTab.OpAdd THEN
|
|
|
+ 2898 folded := QbeGen.Fold2(0, q, q2, qf)
|
|
|
+ 2899 ELSE
|
|
|
+ 2900 folded := QbeGen.Fold2(1, q, q2, qf)
|
|
|
+ 2901 END
|
|
|
+ 2902 END;
|
|
|
+ 2903 IF folded THEN QbeGen.CopyOp(qf, q)
|
|
|
+ 2904 ELSE
|
|
|
+ 2905 QbeGen.CopyOp("@", q)
|
|
|
+ 2906 END
|
|
|
+ 2907 ELSE QbeGen.CopyOp("0", q)
|
|
|
+ 2908 END
|
|
|
+ 2909 END; .) }
|
|
|
+ 2910 (. IF astCur # AST.NoNode THEN AST.SetTy(astCur, t) END; .) .
|
|
|
+ 2911 AddOp<VAR op: INTEGER>
|
|
|
+ 2912 = "+" (. op := SymTab.OpAdd; .)
|
|
|
+ 2913 | "-" (. op := SymTab.OpSub; .)
|
|
|
+ 2914 | "OR" (. op := SymTab.OpOr; .) .
|
|
|
+ 2915 Term<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
+ 2916 (. VAR t2, res2, lt, rt:
|
|
|
+ 2917 SymTab.TypeIndex;
|
|
|
+ 2918 op: INTEGER;
|
|
|
+ 2919 q2, qt, wq, qf:
|
|
|
+ 2920 QbeGen.QVal;
|
|
|
+ 2921 isR, isL, folded: BOOLEAN;
|
|
|
+ 2922 lw, rw, mw: CARDINAL;
|
|
|
+ 2923 lNext, lFalse, lDone, qr, qs: QbeGen.QVal;
|
|
|
+ 2924 astA, astB: AST.Node;
|
|
|
+ 2925 astOp: INTEGER; .)
|
|
|
+ 2926 = Fact<t, q> (. astA := astCur; .) { MulOp<op>
|
|
|
+ 2927 Fact<t2, q2> (. astB := astCur; .)
|
|
|
+ 2928 (. astOp := AST.OpMul;
|
|
|
+ 2929 IF op = SymTab.OpSlash THEN astOp := AST.OpDiv
|
|
|
+ 2930 ELSIF op = SymTab.OpDiv THEN astOp := AST.OpDiv
|
|
|
+ 2931 ELSIF op = SymTab.OpMod THEN astOp := AST.OpMod
|
|
|
+ 2932 ELSIF op = SymTab.OpAnd THEN astOp := AST.OpAnd END;
|
|
|
+ 2933 astA := AST.MakeBin(AST.NkBinExpr, astOp, astA, astB);
|
|
|
+ 2934 astCur := astA;
|
|
|
+ 2935 IF op = SymTab.OpAnd THEN
|
|
|
+ 2936 (* short-circuit: if q is false the RHS is skipped *)
|
|
|
+ 2937 IF SymTab.BoolCheck(t) AND SymTab.BoolCheck(t2) THEN
|
|
|
+ 2938 t := SymTab.BoolType()
|
|
|
+ 2939 ELSE SemError(212); t := SymTab.InvalidType END;
|
|
|
+ 2940 IF t # SymTab.InvalidType THEN QbeGen.CopyOp("@", q)
|
|
|
+ 2941 ELSE QbeGen.CopyOp("0", q)
|
|
|
+ 2942 END
|
|
|
+ 2943 ELSIF (t # SymTab.InvalidType) AND (t2 # SymTab.InvalidType)
|
|
|
+ 2944 AND (SymTab.ClassOf(t) = SymTab.ClSet)
|
|
|
+ 2945 AND (SymTab.ClassOf(t2) = SymTab.ClSet) THEN
|
|
|
+ 2946 lw := SymTab.SetWords(t); rw := SymTab.SetWords(t2);
|
|
|
+ 2947 mw := lw;
|
|
|
+ 2948 IF rw > mw THEN mw := rw END;
|
|
|
+ 2949 t := SymTab.NewSet(
|
|
|
+ 2950 SymTab.NewSubR(0,
|
|
|
+ 2951 VAL(INTEGER, mw) * 32 - 1));
|
|
|
+ 2952 QbeGen.CopyOp("@", q)
|
|
|
+ 2953 ELSE
|
|
|
+ 2954 IF SymTab.ArithCheck(t, t2,
|
|
|
+ 2955 (op = SymTab.OpDiv) OR (op = SymTab.OpMod),
|
|
|
+ 2956 res2) THEN
|
|
|
+ 2957 lt := t; rt := t2; t := res2
|
|
|
+ 2958 ELSE SemError(211); t := SymTab.InvalidType END;
|
|
|
+ 2959 IF t # SymTab.InvalidType THEN
|
|
|
+ 2960 isL := SymTab.IsLongFamily(t);
|
|
|
+ 2961 isR := SymTab.ClassOf(t) = SymTab.ClReal;
|
|
|
+ 2962 folded := FALSE;
|
|
|
+ 2963 IF (NOT isL) AND (NOT isR)
|
|
|
+ 2964 AND QbeGen.IsImm(q) AND QbeGen.IsImm(q2) THEN
|
|
|
+ 2965 IF op = SymTab.OpTimes THEN
|
|
|
+ 2966 folded := QbeGen.Fold2(2, q, q2, qf)
|
|
|
+ 2967 ELSIF op = SymTab.OpDiv THEN
|
|
|
+ 2968 folded := QbeGen.Fold2(3, q, q2, qf)
|
|
|
+ 2969 ELSIF op = SymTab.OpMod THEN
|
|
|
+ 2970 folded := QbeGen.Fold2(4, q, q2, qf)
|
|
|
+ 2971 END
|
|
|
+ 2972 END;
|
|
|
+ 2973 IF folded THEN QbeGen.CopyOp(qf, q)
|
|
|
+ 2974 ELSE
|
|
|
+ 2975 QbeGen.CopyOp("@", q)
|
|
|
+ 2976 END
|
|
|
+ 2977 ELSE QbeGen.CopyOp("0", q)
|
|
|
+ 2978 END
|
|
|
+ 2979 END; .) }
|
|
|
+ 2980 (. IF astCur # AST.NoNode THEN AST.SetTy(astCur, t) END; .) .
|
|
|
+ 2981 MulOp<VAR op: INTEGER>
|
|
|
+ 2982 = "*" (. op := SymTab.OpTimes; .)
|
|
|
+ 2983 | "/" (. op := SymTab.OpSlash; .)
|
|
|
+ 2984 | "DIV" (. op := SymTab.OpDiv; .)
|
|
|
+ 2985 | "MOD" (. op := SymTab.OpMod; .)
|
|
|
+ 2986 | ( "AND" | "&" ) (. op := SymTab.OpAnd; .) .
|
|
|
+ 2987 Fact<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
+ 2988 (. VAR s: ARRAY [0 .. 255] OF CHAR;
|
|
|
+ 2989 et, dt, t2, st, ct2, et2:
|
|
|
+ 2990 SymTab.TypeIndex;
|
|
|
+ 2991 dk: INTEGER;
|
|
|
+ 2992 qd, q2, sq, qa, qm0, qr, qt:
|
|
|
+ 2993 QbeGen.QVal;
|
|
|
+ 2994 qn, vn: SymTab.Name;
|
|
|
+ 2995 vt: SymTab.TypeIndex;
|
|
|
+ 2996 c1, c2: INTEGER;
|
|
|
+ 2997 lo, hi: INTEGER;
|
|
|
+ 2998 isMax: BOOLEAN;
|
|
|
+ 2999 called, isHigh, sfx, isCh,
|
|
|
+ 3000 isU, uok, isStr: BOOLEAN;
|
|
|
+ 3001 ucp: INTEGER; astIsLit: BOOLEAN;
|
|
|
+ 3002 astD: AST.Node;
|
|
|
+ 3003 astCall: BOOLEAN;
|
|
|
+ 3004 astNode, astNot: AST.Node;
|
|
|
+ 3005 j: CARDINAL;
|
|
|
+ 3006 astArg2: AST.Node;
|
|
|
+ 3007 astBrace: AST.Node;
|
|
|
+ 3008 astRes: AST.Node; mname: SymTab.Name; isM: BOOLEAN; .)
|
|
|
+ 3009 = (. astIsLit := FALSE; .)
|
|
|
+ 3010 ( integer (. LexString(s);
|
|
|
+ 3011 QbeGen.NormInt(s, q); IF twoPhase THEN astIsLit := TRUE; astCur := AST.MakeLeaf(AST.NkIntLit, s) END;
|
|
|
+ 3012 t := SymTab.IntType(); .)
|
|
|
+ 3013 | charConst (. LexString(s);
|
|
|
+ 3014 QbeGen.NormLit(s, q, isCh);
|
|
|
+ 3015 IF twoPhase THEN
|
|
|
+ 3016 astIsLit := TRUE;
|
|
|
+ 3017 astCur := AST.MakeLeaf(
|
|
|
+ 3018 AST.NkCharLit, s)
|
|
|
+ 3019 END;
|
|
|
+ 3020 t := SymTab.CharType(); .)
|
|
|
+ 3021 | real (. LexString(s);
|
|
|
+ 3022 QbeGen.NormReal(s, q);
|
|
|
+ 3023 IF twoPhase THEN
|
|
|
+ 3024 astIsLit := TRUE;
|
|
|
+ 3025 astCur := AST.MakeLeaf(
|
|
|
+ 3026 AST.NkRealLit, s)
|
|
|
+ 3027 END;
|
|
|
+ 3028 t := SymTab.RealType(); .)
|
|
|
+ 3029 | string (. LexString(s);
|
|
|
+ 3030 IF twoPhase THEN
|
|
|
+ 3031 astIsLit := TRUE;
|
|
|
+ 3032 astCur := AST.MakeLeaf(
|
|
|
+ 3033 AST.NkStrLit, s)
|
|
|
+ 3034 END;
|
|
|
+ 3035 IF SymTab.StrLen(s) = 3 THEN
|
|
|
+ 3036 t := SymTab.CharType();
|
|
|
+ 3037 QbeGen.IntStr(
|
|
|
+ 3038 QbeGen.CharVal(s), q)
|
|
|
+ 3039 ELSE t := SymTab.NewStr();
|
|
|
+ 3040 QbeGen.DeclStr(s, q);
|
|
|
+ 3041 (* a literal's value IS its
|
|
|
+ 3042 static descriptor address *)
|
|
|
+ 3043 END; .)
|
|
|
+ 3044 | ustring (. LexString(s);
|
|
|
+ 3045 IF twoPhase THEN
|
|
|
+ 3046 astIsLit := TRUE;
|
|
|
+ 3047 astCur := AST.MakeLeaf(
|
|
|
+ 3048 AST.NkStrLit, s)
|
|
|
+ 3049 END;
|
|
|
+ 3050 QbeGen.DeclUStr(s, q, isU, ucp,
|
|
|
+ 3051 uok);
|
|
|
+ 3052 IF NOT uok THEN
|
|
|
+ 3053 SemError(234);
|
|
|
+ 3054 t := SymTab.InvalidType
|
|
|
+ 3055 ELSIF isU THEN
|
|
|
+ 3056 t := SymTab.UCharType();
|
|
|
+ 3057 QbeGen.IntStr(ucp, q)
|
|
|
+ 3058 ELSE
|
|
|
+ 3059 t := SymTab.NewUStr();
|
|
|
+ 3060 END; .)
|
|
|
+ 3061 | Design<dt, dk, qd, qn, sfx> (. astD := astCur; astCall := FALSE; astBrace := AST.NoNode;
|
|
|
+ 3062 astNArgs := 0; called := FALSE;
|
|
|
+ 3063 t := dt;
|
|
|
+ 3064 IF dk = SymTab.KindConst THEN
|
|
|
+ 3065 QbeGen.CopyOp(qd, q)
|
|
|
+ 3066 ELSE QbeGen.CopyOp("@", q)
|
|
|
+ 3067 END; .)
|
|
|
+ 3068 [ TypedBraceLit<dt, q> (. t := dt; astCall := TRUE;
|
|
|
+ 3069 astBrace := astCur; .) ]
|
|
|
+ 3070 [ ArgList<qn, dt, qd, TRUE, FALSE, methCls, ct2, q2, called>
|
|
|
+ 3071 (. astCall := TRUE;
|
|
|
+ 3072 astNode := AstCallNode(astD);
|
|
|
+ 3073 astRes := astNode;
|
|
|
+ 3074 t := ct2;
|
|
|
+ 3075 QbeGen.CopyOp(q2, q);
|
|
|
+ 3076 sfx := FALSE; .)
|
|
|
+ 3077 { ResultComp<t, q, sfx, astRes, mname, methCls, isM>
|
|
|
+ 3078 [ (. astNArgs := 0; .)
|
|
|
+ 3079 ArgList<mname, t, q, TRUE, FALSE, methCls, ct2, q2, called>
|
|
|
+ 3080 (. astNode := AstCallNode(astRes);
|
|
|
+ 3081 astRes := astNode;
|
|
|
+ 3082 t := ct2;
|
|
|
+ 3083 QbeGen.CopyOp(q2, q);
|
|
|
+ 3084 sfx := FALSE; .) ] }
|
|
|
+ 3085 (. IF sfx THEN
|
|
|
+ 3086 IF t = SymTab.InvalidType THEN
|
|
|
+ 3087 QbeGen.CopyOp("0", q)
|
|
|
+ 3088 ELSIF (SymTab.ClassOf(t) #
|
|
|
+ 3089 SymTab.ClRecord)
|
|
|
+ 3090 AND (SymTab.ClassOf(t) # SymTab.ClSet)
|
|
|
+ 3091 AND (SymTab.ClassOf(t) # SymTab.ClArray)
|
|
|
+ 3092 AND (SymTab.ClassOf(t) # SymTab.ClClass) THEN
|
|
|
+ 3093 QbeGen.CopyOp("@", q)
|
|
|
+ 3094 END
|
|
|
+ 3095 END; .) ]
|
|
|
+ 3096 (. IF called THEN
|
|
|
+ 3097 astCur := astRes
|
|
|
+ 3098 ELSIF astCall THEN
|
|
|
+ 3099 astCur := astBrace
|
|
|
+ 3100 ELSE astCur := astD
|
|
|
+ 3101 END;
|
|
|
+ 3102 astIsLit := TRUE;
|
|
|
+ 3103 IF NOT called
|
|
|
+ 3104 AND (dk = SymTab.KindProc) THEN
|
|
|
+ 3105 (* bare zero-arg function
|
|
|
+ 3106 call (parentheses may be
|
|
|
+ 3107 omitted); a proper or
|
|
|
+ 3108 parameterised proc here
|
|
|
+ 3109 is 230 *)
|
|
|
+ 3110 IF (SymTab.ProcNPar(qn) = 0)
|
|
|
+ 3111 AND (SymTab.ProcRes(qn) # SymTab.InvalidType) THEN
|
|
|
+ 3112 t := SymTab.ProcRes(qn);
|
|
|
+ 3113 QbeGen.CopyOp("@", q);
|
|
|
+ 3114 astCur := AST.MakeNode(AST.NkCall);
|
|
|
+ 3115 AST.SetChild(astCur, 0, astD)
|
|
|
+ 3116 ELSE
|
|
|
+ 3117 t := SymTab.ProcTypeOf(qn);
|
|
|
+ 3118 QbeGen.CopyOp("@", q)
|
|
|
+ 3119 END
|
|
|
+ 3120 END; .)
|
|
|
+ 3121 | ( "HIGH" (. isHigh := TRUE; .)
|
|
|
+ 3122 | ( "LEN" | "LENGTH" ) (. isHigh := FALSE; .) )
|
|
|
+ 3123 "(" ( Design<dt, dk, qd, qn, sfx> (. isStr := FALSE;
|
|
|
+ 3124 isU := FALSE; .)
|
|
|
+ 3125 | string (. LexString(s); astCur := AST.MakeLeaf(AST.NkStrLit, s);
|
|
|
+ 3126 isStr := TRUE;
|
|
|
+ 3127 isU := FALSE;
|
|
|
+ 3128 IF SymTab.StrLen(s) = 3 THEN
|
|
|
+ 3129 dt := SymTab.CharType();
|
|
|
+ 3130 QbeGen.IntStr(QbeGen.CharVal(s),
|
|
|
+ 3131 qd)
|
|
|
+ 3132 ELSE
|
|
|
+ 3133 dt := SymTab.NewStr();
|
|
|
+ 3134 QbeGen.DeclStr(s, qd);
|
|
|
+ 3135 END;
|
|
|
+ 3136 dk := -1;
|
|
|
+ 3137 qn[0] := CHR(0); .)
|
|
|
+ 3138 | ustring (. LexString(s); astCur := AST.MakeLeaf(AST.NkStrLit, s);
|
|
|
+ 3139 QbeGen.DeclUStr(s, qd, isU, ucp,
|
|
|
+ 3140 uok);
|
|
|
+ 3141 isStr := FALSE;
|
|
|
+ 3142 IF NOT uok THEN
|
|
|
+ 3143 SemError(234);
|
|
|
+ 3144 dt := SymTab.InvalidType
|
|
|
+ 3145 ELSIF isU THEN
|
|
|
+ 3146 (* one codepoint: a UCHAR;
|
|
|
+ 3147 LEN is 1, HIGH is 0 *)
|
|
|
+ 3148 dt := SymTab.UCharType();
|
|
|
+ 3149 QbeGen.IntStr(ucp, qd)
|
|
|
+ 3150 ELSE
|
|
|
+ 3151 dt := SymTab.NewUStr();
|
|
|
+ 3152 END;
|
|
|
+ 3153 dk := -1;
|
|
|
+ 3154 qn[0] := CHR(0); .) )
|
|
|
+ 3155 ")"
|
|
|
+ 3156 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
+ 3157 IF isHigh THEN AST.SetChild(astNode, 0,
|
|
|
+ 3158 AST.MakeLeaf(AST.NkIdent, "HIGH"))
|
|
|
+ 3159 ELSE AST.SetChild(astNode, 0,
|
|
|
+ 3160 AST.MakeLeaf(AST.NkIdent, "LEN")) END;
|
|
|
+ 3161 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
+ 3162 astCur := astNode; astIsLit := TRUE;
|
|
|
+ 3163 IF (dt # SymTab.InvalidType)
|
|
|
+ 3164 AND (SymTab.ClassOf(dt) = SymTab.ClUStr) THEN
|
|
|
+ 3165 (* UString: the count is
|
|
|
+ 3166 the descriptor header *)
|
|
|
+ 3167 t := SymTab.IntType();
|
|
|
+ 3168 QbeGen.CopyOp("@", q)
|
|
|
+ 3169 ELSIF (dt # SymTab.InvalidType)
|
|
|
+ 3170 AND (SymTab.ClassOf(dt) = SymTab.ClUChar) THEN
|
|
|
+ 3171 (* single UCHAR codepoint *)
|
|
|
+ 3172 IF isHigh THEN
|
|
|
+ 3173 QbeGen.CopyOp("0", qr)
|
|
|
+ 3174 ELSE
|
|
|
+ 3175 QbeGen.CopyOp("1", qr)
|
|
|
+ 3176 END;
|
|
|
+ 3177 t := SymTab.IntType();
|
|
|
+ 3178 QbeGen.CopyOp(qr, q)
|
|
|
+ 3179 ELSIF isStr THEN
|
|
|
+ 3180 (* fold: content length at
|
|
|
+ 3181 compile time *)
|
|
|
+ 3182 IF SymTab.StrLen(s) = 3 THEN
|
|
|
+ 3183 c1 := 1
|
|
|
+ 3184 ELSE
|
|
|
+ 3185 c1 :=
|
|
|
+ 3186 SymTab.StrLen(s) - 2
|
|
|
+ 3187 END;
|
|
|
+ 3188 IF isHigh THEN
|
|
|
+ 3189 DEC(c1)
|
|
|
+ 3190 END;
|
|
|
+ 3191 QbeGen.IntStr(c1, qr);
|
|
|
+ 3192 t := SymTab.IntType();
|
|
|
+ 3193 QbeGen.CopyOp(qr, q)
|
|
|
+ 3194 ELSIF dt = SymTab.InvalidType THEN
|
|
|
+ 3195 t := SymTab.InvalidType;
|
|
|
+ 3196 QbeGen.CopyOp("0", q)
|
|
|
+ 3197 ELSIF SymTab.ClassOf(dt) #
|
|
|
+ 3198 SymTab.ClArray THEN
|
|
|
+ 3199 SemError(217);
|
|
|
+ 3200 t := SymTab.InvalidType;
|
|
|
+ 3201 QbeGen.CopyOp("0", q)
|
|
|
+ 3202 ELSE
|
|
|
+ 3203 IF SymTab.IsOpenArray(dt) THEN
|
|
|
+ 3204 t := SymTab.IntType();
|
|
|
+ 3205 QbeGen.CopyOp("@", q)
|
|
|
+ 3206 ELSE
|
|
|
+ 3207 IF isHigh THEN
|
|
|
+ 3208 QbeGen.IntStr(
|
|
|
+ 3209 SymTab.ArrayHi(dt), qr)
|
|
|
+ 3210 ELSE
|
|
|
+ 3211 QbeGen.IntStr(VAL(
|
|
|
+ 3212 INTEGER,
|
|
|
+ 3213 SymTab.ArrayLen(dt)),
|
|
|
+ 3214 qr)
|
|
|
+ 3215 END;
|
|
|
+ 3216 t := SymTab.IntType();
|
|
|
+ 3217 QbeGen.CopyOp(qr, q)
|
|
|
+ 3218 END
|
|
|
+ 3219 END; .)
|
|
|
+ 3220 | ( "SIZE" | "TSIZE" ) "(" Design<dt, dk, qd, qn, sfx> ")"
|
|
|
+ 3221 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
+ 3222 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "SIZE"));
|
|
|
+ 3223 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
+ 3224 astCur := astNode; astIsLit := TRUE; .)
|
|
|
+ 3225 (. IF dt = SymTab.InvalidType THEN
|
|
|
+ 3226 t := SymTab.InvalidType;
|
|
|
+ 3227 QbeGen.CopyOp("0", q)
|
|
|
+ 3228 ELSE
|
|
|
+ 3229 QbeGen.IntStr(VAL(INTEGER,
|
|
|
+ 3230 SymTab.ObjectSize(dt)), q);
|
|
|
+ 3231 t := SymTab.IntType()
|
|
|
+ 3232 END; .)
|
|
|
+ 3233 | ( "SHIFT" (. isMax := FALSE; .)
|
|
|
+ 3234 | "ROTATE" (. isMax := TRUE; .) )
|
|
|
+ 3235 "(" Expr<et, q> (. astArg2 := astCur; .) "," Expr<et2, q2> ")"
|
|
|
+ 3236 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
+ 3237 IF isMax THEN AST.SetChild(astNode, 0,
|
|
|
+ 3238 AST.MakeLeaf(AST.NkIdent, "ROTATE"))
|
|
|
+ 3239 ELSE AST.SetChild(astNode, 0,
|
|
|
+ 3240 AST.MakeLeaf(AST.NkIdent, "SHIFT")) END;
|
|
|
+ 3241 IF astArg2 # AST.NoNode THEN AST.SetChild(astNode, 1, astArg2) END;
|
|
|
+ 3242 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 2, astCur) END;
|
|
|
+ 3243 astCur := astNode; astIsLit := TRUE;
|
|
|
+ 3244 (* set shift/rotate: isMax
|
|
|
+ 3245 doubles as "rotate" *)
|
|
|
+ 3246 IF (et # SymTab.InvalidType)
|
|
|
+ 3247 AND (SymTab.ClassOf(et) =
|
|
|
+ 3248 SymTab.ClSet) THEN
|
|
|
+ 3249 t := et;
|
|
|
+ 3250 QbeGen.CopyOp("@", q)
|
|
|
+ 3251 ELSE SemError(230);
|
|
|
+ 3252 t := SymTab.InvalidType;
|
|
|
+ 3253 QbeGen.CopyOp("0", q)
|
|
|
+ 3254 END; .)
|
|
|
+ 3255 | ( "MIN" (. isMax := FALSE; .)
|
|
|
+ 3256 | "MAX" (. isMax := TRUE; .) )
|
|
|
+ 3257 "(" Design<dt, dk, qd, qn, sfx> ")"
|
|
|
+ 3258 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
+ 3259 IF isMax THEN AST.SetChild(astNode, 0,
|
|
|
+ 3260 AST.MakeLeaf(AST.NkIdent, "MAX"))
|
|
|
+ 3261 ELSE AST.SetChild(astNode, 0,
|
|
|
+ 3262 AST.MakeLeaf(AST.NkIdent, "MIN")) END;
|
|
|
+ 3263 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
+ 3264 astCur := astNode; astIsLit := TRUE;
|
|
|
+ 3265 IF (dt # SymTab.InvalidType)
|
|
|
+ 3266 AND (SymTab.ClassOf(dt) = SymTab.ClReal) THEN
|
|
|
+ 3267 (* REAL/LONGREAL: the
|
|
|
+ 3268 implementation bounds *)
|
|
|
+ 3269 IF isMax THEN
|
|
|
+ 3270 QbeGen.NormReal(
|
|
|
+ 3271 "3.402823e38", q)
|
|
|
+ 3272 ELSE QbeGen.NormReal(
|
|
|
+ 3273 "-3.402823e38", q)
|
|
|
+ 3274 END;
|
|
|
+ 3275 t := SymTab.RealType()
|
|
|
+ 3276 ELSIF (dt #
|
|
|
+ 3277 SymTab.InvalidType)
|
|
|
+ 3278 AND (SymTab.ClassOf(dt) =
|
|
|
+ 3279 SymTab.ClLong) THEN
|
|
|
+ 3280 IF isMax THEN
|
|
|
+ 3281 QbeGen.CopyOp(
|
|
|
+ 3282 "9223372036854775807", q)
|
|
|
+ 3283 ELSE QbeGen.CopyOp(
|
|
|
+ 3284 "-9223372036854775808", q)
|
|
|
+ 3285 END;
|
|
|
+ 3286 t := SymTab.LongType()
|
|
|
+ 3287 ELSIF SymTab.TypeBounds(dt, lo,
|
|
|
+ 3288 hi) THEN
|
|
|
+ 3289 IF isMax THEN
|
|
|
+ 3290 QbeGen.IntStr(hi, q)
|
|
|
+ 3291 ELSE QbeGen.IntStr(lo, q)
|
|
|
+ 3292 END;
|
|
|
+ 3293 t := SymTab.IntType()
|
|
|
+ 3294 ELSE SemError(230);
|
|
|
+ 3295 t := SymTab.InvalidType;
|
|
|
+ 3296 QbeGen.CopyOp("0", q)
|
|
|
+ 3297 END; .)
|
|
|
+ 3298 | "ADR" "(" Design<dt, dk, qd, qn, sfx> ")"
|
|
|
+ 3299 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
+ 3300 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "ADR"));
|
|
|
+ 3301 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
+ 3302 astCur := astNode; astIsLit := TRUE; .)
|
|
|
+ 3303 (. IF dt = SymTab.InvalidType THEN
|
|
|
+ 3304 t := SymTab.InvalidType;
|
|
|
+ 3305 QbeGen.CopyOp("0", q)
|
|
|
+ 3306 ELSE
|
|
|
+ 3307 IF sfx
|
|
|
+ 3308 OR (dk = SymTab.KindVar)
|
|
|
+ 3309 OR (dk = SymTab.KindParam) THEN
|
|
|
+ 3310 QbeGen.CopyOp("@", q)
|
|
|
+ 3311 ELSE SemError(230);
|
|
|
+ 3312 QbeGen.CopyOp("0", q)
|
|
|
+ 3313 END;
|
|
|
+ 3314 t := SymTab.AddrType()
|
|
|
+ 3315 END; .)
|
|
|
+ 3316 | "CHR" "(" Expr<et, q> ")"
|
|
|
+ 3317 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
+ 3318 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "CHR"));
|
|
|
+ 3319 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
+ 3320 astCur := astNode; astIsLit := TRUE; .)
|
|
|
+ 3321 (. IF (et # SymTab.InvalidType)
|
|
|
+ 3322 AND NOT SymTab.IsIntFamily(et) THEN
|
|
|
+ 3323 SemError(211) END;
|
|
|
+ 3324 t := SymTab.CharType(); .)
|
|
|
+ 3325 | ( "ORD" | "ORDL" ) "(" Expr<et, q> ")"
|
|
|
+ 3326 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
+ 3327 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "ORD"));
|
|
|
+ 3328 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
+ 3329 astCur := astNode; astIsLit := TRUE; .)
|
|
|
+ 3330 (. IF et # SymTab.InvalidType THEN
|
|
|
+ 3331 IF (SymTab.ClassOf(et) #
|
|
|
+ 3332 SymTab.ClChar)
|
|
|
+ 3333 AND (SymTab.ClassOf(et) #
|
|
|
+ 3334 SymTab.ClBool)
|
|
|
+ 3335 AND (SymTab.ClassOf(et) #
|
|
|
+ 3336 SymTab.ClEnum)
|
|
|
+ 3337 AND NOT SymTab.IsIntFamily(et) THEN
|
|
|
+ 3338 SemError(211) END
|
|
|
+ 3339 END;
|
|
|
+ 3340 t := SymTab.IntType(); .)
|
|
|
+ 3341 | "CAP" "(" Expr<et, q> ")"
|
|
|
+ 3342 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
+ 3343 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "CAP"));
|
|
|
+ 3344 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
+ 3345 astCur := astNode; astIsLit := TRUE; .)
|
|
|
+ 3346 (. QbeGen.CopyOp("@", q);
|
|
|
+ 3347 t := SymTab.CharType(); .)
|
|
|
+ 3348 | "UCHR" "(" Expr<et, q> ")"
|
|
|
+ 3349 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
+ 3350 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "UCHR"));
|
|
|
+ 3351 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
+ 3352 astCur := astNode; astIsLit := TRUE; .)
|
|
|
+ 3353 (. (* UCHR: the UCHAR constructor.
|
|
|
+ 3354 CHAR -> UCHAR (identity);
|
|
|
+ 3355 INTEGER familly -> UCHAR
|
|
|
+ 3356 (codepoint value). *)
|
|
|
+ 3357 IF (et # SymTab.InvalidType)
|
|
|
+ 3358 AND (SymTab.ClassOf(et) # SymTab.ClChar)
|
|
|
+ 3359 AND NOT SymTab.IsIntFamily(et) THEN
|
|
|
+ 3360 SemError(211) END;
|
|
|
+ 3361 t := SymTab.UCharType(); .)
|
|
|
+ 3362 | "CHR8" "(" Expr<et, q> ")"
|
|
|
+ 3363 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
+ 3364 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "CHR8"));
|
|
|
+ 3365 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
+ 3366 astCur := astNode; astIsLit := TRUE; .)
|
|
|
+ 3367 (. IF (et # SymTab.InvalidType)
|
|
|
+ 3368 AND (SymTab.ClassOf(et) # SymTab.ClUChar) THEN
|
|
|
+ 3369 SemError(211) END;
|
|
|
+ 3370 t := SymTab.CharType(); .)
|
|
|
+ 3371 | "UORD" "(" Expr<et, q> ")"
|
|
|
+ 3372 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
+ 3373 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "UORD"));
|
|
|
+ 3374 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
+ 3375 astCur := astNode; astIsLit := TRUE; .)
|
|
|
+ 3376 (. (* UORD(u): the codepoint as a
|
|
|
+ 3377 32-bit ordinal (INTEGER),
|
|
|
+ 3378 cf. ORD for CHAR. *)
|
|
|
+ 3379 IF (et # SymTab.InvalidType)
|
|
|
+ 3380 AND (SymTab.ClassOf(et) # SymTab.ClUChar) THEN
|
|
|
+ 3381 SemError(211) END;
|
|
|
+ 3382 t := SymTab.IntType(); .)
|
|
|
+ 3383 | "ABS" "(" Expr<et, q> ")"
|
|
|
+ 3384 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
+ 3385 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "ABS"));
|
|
|
+ 3386 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
+ 3387 astCur := astNode; astIsLit := TRUE; .)
|
|
|
+ 3388 (. IF (et # SymTab.InvalidType)
|
|
|
+ 3389 AND NOT SymTab.IsIntFamily(et)
|
|
|
+ 3390 AND (SymTab.ClassOf(et) #
|
|
|
+ 3391 SymTab.ClReal) THEN
|
|
|
+ 3392 SemError(211)
|
|
|
+ 3393 ELSE QbeGen.CopyOp("@", q)
|
|
|
+ 3394 END;
|
|
|
+ 3395 t := et; .)
|
|
|
+ 3396 | "VAL" "(" GetIdent<vn> (. astArg2 := AST.MakeLeaf(AST.NkIdent, vn); .) "," Expr<et, q> ")"
|
|
|
+ 3397 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
+ 3398 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "VAL"));
|
|
|
+ 3399 IF astArg2 # AST.NoNode THEN AST.SetChild(astNode, 1, astArg2) END;
|
|
|
+ 3400 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 2, astCur) END;
|
|
|
+ 3401 astCur := astNode; astIsLit := TRUE; .)
|
|
|
+ 3402 (. IF NOT SymTab.Lookup(vn) THEN
|
|
|
+ 3403 SemError(201);
|
|
|
+ 3404 t := SymTab.InvalidType
|
|
|
+ 3405 ELSE vt := SymTab.SymType(vn);
|
|
|
+ 3406 IF vt = SymTab.InvalidType THEN
|
|
|
+ 3407 t := SymTab.InvalidType
|
|
|
+ 3408 ELSIF et =
|
|
|
+ 3409 SymTab.InvalidType THEN
|
|
|
+ 3410 t := vt
|
|
|
+ 3411 ELSE
|
|
|
+ 3412 c1 := SymTab.ClassOf(et);
|
|
|
+ 3413 c2 := SymTab.ClassOf(vt);
|
|
|
+ 3414 IF (c1 = SymTab.ClInt)
|
|
|
+ 3415 AND (c2 = SymTab.ClLong) THEN
|
|
|
+ 3416 QbeGen.WidenLong(q, qa);
|
|
|
+ 3417 QbeGen.CopyOp(qa, q);
|
|
|
+ 3418 t := vt
|
|
|
+ 3419 ELSIF (c1 = SymTab.ClLong)
|
|
|
+ 3420 AND (c2 = SymTab.ClInt) THEN
|
|
|
+ 3421 QbeGen.NarrowLong(q, qa);
|
|
|
+ 3422 QbeGen.CopyOp(qa, q);
|
|
|
+ 3423 t := vt
|
|
|
+ 3424 ELSIF (c1 = SymTab.ClInt)
|
|
|
+ 3425 AND (c2 = SymTab.ClReal) THEN
|
|
|
+ 3426 QbeGen.ConvIR(q, qa);
|
|
|
+ 3427 QbeGen.CopyOp(qa, q);
|
|
|
+ 3428 t := vt
|
|
|
+ 3429 ELSIF (c1 = SymTab.ClLong)
|
|
|
+ 3430 AND (c2 = SymTab.ClReal) THEN
|
|
|
+ 3431 QbeGen.ConvLR(q, qa);
|
|
|
+ 3432 QbeGen.CopyOp(qa, q);
|
|
|
+ 3433 t := vt
|
|
|
+ 3434 ELSIF (c1 = SymTab.ClReal)
|
|
|
+ 3435 AND (c2 = SymTab.ClInt) THEN
|
|
|
+ 3436 QbeGen.ConvRI(q, qa);
|
|
|
+ 3437 QbeGen.CopyOp(qa, q);
|
|
|
+ 3438 t := vt
|
|
|
+ 3439 ELSIF (c1 = SymTab.ClReal)
|
|
|
+ 3440 AND (c2 = SymTab.ClLong) THEN
|
|
|
+ 3441 QbeGen.ConvRL(q, qa);
|
|
|
+ 3442 QbeGen.CopyOp(qa, q);
|
|
|
+ 3443 t := vt
|
|
|
+ 3444 ELSIF ((c1 = SymTab.ClInt)
|
|
|
+ 3445 OR (c1 =
|
|
|
+ 3446 SymTab.ClChar)
|
|
|
+ 3447 OR (c1 =
|
|
|
+ 3448 SymTab.ClBool)
|
|
|
3449 OR (c1 =
|
|
|
- 3450 SymTab.ClChar)
|
|
|
- 3451 OR (c1 =
|
|
|
- 3452 SymTab.ClBool)
|
|
|
- 3453 OR (c1 =
|
|
|
- 3454 SymTab.ClEnum))
|
|
|
- 3455 AND ((c2 = SymTab.ClInt)
|
|
|
+ 3450 SymTab.ClEnum))
|
|
|
+ 3451 AND ((c2 = SymTab.ClInt)
|
|
|
+ 3452 OR (c2 =
|
|
|
+ 3453 SymTab.ClChar)
|
|
|
+ 3454 OR (c2 =
|
|
|
+ 3455 SymTab.ClBool)
|
|
|
3456 OR (c2 =
|
|
|
- 3457 SymTab.ClChar)
|
|
|
- 3458 OR (c2 =
|
|
|
- 3459 SymTab.ClBool)
|
|
|
- 3460 OR (c2 =
|
|
|
- 3461 SymTab.ClEnum)) THEN
|
|
|
- 3462 t := vt
|
|
|
- 3463 ELSIF (c1 = SymTab.ClPtr)
|
|
|
- 3464 AND (c2 = SymTab.ClPtr) THEN
|
|
|
- 3465 t := vt
|
|
|
- 3466 ELSIF (c1 = SymTab.ClReal)
|
|
|
- 3467 AND (c2 = SymTab.ClReal) THEN
|
|
|
- 3468 t := vt
|
|
|
- 3469 ELSE SemError(230);
|
|
|
- 3470 t := SymTab.InvalidType
|
|
|
- 3471 END
|
|
|
- 3472 END
|
|
|
- 3473 END; .)
|
|
|
- 3474 | "(" Expr<et, q> ")" (. t := et; astIsLit := TRUE; .)
|
|
|
- 3475 | SetLit<st, sq> (. astIsLit := TRUE; t := st;
|
|
|
- 3476 QbeGen.CopyOp(sq, q); .)
|
|
|
- 3477 | ( "NOT" | "~" ) Fact<t2, q2> (. astNot := astCur;
|
|
|
- 3478 IF SymTab.BoolCheck(t2) THEN
|
|
|
- 3479 t := SymTab.BoolType()
|
|
|
- 3480 ELSE SemError(212);
|
|
|
- 3481 t := SymTab.InvalidType END;
|
|
|
- 3482 IF t # SymTab.InvalidType THEN
|
|
|
- 3483 QbeGen.CopyOp("@", q)
|
|
|
- 3484 ELSE QbeGen.CopyOp("0", q)
|
|
|
- 3485 END;
|
|
|
- 3486 astIsLit := TRUE;
|
|
|
- 3487 astCur := AST.MakeUn(
|
|
|
- 3488 AST.NkUnary, AST.OpNot, astNot); .)
|
|
|
- 3489 )
|
|
|
- 3490 (. IF NOT astIsLit THEN astCur := AST.NoNode END; .)
|
|
|
- 3491 (. IF astCur # AST.NoNode THEN AST.SetTy(astCur, t) END; .) .
|
|
|
- 3492 (* Set literals are SET OF [0..255] (8 words); elements validated
|
|
|
- 3493 0..255 statically when foldable (222 otherwise), runtime trap
|
|
|
- 3494 for computed elements. Ranges always lower via SetRange. *)
|
|
|
- 3495 SetLit<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
- 3496 (. VAR astNode: AST.Node; .)
|
|
|
- 3497 = "{" (. t := SymTab.NewSet(
|
|
|
- 3498 SymTab.NewSubR(0, 255));
|
|
|
- 3499 astNode := AST.MakeNode(AST.NkSetLit);
|
|
|
- 3500 QbeGen.NewSetTemp(8, q);
|
|
|
- 3501 QbeGen.SetZero(q, 8); .)
|
|
|
- 3502 [ SetElem<t, q, astNode> { "," SetElem<t, q, astNode> } ]
|
|
|
- 3503 "}" (. astCur := astNode; .) .
|
|
|
- 3504 (* Typed brace constructor: TypeName{ elems } — BITSET{0} (a set)
|
|
|
- 3505 or ArrayName{...} (an array constructor, GNU Modula-2). The
|
|
|
- 3506 declared type sets the width (set) or element type (array). *)
|
|
|
- 3507 TypedBraceLit<vt: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
- 3508 (. VAR nw: CARDINAL;
|
|
|
- 3509 astNode, astTail: AST.Node;
|
|
|
- 3510 savedCls: INTEGER; .)
|
|
|
- 3511 = "{" (. savedCls := braceCls;
|
|
|
- 3512 astNode := AST.MakeNode(AST.NkBraceLit);
|
|
|
- 3513 AST.SetTy(astNode, vt);
|
|
|
- 3514 astTail := astNode;
|
|
|
- 3515 IF vt = SymTab.InvalidType THEN
|
|
|
- 3516 braceCls := -1
|
|
|
- 3517 ELSE braceCls :=
|
|
|
- 3518 SymTab.ClassOf(vt)
|
|
|
- 3519 END;
|
|
|
- 3520 IF braceCls = SymTab.ClSet THEN
|
|
|
- 3521 IF vt = SymTab.InvalidType THEN
|
|
|
- 3522 nw := 8
|
|
|
- 3523 ELSE nw := SymTab.SetWords(vt);
|
|
|
- 3524 IF nw = 0 THEN nw := 8 END
|
|
|
- 3525 END;
|
|
|
- 3526 QbeGen.NewSetTemp(nw, q);
|
|
|
- 3527 QbeGen.SetZero(q, nw)
|
|
|
- 3528 ELSIF (braceCls =
|
|
|
- 3529 SymTab.ClArray)
|
|
|
- 3530 OR (braceCls =
|
|
|
- 3531 SymTab.ClRecord)
|
|
|
- 3532 OR (braceCls =
|
|
|
- 3533 SymTab.ClClass) THEN
|
|
|
- 3534 QbeGen.CtorBegin(vt)
|
|
|
- 3535 ELSE
|
|
|
- 3536 IF vt # SymTab.InvalidType THEN
|
|
|
- 3537 SemError(230) END;
|
|
|
- 3538 braceCls := -1
|
|
|
- 3539 END; .)
|
|
|
- 3540 [ BraceElem<vt, q, astNode, astTail>
|
|
|
- 3541 { "," BraceElem<vt, q, astNode, astTail> } ]
|
|
|
- 3542 "}" (. IF (braceCls = SymTab.ClArray)
|
|
|
- 3543 OR (braceCls =
|
|
|
- 3544 SymTab.ClRecord)
|
|
|
- 3545 OR (braceCls =
|
|
|
- 3546 SymTab.ClClass) THEN
|
|
|
- 3547 QbeGen.CtorEnd(q)
|
|
|
- 3548 ELSIF braceCls # SymTab.ClSet THEN
|
|
|
- 3549 QbeGen.CopyOp("0", q)
|
|
|
- 3550 END;
|
|
|
- 3551 braceCls := savedCls; .)
|
|
|
- 3552 (. astCur := astNode; .) .
|
|
|
- 3553 BraceElem<vt: SymTab.TypeIndex; VAR sq: QbeGen.QVal;
|
|
|
- 3554 VAR node, tail: AST.Node>
|
|
|
- 3555 (. VAR et, et2: SymTab.TypeIndex;
|
|
|
- 3556 qe, q2: QbeGen.QVal;
|
|
|
- 3557 v, v2, reps, k: INTEGER;
|
|
|
- 3558 elem: SymTab.TypeIndex;
|
|
|
- 3559 lo: INTEGER;
|
|
|
- 3560 span: CARDINAL;
|
|
|
- 3561 cl, cl2: INTEGER;
|
|
|
- 3562 hasR, hasB: BOOLEAN;
|
|
|
- 3563 astEl: AST.Node; .)
|
|
|
- 3564 = (. hasR := FALSE; hasB := FALSE;
|
|
|
- 3565 reps := 1; .)
|
|
|
- 3566 Expr<et, qe> (. astEl := astCur; .)
|
|
|
- 3567 [ ".." Expr<et2, q2> (. astEl := AST.MakeBin(
|
|
|
- 3568 AST.NkSubrange, 0, astEl, astCur);
|
|
|
- 3569 hasR := TRUE; .) ]
|
|
|
- 3570 [ "BY" Expr<et2, q2> (. hasB := TRUE; .) ]
|
|
|
- 3571 (. IF braceCls = SymTab.ClSet THEN
|
|
|
- 3572 IF hasB THEN SemError(230) END;
|
|
|
- 3573 lo := SymTab.SetBaseLo(vt);
|
|
|
- 3574 span := SymTab.SetCount(vt);
|
|
|
- 3575 IF (et = SymTab.InvalidType)
|
|
|
- 3576 OR (hasR AND (et2 =
|
|
|
- 3577 SymTab.InvalidType)) THEN
|
|
|
- 3578 ELSE cl :=
|
|
|
- 3579 SymTab.ClassOf(et);
|
|
|
- 3580 IF hasR THEN
|
|
|
- 3581 cl2 :=
|
|
|
- 3582 SymTab.ClassOf(et2)
|
|
|
- 3583 ELSE cl2 := SymTab.ClInt
|
|
|
- 3584 END;
|
|
|
- 3585 IF NOT SymTab.SetElemClassOk(cl)
|
|
|
- 3586 OR (hasR AND NOT
|
|
|
- 3587 SymTab.SetElemClassOk(cl2))
|
|
|
- 3588 THEN
|
|
|
- 3589 SemError(222)
|
|
|
- 3590 ELSIF hasR
|
|
|
- 3591 AND SymTab.ConstInt(qe, v)
|
|
|
- 3592 AND SymTab.ConstInt(q2,
|
|
|
- 3593 v2)
|
|
|
- 3594 AND ((v < lo)
|
|
|
- 3595 OR (v2 < lo)
|
|
|
- 3596 OR (v >= lo +
|
|
|
- 3597 VAL(INTEGER, span))
|
|
|
- 3598 OR (v2 >= lo +
|
|
|
- 3599 VAL(INTEGER, span))
|
|
|
- 3600 OR (v > v2)) THEN
|
|
|
- 3601 SemError(222)
|
|
|
- 3602 ELSIF hasR THEN
|
|
|
- 3603 QbeGen.SetRange(sq, qe, q2,
|
|
|
- 3604 lo, span)
|
|
|
- 3605 ELSIF SymTab.ConstInt(qe,
|
|
|
- 3606 v)
|
|
|
- 3607 AND ((v < lo)
|
|
|
- 3608 OR (v >= lo +
|
|
|
- 3609 VAL(INTEGER,
|
|
|
- 3610 span))) THEN
|
|
|
- 3611 SemError(222)
|
|
|
- 3612 ELSE QbeGen.SetBit(sq, qe,
|
|
|
- 3613 lo, span)
|
|
|
- 3614 END
|
|
|
- 3615 END
|
|
|
- 3616 ELSIF (braceCls = SymTab.ClArray)
|
|
|
- 3617 OR (braceCls =
|
|
|
- 3618 SymTab.ClRecord)
|
|
|
- 3619 OR (braceCls =
|
|
|
- 3620 SymTab.ClClass) THEN
|
|
|
- 3621 IF hasR THEN SemError(230) END;
|
|
|
- 3622 reps := 1;
|
|
|
- 3623 IF hasB THEN
|
|
|
- 3624 IF SymTab.ConstInt(q2, v2)
|
|
|
- 3625 AND (v2 >= 1) THEN
|
|
|
- 3626 reps := v2
|
|
|
- 3627 ELSE SemError(230)
|
|
|
- 3628 END
|
|
|
- 3629 END;
|
|
|
- 3630 k := 0;
|
|
|
- 3631 WHILE k < reps DO
|
|
|
- 3632 QbeGen.CtorElem(qe);
|
|
|
- 3633 INC(k)
|
|
|
- 3634 END
|
|
|
- 3635 END; .)
|
|
|
- 3636 (. (* the BY form repeats the
|
|
|
- 3637 element; keep the AST in
|
|
|
- 3638 step with CtorElem *)
|
|
|
- 3639 k := 0;
|
|
|
- 3640 WHILE k < reps DO
|
|
|
- 3641 AstAppend(AST.NkBlock,
|
|
|
- 3642 node, tail, astEl);
|
|
|
- 3643 INC(k)
|
|
|
- 3644 END; .) .
|
|
|
- 3645 SetElem<st: SymTab.TypeIndex; sq: QbeGen.QVal; node: AST.Node> (. VAR et, et2: SymTab.TypeIndex;
|
|
|
- 3646 qe, q2: QbeGen.QVal;
|
|
|
- 3647 v, v2: INTEGER;
|
|
|
- 3648 lo: INTEGER;
|
|
|
- 3649 span: CARDINAL;
|
|
|
- 3650 cl, cl2: INTEGER;
|
|
|
- 3651 hasR: BOOLEAN;
|
|
|
- 3652 astEl: AST.Node; .)
|
|
|
- 3653 = (. hasR := FALSE; .)
|
|
|
- 3654 Expr<et, qe> (. astEl := astCur; .)
|
|
|
- 3655 [ ".." Expr<et2, q2> (. astEl := AST.MakeBin(
|
|
|
- 3656 AST.NkSubrange, 0, astEl, astCur);
|
|
|
- 3657 hasR := TRUE; .) ]
|
|
|
- 3658 (. lo := SymTab.SetBaseLo(st);
|
|
|
- 3659 span := SymTab.SetCount(st);
|
|
|
- 3660 IF (et = SymTab.InvalidType)
|
|
|
- 3661 OR (hasR AND (et2 =
|
|
|
- 3662 SymTab.InvalidType)) THEN
|
|
|
- 3663 ELSE cl :=
|
|
|
- 3664 SymTab.ClassOf(et);
|
|
|
- 3665 IF hasR THEN
|
|
|
- 3666 cl2 :=
|
|
|
- 3667 SymTab.ClassOf(et2)
|
|
|
- 3668 ELSE cl2 := SymTab.ClInt
|
|
|
- 3669 END;
|
|
|
- 3670 IF NOT SymTab.SetElemClassOk(cl)
|
|
|
- 3671 OR (hasR AND NOT
|
|
|
- 3672 SymTab.SetElemClassOk(cl2))
|
|
|
- 3673 THEN
|
|
|
- 3674 SemError(222)
|
|
|
- 3675 ELSIF hasR
|
|
|
- 3676 AND SymTab.ConstInt(qe, v)
|
|
|
- 3677 AND SymTab.ConstInt(q2,
|
|
|
- 3678 v2)
|
|
|
- 3679 AND ((v < lo)
|
|
|
- 3680 OR (v2 < lo)
|
|
|
- 3681 OR (v >= lo +
|
|
|
- 3682 VAL(INTEGER, span))
|
|
|
- 3683 OR (v2 >= lo +
|
|
|
- 3684 VAL(INTEGER, span))
|
|
|
- 3685 OR (v > v2)) THEN
|
|
|
- 3686 SemError(222)
|
|
|
- 3687 ELSIF hasR THEN
|
|
|
- 3688 QbeGen.SetRange(sq, qe, q2,
|
|
|
- 3689 lo, span)
|
|
|
- 3690 ELSIF SymTab.ConstInt(qe,
|
|
|
- 3691 v)
|
|
|
- 3692 AND ((v < lo)
|
|
|
- 3693 OR (v >= lo +
|
|
|
- 3694 VAL(INTEGER,
|
|
|
- 3695 span))) THEN
|
|
|
- 3696 SemError(222)
|
|
|
- 3697 ELSE QbeGen.SetBit(sq, qe,
|
|
|
- 3698 lo, span)
|
|
|
- 3699 END
|
|
|
- 3700 END; .)
|
|
|
- 3701 (. AST.SetChild(node,
|
|
|
- 3702 AST.NChild(node), astEl); .) .
|
|
|
- 3703 GetIdent<VAR n: SymTab.Name>
|
|
|
- 3704 = ident (. LexName(n); .) .
|
|
|
- 3705
|
|
|
- 3706 END M2.
|
|
|
+ 3457 SymTab.ClEnum)) THEN
|
|
|
+ 3458 t := vt
|
|
|
+ 3459 ELSIF (c1 = SymTab.ClPtr)
|
|
|
+ 3460 AND (c2 = SymTab.ClPtr) THEN
|
|
|
+ 3461 t := vt
|
|
|
+ 3462 ELSIF (c1 = SymTab.ClReal)
|
|
|
+ 3463 AND (c2 = SymTab.ClReal) THEN
|
|
|
+ 3464 t := vt
|
|
|
+ 3465 ELSE SemError(230);
|
|
|
+ 3466 t := SymTab.InvalidType
|
|
|
+ 3467 END
|
|
|
+ 3468 END
|
|
|
+ 3469 END; .)
|
|
|
+ 3470 | "(" Expr<et, q> ")" (. t := et; astIsLit := TRUE; .)
|
|
|
+ 3471 | SetLit<st, sq> (. astIsLit := TRUE; t := st;
|
|
|
+ 3472 QbeGen.CopyOp(sq, q); .)
|
|
|
+ 3473 | ( "NOT" | "~" ) Fact<t2, q2> (. astNot := astCur;
|
|
|
+ 3474 IF SymTab.BoolCheck(t2) THEN
|
|
|
+ 3475 t := SymTab.BoolType()
|
|
|
+ 3476 ELSE SemError(212);
|
|
|
+ 3477 t := SymTab.InvalidType END;
|
|
|
+ 3478 IF t # SymTab.InvalidType THEN
|
|
|
+ 3479 QbeGen.CopyOp("@", q)
|
|
|
+ 3480 ELSE QbeGen.CopyOp("0", q)
|
|
|
+ 3481 END;
|
|
|
+ 3482 astIsLit := TRUE;
|
|
|
+ 3483 astCur := AST.MakeUn(
|
|
|
+ 3484 AST.NkUnary, AST.OpNot, astNot); .)
|
|
|
+ 3485 )
|
|
|
+ 3486 (. IF NOT astIsLit THEN astCur := AST.NoNode END; .)
|
|
|
+ 3487 (. IF astCur # AST.NoNode THEN AST.SetTy(astCur, t) END; .) .
|
|
|
+ 3488 (* Set literals are SET OF [0..255] (8 words); elements validated
|
|
|
+ 3489 0..255 statically when foldable (222 otherwise), runtime trap
|
|
|
+ 3490 for computed elements. Ranges always lower via SetRange. *)
|
|
|
+ 3491 SetLit<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
+ 3492 (. VAR astNode: AST.Node; .)
|
|
|
+ 3493 = "{" (. t := SymTab.NewSet(
|
|
|
+ 3494 SymTab.NewSubR(0, 255));
|
|
|
+ 3495 astNode := AST.MakeNode(AST.NkSetLit);
|
|
|
+ 3496 QbeGen.NewSetTemp(8, q);
|
|
|
+ 3497 QbeGen.SetZero(q, 8); .)
|
|
|
+ 3498 [ SetElem<t, q, astNode> { "," SetElem<t, q, astNode> } ]
|
|
|
+ 3499 "}" (. astCur := astNode; .) .
|
|
|
+ 3500 (* Typed brace constructor: TypeName{ elems } — BITSET{0} (a set)
|
|
|
+ 3501 or ArrayName{...} (an array constructor, GNU Modula-2). The
|
|
|
+ 3502 declared type sets the width (set) or element type (array). *)
|
|
|
+ 3503 TypedBraceLit<vt: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
+ 3504 (. VAR nw: CARDINAL;
|
|
|
+ 3505 astNode, astTail: AST.Node;
|
|
|
+ 3506 savedCls: INTEGER; .)
|
|
|
+ 3507 = "{" (. savedCls := braceCls;
|
|
|
+ 3508 astNode := AST.MakeNode(AST.NkBraceLit);
|
|
|
+ 3509 AST.SetTy(astNode, vt);
|
|
|
+ 3510 astTail := astNode;
|
|
|
+ 3511 IF vt = SymTab.InvalidType THEN
|
|
|
+ 3512 braceCls := -1
|
|
|
+ 3513 ELSE braceCls :=
|
|
|
+ 3514 SymTab.ClassOf(vt)
|
|
|
+ 3515 END;
|
|
|
+ 3516 IF braceCls = SymTab.ClSet THEN
|
|
|
+ 3517 IF vt = SymTab.InvalidType THEN
|
|
|
+ 3518 nw := 8
|
|
|
+ 3519 ELSE nw := SymTab.SetWords(vt);
|
|
|
+ 3520 IF nw = 0 THEN nw := 8 END
|
|
|
+ 3521 END;
|
|
|
+ 3522 QbeGen.NewSetTemp(nw, q);
|
|
|
+ 3523 QbeGen.SetZero(q, nw)
|
|
|
+ 3524 ELSIF (braceCls =
|
|
|
+ 3525 SymTab.ClArray)
|
|
|
+ 3526 OR (braceCls =
|
|
|
+ 3527 SymTab.ClRecord)
|
|
|
+ 3528 OR (braceCls =
|
|
|
+ 3529 SymTab.ClClass) THEN
|
|
|
+ 3530 QbeGen.CtorBegin(vt)
|
|
|
+ 3531 ELSE
|
|
|
+ 3532 IF vt # SymTab.InvalidType THEN
|
|
|
+ 3533 SemError(230) END;
|
|
|
+ 3534 braceCls := -1
|
|
|
+ 3535 END; .)
|
|
|
+ 3536 [ BraceElem<vt, q, astNode, astTail>
|
|
|
+ 3537 { "," BraceElem<vt, q, astNode, astTail> } ]
|
|
|
+ 3538 "}" (. IF (braceCls = SymTab.ClArray)
|
|
|
+ 3539 OR (braceCls =
|
|
|
+ 3540 SymTab.ClRecord)
|
|
|
+ 3541 OR (braceCls =
|
|
|
+ 3542 SymTab.ClClass) THEN
|
|
|
+ 3543 QbeGen.CtorEnd(q)
|
|
|
+ 3544 ELSIF braceCls # SymTab.ClSet THEN
|
|
|
+ 3545 QbeGen.CopyOp("0", q)
|
|
|
+ 3546 END;
|
|
|
+ 3547 braceCls := savedCls; .)
|
|
|
+ 3548 (. astCur := astNode; .) .
|
|
|
+ 3549 BraceElem<vt: SymTab.TypeIndex; VAR sq: QbeGen.QVal;
|
|
|
+ 3550 VAR node, tail: AST.Node>
|
|
|
+ 3551 (. VAR et, et2: SymTab.TypeIndex;
|
|
|
+ 3552 qe, q2: QbeGen.QVal;
|
|
|
+ 3553 v, v2, reps, k: INTEGER;
|
|
|
+ 3554 elem: SymTab.TypeIndex;
|
|
|
+ 3555 lo: INTEGER;
|
|
|
+ 3556 span: CARDINAL;
|
|
|
+ 3557 cl, cl2: INTEGER;
|
|
|
+ 3558 hasR, hasB: BOOLEAN;
|
|
|
+ 3559 astEl: AST.Node; .)
|
|
|
+ 3560 = (. hasR := FALSE; hasB := FALSE;
|
|
|
+ 3561 reps := 1; .)
|
|
|
+ 3562 Expr<et, qe> (. astEl := astCur; .)
|
|
|
+ 3563 [ ".." Expr<et2, q2> (. astEl := AST.MakeBin(
|
|
|
+ 3564 AST.NkSubrange, 0, astEl, astCur);
|
|
|
+ 3565 hasR := TRUE; .) ]
|
|
|
+ 3566 [ "BY" Expr<et2, q2> (. hasB := TRUE; .) ]
|
|
|
+ 3567 (. IF braceCls = SymTab.ClSet THEN
|
|
|
+ 3568 IF hasB THEN SemError(230) END;
|
|
|
+ 3569 lo := SymTab.SetBaseLo(vt);
|
|
|
+ 3570 span := SymTab.SetCount(vt);
|
|
|
+ 3571 IF (et = SymTab.InvalidType)
|
|
|
+ 3572 OR (hasR AND (et2 =
|
|
|
+ 3573 SymTab.InvalidType)) THEN
|
|
|
+ 3574 ELSE cl :=
|
|
|
+ 3575 SymTab.ClassOf(et);
|
|
|
+ 3576 IF hasR THEN
|
|
|
+ 3577 cl2 :=
|
|
|
+ 3578 SymTab.ClassOf(et2)
|
|
|
+ 3579 ELSE cl2 := SymTab.ClInt
|
|
|
+ 3580 END;
|
|
|
+ 3581 IF NOT SymTab.SetElemClassOk(cl)
|
|
|
+ 3582 OR (hasR AND NOT
|
|
|
+ 3583 SymTab.SetElemClassOk(cl2))
|
|
|
+ 3584 THEN
|
|
|
+ 3585 SemError(222)
|
|
|
+ 3586 ELSIF hasR
|
|
|
+ 3587 AND SymTab.ConstInt(qe, v)
|
|
|
+ 3588 AND SymTab.ConstInt(q2,
|
|
|
+ 3589 v2)
|
|
|
+ 3590 AND ((v < lo)
|
|
|
+ 3591 OR (v2 < lo)
|
|
|
+ 3592 OR (v >= lo +
|
|
|
+ 3593 VAL(INTEGER, span))
|
|
|
+ 3594 OR (v2 >= lo +
|
|
|
+ 3595 VAL(INTEGER, span))
|
|
|
+ 3596 OR (v > v2)) THEN
|
|
|
+ 3597 SemError(222)
|
|
|
+ 3598 ELSIF hasR THEN
|
|
|
+ 3599 QbeGen.SetRange(sq, qe, q2,
|
|
|
+ 3600 lo, span)
|
|
|
+ 3601 ELSIF SymTab.ConstInt(qe,
|
|
|
+ 3602 v)
|
|
|
+ 3603 AND ((v < lo)
|
|
|
+ 3604 OR (v >= lo +
|
|
|
+ 3605 VAL(INTEGER,
|
|
|
+ 3606 span))) THEN
|
|
|
+ 3607 SemError(222)
|
|
|
+ 3608 ELSE QbeGen.SetBit(sq, qe,
|
|
|
+ 3609 lo, span)
|
|
|
+ 3610 END
|
|
|
+ 3611 END
|
|
|
+ 3612 ELSIF (braceCls = SymTab.ClArray)
|
|
|
+ 3613 OR (braceCls =
|
|
|
+ 3614 SymTab.ClRecord)
|
|
|
+ 3615 OR (braceCls =
|
|
|
+ 3616 SymTab.ClClass) THEN
|
|
|
+ 3617 IF hasR THEN SemError(230) END;
|
|
|
+ 3618 reps := 1;
|
|
|
+ 3619 IF hasB THEN
|
|
|
+ 3620 IF SymTab.ConstInt(q2, v2)
|
|
|
+ 3621 AND (v2 >= 1) THEN
|
|
|
+ 3622 reps := v2
|
|
|
+ 3623 ELSE SemError(230)
|
|
|
+ 3624 END
|
|
|
+ 3625 END;
|
|
|
+ 3626 k := 0;
|
|
|
+ 3627 WHILE k < reps DO
|
|
|
+ 3628 QbeGen.CtorElem(qe);
|
|
|
+ 3629 INC(k)
|
|
|
+ 3630 END
|
|
|
+ 3631 END; .)
|
|
|
+ 3632 (. (* the BY form repeats the
|
|
|
+ 3633 element; keep the AST in
|
|
|
+ 3634 step with CtorElem *)
|
|
|
+ 3635 k := 0;
|
|
|
+ 3636 WHILE k < reps DO
|
|
|
+ 3637 AstAppend(AST.NkBlock,
|
|
|
+ 3638 node, tail, astEl);
|
|
|
+ 3639 INC(k)
|
|
|
+ 3640 END; .) .
|
|
|
+ 3641 SetElem<st: SymTab.TypeIndex; sq: QbeGen.QVal; node: AST.Node> (. VAR et, et2: SymTab.TypeIndex;
|
|
|
+ 3642 qe, q2: QbeGen.QVal;
|
|
|
+ 3643 v, v2: INTEGER;
|
|
|
+ 3644 lo: INTEGER;
|
|
|
+ 3645 span: CARDINAL;
|
|
|
+ 3646 cl, cl2: INTEGER;
|
|
|
+ 3647 hasR: BOOLEAN;
|
|
|
+ 3648 astEl: AST.Node; .)
|
|
|
+ 3649 = (. hasR := FALSE; .)
|
|
|
+ 3650 Expr<et, qe> (. astEl := astCur; .)
|
|
|
+ 3651 [ ".." Expr<et2, q2> (. astEl := AST.MakeBin(
|
|
|
+ 3652 AST.NkSubrange, 0, astEl, astCur);
|
|
|
+ 3653 hasR := TRUE; .) ]
|
|
|
+ 3654 (. lo := SymTab.SetBaseLo(st);
|
|
|
+ 3655 span := SymTab.SetCount(st);
|
|
|
+ 3656 IF (et = SymTab.InvalidType)
|
|
|
+ 3657 OR (hasR AND (et2 =
|
|
|
+ 3658 SymTab.InvalidType)) THEN
|
|
|
+ 3659 ELSE cl :=
|
|
|
+ 3660 SymTab.ClassOf(et);
|
|
|
+ 3661 IF hasR THEN
|
|
|
+ 3662 cl2 :=
|
|
|
+ 3663 SymTab.ClassOf(et2)
|
|
|
+ 3664 ELSE cl2 := SymTab.ClInt
|
|
|
+ 3665 END;
|
|
|
+ 3666 IF NOT SymTab.SetElemClassOk(cl)
|
|
|
+ 3667 OR (hasR AND NOT
|
|
|
+ 3668 SymTab.SetElemClassOk(cl2))
|
|
|
+ 3669 THEN
|
|
|
+ 3670 SemError(222)
|
|
|
+ 3671 ELSIF hasR
|
|
|
+ 3672 AND SymTab.ConstInt(qe, v)
|
|
|
+ 3673 AND SymTab.ConstInt(q2,
|
|
|
+ 3674 v2)
|
|
|
+ 3675 AND ((v < lo)
|
|
|
+ 3676 OR (v2 < lo)
|
|
|
+ 3677 OR (v >= lo +
|
|
|
+ 3678 VAL(INTEGER, span))
|
|
|
+ 3679 OR (v2 >= lo +
|
|
|
+ 3680 VAL(INTEGER, span))
|
|
|
+ 3681 OR (v > v2)) THEN
|
|
|
+ 3682 SemError(222)
|
|
|
+ 3683 ELSIF hasR THEN
|
|
|
+ 3684 QbeGen.SetRange(sq, qe, q2,
|
|
|
+ 3685 lo, span)
|
|
|
+ 3686 ELSIF SymTab.ConstInt(qe,
|
|
|
+ 3687 v)
|
|
|
+ 3688 AND ((v < lo)
|
|
|
+ 3689 OR (v >= lo +
|
|
|
+ 3690 VAL(INTEGER,
|
|
|
+ 3691 span))) THEN
|
|
|
+ 3692 SemError(222)
|
|
|
+ 3693 ELSE QbeGen.SetBit(sq, qe,
|
|
|
+ 3694 lo, span)
|
|
|
+ 3695 END
|
|
|
+ 3696 END; .)
|
|
|
+ 3697 (. AST.SetChild(node,
|
|
|
+ 3698 AST.NChild(node), astEl); .) .
|
|
|
+ 3699 GetIdent<VAR n: SymTab.Name>
|
|
|
+ 3700 = ident (. LexName(n); .) .
|
|
|
+ 3701
|
|
|
+ 3702 END M2.
|
|
|
|
|
|
0 errors
|
|
|
|