# Step: Conversions + RealIO Tag `v3-stdlib-conversions`. Suite **122/122**; fixpoint **OK** (`bootstrap/fixpoint.sh`, 2,062,392 bytes). ## Added - **`Conversions`** — scalar ↔ string: - `IntToStr(n, VAR s)`, `CardToStr(n, VAR s)` — decimal, sign for negatives, NUL-terminated (written in Modula-2). - `RealToStr(x, VAR s)` — 6 significant digits, scientific (`%.6E`), via the shim. - `StrToInt(s, VAR n):BOOLEAN`, `StrToCard(s, VAR n):BOOLEAN` — whole-string parse (optional `+`/`-`), `FALSE` on stray chars or empty input. - `StrToReal(VAR s, VAR x):BOOLEAN` — `strtod` via the shim; `FALSE` unless the whole string is consumed. - **`RealIO`** — `WriteReal(x)` (no field), `WriteRealF(x, width)` (right-justified), `ReadReal(VAR x)` (`scanf("%lf")`). - **shim** (`runtime/syslib/shim.c`) — `m2realstr`, `m2strreal`, `m2writereal`, `m2writerealf`, `m2readreal`; all use the existing descriptor convention (`desc[0]` = capacity/length, bytes follow). ## Notes / deviations - `Conversions` uses `BOOLEAN` results rather than the ISO `ConvResults` enumeration (V3 enumeration values in expressions are still `230`). Signatures are otherwise "classic" and simple. - `WriteReal` emits no leading space (consistent with `WriteInt`); `WriteRealF(x, w)` pads to `w`. - The C-ABI match for the existing externals is reused (INTEGER formal ↔ C `long`), as in `Files`. ## Tests - `conv_prog.mod` (exit 127): `IntToStr(-1234)`, `StrToInt("42")`, `StrToInt("-7")`, `StrToInt("4x")` → `FALSE`, `StrToCard("99")`, `StrToReal("3.5")`. - `realio_prog.mod` (exit 42): stdout first line `3.500000E+00`, `ReadReal` of `1.25` from stdin. ## Files `stdlib/conversions.def`/`.mod`, `stdlib/realio.def`/`.mod`, `runtime/syslib/shim.c`, `compiler/tests/conv_prog.mod`, `compiler/tests/realio_prog.mod`, `compiler/run_tests.sh`, `docs/plan.md`, `docs/features.md`.