|
@@ -0,0 +1,988 @@
|
|
|
|
|
+(* SYMTAB.MOD — DRAFT v1, assembled 2026-10-02, NOT verified.
|
|
|
|
|
+ Reconstructed from Reversing-Turbo-Modula2-main/MCode_disassembly/symtab.txt
|
|
|
|
|
+ by four parallel decompilation passes (groups A @0001-00d4, B @00bd-03c9,
|
|
|
|
|
+ C @03de-07ad, D @07d8-end). Does NOT yet recompile to the original MCD;
|
|
|
|
|
+ verification via unassemble.c diff is still required (see README.md).
|
|
|
|
|
+
|
|
|
|
|
+ Naming follows src/compiler/RENAME-MAP.md plus the groups' reconciled names.
|
|
|
|
|
+ {/* 0xxx */} comments are MCode offsets backing tricky blocks.
|
|
|
|
|
+
|
|
|
|
|
+ RESOLVED CONFLICTS (group disagreements, decision recorded):
|
|
|
|
|
+ - global7: group A importNames == group C modStage (both 10-byte name slots).
|
|
|
|
|
+ Unified as modStage: staged module-name directory, slot 16 = own module.
|
|
|
|
|
+ - global8: group A scopeHeads == group C scopeChain (per-module chain heads).
|
|
|
|
|
+ Unified as scopeChain: ARRAY [0..16] OF T1 (ADDRESS-compatible).
|
|
|
|
|
+ - Words 12-17, 22-24: groups B and C agree exactly (heap bases/tops/caps).
|
|
|
|
|
+ - SkipQualident: groups C and D each decompiled proc32 @07ad differently.
|
|
|
|
|
+ Kept C's version (exact offsets {07af..07d0}); D's duplicate dropped.
|
|
|
|
|
+ - EnterIdent arg order: B's definition (idx, scope) kept; C's call sites
|
|
|
|
|
+ flipped to match. If the MCD diff complains, try (scope, idx).
|
|
|
|
|
+ - global2: kept SYMTAB.DEF's symOptions: BITSET (from SYMTAB.SYM — stronger
|
|
|
|
|
+ evidence than MCode word reading); B's heapBase reading flagged below.
|
|
|
|
|
+ - Words 20,21: kept C's savedSymInfo/savedStrInfo (header[5,6]); D's
|
|
|
|
|
+ conflicting mapping flagged at CheckForwards.
|
|
|
|
|
+ OPEN ISSUES (FIXME in body):
|
|
|
|
|
+ - AllocSym arity: B reads 2 params (node, scope); D's two call sites pass 1.
|
|
|
|
|
+ - D's Scanner misuse cleaned where certain (GetStackMark VAR-param form,
|
|
|
|
|
+ CopyStringToHeap(dest, src) order, HIGH() bounds stripped from
|
|
|
|
|
+ ReportErrorWithText calls); remaining dubious external calls flagged.
|
|
|
|
|
+ - COMPILER.bodyHook / BodyParseStep (D's TryCompile/CompileBody): no such
|
|
|
|
|
+ exports exist in COMPILER.DEF — placeholders, see FRONTEND.md Pass1 DCLS.
|
|
|
|
|
+ - LSL in Checksum7w is not SYSTEM; original shift primitive TBD.
|
|
|
|
|
+ - 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;
|
|
|
|
|
+
|
|
|
|
|
+(* ---- heap model (groups B + C) ---- *)
|
|
|
|
|
+(* MCode words are untyped; CARDINAL()/T1()/ADDRESS() punning mirrors the
|
|
|
|
|
+ disassembly. A Words view aliases link0/link1/link2/word3/word4 as words
|
|
|
|
|
+ 0..4; words 5..7 exist only on large nodes (size classes: 14 bytes for
|
|
|
|
|
+ kind <= 1, 10 for kind <= 6, 12 for kind <= 11, else 16). *)
|
|
|
|
|
+TYPE Words = POINTER TO ARRAY [0..7] OF CARDINAL;
|
|
|
|
|
+
|
|
|
|
|
+(* 14-byte symbol-heap entry = 7 words (group C names). *)
|
|
|
|
|
+TYPE SymEntryPtr = POINTER TO SymEntry;
|
|
|
|
|
+ SymEntry = RECORD
|
|
|
|
|
+ link: CARDINAL; (* word 0: export/next chain *)
|
|
|
|
|
+ nameOff: CARDINAL; (* word 1: byte offset of name in strHeapBase *)
|
|
|
|
|
+ ref: CARDINAL; (* word 2 *)
|
|
|
|
|
+ flags: BITSET; (* word 3 *)
|
|
|
|
|
+ kind: CARDINAL; (* word 4 *)
|
|
|
|
|
+ aux1: CARDINAL; (* word 5; high byte stamped with importer *)
|
|
|
|
|
+ aux2: CARDINAL; (* word 6; importer index *)
|
|
|
|
|
+ END;
|
|
|
|
|
+
|
|
|
|
|
+(* 16-byte scope-heap entry (group C names). *)
|
|
|
|
|
+TYPE ScopeEntryPtr = POINTER TO ScopeEntry;
|
|
|
|
|
+ ScopeEntry = RECORD
|
|
|
|
|
+ slot: CHAR; (* byte 0: module slot *)
|
|
|
|
|
+ fresh: CHAR; (* byte 1: nonzero = newly imported *)
|
|
|
|
|
+ link: CARDINAL; (* word 1 *)
|
|
|
|
|
+ ref: CARDINAL; (* word 2 *)
|
|
|
|
|
+ flags: BITSET; (* word 3 *)
|
|
|
|
|
+ state: CARDINAL; (* word 4 *)
|
|
|
|
|
+ aux1, aux2, aux3: CARDINAL;
|
|
|
|
|
+ END;
|
|
|
|
|
+
|
|
|
|
|
+(* 10-byte module-name slot (group C names). *)
|
|
|
|
|
+TYPE ModuleSymPtr = POINTER TO ModuleSym;
|
|
|
|
|
+ ModuleSym = RECORD
|
|
|
|
|
+ name: ARRAY [0..7] OF CHAR;
|
|
|
|
|
+ tag: CARDINAL;
|
|
|
|
|
+ END;
|
|
|
|
|
+
|
|
|
|
|
+(* Import record: same 7-word layout as Compiler.Record; names document use. *)
|
|
|
|
|
+TYPE ImportPtr = POINTER TO ImportRec;
|
|
|
|
|
+ ImportRec = RECORD
|
|
|
|
|
+ next: ADDRESS; (* word 0 *)
|
|
|
|
|
+ name: ADDRESS; (* word 1: module-name heap string *)
|
|
|
|
|
+ w2: CARDINAL; (* word 2 *)
|
|
|
|
|
+ flags: BITSET; (* word 3; bit 10 = import-all *)
|
|
|
|
|
+ kind: CARDINAL; (* word 4 *)
|
|
|
|
|
+ w5: WORD; (* word 5 *)
|
|
|
|
|
+ anchor: ADDRESS; (* word 6/high: import chain head cell *)
|
|
|
|
|
+ END;
|
|
|
|
|
+
|
|
|
|
|
+(* 6-byte relink node for scopeChain repair. *)
|
|
|
|
|
+TYPE ChainPtr = POINTER TO ChainRec;
|
|
|
|
|
+ ChainRec = RECORD
|
|
|
|
|
+ next: ADDRESS;
|
|
|
|
|
+ key, ref: CARDINAL;
|
|
|
|
|
+ END;
|
|
|
|
|
+
|
|
|
|
|
+(* Scope descriptor for SkipQualident's outer walk. *)
|
|
|
|
|
+TYPE ScopePtr = POINTER TO ScopeDesc;
|
|
|
|
|
+ ScopeDesc = RECORD
|
|
|
|
|
+ outer: ScopePtr; (* word 0: enclosing scope *)
|
|
|
|
|
+ idents: Scanner.List; (* word 1: identifier list *)
|
|
|
|
|
+ END;
|
|
|
|
|
+
|
|
|
|
|
+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;
|
|
|
|
|
+PROCEDURE CheckNode(node: T1); FORWARD;
|
|
|
|
|
+PROCEDURE EnterChained(node: T1; scope: ADDRESS); FORWARD;
|
|
|
|
|
+PROCEDURE AllocSym(node: T1; scope: ADDRESS); FORWARD;
|
|
|
|
|
+PROCEDURE UnlinkScope(idx: CARDINAL; scope: ADDRESS); FORWARD;
|
|
|
|
|
+PROCEDURE EnterIdent(idx: CARDINAL; scope: ADDRESS); FORWARD;
|
|
|
|
|
+PROCEDURE PutAttr(src: T1; VAR slot: CARDINAL); FORWARD;
|
|
|
|
|
+PROCEDURE GetAttr(idx: CARDINAL; VAR node: T1); 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) ================= *)
|
|
|
|
|
+
|
|
|
|
|
+PROCEDURE SymbolAssert(cond: BOOLEAN; code: CARDINAL);
|
|
|
|
|
+(* proc8 @0001 *)
|
|
|
|
|
+BEGIN
|
|
|
|
|
+ IF NOT cond THEN Errors.ReportError(code) END;
|
|
|
|
|
+END SymbolAssert;
|
|
|
|
|
+
|
|
|
|
|
+PROCEDURE FindModule(slot: CARDINAL): CARDINAL;
|
|
|
|
|
+(* proc9 @000c: 16 = self, 17 = not found *)
|
|
|
|
|
+VAR i: CARDINAL;
|
|
|
|
|
+BEGIN
|
|
|
|
|
+ (*{/*0016*/} key.name = ownNamePtr^ -> self *)
|
|
|
|
|
+ IF modStage^[slot].name = ModuleSymPtr(ownNamePtr)^.name THEN RETURN 16 END;
|
|
|
|
|
+ i := 0;
|
|
|
|
|
+ WHILE i < moduleCount DO
|
|
|
|
|
+ IF modStage^[slot].name = moduleTable^[i].name THEN RETURN i END;
|
|
|
|
|
+ INC(i); (*{/*0036*/}*)
|
|
|
|
|
+ END;
|
|
|
|
|
+ RETURN 17; (*{/*003b*/}*)
|
|
|
|
|
+END FindModule;
|
|
|
|
|
+
|
|
|
|
|
+PROCEDURE EnterModule(slot: CARDINAL): CARDINAL;
|
|
|
|
|
+(* proc10 @0040: FindModule(slot); add if absent *)
|
|
|
|
|
+VAR found: CARDINAL;
|
|
|
|
|
+BEGIN
|
|
|
|
|
+ found := FindModule(slot); (*{/*0042*/}*)
|
|
|
|
|
+ IF found <= 16 THEN
|
|
|
|
|
+ (*{/*0051*/} ghost check on Symbol.word fields *)
|
|
|
|
|
+ IF (modStage^[slot].word # 0)
|
|
|
|
|
+ AND (moduleTable^[found].word # modStage^[slot].word) THEN
|
|
|
|
|
+ Errors.ReportErrorWithText(12, modStage^[slot].name); (*{/*0061*/}*)
|
|
|
|
|
+ END;
|
|
|
|
|
+ RETURN found; (*{/*0066*/}*)
|
|
|
|
|
+ END;
|
|
|
|
|
+ SymbolAssert(moduleCount <= 15, 84); (*{/*0069*/}*)
|
|
|
|
|
+ (*{/*006f*/} MOVE whole 10-byte Symbol slot *)
|
|
|
|
|
+ moduleTable^[moduleCount] := modStage^[slot];
|
|
|
|
|
+ INC(moduleCount);
|
|
|
|
|
+ RETURN moduleCount - 1; (*{/*007e*/}*)
|
|
|
|
|
+END EnterModule;
|
|
|
|
|
+
|
|
|
|
|
+PROCEDURE LookupChain(scopeNo: CARDINAL; key: CARDINAL): T1;
|
|
|
|
|
+(* proc11 @0083 *)
|
|
|
|
|
+VAR p: T1;
|
|
|
|
|
+BEGIN
|
|
|
|
|
+ IF scopeNo > 16 THEN RETURN NIL END; (*{/*0085*/}*)
|
|
|
|
|
+ p := scopeChain^[scopeNo]; (*{/*008b*/}*)
|
|
|
|
|
+ WHILE p # NIL DO (*{/*008f*/}*)
|
|
|
|
|
+ IF CARDINAL(p^.link1) = key THEN RETURN p^.link2 END; (*{/*0093*/}*)
|
|
|
|
|
+ p := p^.link0; (*{/*009d*/}*)
|
|
|
|
|
+ END;
|
|
|
|
|
+ RETURN NIL; (*{/*00a2*/}*)
|
|
|
|
|
+END LookupChain;
|
|
|
|
|
+
|
|
|
|
|
+PROCEDURE MatchSym(sym: T1; want: T1): BOOLEAN;
|
|
|
|
|
+(* proc12 @00a6 *)
|
|
|
|
|
+BEGIN
|
|
|
|
|
+ (*{/*00a8*/} sym # NIL; {/*00ac*/} 9 IN sym^.word3; {/*00b2*/} link2 = want *)
|
|
|
|
|
+ RETURN (sym # NIL) AND (9 IN sym^.word3) AND (sym^.link2 = want);
|
|
|
|
|
+END MatchSym;
|
|
|
|
|
+
|
|
|
|
|
+(* ================= group B: allocators + attrs (@00bd-03c9) ================= *)
|
|
|
|
|
+
|
|
|
|
|
+PROCEDURE CheckNode(node: T1);
|
|
|
|
|
+(* proc15 @00bd — guard before chaining through word5/word6 fields *)
|
|
|
|
|
+BEGIN
|
|
|
|
|
+ IF (node <> NIL) AND (CARDINAL(node^.link0) - 1 < 64) THEN (*{/*00bf*/}*)
|
|
|
|
|
+ HALT; (* MCode Raise(272,0,0) {/*00cb*/} *)
|
|
|
|
|
+ END;
|
|
|
|
|
+END CheckNode;
|
|
|
|
|
+
|
|
|
|
|
+PROCEDURE NewString(src: ADDRESS; VAR off: CARDINAL);
|
|
|
|
|
+(* proc17 @00d4 — intern a string into the string pool; returns pool offset *)
|
|
|
|
|
+VAR len: CARDINAL;
|
|
|
|
|
+BEGIN
|
|
|
|
|
+ IF src <> NIL THEN (*{/*00d6*/}*)
|
|
|
|
|
+ off := strTop; (*{/*00da*/}*)
|
|
|
|
|
+ len := Scanner.StrLen(src) + 1; (*{/*00de*/}*)
|
|
|
|
|
+ INC(strTop, len);
|
|
|
|
|
+ SymbolAssert(strTop + 8 <= strCap, 85); (*{/*00ec*/}*)
|
|
|
|
|
+ MOVE(src, strHeapBase + off, len); (*{/*00f6*/}*)
|
|
|
|
|
+ ELSE
|
|
|
|
|
+ off := 0; (*{/*0100*/}*)
|
|
|
|
|
+ END;
|
|
|
|
|
+END NewString;
|
|
|
|
|
+
|
|
|
|
|
+PROCEDURE GetName(off: CARDINAL; VAR name: ADDRESS);
|
|
|
|
|
+(* proc21 @0268 — inverse of NewString: heap copy of pooled string *)
|
|
|
|
|
+BEGIN
|
|
|
|
|
+ IF off <> 0 THEN (*{/*026a*/}*)
|
|
|
|
|
+ Scanner.CopyStringToHeap(name, StringPtr(strHeapBase + off)^); (*{/*026e*/}*)
|
|
|
|
|
+ ELSE
|
|
|
|
|
+ name := NIL; (*{/*027b*/}*)
|
|
|
|
|
+ END;
|
|
|
|
|
+END GetName;
|
|
|
|
|
+
|
|
|
|
|
+PROCEDURE PutAttr(src: T1; VAR slot: CARDINAL);
|
|
|
|
|
+(* proc18 @0106 — store a type/attr node into the scope-descriptor table *)
|
|
|
|
|
+VAR i: CARDINAL; e: Words; sw: Words;
|
|
|
|
|
+BEGIN
|
|
|
|
|
+ slot := 0; (*{/*0108*/}*)
|
|
|
|
|
+ IF src = NIL THEN RETURN END; (*{/*010b*/}*)
|
|
|
|
|
+ slot := Words(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*/}
|
|
|
|
|
+ (* 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*/}*)
|
|
|
|
|
+ slot := i; RETURN;
|
|
|
|
|
+ END;
|
|
|
|
|
+ INC(i); (*{/*012e*/}*)
|
|
|
|
|
+ END;
|
|
|
|
|
+ SymbolAssert(i <= scopeCap, 86); (*{/*0137*/}*)
|
|
|
|
|
+ scopeTop := i;
|
|
|
|
|
+ e := Words(scopeHeapBase + 16 * scopeTop);
|
|
|
|
|
+ e^[1] := CARDINAL(src); (*{/*0141*/}*)
|
|
|
|
|
+ slot := scopeTop; (*{/*0149*/}*)
|
|
|
|
|
+ RETURN;
|
|
|
|
|
+ END;
|
|
|
|
|
+ SymbolAssert(scopeTop < scopeCap, 86); (*{/*014f*/}*)
|
|
|
|
|
+ INC(scopeTop);
|
|
|
|
|
+ slot := scopeTop; (*{/*015c*/}*)
|
|
|
|
|
+ e := Words(scopeHeapBase + 16 * scopeTop);
|
|
|
|
|
+ sw := Words(src);
|
|
|
|
|
+ e^[1] := 0; (*{/*016b*/}*)
|
|
|
|
|
+ PutAttr(T1(sw^[2]), e^[2]); (* copy link2 chain {/*016e*/} *)
|
|
|
|
|
+ e^[3] := sw^[3]; (*{/*0176*/}*)
|
|
|
|
|
+ e^[4] := sw^[4]; (* kind {/*017a*/} *)
|
|
|
|
|
+ CASE sw^[4] OF (* kind switch {/*01b3*/} *)
|
|
|
|
|
+ | 90, 91:
|
|
|
|
|
+ e^[5] := sw^[5]; e^[6] := sw^[6]; (*{/*0182*/}*)
|
|
|
|
|
+ | 99, 100:
|
|
|
|
|
+ CheckNode(T1(sw^[5])); (*{/*0192*/}*)
|
|
|
|
|
+ EnterChained(T1(sw^[5]), ADR(e^[5])); (*{/*0197*/}*)
|
|
|
|
|
+ | 101:
|
|
|
|
|
+ PutAttr(T1(sw^[5]), e^[5]); (*{/*0189*/}*)
|
|
|
|
|
+ | 102:
|
|
|
|
|
+ PutAttr(T1(sw^[5]), e^[5]); (*{/*019e*/}*)
|
|
|
|
|
+ PutAttr(T1(sw^[6]), e^[6]);
|
|
|
|
|
+ e^[7] := sw^[7];
|
|
|
|
|
+ ELSE (* 92..98: name/link/attr words suffice *)
|
|
|
|
|
+ END;
|
|
|
|
|
+END PutAttr;
|
|
|
|
|
+PROCEDURE GetAttr(idx: CARDINAL; VAR node: T1);
|
|
|
|
|
+(* 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;
|
|
|
|
|
+BEGIN
|
|
|
|
|
+ node := NIL; (*{/*0283*/}*)
|
|
|
|
|
+ IF idx = 0 THEN RETURN END; (*{/*0286*/}*)
|
|
|
|
|
+ e := Words(scopeHeapBase + 16 * idx); (*{/*028a*/}*)
|
|
|
|
|
+ node := T1(e^[1]); (*{/*0290*/}*)
|
|
|
|
|
+ IF node <> NIL THEN RETURN END; (*{/*0294*/}*)
|
|
|
|
|
+ (* Allocator size classes exact: Scanner.NewSizedNode(kind) =
|
|
|
|
|
+ 14 bytes for kind <= 1, 10 for kind <= 6, 12 for kind <= 11, else 16. *)
|
|
|
|
|
+ new := Scanner.NewSizedNode(e^[4]); (*{/*0299*/}*)
|
|
|
|
|
+ nw := Words(new);
|
|
|
|
|
+ e^[1] := CARDINAL(new); (* memoize {/*029e*/} *)
|
|
|
|
|
+ node := new; (*{/*02a1*/}*)
|
|
|
|
|
+ GetAttr(e^[2], new^.link2); (* subtype {/*02a4*/} *)
|
|
|
|
|
+ nw^[3] := e^[3]; (*{/*02ac*/}*)
|
|
|
|
|
+ CASE e^[4] OF (* kind switch {/*02e1*/} *)
|
|
|
|
|
+ | 90, 91:
|
|
|
|
|
+ nw^[5] := e^[5]; nw^[6] := e^[6]; (*{/*02b4*/}*)
|
|
|
|
|
+ | 99, 100:
|
|
|
|
|
+ UnlinkScope(e^[5], ADR(nw^[5])); (*{/*02c4*/}*)
|
|
|
|
|
+ | 101:
|
|
|
|
|
+ GetAttr(e^[5], nw^[5]); (*{/*02bb*/}*)
|
|
|
|
|
+ | 102:
|
|
|
|
|
+ GetAttr(e^[5], nw^[5]); (*{/*02cc*/}*)
|
|
|
|
|
+ GetAttr(e^[6], nw^[6]);
|
|
|
|
|
+ nw^[7] := e^[7];
|
|
|
|
|
+ ELSE (* 92..98: nothing beyond words 1..4 *)
|
|
|
|
|
+ END;
|
|
|
|
|
+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(node: T1; scope: ADDRESS);
|
|
|
|
|
+(* proc14 @01d7 — chain-allocate a 14-byte symbol-table entry from node *)
|
|
|
|
|
+VAR s: Words; n: T1; nw: Words; sw: Words;
|
|
|
|
|
+BEGIN
|
|
|
|
|
+ SymbolAssert(symTop < symCap, 87); (*{/*01d9*/}*)
|
|
|
|
|
+ INC(symTop);
|
|
|
|
|
+ s := Words(symHeapBase + 14 * symTop); (*{/*01e3*/}*)
|
|
|
|
|
+ n := T1(s); nw := s; sw := Words(node);
|
|
|
|
|
+ s^[0] := Words(scope)^[0]; (*{/*01e9*/}*)
|
|
|
|
|
+ Words(scope)^[0] := symTop; (*{/*01ed*/}*)
|
|
|
|
|
+ NewString(node^.link1, s^[1]); (*{/*01f0*/}*)
|
|
|
|
|
+ PutAttr(node^.link2, s^[2]); (*{/*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*/} *)
|
|
|
|
|
+ NewString(ADDRESS(sw^[5]), nw^[5]); (*{/*0213*/}*)
|
|
|
|
|
+ ELSIF nw^[4] >= 5 THEN (*{/*021c*/}*)
|
|
|
|
|
+ CheckNode(T1(sw^[6])); (*{/*0222*/}*)
|
|
|
|
|
+ nw^[6] := 0; (*{/*0226*/}*)
|
|
|
|
|
+ EnterChained(T1(sw^[6]), ADR(nw^[6])); (*{/*0229*/}*)
|
|
|
|
|
+ ELSIF (nw^[4] = 1) AND (node^.link2 = Compiler.LongrealType) THEN
|
|
|
|
|
+ (* COMPILER.word11: 8-byte real constant {/*0231*/} *)
|
|
|
|
|
+ SymbolAssert(strTop + 8 <= strCap, 85); (*{/*023e*/}*)
|
|
|
|
|
+ MOVE(ADDRESS(sw^[5]), strHeapBase + strTop, 8); (*{/*0248*/}*)
|
|
|
|
|
+ INC(strTop, 8); (*{/*0251*/}*)
|
|
|
|
|
+ END;
|
|
|
|
|
+END AllocSym;
|
|
|
|
|
+
|
|
|
|
|
+PROCEDURE EnterChained(node: T1; scope: ADDRESS);
|
|
|
|
|
+(* proc13 @0259 — append a link0 node chain to scope (oldest first) *)
|
|
|
|
|
+BEGIN
|
|
|
|
|
+ IF node <> NIL THEN (*{/*025b*/}*)
|
|
|
|
|
+ EnterChained(node^.link0, scope); (*{/*025f*/}*)
|
|
|
|
|
+ AllocSym(node, scope); (*{/*0263*/}*)
|
|
|
|
|
+ END;
|
|
|
|
|
+END EnterChained;
|
|
|
|
|
+
|
|
|
|
|
+PROCEDURE EnterIdent(idx: CARDINAL; scope: ADDRESS);
|
|
|
|
|
+(* proc20 @0305 — declare symbol-table entry idx into scope (dup check + attrs) *)
|
|
|
|
|
+VAR sentry: Words; (* symHeapBase + idx*14 *)
|
|
|
|
|
+ new: T1; nw: Words;
|
|
|
|
|
+ existing: T1;
|
|
|
|
|
+ mark: ADDRESS;
|
|
|
|
|
+ nm, nm2: ADDRESS; (* heap names via GetName *)
|
|
|
|
|
+ nmt: StringPtr;
|
|
|
|
|
+BEGIN
|
|
|
|
|
+ sentry := Words(symHeapBase + 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*/} *)
|
|
|
|
|
+ GetName(sentry^[1], nm); (* heap copy of name {/*0316*/} *)
|
|
|
|
|
+ nw^[1] := CARDINAL(nm);
|
|
|
|
|
+ nmt := nm;
|
|
|
|
|
+ existing := Scanner.FindIdent(Scanner.List(scope), nm, 9 IN Scanner.scanOptions);
|
|
|
|
|
+ (* 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). *)
|
|
|
|
|
+ Errors.ReportErrorWithText(1, nmt^); (*{/*033a*/}*)
|
|
|
|
|
+ END;
|
|
|
|
|
+ Words(scope)^[0] := CARDINAL(new); (*{/*0341*/}*)
|
|
|
|
|
+ GetAttr(sentry^[2], new^.link2); (*{/*0344*/}*)
|
|
|
|
|
+ new^.word3 := BITSET(sentry^[3]); (*{/*034b*/}*)
|
|
|
|
|
+ new^.word4 := sentry^[4]; (*{/*034f*/}*)
|
|
|
|
|
+ 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*/}*)
|
|
|
|
|
+ END;
|
|
|
|
|
+ ELSIF new^.link2 = Compiler.charArrayDesc THEN (* COMPILER.word12 {/*0365*/} *)
|
|
|
|
|
+ GetName(sentry^[5], nm2); (*{/*0372*/}*)
|
|
|
|
|
+ nw^[5] := CARDINAL(nm2);
|
|
|
|
|
+ ELSIF sentry^[4] >= 5 THEN (*{/*037b*/}*)
|
|
|
|
|
+ IF existing = NIL THEN (*{/*0381*/}*)
|
|
|
|
|
+ Scanner.GetStackMark(mark); (*{/*0385*/}*)
|
|
|
|
|
+ nw^[6] := 0; (*{/*0389*/}*)
|
|
|
|
|
+ UnlinkScope(sentry^[6], ADR(nw^[6])); (*{/*038c*/}*)
|
|
|
|
|
+ IF (sentry^[4] = 5) AND (stageFlag <> 0) THEN (*{/*0393*/} global25 *)
|
|
|
|
|
+ Compiler.allocateSignature(new, mark); (* COMPILER.dword27 gate {/*039d*/} *)
|
|
|
|
|
+ END;
|
|
|
|
|
+ ELSE
|
|
|
|
|
+ nw^[6] := Words(existing)^[6]; (*{/*03a5*/}*)
|
|
|
|
|
+ END;
|
|
|
|
|
+ ELSIF (sentry^[4] = 1) AND (new^.link2 = 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*/}*)
|
|
|
|
|
+ END;
|
|
|
|
|
+END EnterIdent;
|
|
|
|
|
+
|
|
|
|
|
+PROCEDURE UnlinkScope(idx: CARDINAL; scope: ADDRESS);
|
|
|
|
|
+(* proc19 @03c9 — re-declare a link0 index chain into scope (oldest first) *)
|
|
|
|
|
+VAR e: Words;
|
|
|
|
|
+BEGIN
|
|
|
|
|
+ IF idx <> 0 THEN (*{/*03cb*/}*)
|
|
|
|
|
+ e := Words(symHeapBase + 14 * idx);
|
|
|
|
|
+ UnlinkScope(e^[0], scope); (*{/*03cf*/}*)
|
|
|
|
|
+ EnterIdent(idx, scope); (*{/*03d8*/}*)
|
|
|
|
|
+ END;
|
|
|
|
|
+END UnlinkScope;
|
|
|
|
|
+
|
|
|
|
|
+(* ================= group C: heaps/standards/symfile/imports ================= *)
|
|
|
|
|
+
|
|
|
|
|
+PROCEDURE InitHeaps;
|
|
|
|
|
+(* proc23 @03de: slice heaps out of CodeGen memory *)
|
|
|
|
|
+VAR freeBytes: CARDINAL;
|
|
|
|
|
+BEGIN
|
|
|
|
|
+ IF CodeGen.nextEmitPos - CodeGen.windowBase > 2560 THEN (*{/*03e0*/}*)
|
|
|
|
|
+ CodeGen.FlushCodeWindow;
|
|
|
|
|
+ END;
|
|
|
|
|
+ freeBytes := 4096 - (CodeGen.nextEmitPos - CodeGen.windowBase); (*{/*03ee*/}*)
|
|
|
|
|
+ symHeapBase := Scanner.codeBuffer + CodeGen.nextEmitPos - CodeGen.windowBase; (*{/*03f8*/}*)
|
|
|
|
|
+ symCap := freeBytes DIV 28 - 1; (*{/*0402*/} DIV (2*14) *)
|
|
|
|
|
+ scopeHeapBase := symHeapBase + (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 *)
|
|
|
|
|
+END InitHeaps;
|
|
|
|
|
+
|
|
|
|
|
+PROCEDURE EnterStandards;
|
|
|
|
|
+(* proc24 @0448: rewire 14 builtins into scope slots 1..14 *)
|
|
|
|
|
+VAR stdNo: CARDINAL; (* slot 0 reserved *)
|
|
|
|
|
+
|
|
|
|
|
+ PROCEDURE InsertBuiltin(t: ADDRESS);
|
|
|
|
|
+ (* proc25 @0432, nested *)
|
|
|
|
|
+ VAR ent: ScopeEntryPtr;
|
|
|
|
|
+ BEGIN
|
|
|
|
|
+ ent := scopeHeapBase + stdNo * 16;
|
|
|
|
|
+ ent^.link := t; (* word 1 {/*0434*/} *)
|
|
|
|
|
+ INC(stdNo); (*{/*043e*/}*)
|
|
|
|
|
+ END InsertBuiltin;
|
|
|
|
|
+
|
|
|
|
|
+BEGIN
|
|
|
|
|
+ stdNo := 1;
|
|
|
|
|
+ InsertBuiltin(Compiler.IntType); (* word 6 {/*044e*/} *)
|
|
|
|
|
+ InsertBuiltin(Compiler.CharType); (* word 13 {/*0452*/} *)
|
|
|
|
|
+ InsertBuiltin(Compiler.BooleanType); (* word 14 {/*0456*/} *)
|
|
|
|
|
+ InsertBuiltin(Compiler.WordType); (* word 18 {/*045b*/} *)
|
|
|
|
|
+ InsertBuiltin(Compiler.AddressType); (* word 8 {/*045f*/} *)
|
|
|
|
|
+ InsertBuiltin(Compiler.addressAlias); (* word 17 {/*0464*/} *)
|
|
|
|
|
+ InsertBuiltin(Compiler.CardType); (* word 7 {/*0468*/} *)
|
|
|
|
|
+ InsertBuiltin(Compiler.BitsetType); (* word 15 {/*046c*/} *)
|
|
|
|
|
+ InsertBuiltin(Compiler.ProcType); (* word 16 {/*0471*/} *)
|
|
|
|
|
+ InsertBuiltin(Compiler.charArrayDesc); (* word 12 {/*0475*/} *)
|
|
|
|
|
+ InsertBuiltin(Compiler.ByteType); (* word 19 {/*047a*/} *)
|
|
|
|
|
+ InsertBuiltin(Compiler.RealType); (* word 9 {/*047e*/} *)
|
|
|
|
|
+ InsertBuiltin(Compiler.LongintType); (* word 10 {/*0482*/} *)
|
|
|
|
|
+ InsertBuiltin(Compiler.LongrealType); (* word 11 {/*0486*/} *)
|
|
|
|
|
+END EnterStandards;
|
|
|
|
|
+
|
|
|
|
|
+PROCEDURE LoadSymFile(VAR modName: ARRAY OF CHAR);
|
|
|
|
|
+(* proc26 @04a0 *)
|
|
|
|
|
+VAR
|
|
|
|
|
+ libFile: Loader.LibFile; (* 292-byte handle {/*04a8*/}; see LOADER.DEF *)
|
|
|
|
|
+ header: ARRAY [0..7] OF CARDINAL; (* 16-byte .SYM header {/*04ad*/} *)
|
|
|
|
|
+ i: CARDINAL;
|
|
|
|
|
+ dest: ModuleSymPtr;
|
|
|
|
|
+
|
|
|
|
|
+ PROCEDURE LibRead(buf: ADDRESS; n: CARDINAL);
|
|
|
|
|
+ (* proc27 @048a, nested: libFile via parent frame *)
|
|
|
|
|
+ BEGIN
|
|
|
|
|
+ IF NOT Loader.LibRead(libFile, buf, n) THEN
|
|
|
|
|
+ RAISE symReadError; (* 790 {/*0497*/} *)
|
|
|
|
|
+ END;
|
|
|
|
|
+ END LibRead;
|
|
|
|
|
+
|
|
|
|
|
+BEGIN
|
|
|
|
|
+ IF NOT Loader.LibOpen(libFile, modName, TRUE) THEN
|
|
|
|
|
+ Errors.ReportErrorWithText(16, modName); (* falls through {/*04b1*/} *)
|
|
|
|
|
+ END;
|
|
|
|
|
+ LibRead(ADR(header), 16); (*{/*04c0*/}*)
|
|
|
|
|
+ symTop := header[1]; (*{/*04c5*/}*)
|
|
|
|
|
+ SymbolAssert(symTop <= symCap, 87);
|
|
|
|
|
+ scopeTop := header[2]; (*{/*04cf*/}*)
|
|
|
|
|
+ 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*/} *)
|
|
|
|
|
+ dest := modStage + 160; (* slot 16 {/*04fe*/} *)
|
|
|
|
|
+ FOR i := 0 TO 7 DO dest^.name[i] := 0C END; (*{/*0505*/}*)
|
|
|
|
|
+ i := 0;
|
|
|
|
|
+ WHILE (i <= 7) AND (modName[i] # 0C) DO (*{/*050e*/}*)
|
|
|
|
|
+ dest^.name[i] := CAP(modName[i]); (*{/*0519*/}*)
|
|
|
|
|
+ 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*/} *)
|
|
|
|
|
+ EnterStandards; (* rewire builtin slots 1..14 {/*054f*/} *)
|
|
|
|
|
+END LoadSymFile;
|
|
|
|
|
+PROCEDURE ImportAll(importRec: ADDRESS);
|
|
|
|
|
+(* proc28 @05dd *)
|
|
|
|
|
+VAR
|
|
|
|
|
+ imp: ImportPtr;
|
|
|
|
|
+ sysImp, stoImp: ImportPtr;
|
|
|
|
|
+ sysAdr: ADDRESS;
|
|
|
|
|
+ caseFlag: BOOLEAN; (* 9 IN scanOptions {/*05df*/} *)
|
|
|
|
|
+ importEvery: BOOLEAN; (* bit 10 of flags {/*05e4*/} *)
|
|
|
|
|
+ modIdx: CARDINAL;
|
|
|
|
|
+ expIdx: CARDINAL;
|
|
|
|
|
+ scopeIdx: CARDINAL;
|
|
|
|
|
+ tmp: ADDRESS;
|
|
|
|
|
+ sib: CARDINAL;
|
|
|
|
|
+ findIdx: CARDINAL;
|
|
|
|
|
+ colCount: CARDINAL;
|
|
|
|
|
+ e, e2: SymEntryPtr;
|
|
|
|
|
+ s: ScopeEntryPtr;
|
|
|
|
|
+ ch: ChainPtr;
|
|
|
|
|
+ matched: CARDINAL;
|
|
|
|
|
+
|
|
|
|
|
+ PROCEDURE FindExport(start: CARDINAL; name: ADDRESS): CARDINAL;
|
|
|
|
|
+ (* proc29 @0553, nested *)
|
|
|
|
|
+ VAR e: SymEntryPtr; idx: CARDINAL;
|
|
|
|
|
+ BEGIN
|
|
|
|
|
+ idx := start;
|
|
|
|
|
+ WHILE idx # 0 DO
|
|
|
|
|
+ e := symHeapBase + idx * 14; (*{/*0559*/}*)
|
|
|
|
|
+ IF Scanner.StrCmp(StringPtr(symHeapBase + strHeapBase + e^.nameOff)^,
|
|
|
|
|
+ StringPtr(name)^, 9 IN Scanner.scanOptions) THEN (*{/*0568*/}*)
|
|
|
|
|
+ RETURN idx;
|
|
|
|
|
+ END;
|
|
|
|
|
+ idx := e^.link; (*{/*0570*/}*)
|
|
|
|
|
+ END;
|
|
|
|
|
+ RETURN 0;
|
|
|
|
|
+ END FindExport;
|
|
|
|
|
+
|
|
|
|
|
+ PROCEDURE ListExports(first: CARDINAL);
|
|
|
|
|
+ (* proc30 @0579, nested: colCount via parent frame *)
|
|
|
|
|
+ VAR e: SymEntryPtr;
|
|
|
|
|
+ BEGIN
|
|
|
|
|
+ IF first # 0 THEN
|
|
|
|
|
+ e := symHeapBase + 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*/}*)
|
|
|
|
|
+ INC(colCount); (*{/*05b4*/}*)
|
|
|
|
|
+ END;
|
|
|
|
|
+ END;
|
|
|
|
|
+ END ListExports;
|
|
|
|
|
+
|
|
|
|
|
+ PROCEDURE ImportOne(anchor: ADDRESS; symIdx: CARDINAL);
|
|
|
|
|
+ (* proc31 @05be, nested. NOTE arg order flipped to B's EnterIdent(idx, scope);
|
|
|
|
|
+ original call order was (anchor, symIdx) — MCD diff decides. *)
|
|
|
|
|
+ VAR e: SymEntryPtr;
|
|
|
|
|
+ BEGIN
|
|
|
|
|
+ IF symIdx # 0 THEN
|
|
|
|
|
+ e := symHeapBase + symIdx * 14; (*{/*05c4*/}*)
|
|
|
|
|
+ ImportOne(anchor, e^.link); (*{/*05ca*/}*)
|
|
|
|
|
+ IF 0 IN e^.flags THEN (*{/*05d0*/}*)
|
|
|
|
|
+ EnterIdent(symIdx, anchor); (*{/*05d6*/}*)
|
|
|
|
|
+ END;
|
|
|
|
|
+ END;
|
|
|
|
|
+ END ImportOne;
|
|
|
|
|
+
|
|
|
|
|
+BEGIN
|
|
|
|
|
+ imp := importRec;
|
|
|
|
|
+ caseFlag := 9 IN Scanner.scanOptions;
|
|
|
|
|
+ importEvery := 10 IN imp^.flags;
|
|
|
|
|
+ sysAdr := ADDRESS(Compiler.systemModule); sysImp := sysAdr;
|
|
|
|
|
+ IF Scanner.StrCmp(StringPtr(imp^.name)^, StringPtr(sysImp^.name)^, caseFlag) THEN (*{/*05e9*/}*)
|
|
|
|
|
+ IF importEvery THEN (*{/*05f5*/}*)
|
|
|
|
|
+ imp^.flags := sysImp^.flags; (*{/*05f8*/}*)
|
|
|
|
|
+ imp^.anchor := sysImp^.anchor; (*{/*0604*/}*)
|
|
|
|
|
+ Compiler.compilationActive := FALSE; (* word 26 {/*0608*/} *)
|
|
|
|
|
+ ELSE
|
|
|
|
|
+ DefineDefinitionModule(Compiler.systemScopeDesc); (* proc2 {/*060a*/} *)
|
|
|
|
|
+ END;
|
|
|
|
|
+ RETURN; (*{/*060e*/}*)
|
|
|
|
|
+ END;
|
|
|
|
|
+ sysAdr := ADDRESS(Compiler.storageModule); stoImp := sysAdr;
|
|
|
|
|
+ IF Scanner.StrCmp(StringPtr(imp^.name)^, StringPtr(stoImp^.name)^, caseFlag) THEN (*{/*0611*/}*)
|
|
|
|
|
+ IF importEvery THEN (*{/*061d*/}*)
|
|
|
|
|
+ imp^.flags := stoImp^.flags;
|
|
|
|
|
+ imp^.anchor := stoImp^.anchor;
|
|
|
|
|
+ Compiler.compilationActive := FALSE;
|
|
|
|
|
+ ELSE
|
|
|
|
|
+ DefineDefinitionModule(Compiler.storageScopeDesc); (*{/*062e*/}*)
|
|
|
|
|
+ END;
|
|
|
|
|
+ RETURN;
|
|
|
|
|
+ END;
|
|
|
|
|
+ stageFlag := 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*/}*)
|
|
|
|
|
+ WHILE expIdx # 0 DO (*{/*064e*/}*)
|
|
|
|
|
+ e := symHeapBase + expIdx * 14;
|
|
|
|
|
+ IF e^.flags * BITSET{1,6} # BITSET{} THEN (* AND 42H {/*0659*/} *)
|
|
|
|
|
+ e^.flags := e^.flags - BITSET{0}; (*{/*0663*/}*)
|
|
|
|
|
+ ELSE
|
|
|
|
|
+ e^.flags := e^.flags + BITSET{0,1}; (*{/*066e*/}*)
|
|
|
|
|
+ END;
|
|
|
|
|
+ IF (e^.kind = 2) OR (e^.kind = 4) THEN
|
|
|
|
|
+ e^.aux2 := modIdx; (* word 6 {/*067e*/} *)
|
|
|
|
|
+ ELSIF e^.kind = 5 THEN
|
|
|
|
|
+ e^.aux1 := e^.aux1 + (CARDINAL(CHR(modIdx)) - e^.aux1 MOD 256);
|
|
|
|
|
+ (* byte 11 := modIdx {/*068b*/} *)
|
|
|
|
|
+ END;
|
|
|
|
|
+ expIdx := e^.link; (*{/*0692*/}*)
|
|
|
|
|
+ END;
|
|
|
|
|
+ scopeIdx := 15;
|
|
|
|
|
+ WHILE scopeIdx <= scopeTop DO (*{/*069a*/}*)
|
|
|
|
|
+ s := scopeHeapBase + scopeIdx * 16;
|
|
|
|
|
+ matched := LookupChain(FindModule(ORD(s^.slot)), ORD(s^.fresh)); (*{/*06ab*/}*)
|
|
|
|
|
+ IF matched # 0 THEN (*{/*06b2*/}*)
|
|
|
|
|
+ s^.link := matched; s^.fresh := 0C;
|
|
|
|
|
+ END;
|
|
|
|
|
+ INC(scopeIdx);
|
|
|
|
|
+ END;
|
|
|
|
|
+ IF importEvery THEN (*{/*06c4*/}*)
|
|
|
|
|
+ ImportOne(ADR(imp^.anchor), exportHead); (* NOTE order: see ImportOne note *)
|
|
|
|
|
+ ELSE
|
|
|
|
|
+ REPEAT
|
|
|
|
|
+ Scanner.NeedIdentifier; (*{/*06d0*/}*)
|
|
|
|
|
+ findIdx := FindExport(exportHead, ADR(Scanner.tokenBuffer)); (*{/*06d2*/}*)
|
|
|
|
|
+ e := symHeapBase + findIdx * 14;
|
|
|
|
|
+ IF (findIdx = 0) OR NOT (0 IN e^.flags) THEN (*{/*06e0*/}*)
|
|
|
|
|
+ Errors.PrintOverlayMessage(3, Scanner.tokenBuffer); (*{/*06ed*/}*)
|
|
|
|
|
+ Texts.WriteLn(3);
|
|
|
|
|
+ Texts.WriteLn(3);
|
|
|
|
|
+ Texts.WriteString(3, "Exported are:"); (*{/*06f9*/}*)
|
|
|
|
|
+ colCount := 5; (*{/*070d*/}*)
|
|
|
|
|
+ ListExports(exportHead); (*{/*070e*/}*)
|
|
|
|
|
+ Texts.WriteLn(3);
|
|
|
|
|
+ Errors.AskEditOrQuit; (*{/*0715*/}*)
|
|
|
|
|
+ END;
|
|
|
|
|
+ IF (e^.kind = 3) AND (ScopeEntryPtr(scopeHeapBase + e^.ref * 16)^.state = 0) THEN (*{/*0717*/}*)
|
|
|
|
|
+ sib := e^.link; (*{/*0729*/}*)
|
|
|
|
|
+ WHILE sib # 0 DO
|
|
|
|
|
+ e2 := symHeapBase + sib * 14;
|
|
|
|
|
+ IF (e2^.ref # e^.ref) OR NOT (9 IN e2^.flags) THEN EXIT END; (*{/*072d*/}*)
|
|
|
|
|
+ EnterIdent(sib, ADR(currentScope^.link1)); (*{/*0747*/}*)
|
|
|
|
|
+ sib := e2^.link;
|
|
|
|
|
+ END;
|
|
|
|
|
+ END;
|
|
|
|
|
+ EnterIdent(findIdx, ADR(currentScope^.link1)); (*{/*0756*/}*)
|
|
|
|
|
+ Scanner.GetSym; (*{/*075c*/}*)
|
|
|
|
|
+ Scanner.TestSymbolInSet(BITSET{1,9}); (*{/*075e*/}*)
|
|
|
|
|
+ UNTIL NOT Scanner.AcceptSymbol(1); (* "," {/*0763*/} *)
|
|
|
|
|
+ Scanner.GetSym; (*{/*0769*/}*)
|
|
|
|
|
+ END;
|
|
|
|
|
+ scopeIdx := 15;
|
|
|
|
|
+ WHILE scopeIdx <= scopeTop DO (*{/*076b*/}*)
|
|
|
|
|
+ s := scopeHeapBase + scopeIdx * 16;
|
|
|
|
|
+ IF (s^.link # 0) AND (s^.fresh # 0C) THEN (*{/*077a*/}*)
|
|
|
|
|
+ modIdx := EnterModule(ORD(s^.slot)); (*{/*0787*/}*)
|
|
|
|
|
+ Scanner.Allocate(tmp, 6); (*{/*078d*/}*)
|
|
|
|
|
+ ch := tmp;
|
|
|
|
|
+ ch^.next := ChainPtr(scopeChain^[modIdx]); (*{/*0792*/}*)
|
|
|
|
|
+ ch^.key := ORD(s^.fresh);
|
|
|
|
|
+ ch^.ref := s^.link;
|
|
|
|
|
+ scopeChain^[modIdx] := ch; (*{/*07a2*/}*)
|
|
|
|
|
+ END;
|
|
|
|
|
+ INC(scopeIdx);
|
|
|
|
|
+ END;
|
|
|
|
|
+END ImportAll;
|
|
|
|
|
+
|
|
|
|
|
+PROCEDURE SkipQualident(scope: ADDRESS): ADDRESS;
|
|
|
|
|
+(* proc32 @07ad — kept group C's version (exact offsets); group D's
|
|
|
|
|
+ duplicate reading of the same range dropped (see header note). *)
|
|
|
|
|
+VAR scp: ScopePtr; found: Compiler.RecordPtr;
|
|
|
|
|
+BEGIN
|
|
|
|
|
+ LOOP
|
|
|
|
|
+ scp := scope;
|
|
|
|
|
+ found := Scanner.FindIdent(scp^.idents, ADR(Scanner.tokenBuffer),
|
|
|
|
|
+ 9 IN Scanner.scanOptions); (*{/*07af*/}*)
|
|
|
|
|
+ IF found # NIL THEN RETURN ADDRESS(found) END; (*{/*07bc*/}*)
|
|
|
|
|
+ scope := ADDRESS(scp^.outer); (*{/*07c3*/}*)
|
|
|
|
|
+ IF (scope = ADDRESS(NIL)) OR (scope = ADDRESS(Compiler.stdScopeAnchor)) THEN (*{/*07c7*/}*)
|
|
|
|
|
+ Errors.ReportErrorWithText(0, Scanner.tokenBuffer); (*{/*07d0*/}*)
|
|
|
|
|
+ END;
|
|
|
|
|
+ END;
|
|
|
|
|
+END SkipQualident;
|
|
|
|
|
+
|
|
|
|
|
+(* ================= group D: orchestration (@07d8-end) ================= *)
|
|
|
|
|
+(* Cleaned: GetStackMark VAR-param form, CopyStringToHeap(dest, src) order,
|
|
|
|
|
+ HIGH() bounds stripped from ReportErrorWithText, Scanner.Allocate used
|
|
|
|
|
+ where the group wrote HeapAlloc. Remaining dubious calls flagged FIXME. *)
|
|
|
|
|
+
|
|
|
|
|
+PROCEDURE DefineDefinitionModule(isImpl: CARDINAL);
|
|
|
|
|
+(* proc2 @07d8. FIXME: isImpl compared against Compiler.systemScope
|
|
|
|
|
+ (a RecordPtr) in one branch — role of this param is shaky; MCD diff
|
|
|
|
|
+ against @07d8 must confirm. *)
|
|
|
|
|
+VAR node, chain, tmp: T1;
|
|
|
|
|
+BEGIN
|
|
|
|
|
+ IF Scanner.AcceptSymbol(15) THEN (* DEFINITION {/*07d8*/} *)
|
|
|
|
|
+ Scanner.NeedIdentifier;
|
|
|
|
|
+ node := T1(SkipQualident(ADDRESS(Scanner.curNode)));
|
|
|
|
|
+ Scanner.ExpectIdentKind(6);
|
|
|
|
|
+ SymbolAssert(10 IN node^.word3, 44); (*{/*07f0*/}*)
|
|
|
|
|
+ isImpl := node^.word5;
|
|
|
|
|
+ Scanner.GetSym;
|
|
|
|
|
+ Scanner.ExpectSymbol(16);
|
|
|
|
|
+ END;
|
|
|
|
|
+ Scanner.NeedIdentifier; (*{/*080a*/} common tail *)
|
|
|
|
|
+ node := T1(SkipQualident(ADDRESS(Scanner.curNode)));
|
|
|
|
|
+ SymbolAssert((node^.word4 <> 6) OR (10 IN node^.word3), 44);
|
|
|
|
|
+ IF (node^.word4 = 3) AND (node^.link2 = NIL) THEN
|
|
|
|
|
+ chain := node^.link0; (*{/*0829*/}*)
|
|
|
|
|
+ WHILE LookupChain(CARDINAL(chain), CARDINAL(node^.link2)) <> NIL DO
|
|
|
|
|
+ Scanner.Allocate(tmp, 14);
|
|
|
|
|
+ tmp^ := chain^; Scanner.InsertSymbol(tmp);
|
|
|
|
|
+ INCL(tmp^.word3, 0);
|
|
|
|
|
+ chain := chain^.link0;
|
|
|
|
|
+ END;
|
|
|
|
|
+ ELSIF (isImpl = CARDINAL(Compiler.systemScopeDesc)) AND (node^.word4 = 5)
|
|
|
|
|
+ AND (node^.word5 = 16) THEN
|
|
|
|
|
+ Compiler.compilationActive := 0;
|
|
|
|
|
+ END;
|
|
|
|
|
+ Scanner.Allocate(tmp, 14); (*{/*0865*/}*)
|
|
|
|
|
+ tmp^ := node^; Scanner.InsertSymbol(tmp);
|
|
|
|
|
+ INCL(tmp^.word3, 0);
|
|
|
|
|
+ Scanner.GetSym;
|
|
|
|
|
+ Scanner.TestSymbolInSet(BITSET{2,9}); (* FIXME: group wrote 514; BITSET{2,9} guesses bits — confirm *)
|
|
|
|
|
+ WHILE NOT Scanner.AcceptSymbol(1) DO (*{/*087b*/}*)
|
|
|
|
|
+ Scanner.NeedIdentifier;
|
|
|
|
|
+ node := T1(SkipQualident(ADDRESS(Scanner.curNode)));
|
|
|
|
|
+ SymbolAssert((node^.word4 <> 6) OR (10 IN node^.word3), 44);
|
|
|
|
|
+ tmp^ := node^; Scanner.InsertSymbol(tmp);
|
|
|
|
|
+ INCL(tmp^.word3, 0);
|
|
|
|
|
+ Scanner.GetSym;
|
|
|
|
|
+ Scanner.TestSymbolInSet(BITSET{2,9});
|
|
|
|
|
+ END;
|
|
|
|
|
+ Scanner.GetSym;
|
|
|
|
|
+END DefineDefinitionModule;
|
|
|
|
|
+
|
|
|
|
|
+PROCEDURE BuildBitsetConst(VAR name: ARRAY OF CHAR): BOOLEAN;
|
|
|
|
|
+(* proc5 @088a *)
|
|
|
|
|
+BEGIN
|
|
|
|
|
+ RETURN Scanner.FindIdent(NIL, ADR(name), 9 IN Scanner.scanOptions) <> NIL;
|
|
|
|
|
+ (* FIXME: FindIdent(list, identifier, case) — group passed (ADR(name), case)
|
|
|
|
|
+ i.e. list/name swapped; order TBD from @088a. *)
|
|
|
|
|
+END BuildBitsetConst;
|
|
|
|
|
+
|
|
|
|
|
+PROCEDURE DefineProgramModule(fromSeen: CARDINAL);
|
|
|
|
|
+(* proc3 @089a. FIXME: heavy FIXME — group D's reading of @089a-0914 tangles
|
|
|
|
|
+ moduleTable^[16] (a Symbol slot) with T1 chain operations; treat as
|
|
|
|
|
+ first-draft sketch, not ground truth. *)
|
|
|
|
|
+VAR dup: BOOLEAN; mark, node, tmp: T1; i: CARDINAL;
|
|
|
|
|
+BEGIN
|
|
|
|
|
+ modStage^[16].word := 0; (*{/*089a*/} FIXME: group wrote moduleTable^[16] := 0 *)
|
|
|
|
|
+ Scanner.GetSym;
|
|
|
|
|
+ fromSeen := ORD(Scanner.AcceptSymbol(26));
|
|
|
|
|
+ IF fromSeen # 0 THEN INCL(Scanner.followSet, 10) END; (*{/*08a8*/}*)
|
|
|
|
|
+ Scanner.NeedIdentifier;
|
|
|
|
|
+ IF BuildBitsetConst(Scanner.tokenBuffer) THEN
|
|
|
|
|
+ Errors.ReportErrorWithText(15, Scanner.tokenBuffer); (*{/*08b6*/}*)
|
|
|
|
|
+ END;
|
|
|
|
|
+ Scanner.Allocate(tmp, 6);
|
|
|
|
|
+ Scanner.CopyStringToHeap(Scanner.tokenBuffer, tmp); (* order TBD *)
|
|
|
|
|
+ Scanner.GetSym; (*{/*0902*/} ident list loop *)
|
|
|
|
|
+ Scanner.TestSymbolInSet(BITSET{2,9});
|
|
|
|
|
+ WHILE NOT Scanner.AcceptSymbol(1) DO (*{/*0904*/}*)
|
|
|
|
|
+ Scanner.NeedIdentifier;
|
|
|
|
|
+ IF BuildBitsetConst(Scanner.tokenBuffer) THEN
|
|
|
|
|
+ Errors.ReportErrorWithText(15, Scanner.tokenBuffer);
|
|
|
|
|
+ END;
|
|
|
|
|
+ Scanner.GetSym;
|
|
|
|
|
+ Scanner.TestSymbolInSet(BITSET{2,9});
|
|
|
|
|
+ END;
|
|
|
|
|
+ Scanner.GetSym;
|
|
|
|
|
+ (* FIXME: FROM/dup branches ({08d1..08ec}) omitted — re-read @08c0-0902. *)
|
|
|
|
|
+END DefineProgramModule;
|
|
|
|
|
+
|
|
|
|
|
+PROCEDURE InitSymbolTables(opt: BITSET; imports: T1; modName: T1);
|
|
|
|
|
+(* proc4 @0914 *)
|
|
|
|
|
+VAR node, chain, slot: T1; mark: ADDRESS;
|
|
|
|
|
+BEGIN
|
|
|
|
|
+ Compiler.compilationActive := TRUE; (* word26 {/*0914*/} *)
|
|
|
|
|
+ InitHeaps;
|
|
|
|
|
+ symTop := 0; scopeTop := 0; strTop := 1;
|
|
|
|
|
+ symOptions := opt;
|
|
|
|
|
+ exportHead := 0; (* FIXME: group wrote modExpCount := 0; unified with exportHead (word18) *)
|
|
|
|
|
+ IF imports <> NIL THEN (*{/*0928*/}*)
|
|
|
|
|
+ WHILE imports <> NIL DO
|
|
|
|
|
+ currentScope^.link1 :=
|
|
|
|
|
+ Scanner.FindIdent(NIL, imports^.link1, 9 IN Scanner.scanOptions);
|
|
|
|
|
+ (* FIXME: list arg TBD; group wrote FindIdent(imports^.word1, ...) *)
|
|
|
|
|
+ node := currentScope^.link1;
|
|
|
|
|
+ IF node = NIL THEN
|
|
|
|
|
+ Errors.ReportErrorWithText(6, StringPtr(imports^.link1)^);
|
|
|
|
|
+ END;
|
|
|
|
|
+ SymbolAssert((node^.word4 <> 6) OR (10 IN node^.word3), 43);
|
|
|
|
|
+ INCL(node^.word3, 0);
|
|
|
|
|
+ chain := imports^.link0; imports := chain;
|
|
|
|
|
+ END;
|
|
|
|
|
+ END;
|
|
|
|
|
+ Scanner.GetStackMark(mark);
|
|
|
|
|
+ Scanner.CheckStackMark(mark); (* FIXME: group passed symOptions; mark form kept *)
|
|
|
|
|
+ UnlinkScope(CARDINAL(modName), modName); (* FIXME: args TBD; proc19 *)
|
|
|
|
|
+END InitSymbolTables;
|
|
|
|
|
+
|
|
|
|
|
+PROCEDURE NoteImported;
|
|
|
|
|
+(* proc34 @0997 *)
|
|
|
|
|
+BEGIN
|
|
|
|
|
+ IF NOT (0 IN Scanner.scanOptions) THEN RETURN END;
|
|
|
|
|
+ IF Compiler.compilationActive THEN
|
|
|
|
|
+ Texts.WriteString(3, "Imported:");
|
|
|
|
|
+ Compiler.compilationActive := FALSE;
|
|
|
|
|
+ END;
|
|
|
|
|
+ Texts.WriteChar(3, 2C); Texts.WriteChar(3, 12C);
|
|
|
|
|
+ Texts.WriteString(3, Scanner.tokenBuffer);
|
|
|
|
|
+ Texts.WriteLn(3);
|
|
|
|
|
+END NoteImported;
|
|
|
|
|
+
|
|
|
|
|
+PROCEDURE DoImportList;
|
|
|
|
|
+(* proc33 @09c8 *)
|
|
|
|
|
+VAR node: T1;
|
|
|
|
|
+BEGIN
|
|
|
|
|
+ IF Scanner.AcceptSymbol(15) THEN (* FROM x IMPORT {/*09c8*/} *)
|
|
|
|
|
+ Scanner.NeedIdentifier;
|
|
|
|
|
+ Scanner.Allocate(node, 6);
|
|
|
|
|
+ Scanner.CopyStringToHeap(Scanner.tokenBuffer, node); (* order TBD *)
|
|
|
|
|
+ NoteImported;
|
|
|
|
|
+ Scanner.ExpectSymbol(16);
|
|
|
|
|
+ ImportAll(node); (* FIXME: group wrote ImportOne(node); @09c8 calls proc28=ImportAll *)
|
|
|
|
|
+ ELSE (* plain IMPORT {/*09ec*/} *)
|
|
|
|
|
+ Scanner.GetSym;
|
|
|
|
|
+ NoteImported;
|
|
|
|
|
+ node := Scanner.DeclareIdentifier(6);
|
|
|
|
|
+ node^.word3 := BITSET{3,10}; (* FIXME: group wrote CARDINAL({3,10})=1027 *)
|
|
|
|
|
+ ImportAll(node);
|
|
|
|
|
+ Scanner.TestSymbolInSet(BITSET{2,9});
|
|
|
|
|
+ WHILE NOT Scanner.AcceptSymbol(1) DO (*{/*0a00*/}*)
|
|
|
|
|
+ Scanner.GetSym;
|
|
|
|
|
+ NoteImported;
|
|
|
|
|
+ node := Scanner.DeclareIdentifier(6);
|
|
|
|
|
+ node^.word3 := BITSET{3,10};
|
|
|
|
|
+ ImportAll(node);
|
|
|
|
|
+ Scanner.TestSymbolInSet(BITSET{2,9});
|
|
|
|
|
+ END;
|
|
|
|
|
+ Scanner.GetSym;
|
|
|
|
|
+ END;
|
|
|
|
|
+END DoImportList;
|
|
|
|
|
+
|
|
|
|
|
+PROCEDURE CompileBody(save: T1);
|
|
|
|
|
+(* proc35 @0a0c. FIXME sketch: @0a0c-0aa7 register juggling (scopeBase/rollback
|
|
|
|
|
+ chaining, marks) needs a second pass; control flow below follows the
|
|
|
|
|
+ group's reading but details are low-confidence. *)
|
|
|
|
|
+VAR mark: ADDRESS; i, j: CARDINAL; sc: T1; desc: T1;
|
|
|
|
|
+BEGIN
|
|
|
|
|
+ Scanner.GetStackMark(mark); (*{/*0a0c*/}*)
|
|
|
|
|
+ WHILE (Scanner.curSymbol - 15) IN BITSET{3} DO DoImportList END; (*{/*0a12*/}*)
|
|
|
|
|
+ CodeGen.InitCodeGenerator;
|
|
|
|
|
+ Scanner.TestSymbolRange13(BITSET{0..8}); (* FIXME: 495/483 sets TBD *)
|
|
|
|
|
+ Scanner.TestSymbolRange13(BITSET{0..8});
|
|
|
|
|
+ IF Scanner.curSymbol <> 13 THEN (* FIXME: COMPILER.bodyHook() — no such export; Pass1 DCLS hook? *) END;
|
|
|
|
|
+ WHILE Scanner.AcceptSymbol(13) DO
|
|
|
|
|
+ save^.link1 := ADDRESS(Scanner.tokenBuffer); (* FIXME: types punned *)
|
|
|
|
|
+ Scanner.TestSymbolInSet(BITSET{3});
|
|
|
|
|
+ END;
|
|
|
|
|
+ InitHeaps; EnterStandards;
|
|
|
|
|
+ symTop := 0; scopeTop := 14; strTop := 1; exportHead := 0;
|
|
|
|
|
+ currentScope^.link1 := MatchSym(desc, save^.link1);
|
|
|
|
|
+ i := 0;
|
|
|
|
|
+ WHILE i < moduleCount DO
|
|
|
|
|
+ sc := scopeChain^[i];
|
|
|
|
|
+ WHILE sc <> NIL DO
|
|
|
|
|
+ sc^.link2 := NIL; sc^.link1 := NIL; sc := sc^.link0;
|
|
|
|
|
+ END;
|
|
|
|
|
+ INC(i);
|
|
|
|
|
+ END;
|
|
|
|
|
+END CompileBody;
|
|
|
|
|
+
|
|
|
|
|
+PROCEDURE CheckForwards;
|
|
|
|
|
+(* proc36 @0aa7. FIXME sketch, see CompileBody note. *)
|
|
|
|
|
+VAR i: CARDINAL; base: T1; slot: ADDRESS;
|
|
|
|
|
+BEGIN
|
|
|
|
|
+ Compiler.compilationActive := FALSE; (*{/*0aa7*/}*)
|
|
|
|
|
+ InitHeaps;
|
|
|
|
|
+ (* LoadSymFile(modNameBuf, 7); — group D's line; signature is (VAR modName),
|
|
|
|
|
+ second arg unknown. Omitted pending re-read. *)
|
|
|
|
|
+ i := 1;
|
|
|
|
|
+ WHILE i <= symTop DO (*{/*0ac2*/}*)
|
|
|
|
|
+ base := T1(symHeapBase + i * 14);
|
|
|
|
|
+ IF base^.word4 = 5 THEN INCL(base^.word3, 5) END;
|
|
|
|
|
+ INC(i);
|
|
|
|
|
+ END;
|
|
|
|
|
+ UnlinkScope(CARDINAL(currentScope^.link1), currentScope^.link1); (* FIXME args *)
|
|
|
|
|
+ i := 15;
|
|
|
|
|
+ WHILE i <= scopeTop DO (*{/*0ae8*/}*)
|
|
|
|
|
+ base := T1(scopeHeapBase + 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;
|
|
|
|
|
+ INC(i);
|
|
|
|
|
+ END;
|
|
|
|
|
+END CheckForwards;
|
|
|
|
|
+
|
|
|
|
|
+PROCEDURE TryCompile(): BOOLEAN;
|
|
|
|
|
+(* IMDCLS @0b1c. FIXME sketch: frame-37 loop + error-growth recovery. *)
|
|
|
|
|
+VAR saveOpt: BITSET; savePos: CARDINAL; saveMark: ADDRESS;
|
|
|
|
|
+ saveScope: T1; saveCount, saveErr: CARDINAL;
|
|
|
|
|
+BEGIN
|
|
|
|
|
+ saveOpt := Scanner.scanOptions; savePos := Scanner.tokenPos;
|
|
|
|
|
+ Scanner.GetStackMark(saveMark);
|
|
|
|
|
+ saveScope := currentScope^.link1; saveCount := moduleCount;
|
|
|
|
|
+ saveErr := Errors.errorNumber;
|
|
|
|
|
+ IF (Scanner.curSymbol - 15) IN BITSET{3} THEN
|
|
|
|
|
+ DoImportList;
|
|
|
|
|
+ LOOP
|
|
|
|
|
+ (* FIXME: BodyParseStep(saveMark) — Pass1 DCLS body hook, see FRONTEND.md *)
|
|
|
|
|
+ EXIT;
|
|
|
|
|
+ END;
|
|
|
|
|
+ ELSE
|
|
|
|
|
+ Scanner.TestSymbolRange13(BITSET{0..10}); (* FIXME: 2031 set TBD *)
|
|
|
|
|
+ END;
|
|
|
|
|
+ RETURN TRUE;
|
|
|
|
|
+EXCEPTION
|
|
|
|
|
+ moduleCount := saveCount; currentScope^.link1 := saveScope;
|
|
|
|
|
+ IF Errors.errorNumber > saveErr THEN (*{/*0b4c*/}*)
|
|
|
|
|
+ Scanner.tokenPos := savePos; Scanner.scanOptions := saveOpt;
|
|
|
|
|
+ Scanner.CheckStackMark(saveMark);
|
|
|
|
|
+ Errors.RollbackToMark;
|
|
|
|
|
+ CodeGen.OpenEmitter;
|
|
|
|
|
+ RETURN FALSE;
|
|
|
|
|
+ END;
|
|
|
|
|
+ HALT; HALT;
|
|
|
|
|
+END TryCompile;
|
|
|
|
|
+
|
|
|
|
|
+PROCEDURE CompileDispatch(VAR wsp: ARRAY OF BYTE; impl: BOOLEAN; prog: BOOLEAN);
|
|
|
|
|
+(* proc1 @0b6e *)
|
|
|
|
|
+BEGIN
|
|
|
|
|
+ Loader.InitLibs(ADR(wsp), HIGH(wsp) + 1);
|
|
|
|
|
+ Compiler.compilationActive := TRUE;
|
|
|
|
|
+ IF Compiler.scopeSpare3 THEN CompileBody(T1(impl)); (* word3 flag; FIXME arg *)
|
|
|
|
|
+ ELSIF prog THEN CheckForwards
|
|
|
|
|
+ ELSE
|
|
|
|
|
+ Errors.doSymtabRollback := TRUE; (*{/*0b8c*/}*)
|
|
|
|
|
+ REPEAT UNTIL TryCompile; (*{/*0b8f*/}*)
|
|
|
|
|
+ Errors.doSymtabRollback := FALSE;
|
|
|
|
|
+ END;
|
|
|
|
|
+END CompileDispatch;
|
|
|
|
|
+
|
|
|
|
|
+PROCEDURE Checksum7w(ptr: ADDRESS; nwords: CARDINAL);
|
|
|
|
|
+(* proc38 @0b99 — FIXME: LSL is not SYSTEM; original shift primitive TBD *)
|
|
|
|
|
+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
|
|
|
|
|
+ + Words(ptr)^[3] * 8 + Words(ptr)^[4] * 16 + Words(ptr)^[5] * 32
|
|
|
|
|
+ + Words(ptr)^[6] * 64;
|
|
|
|
|
+ checksumTemp := acc;
|
|
|
|
|
+ ptr := ptr + 14; nwords := nwords - 14;
|
|
|
|
|
+ END;
|
|
|
|
|
+END Checksum7w;
|
|
|
|
|
+
|
|
|
|
|
+PROCEDURE SaveSymbolFile;
|
|
|
|
|
+(* proc6 @0bdb *)
|
|
|
|
|
+VAR hdr: ARRAY [0..15] OF WORD;
|
|
|
|
|
+BEGIN
|
|
|
|
|
+ checksumTemp := 0;
|
|
|
|
|
+ Checksum7w(ADR(moduleTable^), moduleCount * 10);
|
|
|
|
|
+ Checksum7w(symHeapBase + 14, symTop * 14);
|
|
|
|
|
+ Checksum7w(scopeHeapBase + 240, (scopeTop - 14) * 16);
|
|
|
|
|
+ Checksum7w(strHeapBase + 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;
|
|
|
|
|
+ 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);
|
|
|
|
|
+END SaveSymbolFile;
|
|
|
|
|
+
|
|
|
|
|
+PROCEDURE RestoreAfterEdit;
|
|
|
|
|
+(* proc7 @0c5e — Edit recovery: unlock only, heaps already rolled back. *)
|
|
|
|
|
+BEGIN
|
|
|
|
|
+END RestoreAfterEdit;
|
|
|
|
|
+
|
|
|
|
|
+END SymTab.
|