# Step: VAL conversions (LONGINT/REAL) + long→int narrowing Tag `v3-val-conversions`. Suite **148/148**; fixpoint **OK** (image **2,320,770 bytes**). ## What `VAL` now covers the numeric conversions V3 lacked: | From → To | Codegen | | --- | --- | | `INTEGER` → `LONGINT` | `extsw` (sign-extend) | | `LONGINT` → `INTEGER` | `copy w` (low 32 bits) | | `INTEGER` → `REAL` | `swtof` | | `LONGINT` → `REAL` | `sltof` | | `REAL` → `INTEGER` | `dtosi` (truncate toward zero) | | `REAL` → `LONGINT` | `dtosi` | (Ordinal↔ordinal, pointer↔pointer and REAL↔REAL were already allowed.) New `QbeGen` helpers: `NarrowLong`, `ConvRI`, `ConvRL`, `ConvLR` (alongside the existing `WidenLong`/`ConvIR`). ## Payoff `Conversions` is simplified: `StrToInt`/`StrToCard` now accumulate in a `LONGINT` and simply range-check, then narrow with `VAL(INTEGER, v)` / `VAL(CARDINAL, v)` — the previous "detect overflow before the 32-bit wrap" hand-guard is gone. ## Tests `t_valconv.mod` (15): int→long→int round-trip, int→real, real→int truncation, long→real. `ConvProg`/`ConvResultsProg` still pass with the rewritten `Conversions`. ## Files `compiler/src/QbeGen.def`/`.mod` (`NarrowLong`/`ConvRI`/`ConvRL`/ `ConvLR`), `compiler/src/M2.atg` (`VAL` action), `stdlib/conversions.mod`, `compiler/tests/t_valconv.mod`, `compiler/run_tests.sh`, `docs/features.md`.