summary_session-2026-09-28b.md 4.7 KB

Session summary — 2026-09-28 (b): Unicode, stdlib, language polish

Suite 128/128; self-hosting fixpoint OK (bootstrap/fixpoint.sh, image 2,080,607 bytes). master, tree clean except the user's uncommitted compiler/toto.mod.

This session continued from "V3 self-hosts (byte-identical fixpoint)" and completed four workstreams, each its own tagged step. Every step re-ran the fixpoint, so the compiler's own sources are compiled with the new semantics each time.

Steps, tags and headline commits

Step Tag Commit What
Unicode inc. 1 v3-unicode-1 af09dc6 UCHAR, U'..'/U".." literals, strict RFC 3629 → 234, UCHR/CHR8/UORD
Unicode inc. 2 v3-unicode-2 f1bfd76 runtime/syslib/Utf8, TextIO.U* UTF-8 output
stdlib v3-stdlib-conversions 2f80422 Conversions, RealIO (+ shim real helpers)
session doc v3-unicode-stdlib-summary 810946b first consolidated summary
language v3-lang-polish 23e7bf3 enum literals everywhere; string =/#
stdlib v3-programargs-iochan 4afc2b2 ProgramArgs, IOChan (+ SysShim primitives)
showcase v3-showcase14, v3-showcase14-summary 94c4c5e end-to-end program linking 7 modules
language v3-strcat 259f5ac string +, content-copy assignment, LEN of literals

1. Unicode (complete)

  • UCHAR: 32-bit codepoint, a distinct type (QBE w).
  • U'..'/U".." literals with strict RFC 3629 decoding (overlong/surrogate/>10FFFF/truncation → error 234 invalid UTF-8 in U-literal). One codepoint → UCHAR; otherwise a UString descriptor { l count, w cp… }, which is a valid V3 array for an open ARRAY OF UCHAR formal.
  • runtime/syslib/Utf8 (Decode/Encode); TextIO.UWriteChar/ UWriteString/UWriteLn emit real UTF-8 (verified byte-for-byte).
  • Flagged deviations: UORD returns INTEGER (V3 has no LONGCARD name and no 64→32-bit conversion); UCHR also accepts an integer operand; the front-end decode lives in QbeGen.DeclUStr (Stage 1 is gm2-built and cannot import a UCHAR-typed module).
  • Docs: docs/summary_unicode.md.

2. Library

  • Conversions — IntToStr/CardToStr/RealToStr, StrToInt/StrToCard/StrToReal (BOOLEAN results).
  • RealIO — WriteReal/WriteRealF/ReadReal.
  • ProgramArgs — ArgCount (excludes the program name), GetArg (1-based) over /proc/self/cmdline.
  • IOChan — opaque ChanId over the standard streams; ReadChar/WriteChar/WriteString/WriteLn/WriteInt.
  • runtime/syslib/shim.c gained the real, string and stdio helpers; SysShim gained argc/stdin/fgetc/fwriteint.
  • Docs: summary_stdlib-conversions.md, summary_programargs-iochan.md.

3. Language polish

  • Enum literals everywhere: ordinals assigned at declaration; usable in expressions, =/#/ordering, CASE labels, CONST initialisers and as value/parameter types.
  • String =/#: content comparison through the shim.
  • String +: concatenation (strings and a CHAR operand); the result lives in a static shim buffer — consume it immediately.
  • String assignment is now a content copy (truncated to the array capacity, NUL-terminated), replacing the count-checked copy that trapped. a := "abcd" into capacity 3 yields "abc".
  • LEN/LENGTH of string literals fold to the content length.
  • Docs: summary_lang-polish.md, summary_strcat.md.

4. Showcase

compiler/tests/showcase14.mod (Showcase14, exit 42) links seven modules and exercises the whole session: enums (CASE/CONST/ordering), string =/#, Utf8.Decode, Conversions, ProgramArgs, RealIO, TextIO.U* and IOChan.

showcase14 n=42
3.500000E+00 ok ✓

Docs: summary_showcase14.md.

Test suite

128 tests (was 111 at the start of the session): run, trap, reject and session/separate-compilation cases, plus the gm2-import gate. New this session: t_unicode, t_trap_chr8, four invalid-UTF-8 rejects, utf8_prog, utext_prog, conv_prog, realio_prog, t_enum (t_enumdecl promoted from reject), t_streq, progargs_prog, iochan_prog, showcase14, t_strcat, t_strtrunc, t_strempty. expect_run/expect_trap now link the shim.

Resume

cd .../m2compiler-V3
./bootstrap/fixpoint.sh                       # FIXPOINT OK
cd compiler && ./build.sh && ./run_tests.sh   # 128/128

Remaining polish

  • Strict 231 def/impl signature checks (types, not just arity).
  • Variant records (RECORD CASE).
  • Unicode: UString whole-string assignment to a fixed array.
  • IOChan beyond the standard streams (files, ReadString, position).
  • String concat: a growable/consumer-owned buffer instead of the single static 8 KiB slot.