|
|
@@ -32,8 +32,8 @@
|
|
|
- TEXTS handle literal 3 used throughout (screen?); kept as-is. *)
|
|
|
|
|
|
IMPLEMENTATION MODULE SymTab;
|
|
|
-IMPORT Compiler, Files, Loader, Texts, Errors, Scanner, CodeGen;
|
|
|
-FROM SYSTEM IMPORT ADDRESS, ADR, MOVE;
|
|
|
+IMPORT Compiler, Loader, Texts, Errors, Scanner, CodeGen; (* Files comes via DEF import (leak rule); re-listing is a hard error *)
|
|
|
+FROM SYSTEM IMPORT ADR, MOVE; (* ADDRESS/WORD come via DEF import (leak rule) *)
|
|
|
|
|
|
(* ---- heap model (groups B + C) ---- *)
|
|
|
(* MCode words are untyped; CARDINAL()/T1()/ADDRESS() punning mirrors the
|
|
|
@@ -47,23 +47,23 @@ TYPE Words = POINTER TO ARRAY [0..7] OF CARDINAL;
|
|
|
Numbering: DEF vars occupy words 2..9, these follow. *)
|
|
|
VAR
|
|
|
(* word 10 *) ownNamePtr: ADDRESS;
|
|
|
- (* word 11 *) stageSpare11: CARDINAL; (* use TBD *)
|
|
|
- (* word 12 *) symHeapBase: ADDRESS;
|
|
|
- (* word 13 *) scopeHeapBase: ADDRESS;
|
|
|
- (* word 14 *) strHeapBase: ADDRESS;
|
|
|
+ (* word 11 *) spare11: CARDINAL; (* use TBD *)
|
|
|
+ (* word 12 *) symHeap: ADDRESS;
|
|
|
+ (* word 13 *) scpHeap: ADDRESS;
|
|
|
+ (* word 14 *) strHeap: ADDRESS;
|
|
|
(* word 15 *) symTop: CARDINAL;
|
|
|
(* word 16 *) scopeTop: CARDINAL;
|
|
|
(* word 17 *) strTop: CARDINAL;
|
|
|
- (* word 18 *) exportHead: CARDINAL;
|
|
|
- (* word 19 *) stageNameTotal: CARDINAL;
|
|
|
- (* word 20 *) savedSymInfo: CARDINAL;
|
|
|
- (* word 21 *) savedStrInfo: CARDINAL;
|
|
|
+ (* word 18 *) expHead: CARDINAL;
|
|
|
+ (* word 19 *) namTotal: CARDINAL;
|
|
|
+ (* word 20 *) savSym: CARDINAL;
|
|
|
+ (* word 21 *) savStr: CARDINAL;
|
|
|
(* word 22 *) symCap: CARDINAL;
|
|
|
(* word 23 *) scopeCap: CARDINAL;
|
|
|
(* word 24 *) strCap: CARDINAL;
|
|
|
- (* word 25 *) stageFlag: CARDINAL; (* nestedProcFlag / compileActive readings *)
|
|
|
- (* word 26 *) stageSpare26: CARDINAL; (* use TBD *)
|
|
|
- (* word 27 *) checksumTemp: CARDINAL;
|
|
|
+ (* word 25 *) stgFlag: CARDINAL; (* nestedProcFlag / compileActive readings *)
|
|
|
+ (* word 26 *) spare26: CARDINAL; (* use TBD *)
|
|
|
+ (* word 27 *) chkTemp: CARDINAL;
|
|
|
|
|
|
(* 14-byte symbol-heap entry = 7 words (group C names). *)
|
|
|
TYPE SymEntryPtr = POINTER TO SymEntry;
|
|
|
@@ -126,18 +126,18 @@ CONST symReadError = 790; (* RAISE code in LibRead {/*0497*/} *)
|
|
|
|
|
|
(* ---- FORWARDs for the PutAttr/GetAttr <-> EnterChained/AllocSym/
|
|
|
UnlinkScope/EnterIdent recursion cycle (group B) ---- *)
|
|
|
-PROCEDURE SymbolAssert(cond: BOOLEAN; code: CARDINAL); FORWARD;
|
|
|
+(* SymbolAssert/DefineDefinitionModule are DEF-declared: no FORWARD (v1.00 rejects
|
|
|
+ a FORWARD duplicating a DEF declaration, proven on hardware). *)
|
|
|
PROCEDURE CheckNode(node: T1); FORWARD;
|
|
|
PROCEDURE EnterChained(scope: ADDRESS; node: T1); FORWARD;
|
|
|
-PROCEDURE AllocSym(scope: ADDRESS; node: T1); FORWARD;
|
|
|
+PROCEDURE AllocSym(scope: Words; node: T1); FORWARD;
|
|
|
PROCEDURE UnlinkScope(scope: ADDRESS; idx: CARDINAL); FORWARD;
|
|
|
-PROCEDURE EnterIdent(scope: ADDRESS; idx: CARDINAL); FORWARD;
|
|
|
-PROCEDURE PutAttr(VAR slot: CARDINAL; src: T1); FORWARD;
|
|
|
+PROCEDURE EnterIdent(scope: Words; idx: CARDINAL); FORWARD;
|
|
|
+PROCEDURE PutAttr(VAR slot: CARDINAL; src: Words); FORWARD;
|
|
|
PROCEDURE GetAttr(VAR node: T1; idx: CARDINAL); FORWARD;
|
|
|
PROCEDURE LookupChain(scopeNo: CARDINAL; key: CARDINAL): T1; FORWARD;
|
|
|
PROCEDURE InitHeaps; FORWARD;
|
|
|
PROCEDURE EnterStandards; FORWARD;
|
|
|
-PROCEDURE DefineDefinitionModule(isImpl: CARDINAL); FORWARD;
|
|
|
PROCEDURE ImportOne(anchor: ADDRESS; symIdx: CARDINAL); FORWARD;
|
|
|
|
|
|
(* ================= group A: module/scope search (@0001-00d4) ================= *)
|
|
|
@@ -151,9 +151,11 @@ END SymbolAssert;
|
|
|
PROCEDURE FindModule(slot: CARDINAL): CARDINAL;
|
|
|
(* proc9 @000c: 16 = self, 17 = not found *)
|
|
|
VAR i: CARDINAL;
|
|
|
+ key: ModuleSymPtr;
|
|
|
BEGIN
|
|
|
(*{/*0016*/} key.name = ownNamePtr^ -> self *)
|
|
|
- IF modStage^[slot].name = ModuleSymPtr(ownNamePtr)^.name THEN RETURN 16 END;
|
|
|
+ key := ownNamePtr; (* ADDRESS->pointer assignment is legal on v1.00; transfer-call deref is not *)
|
|
|
+ IF modStage^[slot].name = key^.name THEN RETURN 16 END;
|
|
|
i := 0;
|
|
|
WHILE i < moduleCount DO
|
|
|
IF modStage^[slot].name = moduleTable^[i].name THEN RETURN i END;
|
|
|
@@ -221,7 +223,7 @@ BEGIN
|
|
|
len := Scanner.StrLen(src, 128) + 1; (*{/*00de*/}* original pushes bound 128 *)
|
|
|
INC(strTop, len);
|
|
|
SymbolAssert(strTop + 8 <= strCap, 85); (*{/*00ec*/}*)
|
|
|
- MOVE(src, strHeapBase + off, len); (*{/*00f6*/}*)
|
|
|
+ MOVE(src, strHeap + off, len); (*{/*00f6*/}*)
|
|
|
ELSE
|
|
|
off := 0; (*{/*0100*/}*)
|
|
|
END;
|
|
|
@@ -229,36 +231,41 @@ END NewString;
|
|
|
|
|
|
PROCEDURE GetName(VAR name: ADDRESS; off: CARDINAL);
|
|
|
(* proc21 @0268 — inverse of NewString: heap copy of pooled string *)
|
|
|
+VAR cs: StringPtr;
|
|
|
BEGIN
|
|
|
IF off <> 0 THEN (*{/*026a*/}*)
|
|
|
- Scanner.CopyStr(name, StringPtr(strHeapBase + off)^); (*{/*026e*/}*)
|
|
|
+ cs := strHeap + off; (* ADDRESS arithmetic into pointer; transfer-deref is not a VAR actual *)
|
|
|
+ Scanner.CopyStr(name, cs^); (*{/*026e*/}*)
|
|
|
ELSE
|
|
|
name := NIL; (*{/*027b*/}*)
|
|
|
END;
|
|
|
END GetName;
|
|
|
|
|
|
-PROCEDURE PutAttr(VAR slot: CARDINAL; src: T1);
|
|
|
-(* proc18 @0106 — store a type/attr node into the scope-descriptor table *)
|
|
|
+PROCEDURE PutAttr(VAR slot: CARDINAL; src: Words);
|
|
|
+(* proc18 @0106 — store a type/attr node into the scope-descriptor table.
|
|
|
+ src is Words-typed (not T1): v1.00 rejects indexing a transfer result,
|
|
|
+ so callers transfer (zero-cost, W-probes) and the body indexes directly. *)
|
|
|
VAR i: CARDINAL; e: Words; sw: Words;
|
|
|
BEGIN
|
|
|
slot := 0; (*{/*0108*/}*)
|
|
|
IF src = NIL THEN RETURN END; (*{/*010b*/}*)
|
|
|
- slot := Words(src)^[1]; (*{/*010f*/}*)
|
|
|
+ slot := src^[1]; (*{/*010f*/}*)
|
|
|
IF slot <> 0 THEN RETURN END; (* named: referenced by name, no entry *)
|
|
|
- IF CARDINAL(src) < CARDINAL(symHeapBase) THEN (* static node: dedup {/*0118*/}
|
|
|
+ IF CARDINAL(src) < CARDINAL(symHeap) THEN (* static node: dedup {/*0118*/} *)
|
|
|
(* group B read this bound as global word2; reconciled to symHeapBase:
|
|
|
word2 is symOptions: BITSET per SYMTAB.SYM, and the heap base is the
|
|
|
only agreed boundary for "points outside the dynamic heap". *)
|
|
|
i := 1; (*{/*011d*/}*)
|
|
|
WHILE i <= scopeTop DO
|
|
|
- IF Words(scopeHeapBase + 16 * i)^[1] = CARDINAL(src) THEN (*{/*011f*/}*)
|
|
|
+ e := Words(scpHeap + 16 * i); (* temp: transfer results can't be indexed *)
|
|
|
+ IF e^[1] = CARDINAL(src) THEN (*{/*011f*/}*)
|
|
|
slot := i; RETURN;
|
|
|
END;
|
|
|
INC(i); (*{/*012e*/}*)
|
|
|
END;
|
|
|
SymbolAssert(i <= scopeCap, 86); (*{/*0137*/}*)
|
|
|
scopeTop := i;
|
|
|
- e := Words(scopeHeapBase + 16 * scopeTop);
|
|
|
+ e := Words(scpHeap + 16 * scopeTop);
|
|
|
e^[1] := CARDINAL(src); (*{/*0141*/}*)
|
|
|
slot := scopeTop; (*{/*0149*/}*)
|
|
|
RETURN;
|
|
|
@@ -266,10 +273,10 @@ BEGIN
|
|
|
SymbolAssert(scopeTop < scopeCap, 86); (*{/*014f*/}*)
|
|
|
INC(scopeTop);
|
|
|
slot := scopeTop; (*{/*015c*/}*)
|
|
|
- e := Words(scopeHeapBase + 16 * scopeTop);
|
|
|
- sw := Words(src);
|
|
|
+ e := Words(scpHeap + 16 * scopeTop);
|
|
|
+ sw := src;
|
|
|
e^[1] := 0; (*{/*016b*/}*)
|
|
|
- PutAttr(e^[2], T1(sw^[2])); (* copy link2 chain {/*016e*/} *)
|
|
|
+ PutAttr(e^[2], Words(sw^[2])); (* copy link2 chain {/*016e*/} *)
|
|
|
e^[3] := sw^[3]; (*{/*0176*/}*)
|
|
|
e^[4] := sw^[4]; (* kind {/*017a*/} *)
|
|
|
CASE sw^[4] OF (* kind switch {/*01b3*/} *)
|
|
|
@@ -279,10 +286,10 @@ BEGIN
|
|
|
CheckNode(T1(sw^[5])); (*{/*0192*/}*)
|
|
|
EnterChained(ADR(e^[5]), T1(sw^[5])); (*{/*0197*/}*)
|
|
|
| 101:
|
|
|
- PutAttr(e^[5], T1(sw^[5])); (*{/*0189*/}*)
|
|
|
+ PutAttr(e^[5], Words(sw^[5])); (*{/*0189*/}*)
|
|
|
| 102:
|
|
|
- PutAttr(e^[5], T1(sw^[5])); (*{/*019e*/}*)
|
|
|
- PutAttr(e^[6], T1(sw^[6]));
|
|
|
+ PutAttr(e^[5], Words(sw^[5])); (*{/*019e*/}*)
|
|
|
+ PutAttr(e^[6], Words(sw^[6]));
|
|
|
e^[7] := sw^[7];
|
|
|
ELSE (* 92..98: name/link/attr words suffice *)
|
|
|
END;
|
|
|
@@ -290,11 +297,11 @@ END PutAttr;
|
|
|
PROCEDURE GetAttr(VAR node: T1; idx: CARDINAL);
|
|
|
(* proc22 @0281 — load a scope entry back into a heap node (inverse of PutAttr).
|
|
|
Entry word1 = static node pointer or memoized node (returned as-is). *)
|
|
|
-VAR e: Words; new: T1; nw: Words;
|
|
|
+VAR e: Words; new: T1; nw: Words; sub: T1;
|
|
|
BEGIN
|
|
|
node := NIL; (*{/*0283*/}*)
|
|
|
IF idx = 0 THEN RETURN END; (*{/*0286*/}*)
|
|
|
- e := Words(scopeHeapBase + 16 * idx); (*{/*028a*/}*)
|
|
|
+ e := Words(scpHeap + 16 * idx); (*{/*028a*/}*)
|
|
|
node := T1(e^[1]); (*{/*0290*/}*)
|
|
|
IF node <> NIL THEN RETURN END; (*{/*0294*/}*)
|
|
|
(* Allocator size classes exact: Scanner.NewSized(kind) =
|
|
|
@@ -311,10 +318,10 @@ BEGIN
|
|
|
| 99, 100:
|
|
|
UnlinkScope(ADR(nw^[5]), e^[5]); (*{/*02c4*/}*)
|
|
|
| 101:
|
|
|
- GetAttr(nw^[5], e^[5]); (*{/*02bb*/}*)
|
|
|
+ sub := T1(nw^[5]); GetAttr(sub, e^[5]); nw^[5] := CARDINAL(sub); (* in-place reload; VAR needs a real variable (v1.00 OOMs on CARDINAL actual) *)
|
|
|
| 102:
|
|
|
- GetAttr(nw^[5], e^[5]); (*{/*02cc*/}*)
|
|
|
- GetAttr(nw^[6], e^[6]);
|
|
|
+ sub := T1(nw^[5]); GetAttr(sub, e^[5]); nw^[5] := CARDINAL(sub);
|
|
|
+ sub := T1(nw^[6]); GetAttr(sub, e^[6]); nw^[6] := CARDINAL(sub);
|
|
|
nw^[7] := e^[7];
|
|
|
ELSE (* 92..98: nothing beyond words 1..4 *)
|
|
|
END;
|
|
|
@@ -323,31 +330,33 @@ END GetAttr;
|
|
|
(* NOTE (group B): the brief asked for AllocSym(nodeKind): T1, but the MCode
|
|
|
(proc14 @01d7, ProcLeave(2), uses param1+param2) is a 2-param PROCEDURE
|
|
|
chaining a 14-byte entry onto scope and filling it from node. *)
|
|
|
-PROCEDURE AllocSym(scope: ADDRESS; node: T1);
|
|
|
-(* proc14 @01d7 — chain-allocate a 14-byte symbol-table entry from node *)
|
|
|
+PROCEDURE AllocSym(scope: Words; node: T1);
|
|
|
+(* proc14 @01d7 — chain-allocate a 14-byte symbol-table entry from node.
|
|
|
+ scope is Words-typed (not ADDRESS): v1.00 rejects indexing a transfer
|
|
|
+ result; callers transfer (zero-cost). *)
|
|
|
VAR s: Words; n: T1; nw: Words; sw: Words;
|
|
|
BEGIN
|
|
|
SymbolAssert(symTop < symCap, 87); (*{/*01d9*/}*)
|
|
|
INC(symTop);
|
|
|
- s := Words(symHeapBase + 14 * symTop); (*{/*01e3*/}*)
|
|
|
+ s := Words(symHeap + 14 * symTop); (*{/*01e3*/}*)
|
|
|
n := T1(s); nw := s; sw := Words(node);
|
|
|
- s^[0] := Words(scope)^[0]; (*{/*01e9*/}*)
|
|
|
- Words(scope)^[0] := symTop; (*{/*01ed*/}*)
|
|
|
+ s^[0] := scope^[0]; (*{/*01e9*/}*)
|
|
|
+ scope^[0] := symTop; (*{/*01ed*/}*)
|
|
|
NewString(s^[1], node^.link1); (*{/*01f0*/}*)
|
|
|
- PutAttr(s^[2], node^.link2); (*{/*01f7*/}*)
|
|
|
+ PutAttr(s^[2], Words(node^.link2)); (*{/*01f7*/}*)
|
|
|
n^.word3 := node^.word3; (*{/*01fe*/}*)
|
|
|
nw^[5] := sw^[5]; nw^[6] := sw^[6]; (* dword {/*0202*/} *)
|
|
|
n^.word4 := node^.word4; (* kind {/*0208*/} *)
|
|
|
- IF node^.link2 = Compiler.charArrayDesc THEN (* COMPILER.word12 {/*020c*/} *)
|
|
|
+ IF CARDINAL(node^.link2) = CARDINAL(Compiler.charArrayDesc) THEN (* COMPILER.word12 {/*020c*/}; CARDINAL compare: T1 vs RecordPtr rejected *)
|
|
|
NewString(nw^[5], ADDRESS(sw^[5])); (*{/*0213*/}*)
|
|
|
ELSIF nw^[4] >= 5 THEN (*{/*021c*/}*)
|
|
|
CheckNode(T1(sw^[6])); (*{/*0222*/}*)
|
|
|
nw^[6] := 0; (*{/*0226*/}*)
|
|
|
EnterChained(ADR(nw^[6]), T1(sw^[6])); (*{/*0229*/}*)
|
|
|
- ELSIF (nw^[4] = 1) AND (node^.link2 = Compiler.LongrealType) THEN
|
|
|
+ ELSIF (nw^[4] = 1) AND (CARDINAL(node^.link2) = CARDINAL(Compiler.LongrealType)) THEN
|
|
|
(* COMPILER.word11: 8-byte real constant {/*0231*/} *)
|
|
|
SymbolAssert(strTop + 8 <= strCap, 85); (*{/*023e*/}*)
|
|
|
- MOVE(ADDRESS(sw^[5]), strHeapBase + strTop, 8); (*{/*0248*/}*)
|
|
|
+ MOVE(ADDRESS(sw^[5]), strHeap + strTop, 8); (*{/*0248*/}*)
|
|
|
INC(strTop, 8); (*{/*0251*/}*)
|
|
|
END;
|
|
|
END AllocSym;
|
|
|
@@ -357,59 +366,74 @@ PROCEDURE EnterChained(scope: ADDRESS; node: T1);
|
|
|
BEGIN
|
|
|
IF node <> NIL THEN (*{/*025b*/}*)
|
|
|
EnterChained(scope, node^.link0); (*{/*025f*/}*)
|
|
|
- AllocSym(scope, node); (*{/*0263*/}*)
|
|
|
+ AllocSym(Words(scope), node); (*{/*0263*/}*)
|
|
|
END;
|
|
|
END EnterChained;
|
|
|
|
|
|
-PROCEDURE EnterIdent(scope: ADDRESS; idx: CARDINAL);
|
|
|
-(* proc20 @0305 — declare symbol-table entry idx into scope (dup check + attrs) *)
|
|
|
+PROCEDURE EnterIdent(scope: Words; idx: CARDINAL);
|
|
|
+(* proc20 @0305 — declare symbol-table entry idx into scope (dup check + attrs).
|
|
|
+ scope is Words-typed (same transfer-index rule as PutAttr/AllocSym). *)
|
|
|
VAR sentry: Words; (* symHeapBase + idx*14 *)
|
|
|
new: T1; nw: Words;
|
|
|
- existing: T1;
|
|
|
mark: ADDRESS;
|
|
|
nm, nm2: ADDRESS; (* heap names via GetName *)
|
|
|
nmt: StringPtr;
|
|
|
+ vw: Words; (* temp for T1-field views *)
|
|
|
+ rp: Compiler.RecordPtr; (* temp: transfer results can't be dereferenced; also FindIden result *)
|
|
|
BEGIN
|
|
|
- sentry := Words(symHeapBase + 14 * idx); (*{/*0307*/}*)
|
|
|
+ sentry := Words(symHeap + 14 * idx); (*{/*0307*/}*)
|
|
|
new := Scanner.NewNode(sentry^[4]); (* kind; always 14 bytes {/*030d*/} *)
|
|
|
nw := Words(new);
|
|
|
- nw^[0] := Words(scope)^[0]; (* chain at head {/*0312*/} *)
|
|
|
+ nw^[0] := scope^[0]; (* chain at head {/*0312*/} *)
|
|
|
GetName(nm, sentry^[1]); (* heap copy of name {/*0316*/} *)
|
|
|
nw^[1] := CARDINAL(nm);
|
|
|
nmt := nm;
|
|
|
- existing := Scanner.FindIden(Scanner.List(scope), nm, 9 IN Scanner.scanOpt);
|
|
|
+ nm2 := CARDINAL(Scanner.List(scope)); (* stash List word; transfers are zero-cost *)
|
|
|
+ rp := Scanner.FindIden(Scanner.List(nm2), nm, 9 IN Scanner.scanOpt);
|
|
|
(* SCANNER.proc22 + scanOptions {/*031f*/} *)
|
|
|
- IF (existing <> NIL) AND NOT (5 IN Compiler.RecordPtr(existing)^.word3) THEN
|
|
|
- (* FIXME: word3 access needs Compiler.Record layout; original reads the
|
|
|
- found node's flags word. See Compiler.Record (word3: BITSET). *)
|
|
|
+ IF (rp <> NIL) AND NOT (5 IN rp^.word3) THEN
|
|
|
+ (* original reads the found node's flags word (Compiler.Record word3: BITSET). *)
|
|
|
Errors.ReportErrorWithText(1, nmt^); (*{/*033a*/}*)
|
|
|
END;
|
|
|
- Words(scope)^[0] := CARDINAL(new); (*{/*0341*/}*)
|
|
|
+ scope^[0] := CARDINAL(new); (*{/*0341*/}*)
|
|
|
GetAttr(new^.link2, sentry^[2]); (*{/*0344*/}*)
|
|
|
new^.word3 := BITSET(sentry^[3]); (*{/*034b*/}*)
|
|
|
new^.word4 := sentry^[4]; (*{/*034f*/}*)
|
|
|
+ (* NOTE: original chains these as IF/ELSIF; v1.00 retail pins all pending
|
|
|
+ ELSIF conditions in expression heap and OOMs. Flattened to sequential
|
|
|
+ IF+RETURN (equivalent: arms exclusive-first-match and tail-positioned). *)
|
|
|
IF sentry^[4] = 3 THEN (* constant: back-link value node {/*0353*/} *)
|
|
|
- IF Words(new^.link2)^[0] = 0 THEN (*{/*0359*/}*)
|
|
|
- Words(new^.link2)^[0] := CARDINAL(new); (*{/*035f*/}*)
|
|
|
+ vw := Words(new^.link2);
|
|
|
+ IF vw^[0] = 0 THEN (*{/*0359*/}*)
|
|
|
+ vw^[0] := CARDINAL(new); (*{/*035f*/}*)
|
|
|
END;
|
|
|
- ELSIF new^.link2 = Compiler.charArrayDesc THEN (* COMPILER.word12 {/*0365*/} *)
|
|
|
+ RETURN;
|
|
|
+ END;
|
|
|
+ IF CARDINAL(new^.link2) = CARDINAL(Compiler.charArrayDesc) THEN (* COMPILER.word12 {/*0365*/} *)
|
|
|
GetName(nm2, sentry^[5]); (*{/*0372*/}*)
|
|
|
nw^[5] := CARDINAL(nm2);
|
|
|
- ELSIF sentry^[4] >= 5 THEN (*{/*037b*/}*)
|
|
|
- IF existing = NIL THEN (*{/*0381*/}*)
|
|
|
+ RETURN;
|
|
|
+ END;
|
|
|
+ IF sentry^[4] >= 5 THEN (*{/*037b*/}*)
|
|
|
+ IF rp = NIL THEN (*{/*0381*/}*)
|
|
|
Scanner.GetStack(mark); (*{/*0385*/}*)
|
|
|
nw^[6] := 0; (*{/*0389*/}*)
|
|
|
- UnlinkScope(ADR(nw^[6]), sentry^[6]); (*{/*038c*/}*)
|
|
|
- IF (sentry^[4] = 5) AND (stageFlag <> 0) THEN (*{/*0393*/} global25 *)
|
|
|
- Compiler.allocateSignature(new, mark); (* COMPILER.dword27 gate {/*039d*/} *)
|
|
|
+ nm2 := ADDRESS(nw) + 12; (* address of nw^[6] without ADR(indexed) (expression-heap spike on v1.00) *)
|
|
|
+ UnlinkScope(nm2, sentry^[6]); (*{/*038c*/}*)
|
|
|
+ IF (sentry^[4] = 5) AND (stgFlag <> 0) THEN (*{/*0393*/} global25 *)
|
|
|
+ Compiler.allocHook(ADDRESS(new), mark); (* hook ADDRESS set by PASS1 (store dword27); was allocateSignature (a type symbol) — wrong target {/*039d*/} *)
|
|
|
END;
|
|
|
ELSE
|
|
|
- nw^[6] := Words(existing)^[6]; (*{/*03a5*/}*)
|
|
|
+ vw := Words(rp);
|
|
|
+ nw^[6] := vw^[6]; (*{/*03a5*/}*)
|
|
|
END;
|
|
|
- ELSIF (sentry^[4] = 1) AND (new^.link2 = Compiler.LongrealType) THEN
|
|
|
+ RETURN;
|
|
|
+ END;
|
|
|
+ IF (sentry^[4] = 1) AND (CARDINAL(new^.link2) = CARDINAL(Compiler.LongrealType)) THEN
|
|
|
(* COMPILER.word11; 8-byte real value {/*03ab*/} *)
|
|
|
- Scanner.Allocate(ADR(nw^[5]), 8); (*{/*03b8*/}*)
|
|
|
- MOVE(strHeapBase + sentry^[5], ADDRESS(nw^[5]), 8); (*{/*03be*/}*)
|
|
|
+ nm2 := ADR(nw^[5]); (* temp: VAR formal rejects ADR() results (proven "Variable expected"); original pushes computed address directly *)
|
|
|
+ Scanner.Allocate(nm2, 8); (*{/*03b8*/}*)
|
|
|
+ MOVE(strHeap + sentry^[5], ADDRESS(nw^[5]), 8); (*{/*03be*/}*)
|
|
|
END;
|
|
|
END EnterIdent;
|
|
|
|
|
|
@@ -418,9 +442,9 @@ PROCEDURE UnlinkScope(scope: ADDRESS; idx: CARDINAL);
|
|
|
VAR e: Words;
|
|
|
BEGIN
|
|
|
IF idx <> 0 THEN (*{/*03cb*/}*)
|
|
|
- e := Words(symHeapBase + 14 * idx);
|
|
|
+ e := Words(symHeap + 14 * idx);
|
|
|
UnlinkScope(scope, e^[0]); (*{/*03cf*/}*)
|
|
|
- EnterIdent(scope, idx); (*{/*03d8*/}*)
|
|
|
+ EnterIdent(Words(scope), idx); (*{/*03d8*/}*)
|
|
|
END;
|
|
|
END UnlinkScope;
|
|
|
|
|
|
@@ -434,13 +458,13 @@ BEGIN
|
|
|
CodeGen.FlushCodeWindow;
|
|
|
END;
|
|
|
freeBytes := 4096 - (CodeGen.nextEmitPos - CodeGen.windowBase); (*{/*03ee*/}*)
|
|
|
- symHeapBase := Scanner.codeBuf + CodeGen.nextEmitPos - CodeGen.windowBase; (*{/*03f8*/}*)
|
|
|
+ symHeap := Scanner.codeBuf + CodeGen.nextEmitPos - CodeGen.windowBase; (*{/*03f8*/}*)
|
|
|
symCap := freeBytes DIV 28 - 1; (*{/*0402*/} DIV (2*14) *)
|
|
|
- scopeHeapBase := symHeapBase + (symCap + 1) * 14; (*{/*040a*/}*)
|
|
|
+ scpHeap := symHeap + (symCap + 1) * 14; (*{/*040a*/}*)
|
|
|
scopeCap := freeBytes DIV 64 + 7; (*{/*0412*/} DIV (4 SHL 4) *)
|
|
|
- strHeapBase := scopeHeapBase + (scopeCap + 1) * 16; (*{/*041b*/}*)
|
|
|
- strCap := symHeapBase + freeBytes - strHeapBase - 1; (*{/*0423*/}*)
|
|
|
- FILL(symHeapBase, freeBytes, 0); (*{/*042b*/} SYSTEM.FILL unofficial — kept *)
|
|
|
+ strHeap := scpHeap + (scopeCap + 1) * 16; (*{/*041b*/}*)
|
|
|
+ strCap := symHeap + freeBytes - strHeap - 1; (*{/*0423*/}*)
|
|
|
+ FILL(symHeap, freeBytes, 0); (*{/*042b*/} SYSTEM.FILL unofficial — kept *)
|
|
|
END InitHeaps;
|
|
|
|
|
|
PROCEDURE EnterStandards;
|
|
|
@@ -451,7 +475,7 @@ VAR stdNo: CARDINAL; (* slot 0 reserved *)
|
|
|
(* proc25 @0432, nested *)
|
|
|
VAR ent: ScopeEntryPtr;
|
|
|
BEGIN
|
|
|
- ent := scopeHeapBase + stdNo * 16;
|
|
|
+ ent := scpHeap + stdNo * 16;
|
|
|
ent^.link := t; (* word 1 {/*0434*/} *)
|
|
|
INC(stdNo); (*{/*043e*/}*)
|
|
|
END InsertBuiltin;
|
|
|
@@ -501,11 +525,11 @@ BEGIN
|
|
|
SymbolAssert(scopeTop <= scopeCap, 86);
|
|
|
strTop := header[3]; (*{/*04db*/}*)
|
|
|
SymbolAssert(strTop <= strCap, 85);
|
|
|
- exportHead := header[4]; (*{/*04e7*/}*)
|
|
|
- stageNameTotal := header[0]; (*{/*04eb*/}*)
|
|
|
- savedSymInfo := header[5]; (*{/*04ef*/}*)
|
|
|
- savedStrInfo := header[6]; (*{/*04f3*/}*)
|
|
|
- LibRead(modStage, stageNameTotal * 10); (* module-name directory {/*04f7*/} *)
|
|
|
+ expHead := header[4]; (*{/*04e7*/}*)
|
|
|
+ namTotal := header[0]; (*{/*04eb*/}*)
|
|
|
+ savSym := header[5]; (*{/*04ef*/}*)
|
|
|
+ savStr := header[6]; (*{/*04f3*/}*)
|
|
|
+ LibRead(modStage, namTotal * 10); (* module-name directory {/*04f7*/} *)
|
|
|
dest := modStage + 160; (* slot 16 {/*04fe*/} *)
|
|
|
FOR i := 0 TO 7 DO dest^.name[i] := 0C END; (*{/*0505*/}*)
|
|
|
i := 0;
|
|
|
@@ -514,9 +538,9 @@ BEGIN
|
|
|
INC(i);
|
|
|
END;
|
|
|
dest^.tag := header[7]; (*{/*052c*/}*)
|
|
|
- LibRead(symHeapBase + 14, symTop * 14); (* symbol entries 1.. {/*0530*/} *)
|
|
|
- LibRead(scopeHeapBase + 240, (scopeTop - 14) * 16); (* scope entries 15.. {/*053a*/} *)
|
|
|
- LibRead(strHeapBase + 1, strTop - 1); (* string pool {/*0547*/} *)
|
|
|
+ LibRead(symHeap + 14, symTop * 14); (* symbol entries 1.. {/*0530*/} *)
|
|
|
+ LibRead(scpHeap + 240, (scopeTop - 14) * 16); (* scope entries 15.. {/*053a*/} *)
|
|
|
+ LibRead(strHeap + 1, strTop - 1); (* string pool {/*0547*/} *)
|
|
|
EnterStandards; (* rewire builtin slots 1..14 {/*054f*/} *)
|
|
|
END LoadSymFile;
|
|
|
PROCEDURE ImportAll(importRec: ADDRESS);
|
|
|
@@ -545,8 +569,8 @@ VAR
|
|
|
BEGIN
|
|
|
idx := start;
|
|
|
WHILE idx # 0 DO
|
|
|
- e := symHeapBase + idx * 14; (*{/*0559*/}*)
|
|
|
- IF Scanner.StrCmp(StringPtr(symHeapBase + strHeapBase + e^.nameOff)^,
|
|
|
+ e := symHeap + idx * 14; (*{/*0559*/}*)
|
|
|
+ IF Scanner.StrCmp(StringPtr(symHeap + strHeap + e^.nameOff)^,
|
|
|
StringPtr(name)^, 9 IN Scanner.scanOpt) THEN (*{/*0568*/}*)
|
|
|
RETURN idx;
|
|
|
END;
|
|
|
@@ -560,14 +584,14 @@ VAR
|
|
|
VAR e: SymEntryPtr;
|
|
|
BEGIN
|
|
|
IF first # 0 THEN
|
|
|
- e := symHeapBase + first * 14;
|
|
|
+ e := symHeap + first * 14;
|
|
|
ListExports(e^.link); (*{/*0588*/}*)
|
|
|
IF 0 IN e^.flags THEN (*{/*058a*/}*)
|
|
|
IF colCount = 5 THEN (*{/*0590*/}*)
|
|
|
Texts.WriteLn(3); colCount := 0;
|
|
|
END;
|
|
|
Texts.SetCol(3, colCount * 16); (*{/*05a0*/}*)
|
|
|
- Texts.WriteString(3, StringPtr(strHeapBase + e^.nameOff)^); (*{/*05af*/}*)
|
|
|
+ Texts.WriteString(3, StringPtr(strHeap + e^.nameOff)^); (*{/*05af*/}*)
|
|
|
INC(colCount); (*{/*05b4*/}*)
|
|
|
END;
|
|
|
END;
|
|
|
@@ -579,10 +603,10 @@ VAR
|
|
|
VAR e: SymEntryPtr;
|
|
|
BEGIN
|
|
|
IF symIdx # 0 THEN
|
|
|
- e := symHeapBase + symIdx * 14; (*{/*05c4*/}*)
|
|
|
+ e := symHeap + symIdx * 14; (*{/*05c4*/}*)
|
|
|
ImportOne(anchor, e^.link); (*{/*05ca*/}*)
|
|
|
IF 0 IN e^.flags THEN (*{/*05d0*/}*)
|
|
|
- EnterIdent(anchor, symIdx); (*{/*05d6*/}*)
|
|
|
+ EnterIdent(Words(anchor), symIdx); (*{/*05d6*/}*)
|
|
|
END;
|
|
|
END;
|
|
|
END ImportOne;
|
|
|
@@ -613,14 +637,14 @@ BEGIN
|
|
|
END;
|
|
|
RETURN;
|
|
|
END;
|
|
|
- stageFlag := 1; (* word 25 {/*0635*/}; group C reads compileActive *)
|
|
|
+ stgFlag := 1; (* word 25 {/*0635*/}; group C reads compileActive *)
|
|
|
InitHeaps; (*{/*0638*/}*)
|
|
|
LoadSymFile(StringPtr(imp^.name)^);
|
|
|
modIdx := EnterModule(16); (*{/*0640*/}*)
|
|
|
SymbolAssert(modIdx # 16, 48); (*{/*0644*/}*)
|
|
|
- expIdx := exportHead; (*{/*064b*/}*)
|
|
|
+ expIdx := expHead; (*{/*064b*/}*)
|
|
|
WHILE expIdx # 0 DO (*{/*064e*/}*)
|
|
|
- e := symHeapBase + expIdx * 14;
|
|
|
+ e := symHeap + expIdx * 14;
|
|
|
IF e^.flags * BITSET{1,6} # BITSET{} THEN (* AND 42H {/*0659*/} *)
|
|
|
e^.flags := e^.flags - BITSET{0}; (*{/*0663*/}*)
|
|
|
ELSE
|
|
|
@@ -636,7 +660,7 @@ BEGIN
|
|
|
END;
|
|
|
scopeIdx := 15;
|
|
|
WHILE scopeIdx <= scopeTop DO (*{/*069a*/}*)
|
|
|
- s := scopeHeapBase + scopeIdx * 16;
|
|
|
+ s := scpHeap + scopeIdx * 16;
|
|
|
matched := LookupChain(FindModule(ORD(s^.slot)), ORD(s^.fresh)); (*{/*06ab*/}*)
|
|
|
IF matched # 0 THEN (*{/*06b2*/}*)
|
|
|
s^.link := matched; s^.fresh := 0C;
|
|
|
@@ -644,32 +668,32 @@ BEGIN
|
|
|
INC(scopeIdx);
|
|
|
END;
|
|
|
IF importEvery THEN (*{/*06c4*/}*)
|
|
|
- ImportOne(ADR(imp^.anchor), exportHead); (* NOTE order: see ImportOne note *)
|
|
|
+ ImportOne(ADR(imp^.anchor), expHead); (* NOTE order: see ImportOne note *)
|
|
|
ELSE
|
|
|
REPEAT
|
|
|
Scanner.NeedID; (*{/*06d0*/}*)
|
|
|
- findIdx := FindExport(exportHead, ADR(Scanner.tokBuf)); (*{/*06d2*/}*)
|
|
|
- e := symHeapBase + findIdx * 14;
|
|
|
+ findIdx := FindExport(expHead, ADR(Scanner.tokBuf)); (*{/*06d2*/}*)
|
|
|
+ e := symHeap + findIdx * 14;
|
|
|
IF (findIdx = 0) OR NOT (0 IN e^.flags) THEN (*{/*06e0*/}*)
|
|
|
Errors.PrintOverlayMessage(3, Scanner.tokBuf); (*{/*06ed*/}*)
|
|
|
Texts.WriteLn(3);
|
|
|
Texts.WriteLn(3);
|
|
|
Texts.WriteString(3, "Exported are:"); (*{/*06f9*/}*)
|
|
|
colCount := 5; (*{/*070d*/}*)
|
|
|
- ListExports(exportHead); (*{/*070e*/}*)
|
|
|
+ ListExports(expHead); (*{/*070e*/}*)
|
|
|
Texts.WriteLn(3);
|
|
|
Errors.AskEditOrQuit; (*{/*0715*/}*)
|
|
|
END;
|
|
|
- IF (e^.kind = 3) AND (ScopeEntryPtr(scopeHeapBase + e^.ref * 16)^.state = 0) THEN (*{/*0717*/}*)
|
|
|
+ IF (e^.kind = 3) AND (ScopeEntryPtr(scpHeap + e^.ref * 16)^.state = 0) THEN (*{/*0717*/}*)
|
|
|
sib := e^.link; (*{/*0729*/}*)
|
|
|
WHILE sib # 0 DO
|
|
|
- e2 := symHeapBase + sib * 14;
|
|
|
+ e2 := symHeap + sib * 14;
|
|
|
IF (e2^.ref # e^.ref) OR NOT (9 IN e2^.flags) THEN EXIT END; (*{/*072d*/}*)
|
|
|
- EnterIdent(ADR(currentScope^.link1), sib); (*{/*0747*/}*)
|
|
|
+ EnterIdent(Words(ADR(currentScope^.link1)), sib); (*{/*0747*/}*)
|
|
|
sib := e2^.link;
|
|
|
END;
|
|
|
END;
|
|
|
- EnterIdent(ADR(currentScope^.link1), findIdx); (*{/*0756*/}*)
|
|
|
+ EnterIdent(Words(ADR(currentScope^.link1)), findIdx); (*{/*0756*/}*)
|
|
|
Scanner.GetSym; (*{/*075c*/}*)
|
|
|
Scanner.TestSet(BITSET{1,9}); (*{/*075e*/}*)
|
|
|
UNTIL NOT Scanner.AcceptSy(1); (* "," {/*0763*/} *)
|
|
|
@@ -677,7 +701,7 @@ BEGIN
|
|
|
END;
|
|
|
scopeIdx := 15;
|
|
|
WHILE scopeIdx <= scopeTop DO (*{/*076b*/}*)
|
|
|
- s := scopeHeapBase + scopeIdx * 16;
|
|
|
+ s := scpHeap + scopeIdx * 16;
|
|
|
IF (s^.link # 0) AND (s^.fresh # 0C) THEN (*{/*077a*/}*)
|
|
|
modIdx := EnterModule(ORD(s^.slot)); (*{/*0787*/}*)
|
|
|
Scanner.Allocate(tmp, 6); (*{/*078d*/}*)
|
|
|
@@ -807,7 +831,7 @@ BEGIN
|
|
|
InitHeaps;
|
|
|
symTop := 0; scopeTop := 0; strTop := 1;
|
|
|
symOptions := opt;
|
|
|
- exportHead := 0; (* FIXME: group wrote modExpCount := 0; unified with exportHead (word18) *)
|
|
|
+ expHead := 0; (* FIXME: group wrote modExpCount := 0; unified with exportHead (word18) *)
|
|
|
IF imports <> NIL THEN (*{/*0928*/}*)
|
|
|
WHILE imports <> NIL DO
|
|
|
currentScope^.link1 :=
|
|
|
@@ -887,7 +911,7 @@ BEGIN
|
|
|
Scanner.TestSet(BITSET{3});
|
|
|
END;
|
|
|
InitHeaps; EnterStandards;
|
|
|
- symTop := 0; scopeTop := 14; strTop := 1; exportHead := 0;
|
|
|
+ symTop := 0; scopeTop := 14; strTop := 1; expHead := 0;
|
|
|
currentScope^.link1 := MatchSym(desc, save^.link1);
|
|
|
i := 0;
|
|
|
WHILE i < moduleCount DO
|
|
|
@@ -902,6 +926,7 @@ END CompileBody;
|
|
|
PROCEDURE CheckForwards;
|
|
|
(* proc36 @0aa7. FIXME sketch, see CompileBody note. *)
|
|
|
VAR i: CARDINAL; base: T1; slot: ADDRESS;
|
|
|
+ wslot, wbase, wchain: Words; (* temps: transfer results can't be indexed *)
|
|
|
BEGIN
|
|
|
Compiler.compilationActive := FALSE; (*{/*0aa7*/}*)
|
|
|
InitHeaps;
|
|
|
@@ -909,32 +934,35 @@ BEGIN
|
|
|
second arg unknown. Omitted pending re-read. *)
|
|
|
i := 1;
|
|
|
WHILE i <= symTop DO (*{/*0ac2*/}*)
|
|
|
- base := T1(symHeapBase + i * 14);
|
|
|
+ base := T1(symHeap + i * 14);
|
|
|
IF base^.word4 = 5 THEN INCL(base^.word3, 5) END;
|
|
|
INC(i);
|
|
|
END;
|
|
|
UnlinkScope(currentScope^.link1, CARDINAL(currentScope^.link1)); (* FIXME arg roles TBD *)
|
|
|
i := 15;
|
|
|
WHILE i <= scopeTop DO (*{/*0ae8*/}*)
|
|
|
- base := T1(scopeHeapBase + i * 16);
|
|
|
+ base := T1(scpHeap + i * 16);
|
|
|
Scanner.Allocate(slot, 6);
|
|
|
- Words(slot)^[0] := Words(scopeChain^[Words(base)^[0]])^[0];
|
|
|
- Words(slot)^[1] := Words(base)^[1];
|
|
|
- Words(slot)^[2] := CARDINAL(base^.link1);
|
|
|
- scopeChain^[Words(base)^[0]] := slot;
|
|
|
+ wslot := Words(slot); wbase := Words(base);
|
|
|
+ wchain := Words(scopeChain^[wbase^[0]]);
|
|
|
+ wslot^[0] := wchain^[0];
|
|
|
+ wslot^[1] := wbase^[1];
|
|
|
+ wslot^[2] := CARDINAL(base^.link1);
|
|
|
+ scopeChain^[wbase^[0]] := slot;
|
|
|
INC(i);
|
|
|
END;
|
|
|
END CheckForwards;
|
|
|
|
|
|
PROCEDURE TryCompile(): BOOLEAN;
|
|
|
-(* IMDCLS @0b1c. FIXME sketch: frame-37 loop + error-growth recovery. *)
|
|
|
+(* IMDCLS @0b1c. Recovery: on exception, if the user edited (editPos advanced
|
|
|
+ past savePos) roll back to the mark and retry; else HALT. Proven: 0b4c
|
|
|
+ compares ERRORS.word2 (savedEditPos) against saved tokPos. *)
|
|
|
VAR saveOpt: BITSET; savePos: CARDINAL; saveMark: ADDRESS;
|
|
|
- saveScope: T1; saveCount, saveErr: CARDINAL;
|
|
|
+ saveScope: T1; saveCount: CARDINAL;
|
|
|
BEGIN
|
|
|
saveOpt := Scanner.scanOpt; savePos := Scanner.tokPos;
|
|
|
Scanner.GetStack(saveMark);
|
|
|
saveScope := currentScope^.link1; saveCount := moduleCount;
|
|
|
- saveErr := Errors.errorNumber;
|
|
|
IF (Scanner.curSym - 15) IN BITSET{3} THEN
|
|
|
DoImportList;
|
|
|
LOOP
|
|
|
@@ -947,7 +975,7 @@ BEGIN
|
|
|
RETURN TRUE;
|
|
|
EXCEPTION
|
|
|
moduleCount := saveCount; currentScope^.link1 := saveScope;
|
|
|
- IF Errors.errorNumber > saveErr THEN (*{/*0b4c*/}*)
|
|
|
+ IF Errors.savedEditPos > savePos THEN (*{/*0b4c*/}*)
|
|
|
Scanner.tokPos := savePos; Scanner.scanOpt := saveOpt;
|
|
|
Scanner.CheckStk(saveMark);
|
|
|
Errors.RollbackToMark;
|
|
|
@@ -976,10 +1004,10 @@ PROCEDURE Checksum7w(ptr: ADDRESS; nwords: CARDINAL);
|
|
|
VAR acc: CARDINAL;
|
|
|
BEGIN
|
|
|
WHILE nwords >= 14 DO (* FIXME: group condition ptr^ >= 14 kept as count form *)
|
|
|
- acc := checksumTemp + Words(ptr)^[0] + Words(ptr)^[1] * 2 + Words(ptr)^[2] * 4
|
|
|
+ acc := chkTemp + Words(ptr)^[0] + Words(ptr)^[1] * 2 + Words(ptr)^[2] * 4
|
|
|
+ Words(ptr)^[3] * 8 + Words(ptr)^[4] * 16 + Words(ptr)^[5] * 32
|
|
|
+ Words(ptr)^[6] * 64;
|
|
|
- checksumTemp := acc;
|
|
|
+ chkTemp := acc;
|
|
|
ptr := ptr + 14; nwords := nwords - 14;
|
|
|
END;
|
|
|
END Checksum7w;
|
|
|
@@ -988,20 +1016,20 @@ PROCEDURE SaveSymbolFile;
|
|
|
(* proc6 @0bdb *)
|
|
|
VAR hdr: ARRAY [0..15] OF WORD;
|
|
|
BEGIN
|
|
|
- checksumTemp := 0;
|
|
|
+ chkTemp := 0;
|
|
|
Checksum7w(ADR(moduleTable^), moduleCount * 10);
|
|
|
- Checksum7w(symHeapBase + 14, symTop * 14);
|
|
|
- Checksum7w(scopeHeapBase + 240, (scopeTop - 14) * 16);
|
|
|
- Checksum7w(strHeapBase + 1, strTop - 1);
|
|
|
+ Checksum7w(symHeap + 14, symTop * 14);
|
|
|
+ Checksum7w(scpHeap + 240, (scopeTop - 14) * 16);
|
|
|
+ Checksum7w(strHeap + 1, strTop - 1);
|
|
|
hdr[0] := moduleCount; hdr[1] := symTop;
|
|
|
hdr[2] := scopeTop; hdr[3] := strTop;
|
|
|
- hdr[4] := exportHead; hdr[5] := savedSymInfo; hdr[6] := savedStrInfo;
|
|
|
- hdr[7] := checksumTemp;
|
|
|
+ hdr[4] := expHead; hdr[5] := savSym; hdr[6] := savStr;
|
|
|
+ hdr[7] := chkTemp;
|
|
|
Files.WriteBytes(Scanner.codeFile, ADR(hdr), 7);
|
|
|
Files.WriteBytes(Scanner.codeFile, ADR(moduleTable^), moduleCount * 10);
|
|
|
- Files.WriteBytes(Scanner.codeFile, symHeapBase + 14, symTop * 14);
|
|
|
- Files.WriteBytes(Scanner.codeFile, scopeHeapBase + 240, (scopeTop - 14) * 16);
|
|
|
- Files.WriteBytes(Scanner.codeFile, strHeapBase + 1, strTop - 1);
|
|
|
+ Files.WriteBytes(Scanner.codeFile, symHeap + 14, symTop * 14);
|
|
|
+ Files.WriteBytes(Scanner.codeFile, scpHeap + 240, (scopeTop - 14) * 16);
|
|
|
+ Files.WriteBytes(Scanner.codeFile, strHeap + 1, strTop - 1);
|
|
|
END SaveSymbolFile;
|
|
|
|
|
|
PROCEDURE RestoreAfterEdit;
|