Bladeren bron

docs: add complex-type future-work analysis

Eric Streit 3 dagen geleden
bovenliggende
commit
c575d22056
2 gewijzigde bestanden met toevoegingen van 152 en 8 verwijderingen
  1. 2 2
      docs/INDEX.md
  2. 150 6
      docs/future-work-2026-10-25.md

+ 2 - 2
docs/INDEX.md

@@ -35,8 +35,8 @@ bisecting *why* a decision was made, not for reading end-to-end).
 ## Future-work analysis
 
 - **`future-work-2026-10-25.md`** — TBITSIZE, ADDRESS arithmetic, set
-  ordering, PIM vs ISO coroutines, external assembly, dynamic-set design
-  and suggested order.
+  ordering, complex types, PIM vs ISO coroutines, external assembly,
+  dynamic-set design and suggested order.
 
 ## Designs / running records
 

+ 150 - 6
docs/future-work-2026-10-25.md

@@ -1,8 +1,10 @@
 # Future-work analysis — 2026-10-25
 
 This note records the design discussions from 2026-10-25 so the
-questions do not have to be re-derived later.  It is not a commitment
-to implement everything.
+questions do not have to be re-derived later.  It covers `TBITSIZE`,
+address arithmetic, set ordering, complex types, PIM versus ISO
+coroutines, external assembly, and the dynamic-set design.  It is not a
+commitment to implement everything.
 
 **State at the time of writing:** suite 310/310, one-shot fixpoint OK
 (3,845,439 bytes), per-object fixpoint OK (11 objects), corpus
@@ -301,14 +303,156 @@ range lists become too fragmented.
 
 ---
 
-## 7. Suggested order of future work
+## 7. Complex types: built-in types versus a library
+
+V3 currently has no complex arithmetic.  `COMPLEX32`, `COMPLEX64` and
+`COMPLEX128` are declaration-compatible aliases of `REAL` (currently 8
+bytes each), so they are placeholders, not real complex types.  Their
+names imply two 4-, 8- and 16-byte components (8, 16 and 32 bytes
+respectively), so the current aliases are also the wrong size.  The
+comparison table correctly marks `COMPLEX`/`LONGCOMPLEX` as unsupported.
+
+### What ISO expects
+
+ISO Modula-2 treats `COMPLEX`/`LONGCOMPLEX` as **predefined types**.
+The language is expected to provide:
+
+- complex arithmetic operators (`+`, `-`, `*`, `/`);
+- the `CMPLX` constructor;
+- `RE`/`IM` accessors;
+- complex-aware assignment, parameters and function results.
+
+Transcendental functions live in the separate `ComplexMath` and
+`LongComplexMath` library modules.  The ISO architecture is therefore:
+
+```text
+compiler-known COMPLEX/LONGCOMPLEX types
+        + operator lowering / builtins
+        + ComplexMath / LongComplexMath libraries
+```
+
+A separate library can provide complex-number *functions*, but it cannot
+by itself provide natural Modula-2 syntax such as `a + b` or `CMPLX`.
+Operator overloading does not exist in Modula-2, so a library-only design
+is necessarily a nonstandard utility API.
+
+### Why not classes
+
+Classes are a poor fit for complex numbers:
+
+- complex numbers are small value types, not objects with identity;
+- class methods give `a.Add(b)` instead of `a + b`;
+- class allocation/dispatch is unnecessary overhead for a pair of reals;
+- classes are not ISO Modula-2 OO (V3's `CLASS` is Clarion-form);
+- a class still cannot add operators, literals or `RE`/`IM` syntax.
+
+Use a value record or a compiler-known type, not a class.
+
+### What generics can do
+
+V3 has ISO 10514-2 generics, so a generic implementation could share code
+between real and long-real variants:
+
+```modula2
+GENERIC MODULE Complex(T);
+TYPE Value = RECORD re, im : T END;
+...
+END Complex.
+```
+
+That is useful for implementation sharing, but generics still do not
+provide operators, literals or ISO source compatibility.  Since V3's
+`REAL` and `LONGREAL` are both 8 bytes today, two small concrete modules
+are also acceptable and simpler for separate compilation.
+
+### Option A: nonstandard value-record library
+
+For practical complex math without an ISO-conformance claim:
+
+```modula2
+DEFINITION MODULE Complex;
+
+TYPE
+  T = RECORD
+        re, im : REAL
+      END;
+
+PROCEDURE Add (a, b : T) : T;
+PROCEDURE Sub (a, b : T) : T;
+PROCEDURE Mul (a, b : T) : T;
+PROCEDURE Div (a, b : T) : T;
+PROCEDURE Conj (z : T) : T;
+PROCEDURE Abs (z : T) : REAL;
+PROCEDURE Arg (z : T) : REAL;
+
+END Complex.
+```
+
+Advantages: value semantics, no allocation, simple ABI, easy to test.
+Limitations: call syntax only; no operator or literal support; does not
+satisfy ISO `COMPLEX`.
+
+Do **not** call this type `COMPLEX` or reuse the existing `COMPLEX*`
+aliases, because that would falsely suggest ISO support.
+
+### Option B: ISO-compatible built-in types
+
+Implement `COMPLEX`/`LONGCOMPLEX` as compiler-known value types, with
+arithmetic lowered to runtime helpers:
+
+```text
+COMPLEX = two REAL values
+a + b   -> __m2_complex_add(a, b)
+a * b   -> __m2_complex_mul(a, b)
+CMPLX   -> compiler builtin
+RE/IM   -> compiler builtins
+```
+
+Then implement `ComplexMath` and `LongComplexMath` as libraries on top.
+This avoids requiring QBE to understand a native complex type while still
+providing ISO syntax and semantics.
+
+Work items:
+
+- representation/layout (`COMPLEX` is 16 bytes with the current 8-byte
+  `REAL`; `COMPLEX32` cannot be 8 bytes until a real 4-byte `SHORTREAL`
+  exists);
+- type checking for mixed real/complex expressions and conversions;
+- lowering of arithmetic to helper calls;
+- `CMPLX`, `RE`, `IM` and constant expressions;
+- ABI for complex parameters/results, including separate compilation;
+- library implementations of `abs`, `arg`, `conj`, `sqrt`, `exp`, `ln`,
+  trigonometric functions and `polarToComplex`;
+- tests for arithmetic, constants, mixed precision, copying, parameters,
+  function results and separate objects.
+
+For C interop, do not assume the C99 `_Complex` ABI without checking;
+prefer small C wrappers where necessary.
+
+### Recommendation
+
+- If ISO conformance is a project goal, complex types must eventually be
+  built-in; the library is the math layer, not a replacement.
+- If only practical complex math is wanted, add the value-record
+  `Complex` library first, with no classes and no fake `COMPLEX` names.
+- Generics are optional implementation sharing, not a substitute for
+  language support.
+- Regardless of option, remove or clearly mark the current
+  `COMPLEX32/64/128` `REAL` aliases so programs cannot silently get
+  wrong-size, non-complex values.
+
+---
+
+## 8. Suggested order of future work
 
 1. `TBITSIZE` (small, standard-facing).
 2. `ADDADR`/`SUBADR`/`DIFADR` (small, ISO SYSTEM).
 3. Set ordering (bounded gm2 compatibility; fixes `largeset5`).
-4. ISO `COROUTINES` subset, then interrupt/protection layer.
-5. Dynamic `SET CONST` and deep composite copies.
-6. Parser error recovery and diagnostics.
+4. Complex types: choose ISO built-ins versus a nonstandard value-record
+   library; remove the misleading `COMPLEX*` aliases.
+5. ISO `COROUTINES` subset, then interrupt/protection layer.
+6. Dynamic `SET CONST` and deep composite copies.
+7. Parser error recovery and diagnostics.
 
 External assembly needs no compiler work; document it as the supported
 low-level escape hatch.