Surface rename of the signed integer family: s1..s64 become i1..i64
(u1..u64, usize, isize unchanged). 'string' keeps the s-prefix arm in
name classification; width parsing moves to the i-prefix arm next to
isize.
Internal TypeId tags follow the surface (.s8/.s16/.s32/.s64 ->
.i8/.i16/.i32/.i64), as do mono-key mangle fragments (ptr_i64,
tu_i64_bool) and all display/diagnostic formatting (i{d}).
Migrated in the same sweep: stdlib + examples + issue repros + FFI C
companions (shared symbol names like ffi_id_i64), expected
stdout/stderr/ir snapshots, specs.md, readme.md, CLAUDE.md/AGENTS.md,
implementation_plan.md, docs/, issue writeups. Vendored stb_image and
historical flow state left untouched.
zig build test: 426/426; examples suite: 595/595.
A block's value is now its last statement ONLY when that statement is a
trailing expression with no `;`. A trailing `;` discards the value,
leaving the block void. This makes value-vs-statement explicit and lets
the compiler reject "this block was supposed to produce a value".
Compiler:
- Parser records `Block.produces_value` (last stmt is a no-`;` trailing
expression) + `Block.discarded_semi` (the `;` that discarded a value),
via `expectSemicolonAfter`. A trailing expression before `}` may now
omit its `;` (previously a parse error). Match-arm and else-arm bodies
are built value-producing regardless of the arm `;` (arms are exempt —
the `;` is an arm terminator).
- Lowering: `lowerBlockValue` / the block-expr path / `inferExprType`
respect `produces_value`. A value-position block that discards its value
is a hard error (`lowerValueBody` for function bodies; the value-context
`.block` path for if/else branches, `catch` bodies, value bindings,
match arms). Pure-failable `-> !` bodies (value rides the error channel)
and a value-if whose branches are void are handled without false errors.
- `defer`/`onfail` cleanup bodies lower as statements (void), so a
trailing `;` there is fine.
Migration (behavior-preserving — output unchanged):
- stdlib + ~210 examples: dropped the trailing `;` on value-position last
expressions. `format` now ends with an explicit `#insert "return
result;"` (it relied on `#insert`-as-block-value, which `;` discards).
- Two `main :: () -> s32` examples that relied on the old silent
default-return got an explicit trailing `0`.
- Rejection snapshots 0412 / 1013 regenerated (their quoted source lines
lost a `;`); the diagnostics themselves are unchanged.
Docs/tests: specs.md "Block values" section; examples 0040 (rules) + 0041
(rejection); 3 parser unit tests. Filed issue 0066 (pre-existing
match-arm negated-literal phi-width quirk, surfaced not caused here).
Gates: zig build, zig build test, run_examples.sh -> 343 passed,
cross_compile.sh -> 7 passed (also refreshed its stale example names).
20 files (~3,830 lines): view protocol, layout, renderer, glyph cache,
fonts, gestures, animation, scroll, stacks, modifiers, etc.
Internal imports rewritten from "ui/..." to "modules/ui/...".
Consumers now `#import "modules/ui"` from any project; no symlink
hacks needed. Verified by compiling game/main.sx without its local
ui/ — resolves via the Phase 6 stdlib fallback.