Procházet zdrojové kódy

calc: accept forward definitions that repeat only the name (ladder 44567)

A forward FUNCTION was being rejected when its definition was reached: the
lookup only accepted a KProc forward, so a KFunc forward fell into the
duplicate/unexpected branch.  Accept both.

The definition may also omit the parameter list.  HideLocals had made the
forward's formal symbols invisible; when the definition reads no new list,
restore the forward parameter range at the body's lexical level, then hide it
again when the body ends.  This is what CALC's
`function Expression{(...):Real;forward};` requires while its body still uses
ExpressionCh.

Fixture t107_forward covers both the repeated-name shape and execution.
CALC now stops at delete(Formula,1,1), the Delete string builtin.

Verified: compile matrix 108/108, ladder 1/1 at ERR 41 44567, 94 .COM
executions under both oracles, rt_exec 276/276, nonvacuity 121/121, run_all
ALL PASS.
Eric Streit před 4 dny
rodič
revize
21ce8e5629

+ 18 - 12
CALC-COMPILE.md

@@ -97,7 +97,7 @@ Current rung (measured today, normalised position):
 
 | position | blocker |
 |---|---|
-| **43902** | the commented-out parameter list on the forward definition of `Expression` (`ERR 41`) |
+| **44567** | `delete(Formula,1,1)` in `Evaluate` — the `Delete` string builtin (`ERR 41`) |
 
 Rungs behind it (now passed):
 
@@ -155,7 +155,8 @@ Rungs ahead:
 | 40930 | `Exp`/`Ln` - DONE |
 | 41118 | `Sin`/`Cos`/`Arctan` - DONE |
 | 41595 | `Int(f)` - DONE |
-| 43902 | forward definition with a commented parameter list (`ERR 41`) |
+| 43902 | forward definition repeating only the name - DONE |
+| 44567 | `Delete` string builtin (`ERR 41`) |
 
 Corrections the measurements force, worth stating plainly because the stage list
 below was written before them:
@@ -481,10 +482,10 @@ block I/O, text-file output, `Str`, pointer types with `New`/dereference,
 text `Eof`/`Readln`, integer `Str`, integer `Val`, and VAR REAL parameters). The
 ladder has moved from the first typed constant at 7,791 to **35,135**, where
 The real functions `Ln`, `Exp`, `Sin`, `Cos` and `Arctan` are landed.  The
-ladder now stops at `function Expression{(var ExpressionCh : Char):Real;
-forward};` in `CALC.INC`, whose parameter list is commented out while the body
-still uses `ExpressionCh`; this is a source/forward-definition issue rather
-than a missing runtime function.
+forward definition `function Expression{(...):Real;forward};` is also accepted:
+the definition may repeat only the name, and the forward's formal symbols are
+made visible for its body again (`t107_forward`).  The ladder now stops at
+`delete(Formula,1,1)` in `Evaluate`.
 
 The rung commits and their tags, in order (each is one rung with its own
 fixture, red proof, and — where the harness allows — execution under qemu and
@@ -533,7 +534,8 @@ Exec86):
 | `884edba` | `v-TP3-CALC-REALFUNC` | `ERR 102 32482` (REAL constants) |
 | `30782f6` | `v-TP3-CALC-REALEXPR` | `ERR 41 35135` (`Copy`) |
 | `df54e71` | `v-TP3-CALC-COPYVAL` | `ERR 41 40930` (`Exp`) |
-| *(this commit)* | `v-TP3-CALC-TRANSCEND` | **`ERR 41 43902`** (forward definition) |
+| `dcfbf8c` | `v-TP3-CALC-TRANSCEND` | `ERR 41 43902` (forward definition) |
+| *(this commit)* | `v-TP3-CALC-FORWARD` | **`ERR 41 44567`** (`Delete`) |
 
 - **Code HEAD** is the layout rung (`v-TP3-CALC-LAYOUT`).  Nothing is pushed.
   The terminal-config work (`v-TP3-TERMCFG`) and the editor key map
@@ -593,6 +595,11 @@ Exec86):
 - **`Abs`, `Sqr` and `Sqrt` are landed (`t104_mathbasic`).**  `Abs` clears the
   MBF sign, `Sqr` lowers to the real multiply entry, and `Sqrt` is Newton over
   the existing real division/addition entries.
+- **Forward definitions may repeat only the name (`t107_forward`).**  The
+  earlier `function Expression{(...)}` source exposed two bugs: a forward
+  `FUNCTION` was rejected as if it were a duplicate `PROCEDURE`, and the
+  forward's formal parameter symbols stayed hidden from the definition body.
+  Both are fixed; the symbols are hidden again when the body ends.
 - **`Ln`, `Exp`, `Sin`, `Cos` and `Arctan` are landed (`t105_lnexp`,
   `t106_trig`).**  `Exp` scales by 256, evaluates a Taylor series and squares
   eight times; `Ln` extracts the exponent and uses the atanh series.  The
@@ -1224,11 +1231,10 @@ and TEXT file output is done (`t91_textout`), both compile-only because the
 harness has no filesystem.  `Str` real formatting is done (`t92_strreal`),
 pointer types with `New`/`Dispose`/dereference are done (`t93_pointer`), and
 text `Eof`/`Readln` plus integer `Str` are done (`t94_textread`/`t95_strint`).
-The next ladder blocker is the forward definition of `Expression` in
-`CALC.INC`: its parameter list is commented out, so `ExpressionCh` is not in
-scope.  All the REAL builtins CALC uses are now implemented.  The runtime is
-13,955 bytes; `rt_exec` moved to HDR=0x4000 / data 0x5000, and the compiler's
-code ceiling is 0x7F00 so the large CALC image can reach this source point.
+The next ladder blocker is the `Delete` string builtin in `Evaluate`.  All the
+REAL builtins CALC uses are implemented, and forward definitions that repeat
+only the name are accepted.  The runtime is 13,955 bytes; `rt_exec` is at
+HDR=0x4000 / data 0x5000, and the compiler's code ceiling is 0x7F00.
 
 **Stage 14 — the CRT identifiers.** `GotoXY` (25), `LowVideo`/`NormVideo`
 (16 + 16), `ClrEol` (10), `ClrScr` (6), `KeyPressed` (3), `Delay` (1),

+ 5 - 4
SUMMARY.md

@@ -2044,7 +2044,7 @@ the compiler *emitting* a 16,560-byte program). The ratchet and front-end
 features through **file control-block operations and the original memory
 layout** are landed: the ladder (`tests/calc_ladder.sh` +
 `tests/fixtures/calc_ladder.tsv`, run by `run_all.sh`; CALC.PAS now stops at
-`ERR 41` at pos 43902, the commented parameter list on Expression), the `{$I}` include,
+`ERR 41` at pos 44567, `Delete(Formula,1,1)`), the `{$I}` include,
 `^X`/`#nn`, scalar typed constants, sets, enums, records (CellRec = 80),
 subranges, arrays, element/field access, file types, string value parameters,
 `Length`, the CRT identifiers (`ClrScr`/`GotoXY`/`ClrEol`/`LowVideo`/
@@ -2066,9 +2066,10 @@ pointer types with `New`/`Dispose`/dereference (`t93`), text `Eof`/`Readln`
 (`t94`), integer `Str` (`t95`), and integer `Val` (`t96`). The next rung is
 REAL function results (`t98`), value REAL parameters (`t99`), REAL
 literals/comparisons/arithmetic (`t100`) and self-recursion (`t101`). The next
-rung is the forward definition of `Expression`; all REAL builtins used by CALC
-are landed.  The runtime is 13,955 bytes / 54 entries; the rt_exec scaffold
-moved to HDR=0x4000 / data 0x5000. Items 1-4
+rung is the `Delete` string builtin; forward definitions that repeat only the
+name and all REAL builtins used by CALC are landed.  The runtime is 13,955
+bytes / 54 entries; the rt_exec scaffold moved to HDR=0x4000 / data 0x5000.
+Items 1-4
 below are independent of both tracks.
 
 1. The rest of the string language. `v-TP3-STRVAR`/`v-TP3-STRREAD-ASSIGN` cover

+ 21 - 2
shell/Compiler.mod

@@ -7465,6 +7465,7 @@ VAR nm : ARRAY [0..MaxName] OF CHAR ;
     saveLB, savePO, saveRP : CARDINAL ;
     saveR : BOOLEAN ;
     realResult : BOOLEAN ;
+    reusedFwd : BOOLEAN ;
     nestMark : CARDINAL ;             (* symTop just inside this procedure *)
     i, first : CARDINAL ;
 BEGIN
@@ -7476,8 +7477,8 @@ BEGIN
    END ;
    GetWord () ;
    SaveWord (nm) ;
-   IF Search (nm, idx) AND (symtab [idx].tag = KProc)
-      AND (symtab [idx].fwd) THEN
+   IF Search (nm, idx) AND ((symtab [idx].tag = KProc)
+      OR (symtab [idx].tag = KFunc)) AND (symtab [idx].fwd) THEN
       old := idx
    ELSIF Search (nm, idx) THEN
       Err (EUnknown) ;
@@ -7619,6 +7620,21 @@ BEGIN
       symtab [old].parmFirst := nestMark ;
       symtab [old].parmCount := symTop - nestMark
    END ;
+   (* TP3 lets the definition of a forward repeat only the name.  CALC writes
+      `function Expression{(...):Real;forward};` -- the parameter list is in a
+      comment, but the body still uses ExpressionCh.  The forward's formal
+      symbols are still in the table (HideLocals only changed their level), so
+      make exactly that range visible for this body again. *)
+   reusedFwd := FALSE ;
+   IF (symTop = nestMark) AND symtab [old].fwd
+      AND (symtab [old].parmCount > 0) THEN
+      i := symtab [old].parmFirst ;
+      WHILE i < symtab [old].parmFirst + symtab [old].parmCount DO
+         symtab [i].level := lexnest ;
+         INC (i)
+      END ;
+      reusedFwd := TRUE
+   END ;
    realResult := FALSE ;
    IF isFunc THEN
       IF MatchDelim (':') THEN
@@ -7708,6 +7724,9 @@ BEGIN
       INC (i)
    END ;
    HideLocals (nestMark) ;         (* parameters and locals stop here *)
+   IF reusedFwd THEN
+      HideLocals (symtab [old].parmFirst)
+   END ;
    lexnest := saveNest ;
    locFree := saveLoc ;
    resultVar := saveRes ;

+ 1 - 1
shell/tests/fixtures/calc_ladder.tsv

@@ -36,4 +36,4 @@
 # 22280 -> 22706 -> 22859 -> 23700 -> 25674 -> 26066 -> 26924 -> 27648 ->
 # 28074 -> 31758 -> 32096 -> 32284 -> 32482 -> 32564 -> 33374 -> 33537 ->
 # 33778 -> 35135.  The next blocker is the Copy string builtin (TP3 error 41).
-CALC.PAS	ERR	41	43902
+CALC.PAS	ERR	41	44567

+ 3 - 0
shell/tests/fixtures/expected.tsv

@@ -716,3 +716,6 @@ t104_mathbasic	OK	472	80
 t105_lnexp	OK	1154	184
 
 t106_trig	OK	1338	184
+
+#   t107_forward         forward definition repeating only the name; formals stay in scope.
+t107_forward	OK	99	6

+ 1 - 0
shell/tests/fixtures/t107_forward.out

@@ -0,0 +1 @@
+42

+ 18 - 0
shell/tests/fixtures/t107_forward.pas

@@ -0,0 +1,18 @@
+program t107_forward;
+
+{ t107 -- a forward definition may repeat only the name; the formal parameter
+  symbols from the forward declaration remain visible in the body. }
+
+function AddOne (var C : char; N : integer) : integer; forward;
+
+function AddOne{(var C : char; N : integer):integer;forward}: integer;
+begin
+  AddOne := N + 1
+end;
+
+var
+  Ch : char;
+begin
+  Ch := 'x';
+  writeln (AddOne (Ch, 41))
+end.