Make an interface method call resolvable from both halves it needs: the slot
that the interface declaration fixes at compile time, and the table pointer the
value carries at run time. iface_slot resolves the slot from the parser tables
and refuses a name the interface does not declare, so emission never invents an
offset. The call itself stays if_call (E06-S02); this story proves it against
the story's four behaviours, including self identity, two classes per call
site, two interfaces per object, arguments, and one-/two-byte returns.
src/common/ifcalls.inc (new): IS_OK, IS_ERR_METHODsrc/compiler/interfaces.s: iface_slot, is_errortests/compiler/iftable-test.s: slot-resolution checks in phase 7tests/runtime/ifcall-test.s (new)scripts/build-ifcall-test.ps1, scripts/verify-ifcall-test.ps1 (new)docs/decisions.md (D146), docs/architecture.md (status, 7.5),
docs/memory-map.md (call rows)planning/claims/E06-S05.mdbuild/iface_slot returns 0 for IFOO/ALPHA, 1 for IFOO/BETA, and 0 for IBAR/ALPHA
in the table fixture, so the slot is the declaration order assign_slots
recorded; the call fixture then passes those slots as constants to if_call,
which reads the table pointer from the value at run time. Phase 2 swaps only
the table pointer under one slot and reaches a different method for the same
object.self is the underlying object, not the fat-reference address: every
fixture method compares the incoming A/X against its class object
($1111/$2222) while the value records live elsewhere, and any miss counts
self_bad; all phases require self_bad = 0.$1111 (returns $A0) and on $2222
(returns $B0), with each class's call counter at 1.$1111 through the IFOO table (m_a0, $A0) and through
the IBAR table (m_abar, $C0).$5A+1
in A; phase 4 pushes a byte and a word, the method reads them at FP+2..FP+4
and returns $1234+7 in A/X ($3B/$12), and the caller's frame stack
returns to $C000 after discarding three argument bytes.iface_slot reports IS_ERR_METHOD for IBAR/GAMMA and for a
class ID, verified in the table fixture.if_call) and E06-S04 (values); both are complete. The
trampoline and frame ABI were reused unchanged, so this story adds no runtime
entry point and cannot regress dispatch behaviour.iface_slot is the lookup emission will call; codegen still handles only
byte scalars and zero-argument self calls, so wiring interface expressions
into emit.s remains open compiler work rather than part of this story.iface_slot beside assign_slots so the slot's writer and reader live
in one module; it walks the interface's signature rows and returns
C_MEM_SLOT rather than recomputing the index, which keeps a call site
correct if slot assignment ever changes.if_error) so it tests the call
path rather than a private copy of it..assert on the IFOO table: * - tab_a_foo spanned
all four tables. The assertion now subtracts the next label, and a second one
covers the one-slot IBAR table.scripts/verify-iftable-test.ps1 (x128, fresh D81, now including
the slot-resolution checks); scripts/verify-ifcall-test.ps1 (x128, fresh
D81); scripts/verify-parser-test.ps1 (42 semantic/parser fixtures);
git diff --check.NOVA128 IFTABLE TEST OK, and its four MAP records (stub addresses moved to
7573/7574/7576/7577 because interfaces.s grew). The call fixture
reports PASS with all four flags and prints IFCALL OK; its PRG ends $2354.if_call uses one shared
if_vec, safe only because the jump happens before a nested call can reuse
it; and argument pushes are byte-wise, so a stack refusal mid-push leaves the
caller's arguments to be discarded by the caller. Generated-code emission of
interface calls and lifetime remain E06-S06 and later compiler work, and
physical C128 testing remains P2 validation.Powered by TurnKey Linux.