# V3 step 2 — REAL lowering: the scalar story is complete (done 2026-09-19) With step 1.9's statements + this section, every scalar kind lowers: INTEGER/CARDINAL-family, BOOLEAN, CHAR, REAL/LONGREAL (widened to `d`), with conversions, comparisons and full control flow. Suite 30/30 (14 run + 16 reject), LL(1)-clean, zero regressions. ## Backend (`QbeGen`) - `d_` immediates (`NormReal`); `IsImm` accepts them; `NegFold` folds `d_` literals (Test2 recipe). - `DeclVar`: `data $x = { d 0 }` for ClReal. `DeclConst`: zero reals as `d 0` (textual `IsZeroReal`, incl. `-0.0`); non-zero REALs as `d 0` + a recorded runtime `=d copy` flushed at `BeginBody` (this qbe rejects `d 1.5` in `data` — same limit Test2 hit, same workaround). - Threaded `isReal` through LoadVar (`loadd`) / StoreVar (`stored`) / Op3 (`=d`); `Cmp` gains ceqd/cned/cltd/cled/cgtd/cged; `NegQ` via `sub d_0.0`; new `ConvIR` (`swtof`) for INTEGER→REAL assignment widening. ## Grammar (isReal threading, Test1 type rules) - Real literals fold (`NormReal`, no more 230); `/` added to MulOp (OpSlash → `div`, Test2 parity: also defined on integers as truncating division — documented, matches the lenient family). - `VAR x: REAL` accepted; loads/stores carry the class flag in Design (var/param/const), SimExpr/Term (arith + unary minus), Expr (comparisons; flag read before the type becomes BOOLEAN). - Conversions ONLY via assignment (`r := 3` → swtof); mixed arithmetic and mixed comparisons stay 211/213; REAL→INTEGER is 210. No implicit anything else. ## Tests `t_real` → 31 (zero + flushed CONSTs, conversion, all six real comparisons, `/`, real unary-minus temps, int/real branches) with hand-checked `.ssa` (flush block, swtof, cgtd all present); `t_bad_mixed` (`i := r`) → 210. ## Honest leftovers (scalar) - CHAR arithmetic is 211; enum literals don't lower (use is 230); enum/char subrange bounds are integer-only. - `LONGINT`/`LONGREAL` are aliases (true quads = later step). - `5 / 2` on integers truncates (Test2 parity, not Wirth `/`). - Division by zero traps via QBE/SIGFPE (no language Trap yet — arrives with `runtime/syslib/Trap`). Next: step 3 composites (ARRAY/RECORD/SET/POINTER + the locked length-prefixed layout + WITH + IN).