summary_proctypes.md 2.9 KB

Procedure types + indirect calls (step 3)

Tag v3-proctypes. Main suite 109/109 (new t_proctype).

What works

  • Procedure types: TYPE Op = PROCEDURE (a, b : INTEGER) : INTEGER; and anonymous ones in declarations (VAR Error : PROCEDURE (nr, line, col : INTEGER; pos : INT32);).
  • Type-only parameter form (GNU shorthand used by the Coco/R scanner frame): PROCEDURE (INT32) : CHAR, PROCEDURE (INTEGER, INTEGER, INTEGER, INT32).
  • Procedure-typed variables (module-level and local), stored as pointer-sized (l) code pointers, zero-initialised.
  • Assigning a procedure to a procedure variable: f := Add; emits the procedure's code address (storel $Mod_Add_N, $Mod_f).
  • Indirect calls: f(40, 2) emits %r =w call %t(l 0, w 40, w 2) (the leading l 0 is the static link).
  • Qualified proc-typed variables: M2S.Error(...), Error := Err;.

Implementation

  • SymTab: new descriptor form FProc (result in tref) with parameters in flat arrays (procp/procvis, per-type procstart/procn); builder NewProcType + ProcTypeAdd + SetProcTypeRes; accessors ProcTypeNPar/ParamType/ParamIsVar/Res; ProcTypeOf(name) builds the type of a named procedure; ClassOf → ClProc; SizeOf 8; Assignable compares procedure types structurally (ProcTypesOk). Max 1024 param slots.
  • QbeGen: ProcAddr (a procedure's code address as a value); ClProc handled in DeclVar/AllocLocal/ResClass/ LoadDesignator/ResClass; CallBeginInd + CallEnd emit call %<ptr>(...).
  • Grammar: ProcType in Type; ProcTypeSection accepts named (a, b : T) and type-only (T) parameter lists; Fact yields a procedure's code address when a procedure name is used as a value (not followed by (); ArgList/ActParam gained a proc-type + callee path for indirect calls (used from both statement and expression calls).

Limitations / follow-ups

  • Nested procedure values are not supported: only the code address is stored, so the static link passed to an indirect call is always 0 (fine for top-level procedures). The Coco/R driver's Error := StoreError (StoreError nested in ListHandler) will need this, or a source-level restructuring.
  • Type-only parameters that are composite (PROCEDURE (ARRAY OF CHAR)) are not parsed; only identifier type names are.

M2S status after this step

M2S compiled under V3 drops from 30 errors to 3, none procedure-type related:

  1. M2S.mod:111 — LENGTH(s) (GNU builtin; V3 has LEN).
  2. M2S.mod:201 — empty ELSE in a CASE (ELSE END).
  3. M2S.mod:206 — & used for AND (in CR's generated scanner tables, not our scanner.frm).

These are small language-compatibility items (aliases / empty branches), separate from procedure types.

Files

compiler/src/{SymTab.def,SymTab.mod,QbeGen.def,QbeGen.mod,M2.atg}, compiler/tests/t_proctype.mod, compiler/run_tests.sh.