Status: not started (scoped here). Suite 137/137; fixpoint OK.
Classes parse, scope and check — fields, methods, = consts,
single/multiple parent lists, VIRTUAL, and CLASS IMPLEMENTATION
blocks with nested procedures — but every class/method ends in error
230 and method bodies are suppressed (QbeGen.SetNoEmit(TRUE) +
AbortFunc in MethodImpl). See docs/OOP.txt for the grammar.
Make a class a usable value with callable methods:
TYPE
CLASS Point;
x, y : INTEGER;
PROCEDURE Set(a, b : INTEGER);
PROCEDURE Get() : INTEGER;
END Point;
CLASS IMPLEMENTATION Point;
PROCEDURE Set(a, b : INTEGER);
BEGIN x := a; y := b END Set;
PROCEDURE Get() : INTEGER;
BEGIN RETURN x + y END Get;
END Point;
VAR p : Point;
BEGIN p.Set(3, 4); ExitCode := p.Get() END
Layout — a class is a record: fields get declaration-order
offsets via the existing ComputeOffsets/FieldOffset machinery
(already shared with RECORD; PushRecord already accepts
FClass). obj.field then works through the record field path.
Single inheritance prepends the parent's fields (offset by the
parent's size); multiple parents stay 230.
Receiver — each method gets a hidden first parameter THIS
of type POINTER TO <class>. Inside a method body, a bare field
name f is an implicit THIS^.f; the class scope already holds the
fields as KindField, so Design needs a "current receiver"
addressing mode (like WITH): push the receiver register at method
entry, add FieldOffset to it, load/store.
Calls — obj.M(args) binds statically to the method's mangled
symbol and passes ADR obj as the hidden first argument, then the
user arguments. QbeGen.CallBegin/ArgList gain a flag for the
implicit receiver. Non-virtual first; VIRTUAL accepts but
dispatches statically with a 230-free path.
Dispatch (later) — a per-class vtable (one static array of code
pointers, parent entries first) stored as a hidden first field;
VIRTUAL calls load the slot and call indirectly (procedure types
WITH-style field binding — reuse PushRecord/PushWith; the
receiver is the WITH base, so WITH p DO x := 1 END works for
free once (2) lands.
Point program above compiles and exits 7.obj.field read/write, method calls with value and VAR params,
methods returning values.Design's addressing is threaded through several productions;
adding a receiver mode must not change existing RECORD/WITH
codegen (fixpoint is the guard).VIRTUAL/vtable must not perturb layout for non-virtual classes.compiler/src/M2.atg (ClassRest/ClassImplRest/MethodImpl
lowering, Design receiver mode, call-site receiver),
compiler/src/SymTab.def/.mod (receiver scope, parent field
offsets, vtable), compiler/src/QbeGen.def/.mod (receiver param,
vtable emission, indirect VIRTUAL calls),
compiler/tests/t_class*.mod, docs/OOP.txt.