# Session summary — 2026-09-29 (b): VIRTUAL dispatch + showcase18 Suite **144/144**; self-hosting fixpoint **OK** (image **2,310,300 bytes**). `master`, tree clean except the user's uncommitted `compiler/toto.mod`. This session completed the Clarion OOP story by adding **dynamic dispatch**, then showcased it. ## Steps, tags and headline commits | Step | Tag | Commit | What | | --- | --- | --- | --- | | VIRTUAL dispatch | `v3-virtual-dispatch` | `98d3067` | per-class vtables + subtype pointer assignment | | Showcase | `v3-showcase18` | (this commit) | polymorphic Shape hierarchy | ## 1. VIRTUAL dispatch (vtables) `VIRTUAL` methods now resolve at run time. A base-class pointer holding a derived object calls the derived override: ```modula-2 TYPE CLASS Shape; VIRTUAL PROCEDURE Area() : INTEGER; END Shape; CLASS Circle (Shape); VIRTUAL PROCEDURE Area() : INTEGER; END Circle; ... VAR b : POINTER TO Shape; c : POINTER TO Circle; BEGIN NEW(c); b := c; (* subtype pointer assignment *) ExitCode := b^.Area() (* Circle.Area, decided at run time *) END ``` - **vtable** — each class with virtuals owns a slice of a shared pool: the parent's slots are inherited first; a same-named virtual method overrides in place; new ones append. Each method node records its `vslot`. - **vptr** — the class introducing virtuals gets an 8-byte vtable pointer (offset 0 with no parent, else after the parent's fields); subclasses share it, so an object's vptr identifies its dynamic class. - **emission** — `data $vt_ = { l $Method_uid, … }`; a declared-but-unimplemented method is `l 0`. - **init** — static class variables and `NEW` store the vptr. - **dispatch** — a virtual call loads the vptr, fetches the slot, and calls indirectly; the receiver is the hidden first argument. - **subtyping** — `POINTER TO Derived` assigns to `POINTER TO Base` (`IsSubclass`), which lets a base pointer hold a derived object. Docs: `docs/summary_virtual-dispatch.md`. ## 2. Showcase `compiler/tests/showcase18.mod` (`Showcase18`, exit 42): a `Shape` hierarchy (`Circle`, `Square`) with a virtual `Area()`; an array of `POINTER TO Shape` holds objects of both kinds and each area is resolved at run time; the sum is asserted and printed: ``` showcase18 areas sum=139 ``` (The number is built with `Conversions.IntToStr` + CHAR-array `+`, tying in the earlier stdlib/string work.) ## Tests (144, was 143) New: `t_virtual` (3) and `Showcase18` (42). ## Resume ```sh cd .../m2compiler-V3 ./bootstrap/fixpoint.sh # FIXPOINT OK cd compiler && ./build.sh && ./run_tests.sh # 144/144 ``` ## Remaining polish - CLASS: bare sibling-method calls inside a method body, a class `BEGIN … END` init body, multiple parents. - `VAL(LONGINT|REAL, x)` and long→int narrowing. - More stdlib (`SysClock`, richer `Strings`/`Math`).