Browse Source

showcase20: aggregate constructors end to end

- Showcase20 (exit 42): CHAR-array CONST, the BY repeat form, a static
  record constructor (string field + inlined nested record), a runtime
  record constructor and a runtime array constructor; prints
  'showcase20 total=42' via Conversions + TextIO.
- docs/summary_showcase20.md: session summary (constructors + showcase).
- Suite 159/159; fixpoint OK (2,639,067 bytes).
Eric Streit 1 tuần trước cách đây
mục cha
commit
b0494da465
4 tập tin đã thay đổi với 150 bổ sung và 1 xóa
  1. 5 0
      compiler/run_tests.sh
  2. 61 0
      compiler/tests/showcase20.mod
  3. 1 1
      docs/features.md
  4. 83 0
      docs/summary_showcase20.md

+ 5 - 0
compiler/run_tests.sh

@@ -305,6 +305,11 @@ expect_run_files_out Showcase19 42 "showcase19 total=42" \
   ../stdlib/textio.def ../stdlib/textio.mod \
   ../stdlib/conversions.def ../stdlib/conversions.mod \
   showcase19.mod
+expect_run_files_out Showcase20 42 "showcase20 total=42" \
+  ../runtime/syslib/Utf8.def ../runtime/syslib/Utf8.mod \
+  ../stdlib/textio.def ../stdlib/textio.mod \
+  ../stdlib/conversions.def ../stdlib/conversions.mod \
+  showcase20.mod
 expect_run_files_out Showcase18 42 "showcase18 areas sum=139" \
   ../runtime/syslib/Utf8.def ../runtime/syslib/Utf8.mod \
   ../stdlib/textio.def ../stdlib/textio.mod \

+ 61 - 0
compiler/tests/showcase20.mod

@@ -0,0 +1,61 @@
+MODULE Showcase20;
+// Session showcase: array and record constructors (GNU Modula-2).
+//
+//   * a CHAR-array CONST from a constructor;
+//   * a CARDINAL-array CONST using the `expr BY n` repeat form;
+//   * a static record constructor (a nested array-from-string field
+//     and an inlined nested record field);
+//   * a runtime record constructor (fields from variables);
+//   * a runtime array constructor (elements from variables).
+//
+// Expected ExitCode: 42.
+IMPORT TextIO, Conversions;
+
+TYPE
+  Name   = ARRAY [0..7] OF CHAR;
+  Triple = ARRAY [0..2] OF CARDINAL;
+  Date   = RECORD y, m, d : CARDINAL END;
+  Person = RECORD name : Name; born : Date END;
+
+CONST
+  Greet = Name   { 'H','e','l','l','o','!','!','!' };
+  Base  = Triple { 7, 7 BY 2 };          (* the repeat form: 7, 7, 7 *)
+
+VAR
+  p, q  : Person;
+  a, b  : Triple;
+  i     : CARDINAL;
+  total : CARDINAL;
+  msg   : ARRAY [0 .. 63] OF CHAR;
+  num   : ARRAY [0 .. 15] OF CHAR;
+  ExitCode : INTEGER;
+
+BEGIN
+  (* static record constructor: string field + inlined nested record *)
+  p := Person { "Modula", Date { 1980, 5, 3 } };
+
+  (* runtime record constructor: every field is a runtime value *)
+  i := p.born.m;                          (* 5 *)
+  q := Person { "Runtime", Date { i, i + 1, i + 2 } };
+
+  (* runtime array constructor: elements from variables *)
+  a := Triple { i, i + 1, i + 2 };        (* 5, 6, 7 *)
+  b := Triple { Base[0], Base[1], Base[2] };
+
+  total := 0;
+  total := total + Base[0] + Base[1] + Base[2];   (* 7+7+7  = 21 *)
+  total := total + a[0] + a[1] + a[2];            (* 5+6+7  = 18 *)
+  total := total + p.born.d;                      (* 3      = 42 *)
+
+  Conversions.CardToStr(total, num);
+  msg := "showcase20 total=" + num;
+  TextIO.WriteString(msg);
+  TextIO.WriteLn;
+
+  IF (total = 42)
+     AND (Greet[0] = 'H') AND (Greet[7] = '!')
+     AND (p.name[0] = 'M') AND (p.born.y = 1980)
+     AND (q.name[0] = 'R') AND (q.born.d = 7)
+     AND (b[0] = 7) AND (b[2] = 7)
+  THEN ExitCode := 42 ELSE ExitCode := 1 END
+END Showcase20.

+ 1 - 1
docs/features.md

@@ -1,4 +1,4 @@
-# m2compiler-V3 — feature status (at `v3-stdlib-more`, 151/151 green)
+# m2compiler-V3 — feature status (at `v3-showcase20`, 159/159 green)
 
 Pipeline: Coco/R `M2.atg` (1748 lines, 73 productions) → `gm2`-built
 `M2` → QBE `.ssa` → `qbe` → `cc` → run. `SymTab.mod` 1623 lines,

+ 83 - 0
docs/summary_showcase20.md

@@ -0,0 +1,83 @@
+# Session summary — 2026-09-30: aggregate constructors + showcase20
+
+Suite **159/159**; self-hosting fixpoint **OK**
+(image **2,639,067 bytes**). `master`, tree clean except the user's
+uncommitted `compiler/toto.mod`.
+
+This session added GNU Modula-2 **aggregate constructors** and
+showcased them.
+
+## Steps, tags and headline commits
+
+| Step | Tag | Commit | What |
+| --- | --- | --- | --- |
+| Array constructors | `v3-array-ctors` | `c03563e` | `T{…}` static descriptors |
+| Records + runtime | `v3-ctor-records` | `382125a` | `Rec{…}`, runtime build |
+| Showcase | `v3-showcase20` | (this commit) | constructors end to end |
+
+## 1. Constructors
+
+`TypeName{…}` (GNU Modula-2) is now an aggregate constructor for arrays
+and records:
+
+- **Static** — when every element is a constant, `CtorEnd` bakes a
+  pooled descriptor (`data $ctoN = { … }`) with the same layout as a
+  declared object: array `l n, …`, record fields in declaration order,
+  nested constructors inlined as aggregate fields (and consumed),
+  strings inlined into matching `CHAR`-array fields.  A `CONST` of an
+  aggregate type resolves to the descriptor address.
+- **Runtime** — any non-constant element makes `CtorEnd` allocate the
+  descriptor on the stack (`alloc8`) and fill it in place
+  (`ElemStore` / `InitArrHeader`+`CopyArray` / `CopyRecord` /
+  `CopySet`), so constructors also work outside `CONST`.
+- Elements: scalars, nested constructors, strings for `ARRAY OF CHAR`,
+  and the `expr BY n` repeat form.
+
+`QbeGen.CtorBegin/CtorElem/CtorEnd` (`CtorElem` derives the element
+type itself); the old `TypedSetLit` became the unified `TypedBraceLit`
+(`BITSET{…}` stays a set).
+
+## 2. Showcase
+
+`compiler/tests/showcase20.mod` (`Showcase20`, exit 42) exercises:
+
+- `Greet = Name {'H','e','l','l','o','!','!','!'}` — CHAR-array CONST;
+- `Base = Triple {7, 7 BY 2}` — the `BY` repeat form (7,7,7);
+- `p := Person{"Modula", Date{1980, 5, 3}}` — static record
+  constructor (string field + inlined nested record);
+- `q := Person{"Runtime", Date{i, i+1, i+2}}` — runtime record
+  constructor;
+- `a := Triple{i, i+1, i+2}` — runtime array constructor.
+
+Sum: `21 (Base) + 18 (a) + 3 (p.born.d) = 42`.
+
+```
+showcase20 total=42
+```
+
+## Tests (159, was 155)
+
+New: `Showcase20` (42), plus `t_ctor{1..6}` (`t_ctor1` CHAR-array
+copy, `t_ctor2` `BY` repeat, `t_ctor3` nested strings, `t_ctor4`
+static record, `t_ctor5` runtime array, `t_ctor6` runtime record).
+
+## Corpus (with `$V3_LIBS`)
+
+gm2 testsuite **283/612** compile-OK (was 242 before this work; 0
+CRASH).  `strcons.mod`, `testarray.mod`, `arrayconst{1,2,3}.mod`,
+`lazyunique.mod`'s array constructor now compile.
+
+## Resume
+
+```sh
+cd .../m2compiler-V3
+./bootstrap/fixpoint.sh                       # FIXPOINT OK
+cd compiler && ./build.sh && ./run_tests.sh   # 159/159
+```
+
+## Remaining
+
+- Set fields in record constructors; constant string concatenation in
+  constructor elements.
+- `ARRAY <type> OF T` (index-type arrays).
+- `MIN`/`MAX` builtins; more `SYSTEM` facilities.