Branch resolve-check, tree clean. Suite 218/218; fixpoint
OK (3,711,046 bytes); corpus 372 OK / 0 crash.
showcase23.mod builds a doubly linked list with the generic module
DList (T : TYPE) instantiated as IntList = DList(INTEGER):
GENERIC DEFINITION MODULE DList (T : TYPE);
TYPE
Node = POINTER TO NodeRec;
NodeRec = RECORD val : T; prev, next : Node; END;
List = RECORD head, tail : Node; count : INTEGER; END;
PROCEDURE Init(VAR l : List);
PROCEDURE Append(VAR l : List; v : T);
PROCEDURE Prepend(VAR l : List; v : T);
PROCEDURE Count(VAR l : List) : INTEGER;
PROCEDURE Get(VAR l : List; i : INTEGER) : T;
PROCEDURE First / Last(VAR l : List) : T;
PROCEDURE Reverse(VAR l : List);
END DList.
Run wired as expect_run_files_out Showcase23 35 "list: 5 10 20":
list: 5 10 20
reversed: 20 10 5
sum=35
Files: showcase23lib.def/.mod (the generic), showcase23int.def/.mod
(IntList = DList(INTEGER)), showcase23.mod (the program).
While writing it, WHILE i < IntList.Count(l) DO … END returned 0. The
cause was in QbeGen.RecItems: a record's static data initialiser
emitted w 0 (4 bytes) for every scalar field, including pointers
and LONGINT/proc (8-byte) fields, while the record layout gives them 8
bytes. A global of such a record was therefore under-sized, and the
next globals overlapped and clobbered its tail — here List.count.
VAR g : L; a : INTEGER; (* L = RECORD head, tail : P; n : INTEGER END *)
g.n := 5; a := 37; (* a clobbered g.n, at offset 16 *)
Fixed by emitting l 0 for ClPtr/ClLong/ClProc fields (real/char/
set/array/record were already size-correct). Regression: t_recptr
(exits 42 only when g.n survives). $g now emits
{ l 0, l 0, w 0 } instead of { w 0, w 0, w 0 }.
Sum over T
(s : T; s := s + n^.val) is 211 at template parse: an unbound
formal alias is class ClPtr (pointer-like), so numeric checks fail.
Workaround used: do the arithmetic in the concrete program
(acc := acc + Get(l, i)). A principled fix is to let checks skip an
unbound type formal (a distinct form from an opaque alias).235 ("implementation does not match definition"): proc types
are not deduped, so the def's and impl's constructed proc type have
different TypeIndexes and the signature snapshot compares unequal.
Not used in the showcase for that reason.Both are follow-ups; neither affects the showcase.
cd .../m2compiler-V3/compiler
./M2 ../stdlib/sysio.def ../stdlib/sysio.mod \
tests/showcase23lib.def tests/showcase23lib.mod \
tests/showcase23int.def tests/showcase23int.mod tests/showcase23.mod