(* PASS1.MOD — DRAFT v1, assembled 2026-10-03, NOT verified. Reconstructed from Reversing-Turbo-Modula2-main/MCode_disassembly/pass1.txt (2975 lines) by three parallel passes (groups 1 @0001-02e6, 2 @02e6-07a8, 3 @07a8-end). Does NOT yet recompile to the original MCD; verification via unassemble.c diff is still required (see src/compiler/README.md). Frame rule applied throughout (proven, see STATEMEN.MOD header): "param1" = LAST pushed word; call sites from pushes stay source-order. Signatures are source-order with body roles noted; disagreements flagged. OPEN DISPUTES (MCD diff decides): - D1/D2: proc15 (@0411, 0-param, type-symbol dispatch in every TYPE position) reads as ParseType, while proc19 (@02e6, 3-param, ident-list loop) reads as ParseFormalParams — i.e. possibly SWAPPED vs the map used here (proc15=ParseFormalParams, proc19=ParseType). Group 2's detailed enum/pointer/record/array reading of @02e6-0410 is kept. - D3/D4: proc17 body builds ARRAY descriptors, proc18 parses [lo..hi] SUBRANGEs — kept as ParseConstDecl/ParseVarDecl (map names) pending group-3 cross-check of where real const/var decls live (cf. proc23?). - proc9: map said ~WriteSymFile, body parses procedure bodies with NO file calls — kept as ParseProcBody. The real .SYM writer is then probably proc32 @0db2 (file-output path), which was NOT decompiled (missing mini-pass — next workstream). - proc36 @0e93 slot holds the COMPILE link stub's keyword-table search (patched over); original forward-resolution sweep LOST (cf. SymTab.CheckForwards which may be the same sweep). - No bytes exist for proc10/11/26/27/29/30 (FORWARD stubs), PASS1 @1027 / 4NAZBA @105b (FORWARD stubs). - ConstToCard/ConstToInt call shapes (type-first: ConstToCard(CardType,44)) vs EXPRESS.DEF order (errPos, c) disagree — signature-audit item. - PASS1 globals: word2 emitBase (ADDRESS buffer; group 1's tempBase), word3 emitTop (index; group 1's tempTop), word4 nestDepth. Group-1 SymTab.word4/word5 pun uses kept verbatim + FIXME. Words(X)^[N] = numeric-word pun (MCode untyped). BITSET(numeric) sets, CARDINAL<->ADDRESS punning, and `IN`-tests on CARDINAL curSymbol kept verbatim (casts TBD in verification). GOTO kept as faithful rendering. *) IMPLEMENTATION MODULE Pass1; IMPORT Compiler, Scanner, Errors, CodeGen, Express, Statemen, SymTab, Files, Texts, Loader, ComLine; FROM SYSTEM IMPORT ADDRESS, ADR, MOVE, WORD; FROM STORAGE IMPORT ALLOCATE; TYPE Words = POINTER TO ARRAY [0..4095] OF WORD; VAR emitBase: ADDRESS; (* word2: output/emit buffer base *) emitTop: CARDINAL; (* word3: emit buffer top *) nestDepth: CARDINAL; (* word4: DEC'd on PROCDE/MODULD exit *) (* ---- group-1/3 shared FORWARDs (defined below) ---- *) PROCEDURE PushTempMark(): CARDINAL; FORWARD; PROCEDURE PopTempMark(first, second: WORD); FORWARD; PROCEDURE AllocSymEntry(size: WORD); FORWARD; PROCEDURE LinkSymEntry(entry: ADDRESS); FORWARD; PROCEDURE InsertSetConst(first: ADDRESS; limit: CARDINAL); FORWARD; PROCEDURE CondInsert(flag: WORD; slot: ADDRESS; a, b: WORD): CARDINAL; FORWARD; PROCEDURE InsertEntry(setD, counter, slotA, slotB: ADDRESS): CARDINAL; FORWARD; PROCEDURE OpenScopeEmit(node: ADDRESS); FORWARD; PROCEDURE TypeSizeRec(node, link, acc, aux, size: WORD); FORWARD; PROCEDURE GetIdent(): ADDRESS; FORWARD; PROCEDURE ParseImportItem(first: CARDINAL): ADDRESS; FORWARD; PROCEDURE ParseConstDecl(): ADDRESS; FORWARD; PROCEDURE ParseVarDecl(first: WORD); FORWARD; PROCEDURE ParseType(owner: ADDRESS; VAR typ: ADDRESS; limit: CARDINAL): ADDRESS; FORWARD; PROCEDURE ParseFormalParams(): ADDRESS; FORWARD; PROCEDURE ParseValParam(): ADDRESS; FORWARD; PROCEDURE ParseVarParam; FORWARD; PROCEDURE ParseFieldList; FORWARD; PROCEDURE EvalConstExpr; FORWARD; PROCEDURE CheckConformant(): ADDRESS; FORWARD; PROCEDURE ParseRecordType(rec: ADDRESS; VAR size: CARDINAL; tag: CARDINAL); FORWARD; PROCEDURE CloseScopeFixup; FORWARD; PROCEDURE ParseProcedureDecl; FORWARD; PROCEDURE ParseModuleHead; FORWARD; PROCEDURE ParseExportList; FORWARD; PROCEDURE ParseOneDecl; FORWARD; PROCEDURE ParseDeclarations(follow: BITSET): BOOLEAN; FORWARD; PROCEDURE ParseImportFrom; FORWARD; PROCEDURE ParseModuleBlock(modNode: ADDRESS); FORWARD; PROCEDURE ParseProcBody(procNode: ADDRESS); FORWARD; PROCEDURE ParseMainModule(): BOOLEAN; FORWARD; PROCEDURE WriteMcdHeader; FORWARD; PROCEDURE EmitConstVal(buf: ADDRESS; count: CARDINAL); FORWARD; PROCEDURE EmitTypeDesc; FORWARD; (* stubs: no bytes anywhere *) PROCEDURE EmitModuleProlog(node: ADDRESS); FORWARD; (* proc10 *) PROCEDURE ParseDeclSync; FORWARD; (* proc11 *) PROCEDURE ParseConstOrTypeArm; FORWARD; (* proc26 *) PROCEDURE ParseModuleArm; FORWARD; (* proc27 *) PROCEDURE TryParseDecl(tag: CARDINAL): BOOLEAN; FORWARD; (* proc29 *) PROCEDURE ParseImportScope; FORWARD; (* proc30 *) PROCEDURE CheckForwardResolved; FORWARD; (* proc36: body patched away *) PROCEDURE Pass1Main; FORWARD; (* @1027: no bytes *) PROCEDURE InitPass1; FORWARD; (* 4NAZBA @105b: no bytes *) (* SCANNER.proc24 discovery (group 1): 2-param length-prefix function *) PROCEDURE CappedStrLen(s: ADDRESS; maxLen: CARDINAL): CARDINAL; FORWARD; (* PASS1 group 1 @0001..02e5 *) (* SCANNER.proc24 discovery: 2-param FUNCTION (nameAddr, 128) -> length prefix for EmitWord/Emit1. Identity TBD. *) PROCEDURE CappedStrLen(s: ADDRESS; maxLen: CARDINAL): CARDINAL; FORWARD; (* proc4 @0001 ~PushTempMark. 0 params, function. *) PROCEDURE PushTempMark(): CARDINAL; (*{0001}*) BEGIN Express.CentralError(SymTab.stringPoolPtr < emitTop - 1, 82); (*{0003-000a} FIXME: group read SymTab.word4=symFile:FILE — pun suspicious; role TBD *) INC(SymTab.stringPoolPtr); (*{000c-000f} FIXME *) RETURN SymTab.stringPoolPtr; (*{0011-0013} FIXME *) END PushTempMark; (* proc5 @0016 ~PopTempMark. 2 params: body param1 = source formal2. *) PROCEDURE PopTempMark(first, second: WORD); (*{0016} FIXME order: frame rule says formal1=last-pushed *) BEGIN Express.CentralError(SymTab.stringPoolPtr < emitTop - 2, 82); (*{0018-0020} FIXME same as above *) DEC(emitTop); (*{0022-0024} FIXME: group used tempTop *) Words(emitBase)^[emitTop] := second; (*{0025-0028} *) DEC(emitTop); (*{0029-002b}*) Words(emitBase)^[emitTop] := first; (*{002c-002f}*) END PopTempMark; (* proc6 @0032 ~AllocSymEntry. 1 param. *) PROCEDURE AllocSymEntry(size: WORD); (*{0032}*) BEGIN IF Express.spillFlag = 0 THEN (*{0034-0037} *) WHILE (emitTop <= 254) AND (Words(emitBase)^[emitTop] >= size) DO (*{0039-0044}*) emitTop := emitTop + 2; (*{0046-0049} first-fit scan, 2-word slots *) END; END; SymTab.moduleCount := size; (*{004c-004d} FIXME: group wrote word5=stringPoolPtr; moduleCount=word3? BOTH punned — TBD *) END AllocSymEntry; (* proc7 @0051 ~LinkSymEntry. 1 param. *) PROCEDURE LinkSymEntry(entry: ADDRESS); (*{0051}*) BEGIN FILL(entry, 508, 0); (*{0053-0058} per Extended.Fill *) WHILE emitTop <= 254 DO (*{005a-005e}*) Words(emitBase)^[(Words(emitBase)^[emitTop] DIV 2) - 2] := Words(emitBase)^[emitTop + 1]; (*{0060-006c} dead push harmless *) emitTop := emitTop + 2; (*{006d-0070}*) END; END LinkSymEntry; (* proc1 @007c ~InsertSetConst. 2 params: first = body param2. *) PROCEDURE InsertSetConst(first: ADDRESS; limit: CARDINAL); (*{007c} FIXME roles *) VAR setBitsA: ARRAY [0..3] OF WORD; elemBufA: ARRAY [0..63] OF WORD; setBits: ADDRESS; elemBuf: ADDRESS; cursor: ADDRESS; count: CARDINAL; allocSize: CARDINAL; heapStr: ADDRESS; tmp: WORD; BEGIN setBits := ADDRESS(ADR(setBitsA)); (*{007e-0080} *) elemBuf := ADDRESS(ADR(elemBufA)); (*{0081-0084} *) cursor := Words(first)^[6]; (*{0085-0087} FIXME field roles TBD *) IF (cursor # NIL) AND (Compiler.scopeSpare3 = NIL) AND NOT SymTab.BuildBitsetConst(Words(first)^[1]) THEN (* FIXME: VAR ARRAY arg pun *) count := 0; (*{0097-0098}*) LOOP (*{0099}*) tmp := Words(cursor)^[2]; (*{0099-009b} element value *) IF tmp >= limit THEN RETURN END; (*{009b-009f} *) IF 4 IN BITSET(Words(cursor)^[3]) THEN (*{00a0-00a4} *) Words(setBits)^[count DIV 16] := CARDINAL(BITSET(Words(setBits)^[count DIV 16]) + BITSET{count MOD 16}); (*{00a6-00b4} *) END; Words(elemBuf)^[count] := tmp; (*{00b5-00b9} *) INC(count); (*{00ba-00bc}*) cursor := Words(cursor)^[0]; (*{00bd-00bf} next link *) IF cursor = NIL THEN EXIT END; (*{00c0-00c2}*) END; Scanner.CheckStackMark(ADDRESS(limit)); (*{00c4-00c5} FIXME: limit punned as mark *) allocSize := ((count + 15) DIV 16) * 2; (*{00c7-00cc} *) Scanner.Allocate(heapStr, allocSize + count * 2 + 2); (*{00cf-00d8} *) Words(heapStr)^[0] := count; (*{00da-00dc}*) MOVE(ADDRESS(Words(heapStr)^[1]), setBits, allocSize); (*{00dd-00e3} *) MOVE(ADDRESS(Words(Words(heapStr)^[1] + allocSize)^[0]), elemBuf, count * 2); (*{00e4-00ed} *) Words(first)^[6] := heapStr; (*{00ef-00f1} *) ELSE Words(first)^[6] := heapStr; (*{00ef-00f1} FIXME: guard-false store quirk TBD *) END; END InsertSetConst; (* proc2 @00f4 ~CondInsert. 4 params: (flag,slot,a,b) = body (param4..1). *) PROCEDURE CondInsert(flag: WORD; slot: ADDRESS; a, b: WORD): CARDINAL; (*{00f4}*) BEGIN IF flag # 0 THEN (*{00f6-00f8}*) Words(slot)^[0] := flag; (*{00fa-00fc}*) IF Words(flag)^[0] - 1 < 64 THEN (*{00fd-0107} flag punned as address *) Words(slot)^[0] := 1; END; RETURN InsertEntry(flag, slot, a, b); (*{0108-010d} *) END; RETURN 0; (*{010f-0110}*) END CondInsert; (* proc3 @0113 ~InsertEntry. 4 params. *) PROCEDURE InsertEntry(setD, counter, slotA, slotB: ADDRESS): CARDINAL; (*{0113}*) VAR idx: CARDINAL; base: ADDRESS; BEGIN IF Words(counter)^[0] # 0 THEN (*{0115-0118}*) IF Words(setD)^[0] - 1 < 64 THEN (*{011a-0120} small-set path *) idx := Words(counter)^[0] - 1; (*{0122-0125}*) base := setD; (*{0126-0127}*) Words(slotA)^[0] := Words(base)^[1 + (Words(base)^[0] + 15) DIV 16 + idx]; (*{0128-0138} *) Words(slotB)^[0] := ORD((idx MOD 16) IN BITSET(Words(base)^[1 + idx DIV 16])); (*{0139-0148} *) Words(counter)^[0] := idx + 2; (*{0149-014d} *) IF Words(base)^[0] - 1 = idx THEN Words(counter)^[0] := 0; (*{0155-0157} full *) END; ELSE (*{015a} large path *) Words(slotA)^[0] := Words(Words(counter)^[0])^[2]; (*{015a-015e} *) Words(slotB)^[0] := ORD(4 IN BITSET(Words(Words(counter)^[0])^[3])); (*{015f-0165} *) Words(counter)^[0] := Words(Words(counter)^[0])^[0]; (*{0166-016a} *) END; RETURN 1; (*{016b-016c}*) END; RETURN 0; (*{016e-016f}*) END InsertEntry; (* proc8 @017b ~OpenScopeEmit. 1 param. *) PROCEDURE OpenScopeEmit(node: ADDRESS); (*{017b}*) VAR mark: CARDINAL; BEGIN mark := PushTempMark(); (*{017d-017e} *) IF Compiler.rangeCheckEnabled THEN (*{017f-0182} *) CodeGen.EmitExtCall3(2, mark, 0); (*{0183-0186} *) CodeGen.EmitWord(CappedStrLen(Words(node)^[5], 128)); (*{0189-0190} *) Words(node)^[6] := mark; (*{0192-0194} *) Words(emitBase)^[mark] := CodeGen.nextEmitPos; (*{0195-0199} *) CodeGen.EmitString(Words(node)^[5]); (*{019a-019c} NUL-terminated *) END; END OpenScopeEmit; (* proc12 @01a1 ~TypeSizeRec. 5 params, RECURSIVE. *) PROCEDURE TypeSizeRec(node, link, acc, aux, size: WORD); (*{01a1} FIXME roles/order *) VAR skipAdd: BOOLEAN; BEGIN IF Words(node)^[0] # link THEN (*{01a3-01a7} follow indirection *) TypeSizeRec(Words(node)^[0], link, acc, aux, size); (*{01a9-01b0} *) END; IF Words(node)^[4] = 4 THEN (*{01b2-01b6} record-ish kind *) Words(node)^[2] := aux; (*{01b8-01ba}*) IF NOT (8 IN BITSET(Words(node)^[3])) THEN RETURN END; (*{01bb-01c0} *) skipAdd := (Express.spillFlag # 0) AND (Words(node)^[3] = 0); (*{01c2-01cb} *) IF skipAdd THEN (*{01cc-01d4} *) Words(acc)^[0] := Words(acc)^[0] - size; END; Words(node)^[5] := Words(acc)^[0]; (*{01d5-01d8} publish offset *) IF (Express.spillFlag = 0) AND (Words(aux)^[4] > 9) AND (Words(node)^[3] = 0) THEN (*{01d9-01e8} *) PopTempMark(Words(acc)^[0], (Words(aux)^[3] + 1) DIV 2 * 2); (*{01ea-01f3} *) END; IF NOT skipAdd THEN (*{01f4-01fd} *) Words(acc)^[0] := Words(acc)^[0] + size; END; END; END TypeSizeRec; (* proc13 @0201 ~GetIdent. 0 params, function. *) PROCEDURE GetIdent(): ADDRESS; (*{0201} FIXME: name says ident, returns a TYPE *) VAR typ: ADDRESS; BEGIN Scanner.PushWithScope; (*{0203} *) Scanner.ExpectIdentKind(3); (*{0205-0206} *) typ := Scanner.literalType; (*{0208-020a} pre-GetSym *) Scanner.GetSym; (*{020b}*) RETURN typ; (*{020d-020e}*) END GetIdent; (* proc16 @0211 ~ParseImportItem. 1 param function. *) PROCEDURE ParseImportItem(first: CARDINAL): ADDRESS; (*{0211} FIXME role of flag *) VAR item: ADDRESS; node: ADDRESS; BEGIN Scanner.ExpectSymbol(42); (*{0213-0216} FROM *) node := Scanner.NewSizedNode(5); (*{0217-021a}*) Words(node)^[3] := 2; (*{021b-021e}*) IF (first # 0) AND (Scanner.identKind = 0) AND (Scanner.scopeCursor = NIL) THEN (*{021e-0229} *) item := Scanner.DeclareIdentifier(0); (*{022b-022f} plain item *) Words(item)^[2] := node; (*{0230-0232} *) ELSE Words(node)^[2] := ParseType(); (*{0235-0239} FIXME: 0-arg vs 3-param def *) END; RETURN node; (*{023a-023b}*) END ParseImportItem; (* proc17 @023e ~ParseConstDecl. 0 params function. DISPUTE D3: body builds an ARRAY descriptor — rename to ParseArrayType pending group-3 cross-check. Map name kept. *) PROCEDURE ParseConstDecl(): ADDRESS; (*{023e}*) VAR arrDesc: ADDRESS; idxDesc: ADDRESS; elemDesc: ADDRESS; BEGIN arrDesc := Scanner.NewSizedNode(11); (*{0240-0243}*) idxDesc := ParseType(); (*{0244-0248} FIXME arity *) Words(Express.curDesc.raw[0])^[0] := idxDesc; (*{024c-0250} *) Express.MatchOpClass(BITSET{3}, 47); (*{0251-0253} index ordinal *) IF Scanner.AcceptSymbol(1) THEN (*{0255-0256} *) elemDesc := ParseConstDecl(); (*{025a-025d} recurse *) ELSE Scanner.ExpectSymbol(41); (*{0260-0262} OF *) elemDesc := ParseType(); (*{0264-0268} FIXME arity *) END; Words(arrDesc)^[5] := elemDesc; (*{0269-026b} *) Words(arrDesc)^[3] := (Words(idxDesc)^[6] - Words(idxDesc)^[5] + 1) * Words(elemDesc)^[3]; (*{026c-0276} *) RETURN arrDesc; (*{0277-0278}*) END ParseConstDecl; (* proc18 @027b ~ParseVarDecl. 1 param function. DISPUTE D4: body parses [lo..hi] SUBRANGE — rename to ParseSubrangeType pending. Map name kept. *) PROCEDURE ParseVarDecl(first: WORD); (*{027b} FIXME punned ADDRESS/value *) VAR desc: ADDRESS; BEGIN desc := Scanner.NewSizedNode(1); (*{027d-0280} subrange desc *) Express.GetConstVal; (*{0281} lower bound *) IF first = 0 THEN (*{0283-0285} anonymous *) Words(desc)^[2] := Words(Express.curDesc.raw[0])^[0]; (*{0287-028c} *) ELSE IF Words(first)^[4] = 1 THEN first := Words(first)^[2] END; (*{028e-0296} *) Express.ConstToCard(first, 0); (*{0297-0299} FIXME: (c,errPos) vs DEF order *) Words(desc)^[2] := first; (*{029b-029d} lo *) END; Express.MatchOpClass(BITSET{5}, 0); (*{029e-02a0} FIXME errCode 0 *) Words(desc)^[5] := Words(Express.curDesc.raw[0])^[2]; (*{02a2-02a6} lo value *) Scanner.ExpectSymbol(4); (*{02a7-02a8} `..` *) Express.GetConstVal; (*{02aa} upper bound *) Express.ConstToCard(Words(desc)^[2], 0); (*{02ac-02af} FIXME order *) Words(desc)^[6] := Words(Express.curDesc.raw[0])^[2]; (*{02b1-02b5} hi value *) IF Words(desc)^[2] = Compiler.IntType THEN Express.CentralError(Words(desc)^[6] >= Words(desc)^[5], 46); (*{02bd-02c4} *) ELSE Express.CentralError(Words(desc)^[6] >= Words(desc)^[5], 46); (*{02c8-02cf} *) END; Scanner.ExpectSymbol(6); (*{02d1-02d2} `]` *) Words(desc)^[3] := ORD((Words(desc)^[5] > 32767) OR (Words(desc)^[6] > 255)) + 1; (*{02d4-02e2} *) RETURN desc; (*{02e2-02e3}*) END ParseVarDecl; (* PASS1 group 2 @02e6-0783. DISPUTE D1/D2 (group 1): proc15 reads as ParseType, proc19 as ParseFormalParams. Group 2's detailed readings kept with map names; MCD diff decides. See header. *) (* proc19 @02e6 — ~ParseType (map name; see D2). 3 formals. *) PROCEDURE ParseType(owner: ADDRESS; VAR typ: ADDRESS; limit: CARDINAL): ADDRESS; VAR t, u: ADDRESS; lo, hi: CARDINAL; loA, hiA: ADDRESS; n, cnt, elemT: CARDINAL; enumBase: ADDRESS; tmp: CARDINAL; BEGIN WHILE Scanner.curSymbol IN BITSET{9984H} DO (*{02eb} FIXME: set TBD *) IF Scanner.AcceptSymbol(40) THEN (*{02f5} *) IF Scanner.AcceptSymbol(2) THEN (*{02fb} *) elemT := CARDINAL(GetIdent()); (*{0300} FIXME pun *) ELSE Scanner.DeclareIdentifier(4); (*{0308} *) typ := owner; (*{030d-0327} FIXME: stack shuffles idealized *) elemT := CARDINAL(GetIdent()); END; Express.MatchOpClass(BITSET{7}, 40); (*{032c} *) Scanner.ExpectSymbol(41); (*{0331} *) enumBase := typ; (*{0335} *) cnt := 0; (*{0338} *) WHILE NOT (Scanner.curSymbol IN BITSET{9472H}) DO (*{033a-03b1} enum loop *) tmp := cnt; t := elemT; (*{0343-0344}*) Express.GetTypeDesc(loA, hiA, NIL); (*{0346} FIXME: (dest,mode,src) roles *) lo := CARDINAL(loA); hi := CARDINAL(hiA); (*{034c-034f} FIXME pun *) IF lo <= hi THEN (*{0350} *) t := cnt; REPEAT t := Scanner.NewSizedNode(12); (*{0357} *) Words(t)^[6] := u; Words(t)^[2] := elemT; (*{035b-0366} FIXME pun *) Words(t)^[3] := enumBase; Words(t)^[7] := lo; (*{0361-0366}*) IF u # NIL THEN (*{0367} *) IF u # lo THEN Express.CentralError(TRUE, 47); END; (*{036b-0371} FIXME cond *) u := Words(u)^[6]; (*{0373-0375} FIXME pun *) END; INC(lo); (*{0378-037a} *) UNTIL lo > hi; END; IF NOT (Scanner.TestSymbolInSet(6) AND Scanner.AcceptSymbol(1)) THEN EXIT END; (*{037c-0384} FIXME: TestSymbolInSet is VOID assert *) Scanner.GetSym; (*{0386} *) t := cnt; typ := ParseType(owner, t, limit); (*{0388-0390} recursive FIXME arity *) u := typ; IF Words(t)^[3] > limit THEN limit := Words(t)^[3]; END; (*{03a6-03b0} *) END; WHILE NOT (Scanner.TestSymbolInSet(8) AND Scanner.AcceptSymbol(1)) DO END; (*{03b6-03ba} FIXME shape *) IF Scanner.AcceptSymbol(10) THEN (*{03bc-03bf} *) tmp := CARDINAL(ParseType(owner, tmp, limit)); (*{03c1-03c7} FIXME pun *) IF CARDINAL(enumBase) > limit THEN limit := CARDINAL(enumBase); END; (*{03c9-03d1} FIXME *) END; Scanner.ExpectSymbol(13); (*{03d2} *) typ := ADDRESS(cnt); (*{03d5-03d7} FIXME pun *) ELSE Scanner.DeclareIdentifier(4); (*{03da} *) tmp := Scanner.curNode; (*{03de} FIXME: ADDRESS := RecordPtr pun *) WHILE NOT (Scanner.TestSymbolInSet(6) AND Scanner.AcceptSymbol(1)) DO END; (*{03e2-03e9} FIXME shape *) Scanner.GetSym; (*{03eb} *) elemT := CARDINAL(ParseFormalParams()); (*{03ed} FIXME pun *) typ := owner; (*{03f2-0406} FIXME: TypeSizeRec + word9 wiring *) tmp := TypeSizeRec(owner, elemT, elemT, elemT, elemT); (*{03f7-0400} FIXME: 5-arg shape TBD *) END; IF NOT Scanner.AcceptSymbol(9) THEN EXIT END; (*{0407-040b} *) END; RETURN typ; (*{040e} *) END ParseType; (* proc15 @0411 — ~ParseFormalParams (map name; see D1). 0-param function. *) PROCEDURE ParseFormalParams(): ADDRESS; VAR head, n, kind: CARDINAL; tail, cur: ADDRESS; BEGIN IF Scanner.AcceptSymbol(43) THEN (*{0413} *) head := CARDINAL(Scanner.NewSizedNode(0)); n := 0; (*{0419-041e} FIXME pun *) Scanner.DeclareIdentifier(1); kind := CARDINAL(Scanner.curNode); (*{041f-0423} FIXME *) INC(n); WHILE Scanner.TestSymbolInSet(34) AND Scanner.AcceptSymbol(1) DO (*{0432-0439} FIXME shape *) Scanner.DeclareIdentifier(1); END; Scanner.GetSym; (*{043c} *) ELSIF Scanner.AcceptSymbol(44) THEN (*{044c-044e} *) head := CARDINAL(ParseVarDecl(0)); (* nested proc18 FIXME *) ELSIF Scanner.AcceptSymbol(50) THEN (*{0458-045b} *) Scanner.ExpectSymbol(41); (*{045e} *) head := CARDINAL(Scanner.NewSizedNode(4)); (*{0462} FIXME *) Words(ADDRESS(head))^[3] := 2; (*{0466-0468} FIXME *) tail := ParseFormalParams(); (*{0469} FIXME: recursion? *) Words(ADDRESS(head))^[2] := tail; (*{046d-046f} FIXME *) Express.MatchOpClass(BITSET{3}, 50); (*{0470-0477} *) IF Words(tail)^[6] > 15 THEN Express.CentralError(TRUE, 41); END; (*{0479} FIXME cond *) ELSIF Scanner.AcceptSymbol(48) THEN (*{0483-0486} *) head := CARDINAL(ParseImportItem(0)); (*{0489} FIXME *) ELSIF Scanner.AcceptSymbol(21) THEN (*{0490-0493} *) head := CARDINAL(Scanner.NewSizedNode(9)); (*{0496} FIXME *) Words(ADDRESS(head))^[3] := 4; (*{049a-049c} FIXME *) ParseRecordType(ADDRESS(head), sizeTmp, 1); (*{049d-04a5} FIXME: VAR/size shape TBD *) ELSIF Scanner.AcceptSymbol(47) THEN (*{04a9-04ac} *) head := CARDINAL(ParseConstDecl()); (* nested proc17 *) ELSIF Scanner.AcceptSymbol(49) THEN (*{04b4-04b7} *) head := CARDINAL(Scanner.NewSizedNode(10)); (*{04ba} FIXME *) Scanner.OpenScope(SymTab.currentScope, NIL); (*{04bd-04bf} FIXME args *) ParseType(ADDRESS(head), typeTmp, typeLim); (*{04c1-04cd} FIXME args *) Scanner.ExpectSymbol(13); (*{04cf} *) SymTab.currentScope := Scanner.curNode; (*{04d2-04d5} FIXME: T1 := RecordPtr pun *) IF Words(ADDRESS(head))^[3] < 2 THEN Words(ADDRESS(head))^[3] := 2; END; (*{04d7-04df} *) ELSE head := CARDINAL(GetIdent()); (*{04e2} FIXME pun *) IF Scanner.AcceptSymbol(44) THEN head := CARDINAL(ParseVarDecl(0)); END; (*{04e6-04ef} *) END; RETURN ADDRESS(head); (*{04f0} FIXME pun *) END ParseFormalParams; (* proc20 @04f4 — ~ParseValParam. 0 formals, returns type desc. *) PROCEDURE ParseValParam(): ADDRESS; VAR t: ADDRESS; BEGIN IF Scanner.AcceptSymbol(48) THEN (*{04f6} *) t := ParseImportItem(0); (*{04fc-04fe} FIXME arg *) ELSE t := ParseFormalParams(); (*{0503-0504} *) END; RETURN t; (*{0507} *) END ParseValParam; (* proc21 @050b — ~ParseVarParam. 0 formals, no result. *) PROCEDURE ParseVarParam; VAR t: ADDRESS; BEGIN WHILE Scanner.curSymbol = 0 DO (*{050d-0543} *) t := Scanner.MakeIdentifierNode(1); (*{0512-0514} FIXME: ADDRESS := ADDRESS ok *) Scanner.ExpectSymbol(52); (*{0516-0518} *) Express.GetConstVal; (*{051b} *) Words(t)^[2] := Express.curDesc.raw[0]; (*{051d-0521} FIXME pun *) Words(t)^[6] := Express.curDesc.raw[2]; (*{0522-0528} dword spill idealized *) IF (Words(t)^[2] = Compiler.charArrayDesc) AND (NOT Compiler.compilationActive) AND (Words(t)^[6] = 0) THEN (*{0529-0537} FIXME: compilationActive BOOLEAN vs 0 *) OpenScopeEmit(t); (*{053a} *) END; Scanner.InsertSymbol(t); (*{053c-0541} FIXME: T1 pun *) Scanner.ExpectSymbol(9); (*{0542} *) END; END ParseVarParam; (* proc22 @0548 — ~ParseFieldList. 0 formals. *) PROCEDURE ParseFieldList; VAR saveScope: ADDRESS; tag, fld: CARDINAL; node: ADDRESS; BEGIN saveScope := ADDRESS(SymTab.currentScope); (*{054a-0550} FIXME pun *) IF Scanner.curSymbol = 0 THEN (*{054e-0551} *) Scanner.NeedIdentifier; tag := CARDINAL(Scanner.curNode); (*{0553-0556} FIXME *) IF Scanner.TestSymbolInSet(6) THEN (*{0558?} FIXME: group wove word13/identKind guards; shape TBD *) Scanner.GetSym; Scanner.ExpectSymbol(52); fld := CARDINAL(ParseValParam()); (*{056d-0570} FIXME *) Words(ADDRESS(tag))^[2] := fld; (*{0571-0579} FIXME *) ELSE tag := CARDINAL(Scanner.MakeIdentifierNode(3)); (*{05b9-05bd} FIXME *) IF Compiler.compilationActive AND (Scanner.curSymbol = 9) THEN (*{05be-05c6} *) fld := CARDINAL(Scanner.NewSizedNode(6)); Words(ADDRESS(fld))^[3] := 2; (*{05c8-05ce} FIXME *) ELSE Scanner.ExpectSymbol(52); (*{05d1-05d3} *) fld := CARDINAL(ParseValParam()); (*{05d5-05d8} *) END; Words(ADDRESS(tag))^[2] := fld; (*{05d9-05db} FIXME *) Scanner.InsertSymbol(ADDRESS(tag)); (*{05dc-05dd} FIXME T1 pun *) END; Scanner.ExpectSymbol(9); (*{05e0} *) ELSE tag := CARDINAL(SymTab.currentScope); node := saveScope; (*{05ed-05f1} FIXME *) WHILE ADDRESS(tag) # node DO (*{05f1-0605} FIXME *) IF ADDRESS(tag) = NIL THEN Errors.ReportErrorWithText(5, Scanner.tokenBuffer); END; (*{05f9-0600} *) tag := CARDINAL(Words(ADDRESS(tag))^[0]); (*{0602-0604} FIXME *) END; END; END ParseFieldList; (* proc23 @060a — ~EvalConstExpr. 0 formals. Const-expr list evaluator. *) PROCEDURE EvalConstExpr; VAR t, u, v: CARDINAL; n: CARDINAL; BEGIN WHILE Scanner.curSymbol = 0 DO (*{060c-0682} *) t := CARDINAL(SymTab.currentScope); (*{0611-0613} FIXME *) Scanner.DeclareIdentifier(4); u := CARDINAL(Scanner.curNode); (*{0615-0619} FIXME *) Words(ADDRESS(u))^[4] := Express.spillFlag; (*{061b-061d} FIXME *) IF Scanner.AcceptSymbol(44) THEN (*{061e-0622} *) Express.GetConstVal; (*{0624} *) Express.ConstToCard(Compiler.CardType, 44); (*{0626-062a} FIXME: (type,code) vs DEF order *) Words(ADDRESS(u))^[2] := Express.curDesc.raw[2]; (*{062b-062f} FIXME *) Words(ADDRESS(u))^[3] := 256; (*{0631-0637} *) Scanner.ExpectSymbol(6); (*{0638} *) END; IF NOT (Scanner.TestSymbolInSet(6) AND Scanner.AcceptSymbol(1)) THEN EXIT END; (*{0639-0640} FIXME shape *) Scanner.GetSym; (*{0642} *) v := CARDINAL(ParseFormalParams()); (*{0644-0647} FIXME *) IF Words(ADDRESS(v))^[4] > 9 THEN n := 2; ELSE n := (Words(ADDRESS(v))^[3] + 1) DIV 2; END; (*{0648-0659} FIXME *) TypeSizeRec(ADDRESS(t), ADDRESS(u), ADR(SymTab.stringPoolPtr), ADDRESS(v), n); (*{065a-0662} FIXME: 5-arg punned shape *) Scanner.ExpectSymbol(9); (*{0664} *) IF Express.spillFlag = 0 THEN (*{0667-066d} *) IF SymTab.stringPoolPtr <= 510 THEN Express.CentralError(TRUE, 83); END; (*{066c-0674} FIXME cond *) ELSE IF SymTab.stringPoolPtr >= 384 THEN Express.CentralError(TRUE, 81); END; (*{0678-0680} FIXME cond *) END; END; END EvalConstExpr; (* proc24 @0687 — ~CheckConformant. 0 formals, returns ADDRESS. *) PROCEDURE CheckConformant(): ADDRESS; VAR t: ADDRESS; BEGIN IF Scanner.AcceptSymbol(47) THEN (*{0689-068d} *) Scanner.ExpectSymbol(41); (*{068f-0691} *) t := Scanner.NewSizedNode(11); (*{0693-0695} *) CheckConformantTail(t); (*{0697-0699} FIXME: self/nested-variant TBD *) ELSE t := GetIdent(); (*{069e-06a0} *) END; RETURN t; (*{06a3} *) END CheckConformant; (* proc14 @06a7 — ~ParseRecordType (map name). 3 formals. *) PROCEDURE ParseRecordType(rec: ADDRESS; VAR size: CARDINAL; tag: CARDINAL); VAR total: CARDINAL; fld, head, cur: ADDRESS; disc, code: CARDINAL; lo, hi: CARDINAL; BEGIN total := 6; size := 0; (*{06a9-06b0} *) IF Scanner.curSymbol # 9 THEN (*{06b1-06b5} *) Scanner.ExpectSymbol(43); (*{06b7-06b9} *) IF NOT Scanner.AcceptSymbol(5) THEN GOTO noFixed END; (*{06bb-06bf} *) Scanner.OpenScope(SymTab.currentScope, NIL); (*{06c1-06c4} FIXME args *) IF Scanner.AcceptSymbol(20) THEN code := 24; ELSE code := 8; END; (*{06c7-06d3} *) IF tag # 0 THEN (*{06d4} *) fld := Scanner.NewNode(4); (*{06d7-06d9} *) Words(fld)^[1] := SymTab.currentScope; Words(fld)^[0] := SymTab.currentScope; (*{06db-06e3} FIXME T1 pun *) Words(fld)^[3] := code; disc := 1; hi := 34; (*{06e4-06eb} *) ELSE Scanner.DeclareIdentifier(4); fld := Scanner.curNode; (*{06ee-06f2} FIXME T1 pun *) Words(fld)^[3] := code; Words(fld)^[6] := Express.spillFlag + 1; (*{06f3-06fb} FIXME *) IF NOT (Scanner.TestSymbolInSet(6) AND Scanner.AcceptSymbol(1)) THEN EXIT END; (* FIXME shape *) Scanner.GetSym; disc := 9; hi := 544; (*{0704-070b} *) END; fixedLoop: head := CheckConformant(); (*{070c} *) cur := fld; WHILE cur # rec DO cur := Words(cur)^[0]; END; (*{0711-071b} *) rec := fld; (*{071d-071f} *) IF NOT Scanner.TestSymbolInSet(hi) THEN GOTO doneVariants END; (*{0720-0726} FIXME set TBD *) Scanner.GetSym; (*{0729} *) IF fld # NIL THEN (*{072b-072d} *) fld := Words(fld)^[2]; head := fld; (*{072f-0733} *) IF (4 IN Words(fld)^[3]) OR (Words(head)^[4] > 9) THEN (*{0734-073c} FIXME set TBD *) code := 2; (*{073e-073f} *) REPEAT head := Words(head)^[5]; (*{0746-074c} FIXME: ConstToIntRange idealized *) UNTIL FALSE; ELSE code := (Words(head)^[3] + 1) DIV 2; (*{0751-0758} *) END; END; SymTab.currentScope := SymTab.currentScope; (*{0765-0768} self-store? slot shuffle FIXME *) noFixed: IF Scanner.AcceptSymbol(2) THEN (*{076a-076d} *) disc := CARDINAL(GetIdent()); (*{076f-0772} FIXME *) Express.MatchOpClass(BITSET{511}, 2); (*{0773-077b} *) size := disc; (*{077d-077f} *) END; doneVariants: ; END ParseRecordType; (* proc25 @0783 — ~CloseScopeFixup. 0 formals. *) PROCEDURE CloseScopeFixup; BEGIN IF 0 IN Scanner.curSymbol THEN (*{0785-078a} FIXME: CARDINAL set test *) Texts.WriteString(3, ""); (*{078c-0791} FIXME: proc21 args TBD *) Texts.WriteString(3, Scanner.tokenBuffer); (*{0793-0798} FIXME *) Texts.WriteLn(3); (*{079a-079c} FIXME *) END; INC(nestDepth); (*{079d-079f} FIXME: group used Pass1.tempDepth *) END CloseScopeFixup; (* PASS1 group 3 @07a8-end. Missing/stubbed: proc10/11/26/27/29/30 (no bytes), proc36 body (patched over), PASS1/4NAZBA (no bytes). DISPUTE: proc9 = ParseProcBody per body (no file calls) vs ~WriteSymFile per map. *) (* FIXME-NYC stubs for called-but-absent procedures *) PROCEDURE EmitModuleProlog(node: ADDRESS); FORWARD; (* proc10: 1 push *) PROCEDURE ParseDeclSync; FORWARD; (* proc11: 0 pushes *) PROCEDURE ParseConstOrTypeArm; FORWARD; (* proc26: DCL arm 111 *) PROCEDURE ParseModuleArm; FORWARD; (* proc27: DCL arm 112 *) PROCEDURE TryParseDecl(tag: CARDINAL): BOOLEAN; FORWARD; (* proc29: 1 push; 2-push sites FIXME *) PROCEDURE ParseImportScope; FORWARD; (* proc30: display-only *) (*{07a8} PROCDE — ParseProcedureDecl. 0 params. *) PROCEDURE ParseProcedureDecl; VAR l2, l3, l4, l5: ADDRESS; s0, s1, s2, s3, s5, s6: WORD; BEGIN CloseScopeFixup; (*{07aa} proc25 *) Scanner.NeedIdentifier; (*{07ad} *) IF (Scanner.word13 = SymTab.currentScope) & (Compiler.scopeSpare3 = NIL) & (5 IN Scanner.followSet) THEN (*{07af-07bf} FIXME codes *) l3 := Scanner.curNode; (*{07c1-07c3} FIXME pun *) Scanner.Allocate(ADR(l2), 14); (*{07c4-07c7} FIXME: group wrote Proc7 *) MOVE(l3, l2, 14); (*{07c9-07cc} FIXME dst/src order *) Scanner.GetSym; (*{07d6} *) ELSE l2 := Scanner.DeclareIdentifier(5); (*{07da-07de} *) Words(l2)^[5] := PushTempMark(); (*{07df-07e4} FIXME pun *) Words(l2 + 1)^[5] := Express.spillFlag; (*{07e5-07eb} FIXME cell *) END; Scanner.GetStackMark(ADR(l6)); (*{07ec-07ee} FIXME slot *) ParseRecordType(l2 + 6, l2 + 2, 0); (*{07f0-07f8} FIXME: ADDRESS arith + (rec,size,tag) roles *) Scanner.ExpectSymbol(9); (*{07fa-07fb} *) IF 5 IN Words(l2)^[3] THEN (*{07fd-0801} FIXME: group ternary w/ s3 TBD *) Express.CentralError(TRUE, 68); (*{080f-0814} FIXME: Proc21 8-cell call TBD *) WHILE l4 # NIL DO (*{0816-082f} formal walk FIXME *) Express.CentralError(TRUE, 68); (*{081a-0827} FIXME: Proc23 5-push call TBD *) l4 := Words(l4)^[0]; END; Words(l2)^[3] := Words(l2)^[3] - BITSET{5}; (*{0831-0838} *) Scanner.CheckStackMark(l2 + 14); (*{0839-083c} FIXME arith *) ParseProcBody(l2); (*{0843} `f9 proc9` *) ELSE IF Compiler.scopeSpare3 = NIL THEN (*{0846-0849} *) IF Scanner.AcceptSymbol(67) THEN (*{084b-084e} FIXME: 67=END? *) s3 := 32; (*{0851-0856} FIXME *) Scanner.ExpectSymbol(9); (*{0856} *) ELSE ParseProcBody(l2); (*{085a-085b} *) InsertSetConst(NIL, 0); (*{085c-085e} FIXME args *) END; END; END; DEC(nestDepth); (*{085f-0861} *) END ParseProcedureDecl; (*{0878} MODULD — ParseModuleHead. 0 params. *) PROCEDURE ParseModuleHead; VAR l2, l3: ADDRESS; BEGIN CloseScopeFixup; (*{087d} *) l3 := ADDRESS(Statemen.withPending); (*{087e-087f} FIXME pun *) l2 := Scanner.DeclareIdentifier(6); (*{0880-0884} *) IF Scanner.AcceptSymbol(44) THEN (*{0885-0887} FIXME: 44 here? *) Statemen.withPending := 1; (*{088b-088c} *) Express.EvalConstExpr; (*{088d} FIXME: group saw proc13=GetConstVal *) Scanner.ExpectSymbol(6); (*{088f-0891} *) END; Scanner.ExpectSymbol(9); (*{0893-0894} *) EmitModuleProlog(l2); (*{0896-0897} FIXME-NYC *) Statemen.withPending := CARDINAL(l3); (*{0898-0899} FIXME *) DEC(nestDepth); (*{089b-089d} *) END ParseModuleHead; (*{08b2} proc28 — ParseExportList. 0 params. From DCL arm 104. *) PROCEDURE ParseExportList; VAR l2: ADDRESS; l3: WORD; BEGIN l2 := Scanner.DeclareIdentifier(2); (*{08b4-08b8} *) l3 := PushTempMark(); (*{08b9-08ba} FIXME: WORD := CARDINAL pun *) IF Compiler.scopeSpare3 = NIL THEN (*{08be-08c1} *) CodeGen.OpenFixup(1, l3, 0); (*{08c3-08c6} FIXME: (pos?,...) arity *) Words(emitBase)^[CARDINAL(l3)] := CodeGen.nextEmitPos; (*{08c9-08cd} FIXME *) Scanner.EmitString(l2, s1, 128); (*{08ce-08d2} FIXME-NYC: no such export; module suspect *) CodeGen.EmitConst(l2); (*{08d5} FIXME-NYC *) CodeGen.EmitConst2(l2, s1); (*{08d7-08d9} FIXME-NYC *) END; Scanner.TestSymbolInSet(514); (*{08dc-08df} FIXME: CARDINAL set pun *) WHILE NOT Scanner.AcceptSymbol(1) DO (*{08e1-08e5} FIXME loop shape *) Scanner.GetSym; (*{08e7} *) END; END ParseExportList; (*{08f1} DCL — ParseOneDecl. 0 params. Dispatch on saved curSymbol. *) PROCEDURE ParseOneDecl; VAR l2: CARDINAL; l3: ADDRESS; l4: WORD; BEGIN l4 := Express.spillFlag; (*{08f3-08f5} FIXME: group wrote word4 *) l3 := SymTab.currentScope; (*{08f6-08f8} FIXME T1 pun *) l2 := Scanner.curSymbol; (*{08f9-08fc} *) Scanner.GetSym; (*{08fd} *) CASE l2 OF (*{08fe-0913} callswitch 104..112 *) 104: ParseExportList(); (*{0901} *) | 108: ParseValParam(); (*{0904} FIXME: VALUE-parser as CONST arm? *) | 110: EvalConstExpr(); (*{0907} FIXME: const-EVAL as VAR arm? *) | 109: ParseFieldList(); (*{090a} FIXME: field-parser as TYPE arm? *) | 111: ParseConstOrTypeArm(); (*{090d} FIXME-NYC *) | 112: ParseModuleArm(); (*{0910} FIXME-NYC *) END; Express.spillFlag := l4; (*{092d-092e} FIXME type *) SymTab.currentScope := l3; (*{0930-0931} FIXME pun *) END ParseOneDecl; (*{0943} DCLS — ParseDeclarations. 1 param, BOOLEAN function. *) PROCEDURE ParseDeclarations(follow: BITSET): BOOLEAN; VAR l2: CARDINAL; l3: CARDINAL; l4: CARDINAL; l5: CARDINAL; l6: ADDRESS; l7: ADDRESS; BEGIN l2 := CARDINAL(Scanner.scanOptions); (*{0945-0947} FIXME pun *) l3 := Scanner.tokenPos; (*{0948-094b} FIXME: group wrote word25 *) Scanner.GetStackMark(ADR(l6)); (*{094c-094e} *) l5 := CodeGen.nextEmitPos; (*{0950-0952} FIXME: group wrote word2 *) l7 := SymTab.currentScope; (*{0953-0956} FIXME pun *) l4 := SymTab.moduleCount + SymTab.stringPoolPtr * 128; (*{0957-095e} FIXME: group packed word4+word5 *) IF (Scanner.curSymbol = 13) OR (Scanner.curSymbol = 23) THEN (*{095f-096a} FIXME codes *) Statemen.GuardedStatSeq(follow); (*{096c-096d} *) ELSE Scanner.TestSymbolInSet(2018); (*{0971-0974} FIXME: CARDINAL set pun *) ParseDeclSync(); (*{0976} *) WHILE NOT TryParseDecl(follow) DO END; (*{0977-097a} FIXME polarity *) END; RETURN TRUE; (*{097c-097d} *) (* guarded-recovery handler: *) SymTab.moduleCount := l4 MOD 256; (*{097f-0983} FIXME *) AllocSymEntry((l4 DIV 256) * 2); (*{0984-098a} FIXME role *) IF Errors.savedEditPos > l3 THEN (*{098d-0993} FIXME: group wrote word2 *) Scanner.tokenPos := l3; (*{0995-0996} *) Scanner.scanOptions := BITSET(l2); (*{0999-099a} FIXME *) CodeGen.nextEmitPos := l5; (*{099c-099d} FIXME: assignable? *) Scanner.CheckStackMark(l6); (*{099f-09a0} *) Errors.RollbackToMark; (*{09a2} *) CodeGen.OpenEmitter; (*{09a4} *) RETURN FALSE; (*{09a7-09a8} *) END; END ParseDeclarations; (*{09b9} IMEXDC — ParseImportFrom. 0 params. *) PROCEDURE ParseImportFrom; BEGIN IF (Scanner.curSymbol = 15) OR (Scanner.curSymbol = 16) THEN (*{09bb-09c6} FIXME codes *) SymTab.DefineDefinitionModule(0); (*{09c8-09cc} FIXME: 2 pushes vs 1 formal *) ParseImportScope(); (*{09ce-09cf} FIXME-NYC *) ELSIF (Scanner.curSymbol = 23) OR (Scanner.curSymbol = 13) THEN (*{09d3-09de} *) Statemen.GuardedStatSeq(BITSET{}); (*{09e0-09e2} FIXME: extra push TBD *) ELSE Scanner.TestSymbolInSet(2046); (*{09e6-09e9} FIXME pun *) IF Scanner.curSymbol = 17 THEN (*{09eb-09ef} *) SymTab.DefineProgramModule(0); (*{09f2-09f9} FIXME: 6 pushes vs 1 formal *) ELSE ParseDeclSync(); (*{09fd} *) END; WHILE NOT TryParseDecl(0) DO END; (*{09fe-0a02} FIXME: extra (ix) push *) END; END ParseImportFrom; (*{0a0c} MODBLO — ParseModuleBlock. 1 param (module node). *) PROCEDURE ParseModuleBlock(modNode: ADDRESS); VAR l2: ADDRESS; l3: ADDRESS; l4: ADDRESS; l5: WORD; BEGIN l2 := SymTab.currentScope; (*{0a0e-0a10} FIXME pun *) l3 := SymTab.ownNamePtr; (*{0a11-0a13} FIXME: group wrote word11 *) SymTab.ownNamePtr := NIL; (*{0a14-0a15} FIXME *) Scanner.OpenScope(SymTab.currentScope, NIL); (*{0a17-0a1a} FIXME args *) Scanner.GetStackMark(ADR(l5)); (*{0a1d-0a1f} FIXME slot *) ParseImportScope(); (*{0a21} *) Scanner.GetSym; (*{0a23} *) l4 := SymTab.ownNamePtr; (*{0a25-0a27} FIXME *) SymTab.ownNamePtr := l3; (*{0a28-0a29} FIXME *) IF TRUE THEN (*{0a2b-0a2f} FIXME: 10 IN NodeFlagSet(modNode, s3) *) SymTab.InitSymbolTables(BITSET{}, l4, modNode); (*{0a34-0a39} FIXME: 4-5 pushes vs 3 formals *) ELSE SymTab.InitSymbolTables(BITSET{}, l4, l2); (*{0a3d-0a42} FIXME *) END; SymTab.currentScope := l2; (*{0a44-0a45} FIXME pun *) END ParseModuleBlock; (*{0a56} proc9 — ParseProcBody (DISPUTE: map said ~WriteSymFile, but body parses decls + body block per procedure and issues NO file calls). *) PROCEDURE ParseProcBody(procNode: ADDRESS); VAR l2: CARDINAL; l3: ADDRESS; l4: CARDINAL; BEGIN Scanner.GetStackMark(ADR(l3)); (*{0a58-0a5a} *) l2 := SymTab.stringPoolPtr; (*{0a5c-0a5e} FIXME: group wrote word5 *) SymTab.stringPoolPtr := 510; (*{0a5f-0a62} FIXME pun *) Scanner.OpenScope(SymTab.currentScope, procNode); (*{0a64-0a68} FIXME: 3rd push TBD *) Express.spillFlag := Express.spillFlag + 1; (*{0a6b-0a6d} FIXME: group wrote word4 *) Scanner.PushWithScope; (*{0a70} *) IF Scanner.curSymbol = 0 THEN (*{0a72?} FIXME: group wove word10/9/8 guard; shape TBD *) Statemen.GuardedStatSeq(BITSET{}); (*{0a85-0a86} FIXME arg *) ELSE l4 := 0; (*{0a8f-0a90} *) (*{0a91-0aa9} NUL-terminated name scan FIXME *) (*{0aab-0ab8} IF name = "CODE" THEN Errors.ReportError(11) FIXME callee *) WHILE NOT TryParseDecl(0) DO END; (*{0abd-0ac0} FIXME arg *) END; Scanner.GetSym; (*{0ac2} *) Express.spillFlag := Express.spillFlag - 1; (*{0ac9-0acc} FIXME *) SymTab.stringPoolPtr := l2; (*{0ace-0acf} FIXME *) Scanner.CheckStackMark(l3); (*{0ad1-0ad2} *) Words(emitBase)^[0] := Scanner.codeSize; (*{0ad4-0ade} FIXME: indexed-emit shape *) END ParseProcBody; (*{0ae5} MAINDE — ParseMainModule. 0-param BOOLEAN function. *) PROCEDURE ParseMainModule(): BOOLEAN; VAR l2: ADDRESS; l3: ADDRESS; l4: ADDRESS; l5: ADDRESS; l6: CARDINAL; l7: CARDINAL; l8, l10: CARDINAL; l9: ADDRESS; BEGIN Scanner.GetStackMark(ADR(l9)); (*{0af1-0af3} *) Scanner.AcceptSymbol(25); (*{0af5-0af7} *) l6 := ORD(NOT Compiler.scopeSpare3) AND ORD(Scanner.AcceptSymbol(24)); (*{0af9-0b0d} FIXME shape *) Scanner.ExpectSymbol(22); (*{0b0e-0b10} *) l7 := 0; (*{0b12-0b13} *) l3 := Scanner.MakeIdentifierNode(5); (*{0b4e-0b52} *) IF Scanner.AcceptSymbol(44) THEN (*{0b53-0b55} FIXME: 44 here? *) IF Statemen.withPending # 0 THEN (*{0b59-0b5b} *) Scanner.ExpectIdentKind(1); Scanner.GetSym; (*{0b5d-0b60} *) Scanner.ExpectSymbol(6); (*{0b62-0b63} *) END; END; Scanner.ExpectSymbol(9); (*{0b65-0b66} *) Scanner.TestSymbolInSet(2031); (*{0b68-0b6b} FIXME pun *) IF Compiler.scopeSpare3 OR (l6 # 0) OR (Scanner.curSymbol - 13 IN BITSET{0..12}) THEN (*{0b6d-0b7a} FIXME *) CASE CARDINAL(0) OF (*{0ba1} FIXME: Loader.Proc5()+1 DIV 2 dispatch, codes 92/93/94 *) 92: SymTab.CompileDispatch(l2, TRUE, l6 # 0); (*{0b83-0b8c} FIXME: 5 pushes vs 3 formals *) | 93: SymTab.CompileDispatch(l2, TRUE, l6 # 0); (*{0b8d-0b96} FIXME *) | 94: SymTab.CompileDispatch(l2, TRUE, l6 # 0); (*{0b97-0ba0} FIXME *) ELSE SymTab.CompileDispatch(l2, TRUE, l6 # 0); (*{0bae-0bb5} FIXME *) END; END; CodeGen.InitCodeGenerator; (*{0bb7} *) IF Compiler.scopeSpare3 = NIL THEN (*{0bba-0bbd} *) Compiler.compilationActive := FALSE; (*{0bbf-0bc1} FIXME: group gated on l6 *) l4 := SymTab.currentScope; (*{0bc6-0bc9} FIXME pun *) WHILE l4 # NIL DO (*{0bca-0c43} export-emit walk *) IF Words(l4)^[4] = 6 THEN (*{0bd0-0bd2} *) l5 := Words(l4)^[6]; (*{0bd4-0bd6} FIXME pun *) WHILE l5 # NIL DO (*{0bd7-0be7} *) OpenScopeEmit(l5); (*{0be2-0be5} *) l5 := Words(l5)^[0]; (*{0be6-0be8} *) END; ELSIF Words(l4)^[2] = Compiler.charArrayDesc THEN (*{0beb-0bef} FIXME pun *) OpenScopeEmit(l4); (*{0bf2-0bf3} *) ELSIF (Words(l4)^[4] = 2) THEN (*{0bf6-0c03} FIXME: bit-66 conjunct TBD *) CodeGen.OpenFixup(1, Words(l4)^[5], 0); (*{0c05-0c09} FIXME arity *) Words(emitBase)^[Words(l4)^[5]] := CodeGen.nextEmitPos; (*{0c0c-0c11} FIXME *) ELSIF (Words(l4)^[4] = 4) AND (Words(l4)^[2] > 9) AND (Words(l4)^[3] = 0) THEN (*{0c22-0c33} *) PopTempMark(Words(l4)^[5], 0); (*{0c35-0c3f} FIXME: 8-cell grouping *) END; l4 := Words(l4)^[0]; (*{0c40-0c42} *) END; IF (Scanner.curSymbol # 23) AND (Scanner.curSymbol # 13) THEN (*{0c45-0c50} *) WHILE NOT TryParseDecl(0) DO END; (*{0c52-0c55} FIXME arg *) ELSE Statemen.GuardedStatSeq(BITSET{}); (*{0c59-0c5a} FIXME arg *) END; Words(emitBase)^[0] := Scanner.codeSize; (*{0c5c-0c61} FIXME shape *) END; RETURN TRUE; (*{0c62-0c63} *) (* guarded-recovery handler: *) IF Errors.savedEditPos > l10 THEN (*{0c65-0c69} FIXME: group wrote word2; l10 uninit here TBD *) Scanner.tokenPos := l10; Scanner.scanOptions := BITSET(l8); (*{0c6b-0c70} FIXME *) Scanner.CheckStackMark(l9); (*{0c72} *) Errors.RollbackToMark; (*{0c75} *) CodeGen.OpenEmitter; (*{0c77} *) RETURN FALSE; (*{0c7a-0c7b} *) END; Errors.DoError("X"); (*{0c84-0c86} FIXME: group saw proc17(69); unmapped *) END ParseMainModule; (*{0c93} proc33 — WriteMcdHeader. 0 params. *) PROCEDURE WriteMcdHeader; VAR l2: CARDINAL; l3: ADDRESS; BEGIN Scanner.Allocate(l3, 16); (*{0c95-0c98} FIXME: group wrote Reserve *) l2 := SymTab.moduleCount + 1; (*{0c99-0c9c} FIXME: group wrote word4 *) WHILE l2 # 0 DO (*{0c9d-0caa} *) DEC(l2); CodeGen.CloseFixup(Words(emitBase)^[l2], 0); (*{0ca4-0ca8} FIXME pun *) END; IF CodeGen.windowBase = 0 THEN (*{0cd2-0cd5} FIXME: group wrote word3 *) MOVE(Scanner.codeBuffer, l3, 16); (*{0cd7-0cdc} FIXME dst/src order *) END; IF Compiler.rangeCheckEnabled = FALSE THEN (*{0cef-0cf1} FIXME: group wrote word2 *) Texts.WriteString(3, "Compiled bytes:"); (* FIXME *) Texts.WriteCard(3, CodeGen.nextEmitPos - 16, 6); (* FIXME *) Texts.WriteLn(3); (* FIXME *) END; END WriteMcdHeader; (*{0d17} proc35 — EmitConstVal. 2 params: (buf, count) per frame rule. *) PROCEDURE EmitConstVal(buf: ADDRESS; count: CARDINAL); BEGIN WHILE count # 0 DO (*{0d19-0d1b} *) CodeGen.EmitString(buf); (*{0d1d-0d1f} FIXME-NYC: group saw Proc3 *) buf := buf + 2; (*{0d21-0d24} FIXME: ADDRESS arith *) count := count - 2; (*{0d25-0d28} *) END; END EmitConstVal; (*{0d2e} proc34 — EmitTypeDesc. 0 params. *) PROCEDURE EmitTypeDesc; VAR l2: ADDRESS; l3: ADDRESS; l4, l5, l6: CARDINAL; BEGIN Scanner.Allocate(l2, 84); (*{0d30-0d32} FIXME: group wrote Reserve *) Scanner.Allocate(l3, 508); (*{0d34-0d38} FIXME *) l5 := CodeGen.nextEmitPos - 18; (*{0d39-0d3d} *) l6 := 2 * (32 - SymTab.moduleCount); (*{0d70-0d76} FIXME: group wrote word3 *) EmitConstVal(l2 + l6, 84 - l6); (*{0d78-0d7f} FIXME arith *) LinkSymEntry(l3); (*{0d81-0d82} *) EmitConstVal(l3, SymTab.stringPoolPtr - 4); (*{0d83-0d88} FIXME: group wrote word5 *) l4 := SymTab.moduleCount; (*{0d8a-0d8c} FIXME *) WHILE l4 # 0 DO (*{0d8d-0da7} per-scope emit loop *) DEC(l4); EmitConstVal(SymTab.moduleTable + l4 * 10, 10); (*{0d94-0d9b} FIXME: word6 base? *) CodeGen.EmitString(l5 + (SymTab.moduleCount - l4) * 2); (*{0d9d-0da5} FIXME-NYC: group saw Proc3 *) END; CodeGen.EmitString(0); (*{0da9-0daa} FIXME *) CodeGen.EmitString(0); (*{0dac-0dad} FIXME *) END EmitTypeDesc; (*{0e93} proc36 — CheckForwardResolved: NO BODY (slot patched over by the COMPILE link stub's keyword-table search). Reconstruct from SymTab.CheckForwards or another MCD. *) PROCEDURE CheckForwardResolved; FORWARD; (*{1027} PASS1 — Pass1Main: NO bytes in pass1.txt (ends ~101a). *) PROCEDURE Pass1Main; FORWARD; (*{105b} 4NAZBA — module init: NO bytes. *) PROCEDURE InitPass1; FORWARD; END Pass1.