PASS1.MOD 46 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024
  1. (* PASS1.MOD — DRAFT v1, assembled 2026-10-03, NOT verified.
  2. Reconstructed from Reversing-Turbo-Modula2-main/MCode_disassembly/pass1.txt
  3. (2975 lines) by three parallel passes (groups 1 @0001-02e6, 2 @02e6-07a8,
  4. 3 @07a8-end). Does NOT yet recompile to the original MCD; verification
  5. via unassemble.c diff is still required (see src/compiler/README.md).
  6. Frame rule applied throughout (proven, see STATEMEN.MOD header):
  7. "param1" = LAST pushed word; call sites from pushes stay source-order.
  8. Signatures are source-order with body roles noted; disagreements flagged.
  9. OPEN DISPUTES (MCD diff decides):
  10. - D1/D2: proc15 (@0411, 0-param, type-symbol dispatch in every TYPE
  11. position) vs proc19 (@02e6, 3-param, ident-list loop). Re-read verdict:
  12. arity is frame-correct as mapped (0-param proc15, 3-param proc19 — only
  13. @02e6 can host the 3-push call sites), so the dispute is NAMES-only:
  14. either (proc15=ParseType, proc19=ParseFormalParams) or the reverse.
  15. Map names kept; MCD diff or call-graph analysis decides.
  16. - D3/D4: proc17 body builds ARRAY descriptors, proc18 parses [lo..hi]
  17. SUBRANGEs — kept as ParseConstDecl/ParseVarDecl (map names) pending
  18. group-3 cross-check of where real const/var decls live (cf. proc23?).
  19. - proc9: map said ~WriteSymFile, body parses procedure bodies with NO
  20. file calls — kept as ParseProcBody. The real .SYM writer is then
  21. probably proc32 @0db2 (file-output path), which was NOT decompiled
  22. (missing mini-pass — next workstream).
  23. - proc36 @0e93 slot holds the COMPILE link stub's keyword-table search
  24. (patched over); original forward-resolution sweep LOST (cf.
  25. SymTab.CheckForwards which may be the same sweep).
  26. - No bytes exist for proc10/11/26/27/29/30 (FORWARD stubs),
  27. PASS1 @1027 / 4NAZBA @105b (FORWARD stubs).
  28. - ConstToCard/ConstToInt call shapes (type-first: ConstToCard(CardType,44))
  29. vs EXPRESS.DEF order (errPos, c) disagree — signature-audit item.
  30. - PASS1 globals: word2 emitBase (ADDRESS buffer; group 1's tempBase),
  31. word3 emitTop (index; group 1's tempTop), word4 nestDepth.
  32. Group-1 SymTab.word4/word5 pun uses kept verbatim + FIXME.
  33. Words(X)^[N] = numeric-word pun (MCode untyped). BITSET(numeric) sets,
  34. CARDINAL<->ADDRESS punning, and `IN`-tests on CARDINAL curSymbol kept
  35. verbatim (casts TBD in verification). GOTO kept as faithful rendering. *)
  36. IMPLEMENTATION MODULE Pass1;
  37. IMPORT Compiler, Scanner, Errors, CodeGen, Express, Statemen, SymTab, Files,
  38. Texts, Loader, ComLine;
  39. FROM SYSTEM IMPORT ADDRESS, ADR, MOVE, WORD;
  40. FROM STORAGE IMPORT ALLOCATE;
  41. TYPE Words = POINTER TO ARRAY [0..4095] OF WORD;
  42. VAR
  43. emitBase: ADDRESS; (* word2: output/emit buffer base *)
  44. emitTop: CARDINAL; (* word3: emit buffer top *)
  45. nestDepth: CARDINAL; (* word4: DEC'd on PROCDE/MODULD exit *)
  46. (* ---- group-1/3 shared FORWARDs (defined below) ---- *)
  47. PROCEDURE PushTempMark(): CARDINAL; FORWARD;
  48. PROCEDURE PopTempMark(first, second: WORD); FORWARD;
  49. PROCEDURE AllocSymEntry(size: WORD); FORWARD;
  50. PROCEDURE LinkSymEntry(entry: ADDRESS); FORWARD;
  51. PROCEDURE InsertSetConst(first: ADDRESS; limit: CARDINAL); FORWARD;
  52. PROCEDURE CondInsert(flag: WORD; slot: ADDRESS; a, b: WORD): CARDINAL; FORWARD;
  53. PROCEDURE InsertEntry(setD, counter, slotA, slotB: ADDRESS): CARDINAL; FORWARD;
  54. PROCEDURE OpenScopeEmit(node: ADDRESS); FORWARD;
  55. PROCEDURE TypeSizeRec(node, link, acc, aux, size: WORD); FORWARD;
  56. PROCEDURE GetIdent(): ADDRESS; FORWARD;
  57. PROCEDURE ParseImportItem(first: CARDINAL): ADDRESS; FORWARD;
  58. PROCEDURE ParseConstDecl(): ADDRESS; FORWARD;
  59. PROCEDURE ParseVarDecl(first: WORD); FORWARD;
  60. PROCEDURE ParseType(owner: ADDRESS; VAR typ: ADDRESS; limit: CARDINAL): ADDRESS; FORWARD;
  61. PROCEDURE ParseFormalParams(): ADDRESS; FORWARD;
  62. PROCEDURE ParseValParam(): ADDRESS; FORWARD;
  63. PROCEDURE ParseVarParam; FORWARD;
  64. PROCEDURE ParseFieldList; FORWARD;
  65. PROCEDURE EvalConstExpr; FORWARD;
  66. PROCEDURE CheckConformant(): ADDRESS; FORWARD;
  67. PROCEDURE ParseRecordType(rec: ADDRESS; VAR size: CARDINAL; tag: CARDINAL); FORWARD;
  68. PROCEDURE CloseScopeFixup; FORWARD;
  69. PROCEDURE ParseProcedureDecl; FORWARD;
  70. PROCEDURE ParseModuleHead; FORWARD;
  71. PROCEDURE ParseExportList; FORWARD;
  72. PROCEDURE ParseOneDecl; FORWARD;
  73. PROCEDURE ParseDeclarations(follow: BITSET): BOOLEAN; FORWARD;
  74. PROCEDURE ParseImportFrom; FORWARD;
  75. PROCEDURE ParseModuleBlock(modNode: ADDRESS); FORWARD;
  76. PROCEDURE ParseProcBody(procNode: ADDRESS); FORWARD;
  77. PROCEDURE ParseMainModule(): BOOLEAN; FORWARD;
  78. PROCEDURE WriteMcdHeader; FORWARD;
  79. PROCEDURE EmitConstVal(buf: ADDRESS; count: CARDINAL); FORWARD;
  80. PROCEDURE EmitTypeDesc; FORWARD;
  81. (* stubs: no bytes anywhere *)
  82. PROCEDURE EmitModuleProlog(node: ADDRESS); FORWARD; (* proc10 *)
  83. PROCEDURE ParseDeclSync; FORWARD; (* proc11 *)
  84. PROCEDURE ParseConstOrTypeArm; FORWARD; (* proc26 *)
  85. PROCEDURE ParseModuleArm; FORWARD; (* proc27 *)
  86. PROCEDURE TryParseDecl(tag: CARDINAL): BOOLEAN; FORWARD; (* proc29 *)
  87. PROCEDURE ParseImportScope; FORWARD; (* proc30 *)
  88. PROCEDURE CheckForwardResolved; FORWARD; (* proc36: body patched away *)
  89. PROCEDURE Pass1Main; FORWARD; (* @1027: no bytes *)
  90. PROCEDURE InitPass1; FORWARD; (* 4NAZBA @105b: no bytes *)
  91. (* SCANNER.proc24 discovery (group 1): 2-param length-prefix function *)
  92. PROCEDURE CappedStrLen(s: ADDRESS; maxLen: CARDINAL): CARDINAL; FORWARD;
  93. (* PASS1 group 1 @0001..02e5 *)
  94. (* SCANNER.proc24 discovery: 2-param FUNCTION (nameAddr, 128) -> length
  95. prefix for EmitWord/Emit1. Identity TBD. *)
  96. PROCEDURE CappedStrLen(s: ADDRESS; maxLen: CARDINAL): CARDINAL; FORWARD;
  97. (* proc4 @0001 ~PushTempMark. 0 params, function. *)
  98. PROCEDURE PushTempMark(): CARDINAL; (*{0001}*)
  99. BEGIN
  100. Express.CentralError(SymTab.stringPoolPtr < emitTop - 1, 82); (*{0003-000a} FIXME: group read SymTab.word4=symFile:FILE — pun suspicious; role TBD *)
  101. INC(SymTab.stringPoolPtr); (*{000c-000f} FIXME *)
  102. RETURN SymTab.stringPoolPtr; (*{0011-0013} FIXME *)
  103. END PushTempMark;
  104. (* proc5 @0016 ~PopTempMark. 2 params: body param1 = source formal2. *)
  105. PROCEDURE PopTempMark(first, second: WORD); (*{0016} FIXME order: frame rule says formal1=last-pushed *)
  106. BEGIN
  107. Express.CentralError(SymTab.stringPoolPtr < emitTop - 2, 82); (*{0018-0020} FIXME same as above *)
  108. DEC(emitTop); (*{0022-0024} FIXME: group used tempTop *)
  109. Words(emitBase)^[emitTop] := second; (*{0025-0028} *)
  110. DEC(emitTop); (*{0029-002b}*)
  111. Words(emitBase)^[emitTop] := first; (*{002c-002f}*)
  112. END PopTempMark;
  113. (* proc6 @0032 ~AllocSymEntry. 1 param. *)
  114. PROCEDURE AllocSymEntry(size: WORD); (*{0032}*)
  115. BEGIN
  116. IF Express.spillFlag = 0 THEN (*{0034-0037} *)
  117. WHILE (emitTop <= 254) AND (Words(emitBase)^[emitTop] >= size) DO (*{0039-0044}*)
  118. emitTop := emitTop + 2; (*{0046-0049} first-fit scan, 2-word slots *)
  119. END;
  120. END;
  121. SymTab.moduleCount := size; (*{004c-004d} FIXME: group wrote word5=stringPoolPtr; moduleCount=word3? BOTH punned — TBD *)
  122. END AllocSymEntry;
  123. (* proc7 @0051 ~LinkSymEntry. 1 param. *)
  124. PROCEDURE LinkSymEntry(entry: ADDRESS); (*{0051}*)
  125. BEGIN
  126. FILL(entry, 508, 0); (*{0053-0058} per Extended.Fill *)
  127. WHILE emitTop <= 254 DO (*{005a-005e}*)
  128. Words(emitBase)^[(Words(emitBase)^[emitTop] DIV 2) - 2] := Words(emitBase)^[emitTop + 1]; (*{0060-006c} dead push harmless *)
  129. emitTop := emitTop + 2; (*{006d-0070}*)
  130. END;
  131. END LinkSymEntry;
  132. (* proc1 @007c ~InsertSetConst. 2 params: first = body param2. *)
  133. PROCEDURE InsertSetConst(first: ADDRESS; limit: CARDINAL); (*{007c} FIXME roles *)
  134. VAR
  135. setBitsA: ARRAY [0..3] OF WORD;
  136. elemBufA: ARRAY [0..63] OF WORD;
  137. setBits: ADDRESS;
  138. elemBuf: ADDRESS;
  139. cursor: ADDRESS;
  140. count: CARDINAL;
  141. allocSize: CARDINAL;
  142. heapStr: ADDRESS;
  143. tmp: WORD;
  144. BEGIN
  145. setBits := ADDRESS(ADR(setBitsA)); (*{007e-0080} *)
  146. elemBuf := ADDRESS(ADR(elemBufA)); (*{0081-0084} *)
  147. cursor := Words(first)^[6]; (*{0085-0087} FIXME field roles TBD *)
  148. IF (cursor # NIL)
  149. AND (Compiler.scopeSpare3 = NIL)
  150. AND NOT SymTab.BuildBitsetConst(Words(first)^[1]) THEN (* FIXME: VAR ARRAY arg pun *)
  151. count := 0; (*{0097-0098}*)
  152. LOOP (*{0099}*)
  153. tmp := Words(cursor)^[2]; (*{0099-009b} element value *)
  154. IF tmp >= limit THEN RETURN END; (*{009b-009f} *)
  155. IF 4 IN BITSET(Words(cursor)^[3]) THEN (*{00a0-00a4} *)
  156. Words(setBits)^[count DIV 16] :=
  157. CARDINAL(BITSET(Words(setBits)^[count DIV 16]) + BITSET{count MOD 16}); (*{00a6-00b4} *)
  158. END;
  159. Words(elemBuf)^[count] := tmp; (*{00b5-00b9} *)
  160. INC(count); (*{00ba-00bc}*)
  161. cursor := Words(cursor)^[0]; (*{00bd-00bf} next link *)
  162. IF cursor = NIL THEN EXIT END; (*{00c0-00c2}*)
  163. END;
  164. Scanner.CheckStackMark(ADDRESS(limit)); (*{00c4-00c5} FIXME: limit punned as mark *)
  165. allocSize := ((count + 15) DIV 16) * 2; (*{00c7-00cc} *)
  166. Scanner.Allocate(heapStr, allocSize + count * 2 + 2); (*{00cf-00d8} *)
  167. Words(heapStr)^[0] := count; (*{00da-00dc}*)
  168. MOVE(ADDRESS(Words(heapStr)^[1]), setBits, allocSize); (*{00dd-00e3} *)
  169. MOVE(ADDRESS(Words(Words(heapStr)^[1] + allocSize)^[0]), elemBuf, count * 2); (*{00e4-00ed} *)
  170. Words(first)^[6] := heapStr; (*{00ef-00f1} *)
  171. ELSE
  172. Words(first)^[6] := heapStr; (*{00ef-00f1} FIXME: guard-false store quirk TBD *)
  173. END;
  174. END InsertSetConst;
  175. (* proc2 @00f4 ~CondInsert. 4 params: (flag,slot,a,b) = body (param4..1). *)
  176. PROCEDURE CondInsert(flag: WORD; slot: ADDRESS; a, b: WORD): CARDINAL; (*{00f4}*)
  177. BEGIN
  178. IF flag # 0 THEN (*{00f6-00f8}*)
  179. Words(slot)^[0] := flag; (*{00fa-00fc}*)
  180. IF Words(flag)^[0] - 1 < 64 THEN (*{00fd-0107} flag punned as address *)
  181. Words(slot)^[0] := 1;
  182. END;
  183. RETURN InsertEntry(flag, slot, a, b); (*{0108-010d} *)
  184. END;
  185. RETURN 0; (*{010f-0110}*)
  186. END CondInsert;
  187. (* proc3 @0113 ~InsertEntry. 4 params. *)
  188. PROCEDURE InsertEntry(setD, counter, slotA, slotB: ADDRESS): CARDINAL; (*{0113}*)
  189. VAR
  190. idx: CARDINAL;
  191. base: ADDRESS;
  192. BEGIN
  193. IF Words(counter)^[0] # 0 THEN (*{0115-0118}*)
  194. IF Words(setD)^[0] - 1 < 64 THEN (*{011a-0120} small-set path *)
  195. idx := Words(counter)^[0] - 1; (*{0122-0125}*)
  196. base := setD; (*{0126-0127}*)
  197. Words(slotA)^[0] := Words(base)^[1 + (Words(base)^[0] + 15) DIV 16 + idx]; (*{0128-0138} *)
  198. Words(slotB)^[0] := ORD((idx MOD 16) IN BITSET(Words(base)^[1 + idx DIV 16])); (*{0139-0148} *)
  199. Words(counter)^[0] := idx + 2; (*{0149-014d} *)
  200. IF Words(base)^[0] - 1 = idx THEN
  201. Words(counter)^[0] := 0; (*{0155-0157} full *)
  202. END;
  203. ELSE (*{015a} large path *)
  204. Words(slotA)^[0] := Words(Words(counter)^[0])^[2]; (*{015a-015e} *)
  205. Words(slotB)^[0] := ORD(4 IN BITSET(Words(Words(counter)^[0])^[3])); (*{015f-0165} *)
  206. Words(counter)^[0] := Words(Words(counter)^[0])^[0]; (*{0166-016a} *)
  207. END;
  208. RETURN 1; (*{016b-016c}*)
  209. END;
  210. RETURN 0; (*{016e-016f}*)
  211. END InsertEntry;
  212. (* proc8 @017b ~OpenScopeEmit. 1 param. *)
  213. PROCEDURE OpenScopeEmit(node: ADDRESS); (*{017b}*)
  214. VAR mark: CARDINAL;
  215. BEGIN
  216. mark := PushTempMark(); (*{017d-017e} *)
  217. IF Compiler.rangeCheckEnabled THEN (*{017f-0182} *)
  218. CodeGen.EmitExtCall3(2, mark, 0); (*{0183-0186} *)
  219. CodeGen.EmitWord(CappedStrLen(Words(node)^[5], 128)); (*{0189-0190} *)
  220. Words(node)^[6] := mark; (*{0192-0194} *)
  221. Words(emitBase)^[mark] := CodeGen.nextEmitPos; (*{0195-0199} *)
  222. CodeGen.EmitString(Words(node)^[5]); (*{019a-019c} NUL-terminated *)
  223. END;
  224. END OpenScopeEmit;
  225. (* proc12 @01a1 ~TypeSizeRec. 5 params, RECURSIVE. *)
  226. PROCEDURE TypeSizeRec(node, link, acc, aux, size: WORD); (*{01a1} FIXME roles/order *)
  227. VAR skipAdd: BOOLEAN;
  228. BEGIN
  229. IF Words(node)^[0] # link THEN (*{01a3-01a7} follow indirection *)
  230. TypeSizeRec(Words(node)^[0], link, acc, aux, size); (*{01a9-01b0} *)
  231. END;
  232. IF Words(node)^[4] = 4 THEN (*{01b2-01b6} record-ish kind *)
  233. Words(node)^[2] := aux; (*{01b8-01ba}*)
  234. IF NOT (8 IN BITSET(Words(node)^[3])) THEN RETURN END; (*{01bb-01c0} *)
  235. skipAdd := (Express.spillFlag # 0) AND (Words(node)^[3] = 0); (*{01c2-01cb} *)
  236. IF skipAdd THEN (*{01cc-01d4} *)
  237. Words(acc)^[0] := Words(acc)^[0] - size;
  238. END;
  239. Words(node)^[5] := Words(acc)^[0]; (*{01d5-01d8} publish offset *)
  240. IF (Express.spillFlag = 0) AND (Words(aux)^[4] > 9)
  241. AND (Words(node)^[3] = 0) THEN (*{01d9-01e8} *)
  242. PopTempMark(Words(acc)^[0], (Words(aux)^[3] + 1) DIV 2 * 2); (*{01ea-01f3} *)
  243. END;
  244. IF NOT skipAdd THEN (*{01f4-01fd} *)
  245. Words(acc)^[0] := Words(acc)^[0] + size;
  246. END;
  247. END;
  248. END TypeSizeRec;
  249. (* proc13 @0201 ~GetIdent. 0 params, function. *)
  250. PROCEDURE GetIdent(): ADDRESS; (*{0201} FIXME: name says ident, returns a TYPE *)
  251. VAR typ: ADDRESS;
  252. BEGIN
  253. Scanner.PushWithScope; (*{0203} *)
  254. Scanner.ExpectIdentKind(3); (*{0205-0206} *)
  255. typ := Scanner.literalType; (*{0208-020a} pre-GetSym *)
  256. Scanner.GetSym; (*{020b}*)
  257. RETURN typ; (*{020d-020e}*)
  258. END GetIdent;
  259. (* proc16 @0211 ~ParseImportItem. 1 param function. *)
  260. PROCEDURE ParseImportItem(first: CARDINAL): ADDRESS; (*{0211} FIXME role of flag *)
  261. VAR
  262. item: ADDRESS;
  263. node: ADDRESS;
  264. BEGIN
  265. Scanner.ExpectSymbol(42); (*{0213-0216} FROM *)
  266. node := Scanner.NewSizedNode(5); (*{0217-021a}*)
  267. Words(node)^[3] := 2; (*{021b-021e}*)
  268. IF (first # 0) AND (Scanner.identKind = 0)
  269. AND (Scanner.scopeCursor = NIL) THEN (*{021e-0229} *)
  270. item := Scanner.DeclareIdentifier(0); (*{022b-022f} plain item *)
  271. Words(item)^[2] := node; (*{0230-0232} *)
  272. ELSE
  273. Words(node)^[2] := ParseType(); (*{0235-0239} FIXME: 0-arg vs 3-param def *)
  274. END;
  275. RETURN node; (*{023a-023b}*)
  276. END ParseImportItem;
  277. (* proc17 @023e ~ParseConstDecl. 0 params function.
  278. DISPUTE D3: body builds an ARRAY descriptor — rename to ParseArrayType
  279. pending group-3 cross-check. Map name kept. *)
  280. PROCEDURE ParseConstDecl(): ADDRESS; (*{023e}*)
  281. VAR
  282. arrDesc: ADDRESS;
  283. idxDesc: ADDRESS;
  284. elemDesc: ADDRESS;
  285. BEGIN
  286. arrDesc := Scanner.NewSizedNode(11); (*{0240-0243}*)
  287. idxDesc := ParseType(); (*{0244-0248} FIXME arity *)
  288. Words(Express.curDesc.raw[0])^[0] := idxDesc; (*{024c-0250} *)
  289. Express.MatchOpClass(BITSET{3}, 47); (*{0251-0253} index ordinal *)
  290. IF Scanner.AcceptSymbol(1) THEN (*{0255-0256} *)
  291. elemDesc := ParseConstDecl(); (*{025a-025d} recurse *)
  292. ELSE
  293. Scanner.ExpectSymbol(41); (*{0260-0262} OF *)
  294. elemDesc := ParseType(); (*{0264-0268} FIXME arity *)
  295. END;
  296. Words(arrDesc)^[5] := elemDesc; (*{0269-026b} *)
  297. Words(arrDesc)^[3] := (Words(idxDesc)^[6] - Words(idxDesc)^[5] + 1) * Words(elemDesc)^[3]; (*{026c-0276} *)
  298. RETURN arrDesc; (*{0277-0278}*)
  299. END ParseConstDecl;
  300. (* proc18 @027b ~ParseVarDecl. 1 param function.
  301. DISPUTE D4: body parses [lo..hi] SUBRANGE — rename to ParseSubrangeType
  302. pending. Map name kept. *)
  303. PROCEDURE ParseVarDecl(first: WORD); (*{027b} FIXME punned ADDRESS/value *)
  304. VAR desc: ADDRESS;
  305. BEGIN
  306. desc := Scanner.NewSizedNode(1); (*{027d-0280} subrange desc *)
  307. Express.GetConstVal; (*{0281} lower bound *)
  308. IF first = 0 THEN (*{0283-0285} anonymous *)
  309. Words(desc)^[2] := Words(Express.curDesc.raw[0])^[0]; (*{0287-028c} *)
  310. ELSE
  311. IF Words(first)^[4] = 1 THEN first := Words(first)^[2] END; (*{028e-0296} *)
  312. Express.ConstToCard(first, 0); (*{0297-0299} FIXME: (c,errPos) vs DEF order *)
  313. Words(desc)^[2] := first; (*{029b-029d} lo *)
  314. END;
  315. Express.MatchOpClass(BITSET{5}, 0); (*{029e-02a0} FIXME errCode 0 *)
  316. Words(desc)^[5] := Words(Express.curDesc.raw[0])^[2]; (*{02a2-02a6} lo value *)
  317. Scanner.ExpectSymbol(4); (*{02a7-02a8} `..` *)
  318. Express.GetConstVal; (*{02aa} upper bound *)
  319. Express.ConstToCard(Words(desc)^[2], 0); (*{02ac-02af} FIXME order *)
  320. Words(desc)^[6] := Words(Express.curDesc.raw[0])^[2]; (*{02b1-02b5} hi value *)
  321. IF Words(desc)^[2] = Compiler.IntType THEN
  322. Express.CentralError(Words(desc)^[6] >= Words(desc)^[5], 46); (*{02bd-02c4} *)
  323. ELSE
  324. Express.CentralError(Words(desc)^[6] >= Words(desc)^[5], 46); (*{02c8-02cf} *)
  325. END;
  326. Scanner.ExpectSymbol(6); (*{02d1-02d2} `]` *)
  327. Words(desc)^[3] := ORD((Words(desc)^[5] > 32767) OR (Words(desc)^[6] > 255)) + 1; (*{02d4-02e2} *)
  328. RETURN desc; (*{02e2-02e3}*)
  329. END ParseVarDecl;
  330. (* PASS1 group 2 @02e6-0783.
  331. D1/D2 (re-read verdict): arity is frame-correct as mapped (0-param @0411,
  332. 3-param @02e6); dispute is NAMES-only. Map names kept. See header. *)
  333. (* proc19 @02e6 — ~ParseType (map name; see D2). 3 formals. *)
  334. PROCEDURE ParseType(owner: ADDRESS; VAR typ: ADDRESS; limit: CARDINAL): ADDRESS;
  335. VAR t, u: ADDRESS;
  336. lo, hi: CARDINAL;
  337. loA, hiA: ADDRESS;
  338. n, cnt, elemT: CARDINAL;
  339. enumBase: ADDRESS;
  340. tmp: CARDINAL;
  341. BEGIN
  342. WHILE Scanner.curSymbol IN BITSET{9984H} DO (*{02eb} FIXME: set TBD *)
  343. IF Scanner.AcceptSymbol(40) THEN (*{02f5} *)
  344. IF Scanner.AcceptSymbol(2) THEN (*{02fb} *)
  345. elemT := CARDINAL(GetIdent()); (*{0300} FIXME pun *)
  346. ELSE
  347. Scanner.DeclareIdentifier(4); (*{0308} *)
  348. typ := owner; (*{030d-0327} FIXME: stack shuffles idealized *)
  349. elemT := CARDINAL(GetIdent());
  350. END;
  351. Express.MatchOpClass(BITSET{7}, 40); (*{032c} *)
  352. Scanner.ExpectSymbol(41); (*{0331} *)
  353. enumBase := typ; (*{0335} *)
  354. cnt := 0; (*{0338} *)
  355. WHILE NOT (Scanner.curSymbol IN BITSET{9472H}) DO (*{033a-03b1} enum loop *)
  356. tmp := cnt; t := elemT; (*{0343-0344}*)
  357. Express.GetTypeDesc(loA, hiA, NIL); (*{0346} FIXME: (dest,mode,src) roles *)
  358. lo := CARDINAL(loA); hi := CARDINAL(hiA); (*{034c-034f} FIXME pun *)
  359. IF lo <= hi THEN (*{0350} *)
  360. t := cnt;
  361. REPEAT
  362. t := Scanner.NewSizedNode(12); (*{0357} *)
  363. Words(t)^[6] := u; Words(t)^[2] := elemT; (*{035b-0366} FIXME pun *)
  364. Words(t)^[3] := enumBase; Words(t)^[7] := lo; (*{0361-0366}*)
  365. IF u # NIL THEN (*{0367} *)
  366. IF u # lo THEN Express.CentralError(TRUE, 47); END; (*{036b-0371} FIXME cond *)
  367. u := Words(u)^[6]; (*{0373-0375} FIXME pun *)
  368. END;
  369. INC(lo); (*{0378-037a} *)
  370. UNTIL lo > hi;
  371. END;
  372. IF NOT (Scanner.TestSymbolInSet(6) AND Scanner.AcceptSymbol(1)) THEN EXIT END; (*{037c-0384} FIXME: TestSymbolInSet is VOID assert *)
  373. Scanner.GetSym; (*{0386} *)
  374. t := cnt;
  375. typ := ParseType(owner, t, limit); (*{0388-0390} recursive FIXME arity *)
  376. u := typ;
  377. IF Words(t)^[3] > limit THEN limit := Words(t)^[3]; END; (*{03a6-03b0} *)
  378. END;
  379. WHILE NOT (Scanner.TestSymbolInSet(8) AND Scanner.AcceptSymbol(1)) DO END; (*{03b6-03ba} FIXME shape *)
  380. IF Scanner.AcceptSymbol(10) THEN (*{03bc-03bf} *)
  381. tmp := CARDINAL(ParseType(owner, tmp, limit)); (*{03c1-03c7} FIXME pun *)
  382. IF CARDINAL(enumBase) > limit THEN limit := CARDINAL(enumBase); END; (*{03c9-03d1} FIXME *)
  383. END;
  384. Scanner.ExpectSymbol(13); (*{03d2} *)
  385. typ := ADDRESS(cnt); (*{03d5-03d7} FIXME pun *)
  386. ELSE
  387. Scanner.DeclareIdentifier(4); (*{03da} *)
  388. tmp := Scanner.curNode; (*{03de} FIXME: ADDRESS := RecordPtr pun *)
  389. WHILE NOT (Scanner.TestSymbolInSet(6) AND Scanner.AcceptSymbol(1)) DO END; (*{03e2-03e9} FIXME shape *)
  390. Scanner.GetSym; (*{03eb} *)
  391. elemT := CARDINAL(ParseFormalParams()); (*{03ed} FIXME pun *)
  392. typ := owner; (*{03f2-0406} FIXME: TypeSizeRec + word9 wiring *)
  393. tmp := TypeSizeRec(owner, elemT, elemT, elemT, elemT); (*{03f7-0400} FIXME: 5-arg shape TBD *)
  394. END;
  395. IF NOT Scanner.AcceptSymbol(9) THEN EXIT END; (*{0407-040b} *)
  396. END;
  397. RETURN typ; (*{040e} *)
  398. END ParseType;
  399. (* proc15 @0411 — ~ParseFormalParams (map name; see D1). 0-param function. *)
  400. PROCEDURE ParseFormalParams(): ADDRESS;
  401. VAR head, n, kind: CARDINAL;
  402. tail, cur: ADDRESS;
  403. BEGIN
  404. IF Scanner.AcceptSymbol(43) THEN (*{0413} *)
  405. head := CARDINAL(Scanner.NewSizedNode(0)); n := 0; (*{0419-041e} FIXME pun *)
  406. Scanner.DeclareIdentifier(1); kind := CARDINAL(Scanner.curNode); (*{041f-0423} FIXME *)
  407. INC(n);
  408. WHILE Scanner.TestSymbolInSet(34) AND Scanner.AcceptSymbol(1) DO (*{0432-0439} FIXME shape *)
  409. Scanner.DeclareIdentifier(1);
  410. END;
  411. Scanner.GetSym; (*{043c} *)
  412. ELSIF Scanner.AcceptSymbol(44) THEN (*{044c-044e} *)
  413. head := CARDINAL(ParseVarDecl(0)); (* nested proc18 FIXME *)
  414. ELSIF Scanner.AcceptSymbol(50) THEN (*{0458-045b} *)
  415. Scanner.ExpectSymbol(41); (*{045e} *)
  416. head := CARDINAL(Scanner.NewSizedNode(4)); (*{0462} FIXME *)
  417. Words(ADDRESS(head))^[3] := 2; (*{0466-0468} FIXME *)
  418. tail := ParseFormalParams(); (*{0469} FIXME: recursion? *)
  419. Words(ADDRESS(head))^[2] := tail; (*{046d-046f} FIXME *)
  420. Express.MatchOpClass(BITSET{3}, 50); (*{0470-0477} *)
  421. IF Words(tail)^[6] > 15 THEN Express.CentralError(TRUE, 41); END; (*{0479} FIXME cond *)
  422. ELSIF Scanner.AcceptSymbol(48) THEN (*{0483-0486} *)
  423. head := CARDINAL(ParseImportItem(0)); (*{0489} FIXME *)
  424. ELSIF Scanner.AcceptSymbol(21) THEN (*{0490-0493} *)
  425. head := CARDINAL(Scanner.NewSizedNode(9)); (*{0496} FIXME *)
  426. Words(ADDRESS(head))^[3] := 4; (*{049a-049c} FIXME *)
  427. ParseRecordType(ADDRESS(head), sizeTmp, 1); (*{049d-04a5} FIXME: VAR/size shape TBD *)
  428. ELSIF Scanner.AcceptSymbol(47) THEN (*{04a9-04ac} *)
  429. head := CARDINAL(ParseConstDecl()); (* nested proc17 *)
  430. ELSIF Scanner.AcceptSymbol(49) THEN (*{04b4-04b7} *)
  431. head := CARDINAL(Scanner.NewSizedNode(10)); (*{04ba} FIXME *)
  432. Scanner.OpenScope(SymTab.currentScope, NIL); (*{04bd-04bf} FIXME args *)
  433. ParseType(ADDRESS(head), typeTmp, typeLim); (*{04c1-04cd} FIXME args *)
  434. Scanner.ExpectSymbol(13); (*{04cf} *)
  435. SymTab.currentScope := Scanner.curNode; (*{04d2-04d5} FIXME: T1 := RecordPtr pun *)
  436. IF Words(ADDRESS(head))^[3] < 2 THEN Words(ADDRESS(head))^[3] := 2; END; (*{04d7-04df} *)
  437. ELSE
  438. head := CARDINAL(GetIdent()); (*{04e2} FIXME pun *)
  439. IF Scanner.AcceptSymbol(44) THEN head := CARDINAL(ParseVarDecl(0)); END; (*{04e6-04ef} *)
  440. END;
  441. RETURN ADDRESS(head); (*{04f0} FIXME pun *)
  442. END ParseFormalParams;
  443. (* proc20 @04f4 — ~ParseValParam. 0 formals, returns type desc. *)
  444. PROCEDURE ParseValParam(): ADDRESS;
  445. VAR t: ADDRESS;
  446. BEGIN
  447. IF Scanner.AcceptSymbol(48) THEN (*{04f6} *)
  448. t := ParseImportItem(0); (*{04fc-04fe} FIXME arg *)
  449. ELSE
  450. t := ParseFormalParams(); (*{0503-0504} *)
  451. END;
  452. RETURN t; (*{0507} *)
  453. END ParseValParam;
  454. (* proc21 @050b — ~ParseVarParam. 0 formals, no result. *)
  455. PROCEDURE ParseVarParam;
  456. VAR t: ADDRESS;
  457. BEGIN
  458. WHILE Scanner.curSymbol = 0 DO (*{050d-0543} *)
  459. t := Scanner.MakeIdentifierNode(1); (*{0512-0514} FIXME: ADDRESS := ADDRESS ok *)
  460. Scanner.ExpectSymbol(52); (*{0516-0518} *)
  461. Express.GetConstVal; (*{051b} *)
  462. Words(t)^[2] := Express.curDesc.raw[0]; (*{051d-0521} FIXME pun *)
  463. Words(t)^[6] := Express.curDesc.raw[2]; (*{0522-0528} dword spill idealized *)
  464. IF (Words(t)^[2] = Compiler.charArrayDesc) AND (NOT Compiler.compilationActive)
  465. AND (Words(t)^[6] = 0) THEN (*{0529-0537} FIXME: compilationActive BOOLEAN vs 0 *)
  466. OpenScopeEmit(t); (*{053a} *)
  467. END;
  468. Scanner.InsertSymbol(t); (*{053c-0541} FIXME: T1 pun *)
  469. Scanner.ExpectSymbol(9); (*{0542} *)
  470. END;
  471. END ParseVarParam;
  472. (* proc22 @0548 — ~ParseFieldList. 0 formals. *)
  473. PROCEDURE ParseFieldList;
  474. VAR saveScope: ADDRESS; tag, fld: CARDINAL;
  475. node: ADDRESS;
  476. BEGIN
  477. saveScope := ADDRESS(SymTab.currentScope); (*{054a-0550} FIXME pun *)
  478. IF Scanner.curSymbol = 0 THEN (*{054e-0551} *)
  479. Scanner.NeedIdentifier; tag := CARDINAL(Scanner.curNode); (*{0553-0556} FIXME *)
  480. IF Scanner.TestSymbolInSet(6) THEN (*{0558?} FIXME: group wove word13/identKind guards; shape TBD *)
  481. Scanner.GetSym;
  482. Scanner.ExpectSymbol(52);
  483. fld := CARDINAL(ParseValParam()); (*{056d-0570} FIXME *)
  484. Words(ADDRESS(tag))^[2] := fld; (*{0571-0579} FIXME *)
  485. ELSE
  486. tag := CARDINAL(Scanner.MakeIdentifierNode(3)); (*{05b9-05bd} FIXME *)
  487. IF Compiler.compilationActive AND (Scanner.curSymbol = 9) THEN (*{05be-05c6} *)
  488. fld := CARDINAL(Scanner.NewSizedNode(6)); Words(ADDRESS(fld))^[3] := 2; (*{05c8-05ce} FIXME *)
  489. ELSE
  490. Scanner.ExpectSymbol(52); (*{05d1-05d3} *)
  491. fld := CARDINAL(ParseValParam()); (*{05d5-05d8} *)
  492. END;
  493. Words(ADDRESS(tag))^[2] := fld; (*{05d9-05db} FIXME *)
  494. Scanner.InsertSymbol(ADDRESS(tag)); (*{05dc-05dd} FIXME T1 pun *)
  495. END;
  496. Scanner.ExpectSymbol(9); (*{05e0} *)
  497. ELSE
  498. tag := CARDINAL(SymTab.currentScope); node := saveScope; (*{05ed-05f1} FIXME *)
  499. WHILE ADDRESS(tag) # node DO (*{05f1-0605} FIXME *)
  500. IF ADDRESS(tag) = NIL THEN Errors.ReportErrorWithText(5, Scanner.tokenBuffer); END; (*{05f9-0600} *)
  501. tag := CARDINAL(Words(ADDRESS(tag))^[0]); (*{0602-0604} FIXME *)
  502. END;
  503. END;
  504. END ParseFieldList;
  505. (* proc23 @060a — ~EvalConstExpr. 0 formals. Const-expr list evaluator. *)
  506. PROCEDURE EvalConstExpr;
  507. VAR t, u, v: CARDINAL;
  508. n: CARDINAL;
  509. BEGIN
  510. WHILE Scanner.curSymbol = 0 DO (*{060c-0682} *)
  511. t := CARDINAL(SymTab.currentScope); (*{0611-0613} FIXME *)
  512. Scanner.DeclareIdentifier(4); u := CARDINAL(Scanner.curNode); (*{0615-0619} FIXME *)
  513. Words(ADDRESS(u))^[4] := Express.spillFlag; (*{061b-061d} FIXME *)
  514. IF Scanner.AcceptSymbol(44) THEN (*{061e-0622} *)
  515. Express.GetConstVal; (*{0624} *)
  516. Express.ConstToCard(Compiler.CardType, 44); (*{0626-062a} FIXME: (type,code) vs DEF order *)
  517. Words(ADDRESS(u))^[2] := Express.curDesc.raw[2]; (*{062b-062f} FIXME *)
  518. Words(ADDRESS(u))^[3] := 256; (*{0631-0637} *)
  519. Scanner.ExpectSymbol(6); (*{0638} *)
  520. END;
  521. IF NOT (Scanner.TestSymbolInSet(6) AND Scanner.AcceptSymbol(1)) THEN EXIT END; (*{0639-0640} FIXME shape *)
  522. Scanner.GetSym; (*{0642} *)
  523. v := CARDINAL(ParseFormalParams()); (*{0644-0647} FIXME *)
  524. IF Words(ADDRESS(v))^[4] > 9 THEN n := 2; ELSE n := (Words(ADDRESS(v))^[3] + 1) DIV 2; END; (*{0648-0659} FIXME *)
  525. TypeSizeRec(ADDRESS(t), ADDRESS(u), ADR(SymTab.stringPoolPtr), ADDRESS(v), n); (*{065a-0662} FIXME: 5-arg punned shape *)
  526. Scanner.ExpectSymbol(9); (*{0664} *)
  527. IF Express.spillFlag = 0 THEN (*{0667-066d} *)
  528. IF SymTab.stringPoolPtr <= 510 THEN Express.CentralError(TRUE, 83); END; (*{066c-0674} FIXME cond *)
  529. ELSE
  530. IF SymTab.stringPoolPtr >= 384 THEN Express.CentralError(TRUE, 81); END; (*{0678-0680} FIXME cond *)
  531. END;
  532. END;
  533. END EvalConstExpr;
  534. (* proc24 @0687 — ~CheckConformant. 0 formals, returns ADDRESS. *)
  535. PROCEDURE CheckConformant(): ADDRESS;
  536. VAR t: ADDRESS;
  537. BEGIN
  538. IF Scanner.AcceptSymbol(47) THEN (*{0689-068d} *)
  539. Scanner.ExpectSymbol(41); (*{068f-0691} *)
  540. t := Scanner.NewSizedNode(11); (*{0693-0695} *)
  541. CheckConformantTail(t); (*{0697-0699} FIXME: self/nested-variant TBD *)
  542. ELSE
  543. t := GetIdent(); (*{069e-06a0} *)
  544. END;
  545. RETURN t; (*{06a3} *)
  546. END CheckConformant;
  547. (* proc14 @06a7 — ~ParseRecordType (map name). 3 formals. *)
  548. PROCEDURE ParseRecordType(rec: ADDRESS; VAR size: CARDINAL; tag: CARDINAL);
  549. VAR total: CARDINAL;
  550. fld, head, cur: ADDRESS;
  551. disc, code: CARDINAL;
  552. lo, hi: CARDINAL;
  553. BEGIN
  554. total := 6; size := 0; (*{06a9-06b0} *)
  555. IF Scanner.curSymbol # 9 THEN (*{06b1-06b5} *)
  556. Scanner.ExpectSymbol(43); (*{06b7-06b9} *)
  557. IF NOT Scanner.AcceptSymbol(5) THEN GOTO noFixed END; (*{06bb-06bf} *)
  558. Scanner.OpenScope(SymTab.currentScope, NIL); (*{06c1-06c4} FIXME args *)
  559. IF Scanner.AcceptSymbol(20) THEN code := 24; ELSE code := 8; END; (*{06c7-06d3} *)
  560. IF tag # 0 THEN (*{06d4} *)
  561. fld := Scanner.NewNode(4); (*{06d7-06d9} *)
  562. Words(fld)^[1] := SymTab.currentScope; Words(fld)^[0] := SymTab.currentScope; (*{06db-06e3} FIXME T1 pun *)
  563. Words(fld)^[3] := code; disc := 1; hi := 34; (*{06e4-06eb} *)
  564. ELSE
  565. Scanner.DeclareIdentifier(4); fld := Scanner.curNode; (*{06ee-06f2} FIXME T1 pun *)
  566. Words(fld)^[3] := code; Words(fld)^[6] := Express.spillFlag + 1; (*{06f3-06fb} FIXME *)
  567. IF NOT (Scanner.TestSymbolInSet(6) AND Scanner.AcceptSymbol(1)) THEN EXIT END; (* FIXME shape *)
  568. Scanner.GetSym; disc := 9; hi := 544; (*{0704-070b} *)
  569. END;
  570. fixedLoop:
  571. head := CheckConformant(); (*{070c} *)
  572. cur := fld;
  573. WHILE cur # rec DO cur := Words(cur)^[0]; END; (*{0711-071b} *)
  574. rec := fld; (*{071d-071f} *)
  575. IF NOT Scanner.TestSymbolInSet(hi) THEN GOTO doneVariants END; (*{0720-0726} FIXME set TBD *)
  576. Scanner.GetSym; (*{0729} *)
  577. IF fld # NIL THEN (*{072b-072d} *)
  578. fld := Words(fld)^[2]; head := fld; (*{072f-0733} *)
  579. IF (4 IN Words(fld)^[3]) OR (Words(head)^[4] > 9) THEN (*{0734-073c} FIXME set TBD *)
  580. code := 2; (*{073e-073f} *)
  581. REPEAT
  582. head := Words(head)^[5]; (*{0746-074c} FIXME: ConstToIntRange idealized *)
  583. UNTIL FALSE;
  584. ELSE
  585. code := (Words(head)^[3] + 1) DIV 2; (*{0751-0758} *)
  586. END;
  587. END;
  588. SymTab.currentScope := SymTab.currentScope; (*{0765-0768} self-store? slot shuffle FIXME *)
  589. noFixed:
  590. IF Scanner.AcceptSymbol(2) THEN (*{076a-076d} *)
  591. disc := CARDINAL(GetIdent()); (*{076f-0772} FIXME *)
  592. Express.MatchOpClass(BITSET{511}, 2); (*{0773-077b} *)
  593. size := disc; (*{077d-077f} *)
  594. END;
  595. doneVariants: ;
  596. END ParseRecordType;
  597. (* proc25 @0783 — ~CloseScopeFixup. 0 formals. *)
  598. PROCEDURE CloseScopeFixup;
  599. BEGIN
  600. IF 0 IN Scanner.curSymbol THEN (*{0785-078a} FIXME: CARDINAL set test *)
  601. Texts.WriteString(3, ""); (*{078c-0791} FIXME: proc21 args TBD *)
  602. Texts.WriteString(3, Scanner.tokenBuffer); (*{0793-0798} FIXME *)
  603. Texts.WriteLn(3); (*{079a-079c} FIXME *)
  604. END;
  605. INC(nestDepth); (*{079d-079f} FIXME: group used Pass1.tempDepth *)
  606. END CloseScopeFixup;
  607. (* PASS1 group 3 @07a8-end. Missing/stubbed: proc10/11/26/27/29/30 (no bytes),
  608. proc36 body (patched over), PASS1/4NAZBA (no bytes). DISPUTE: proc9 =
  609. ParseProcBody per body (no file calls) vs ~WriteSymFile per map. *)
  610. (* FIXME-NYC stubs for called-but-absent procedures *)
  611. PROCEDURE EmitModuleProlog(node: ADDRESS); FORWARD; (* proc10: 1 push *)
  612. PROCEDURE ParseDeclSync; FORWARD; (* proc11: 0 pushes *)
  613. PROCEDURE ParseConstOrTypeArm; FORWARD; (* proc26: DCL arm 111 *)
  614. PROCEDURE ParseModuleArm; FORWARD; (* proc27: DCL arm 112 *)
  615. PROCEDURE TryParseDecl(tag: CARDINAL): BOOLEAN; FORWARD; (* proc29: 1 push; 2-push sites FIXME *)
  616. PROCEDURE ParseImportScope; FORWARD; (* proc30: display-only *)
  617. (*{07a8} PROCDE — ParseProcedureDecl. 0 params. *)
  618. PROCEDURE ParseProcedureDecl;
  619. VAR l2, l3, l4, l5: ADDRESS; s0, s1, s2, s3, s5, s6: WORD;
  620. BEGIN
  621. CloseScopeFixup; (*{07aa} proc25 *)
  622. Scanner.NeedIdentifier; (*{07ad} *)
  623. IF (Scanner.word13 = SymTab.currentScope) & (Compiler.scopeSpare3 = NIL) & (5 IN Scanner.followSet) THEN (*{07af-07bf} FIXME codes *)
  624. l3 := Scanner.curNode; (*{07c1-07c3} FIXME pun *)
  625. Scanner.Allocate(ADR(l2), 14); (*{07c4-07c7} FIXME: group wrote Proc7 *)
  626. MOVE(l3, l2, 14); (*{07c9-07cc} FIXME dst/src order *)
  627. Scanner.GetSym; (*{07d6} *)
  628. ELSE
  629. l2 := Scanner.DeclareIdentifier(5); (*{07da-07de} *)
  630. Words(l2)^[5] := PushTempMark(); (*{07df-07e4} FIXME pun *)
  631. Words(l2 + 1)^[5] := Express.spillFlag; (*{07e5-07eb} FIXME cell *)
  632. END;
  633. Scanner.GetStackMark(ADR(l6)); (*{07ec-07ee} FIXME slot *)
  634. ParseRecordType(l2 + 6, l2 + 2, 0); (*{07f0-07f8} FIXME: ADDRESS arith + (rec,size,tag) roles *)
  635. Scanner.ExpectSymbol(9); (*{07fa-07fb} *)
  636. IF 5 IN Words(l2)^[3] THEN (*{07fd-0801} FIXME: group ternary w/ s3 TBD *)
  637. Express.CentralError(TRUE, 68); (*{080f-0814} FIXME: Proc21 8-cell call TBD *)
  638. WHILE l4 # NIL DO (*{0816-082f} formal walk FIXME *)
  639. Express.CentralError(TRUE, 68); (*{081a-0827} FIXME: Proc23 5-push call TBD *)
  640. l4 := Words(l4)^[0];
  641. END;
  642. Words(l2)^[3] := Words(l2)^[3] - BITSET{5}; (*{0831-0838} *)
  643. Scanner.CheckStackMark(l2 + 14); (*{0839-083c} FIXME arith *)
  644. ParseProcBody(l2); (*{0843} `f9 proc9` *)
  645. ELSE
  646. IF Compiler.scopeSpare3 = NIL THEN (*{0846-0849} *)
  647. IF Scanner.AcceptSymbol(67) THEN (*{084b-084e} FIXME: 67=END? *)
  648. s3 := 32; (*{0851-0856} FIXME *)
  649. Scanner.ExpectSymbol(9); (*{0856} *)
  650. ELSE
  651. ParseProcBody(l2); (*{085a-085b} *)
  652. InsertSetConst(NIL, 0); (*{085c-085e} FIXME args *)
  653. END;
  654. END;
  655. END;
  656. DEC(nestDepth); (*{085f-0861} *)
  657. END ParseProcedureDecl;
  658. (*{0878} MODULD — ParseModuleHead. 0 params. *)
  659. PROCEDURE ParseModuleHead;
  660. VAR l2, l3: ADDRESS;
  661. BEGIN
  662. CloseScopeFixup; (*{087d} *)
  663. l3 := ADDRESS(Statemen.withPending); (*{087e-087f} FIXME pun *)
  664. l2 := Scanner.DeclareIdentifier(6); (*{0880-0884} *)
  665. IF Scanner.AcceptSymbol(44) THEN (*{0885-0887} FIXME: 44 here? *)
  666. Statemen.withPending := 1; (*{088b-088c} *)
  667. Express.EvalConstExpr; (*{088d} FIXME: group saw proc13=GetConstVal *)
  668. Scanner.ExpectSymbol(6); (*{088f-0891} *)
  669. END;
  670. Scanner.ExpectSymbol(9); (*{0893-0894} *)
  671. EmitModuleProlog(l2); (*{0896-0897} FIXME-NYC *)
  672. Statemen.withPending := CARDINAL(l3); (*{0898-0899} FIXME *)
  673. DEC(nestDepth); (*{089b-089d} *)
  674. END ParseModuleHead;
  675. (*{08b2} proc28 — ParseExportList. 0 params. From DCL arm 104. *)
  676. PROCEDURE ParseExportList;
  677. VAR l2: ADDRESS; l3: WORD;
  678. BEGIN
  679. l2 := Scanner.DeclareIdentifier(2); (*{08b4-08b8} *)
  680. l3 := PushTempMark(); (*{08b9-08ba} FIXME: WORD := CARDINAL pun *)
  681. IF Compiler.scopeSpare3 = NIL THEN (*{08be-08c1} *)
  682. CodeGen.OpenFixup(1, l3, 0); (*{08c3-08c6} FIXME: (pos?,...) arity *)
  683. Words(emitBase)^[CARDINAL(l3)] := CodeGen.nextEmitPos; (*{08c9-08cd} FIXME *)
  684. Scanner.EmitString(l2, s1, 128); (*{08ce-08d2} FIXME-NYC: no such export; module suspect *)
  685. CodeGen.EmitConst(l2); (*{08d5} FIXME-NYC *)
  686. CodeGen.EmitConst2(l2, s1); (*{08d7-08d9} FIXME-NYC *)
  687. END;
  688. Scanner.TestSymbolInSet(514); (*{08dc-08df} FIXME: CARDINAL set pun *)
  689. WHILE NOT Scanner.AcceptSymbol(1) DO (*{08e1-08e5} FIXME loop shape *)
  690. Scanner.GetSym; (*{08e7} *)
  691. END;
  692. END ParseExportList;
  693. (*{08f1} DCL — ParseOneDecl. 0 params. Dispatch on saved curSymbol. *)
  694. PROCEDURE ParseOneDecl;
  695. VAR l2: CARDINAL; l3: ADDRESS; l4: WORD;
  696. BEGIN
  697. l4 := Express.spillFlag; (*{08f3-08f5} FIXME: group wrote word4 *)
  698. l3 := SymTab.currentScope; (*{08f6-08f8} FIXME T1 pun *)
  699. l2 := Scanner.curSymbol; (*{08f9-08fc} *)
  700. Scanner.GetSym; (*{08fd} *)
  701. CASE l2 OF (*{08fe-0913} callswitch 104..112 *)
  702. 104: ParseExportList(); (*{0901} *)
  703. | 108: ParseValParam(); (*{0904} FIXME: VALUE-parser as CONST arm? *)
  704. | 110: EvalConstExpr(); (*{0907} FIXME: const-EVAL as VAR arm? *)
  705. | 109: ParseFieldList(); (*{090a} FIXME: field-parser as TYPE arm? *)
  706. | 111: ParseConstOrTypeArm(); (*{090d} FIXME-NYC *)
  707. | 112: ParseModuleArm(); (*{0910} FIXME-NYC *)
  708. END;
  709. Express.spillFlag := l4; (*{092d-092e} FIXME type *)
  710. SymTab.currentScope := l3; (*{0930-0931} FIXME pun *)
  711. END ParseOneDecl;
  712. (*{0943} DCLS — ParseDeclarations. 1 param, BOOLEAN function. *)
  713. PROCEDURE ParseDeclarations(follow: BITSET): BOOLEAN;
  714. VAR l2: CARDINAL; l3: CARDINAL; l4: CARDINAL; l5: CARDINAL;
  715. l6: ADDRESS; l7: ADDRESS;
  716. BEGIN
  717. l2 := CARDINAL(Scanner.scanOptions); (*{0945-0947} FIXME pun *)
  718. l3 := Scanner.tokenPos; (*{0948-094b} FIXME: group wrote word25 *)
  719. Scanner.GetStackMark(ADR(l6)); (*{094c-094e} *)
  720. l5 := CodeGen.nextEmitPos; (*{0950-0952} FIXME: group wrote word2 *)
  721. l7 := SymTab.currentScope; (*{0953-0956} FIXME pun *)
  722. l4 := SymTab.moduleCount + SymTab.stringPoolPtr * 128; (*{0957-095e} FIXME: group packed word4+word5 *)
  723. IF (Scanner.curSymbol = 13) OR (Scanner.curSymbol = 23) THEN (*{095f-096a} FIXME codes *)
  724. Statemen.GuardedStatSeq(follow); (*{096c-096d} *)
  725. ELSE
  726. Scanner.TestSymbolInSet(2018); (*{0971-0974} FIXME: CARDINAL set pun *)
  727. ParseDeclSync(); (*{0976} *)
  728. WHILE NOT TryParseDecl(follow) DO END; (*{0977-097a} FIXME polarity *)
  729. END;
  730. RETURN TRUE; (*{097c-097d} *)
  731. (* guarded-recovery handler: *)
  732. SymTab.moduleCount := l4 MOD 256; (*{097f-0983} FIXME *)
  733. AllocSymEntry((l4 DIV 256) * 2); (*{0984-098a} FIXME role *)
  734. IF Errors.savedEditPos > l3 THEN (*{098d-0993} FIXME: group wrote word2 *)
  735. Scanner.tokenPos := l3; (*{0995-0996} *)
  736. Scanner.scanOptions := BITSET(l2); (*{0999-099a} FIXME *)
  737. CodeGen.nextEmitPos := l5; (*{099c-099d} FIXME: assignable? *)
  738. Scanner.CheckStackMark(l6); (*{099f-09a0} *)
  739. Errors.RollbackToMark; (*{09a2} *)
  740. CodeGen.OpenEmitter; (*{09a4} *)
  741. RETURN FALSE; (*{09a7-09a8} *)
  742. END;
  743. END ParseDeclarations;
  744. (*{09b9} IMEXDC — ParseImportFrom. 0 params. *)
  745. PROCEDURE ParseImportFrom;
  746. BEGIN
  747. IF (Scanner.curSymbol = 15) OR (Scanner.curSymbol = 16) THEN (*{09bb-09c6} FIXME codes *)
  748. SymTab.DefineDefinitionModule(0); (*{09c8-09cc} FIXME: 2 pushes vs 1 formal *)
  749. ParseImportScope(); (*{09ce-09cf} FIXME-NYC *)
  750. ELSIF (Scanner.curSymbol = 23) OR (Scanner.curSymbol = 13) THEN (*{09d3-09de} *)
  751. Statemen.GuardedStatSeq(BITSET{}); (*{09e0-09e2} FIXME: extra push TBD *)
  752. ELSE
  753. Scanner.TestSymbolInSet(2046); (*{09e6-09e9} FIXME pun *)
  754. IF Scanner.curSymbol = 17 THEN (*{09eb-09ef} *)
  755. SymTab.DefineProgramModule(0); (*{09f2-09f9} FIXME: 6 pushes vs 1 formal *)
  756. ELSE
  757. ParseDeclSync(); (*{09fd} *)
  758. END;
  759. WHILE NOT TryParseDecl(0) DO END; (*{09fe-0a02} FIXME: extra (ix) push *)
  760. END;
  761. END ParseImportFrom;
  762. (*{0a0c} MODBLO — ParseModuleBlock. 1 param (module node). *)
  763. PROCEDURE ParseModuleBlock(modNode: ADDRESS);
  764. VAR l2: ADDRESS; l3: ADDRESS;
  765. l4: ADDRESS; l5: WORD;
  766. BEGIN
  767. l2 := SymTab.currentScope; (*{0a0e-0a10} FIXME pun *)
  768. l3 := SymTab.ownNamePtr; (*{0a11-0a13} FIXME: group wrote word11 *)
  769. SymTab.ownNamePtr := NIL; (*{0a14-0a15} FIXME *)
  770. Scanner.OpenScope(SymTab.currentScope, NIL); (*{0a17-0a1a} FIXME args *)
  771. Scanner.GetStackMark(ADR(l5)); (*{0a1d-0a1f} FIXME slot *)
  772. ParseImportScope(); (*{0a21} *)
  773. Scanner.GetSym; (*{0a23} *)
  774. l4 := SymTab.ownNamePtr; (*{0a25-0a27} FIXME *)
  775. SymTab.ownNamePtr := l3; (*{0a28-0a29} FIXME *)
  776. IF TRUE THEN (*{0a2b-0a2f} FIXME: 10 IN NodeFlagSet(modNode, s3) *)
  777. SymTab.InitSymbolTables(BITSET{}, l4, modNode); (*{0a34-0a39} FIXME: 4-5 pushes vs 3 formals *)
  778. ELSE
  779. SymTab.InitSymbolTables(BITSET{}, l4, l2); (*{0a3d-0a42} FIXME *)
  780. END;
  781. SymTab.currentScope := l2; (*{0a44-0a45} FIXME pun *)
  782. END ParseModuleBlock;
  783. (*{0a56} proc9 — ParseProcBody (DISPUTE: map said ~WriteSymFile, but body
  784. parses decls + body block per procedure and issues NO file calls). *)
  785. PROCEDURE ParseProcBody(procNode: ADDRESS);
  786. VAR l2: CARDINAL; l3: ADDRESS; l4: CARDINAL;
  787. BEGIN
  788. Scanner.GetStackMark(ADR(l3)); (*{0a58-0a5a} *)
  789. l2 := SymTab.stringPoolPtr; (*{0a5c-0a5e} FIXME: group wrote word5 *)
  790. SymTab.stringPoolPtr := 510; (*{0a5f-0a62} FIXME pun *)
  791. Scanner.OpenScope(SymTab.currentScope, procNode); (*{0a64-0a68} FIXME: 3rd push TBD *)
  792. Express.spillFlag := Express.spillFlag + 1; (*{0a6b-0a6d} FIXME: group wrote word4 *)
  793. Scanner.PushWithScope; (*{0a70} *)
  794. IF Scanner.curSymbol = 0 THEN (*{0a72?} FIXME: group wove word10/9/8 guard; shape TBD *)
  795. Statemen.GuardedStatSeq(BITSET{}); (*{0a85-0a86} FIXME arg *)
  796. ELSE
  797. l4 := 0; (*{0a8f-0a90} *)
  798. (*{0a91-0aa9} NUL-terminated name scan FIXME *)
  799. (*{0aab-0ab8} IF name = "CODE" THEN Errors.ReportError(11) FIXME callee *)
  800. WHILE NOT TryParseDecl(0) DO END; (*{0abd-0ac0} FIXME arg *)
  801. END;
  802. Scanner.GetSym; (*{0ac2} *)
  803. Express.spillFlag := Express.spillFlag - 1; (*{0ac9-0acc} FIXME *)
  804. SymTab.stringPoolPtr := l2; (*{0ace-0acf} FIXME *)
  805. Scanner.CheckStackMark(l3); (*{0ad1-0ad2} *)
  806. Words(emitBase)^[0] := Scanner.codeSize; (*{0ad4-0ade} FIXME: indexed-emit shape *)
  807. END ParseProcBody;
  808. (*{0ae5} MAINDE — ParseMainModule. 0-param BOOLEAN function. *)
  809. PROCEDURE ParseMainModule(): BOOLEAN;
  810. VAR l2: ADDRESS; l3: ADDRESS;
  811. l4: ADDRESS; l5: ADDRESS;
  812. l6: CARDINAL; l7: CARDINAL;
  813. l8, l10: CARDINAL; l9: ADDRESS;
  814. BEGIN
  815. Scanner.GetStackMark(ADR(l9)); (*{0af1-0af3} *)
  816. Scanner.AcceptSymbol(25); (*{0af5-0af7} *)
  817. l6 := ORD(NOT Compiler.scopeSpare3) AND ORD(Scanner.AcceptSymbol(24)); (*{0af9-0b0d} FIXME shape *)
  818. Scanner.ExpectSymbol(22); (*{0b0e-0b10} *)
  819. l7 := 0; (*{0b12-0b13} *)
  820. l3 := Scanner.MakeIdentifierNode(5); (*{0b4e-0b52} *)
  821. IF Scanner.AcceptSymbol(44) THEN (*{0b53-0b55} FIXME: 44 here? *)
  822. IF Statemen.withPending # 0 THEN (*{0b59-0b5b} *)
  823. Scanner.ExpectIdentKind(1); Scanner.GetSym; (*{0b5d-0b60} *)
  824. Scanner.ExpectSymbol(6); (*{0b62-0b63} *)
  825. END;
  826. END;
  827. Scanner.ExpectSymbol(9); (*{0b65-0b66} *)
  828. Scanner.TestSymbolInSet(2031); (*{0b68-0b6b} FIXME pun *)
  829. IF Compiler.scopeSpare3 OR (l6 # 0) OR (Scanner.curSymbol - 13 IN BITSET{0..12}) THEN (*{0b6d-0b7a} FIXME *)
  830. CASE CARDINAL(0) OF (*{0ba1} FIXME: Loader.Proc5()+1 DIV 2 dispatch, codes 92/93/94 *)
  831. 92: SymTab.CompileDispatch(l2, TRUE, l6 # 0); (*{0b83-0b8c} FIXME: 5 pushes vs 3 formals *)
  832. | 93: SymTab.CompileDispatch(l2, TRUE, l6 # 0); (*{0b8d-0b96} FIXME *)
  833. | 94: SymTab.CompileDispatch(l2, TRUE, l6 # 0); (*{0b97-0ba0} FIXME *)
  834. ELSE SymTab.CompileDispatch(l2, TRUE, l6 # 0); (*{0bae-0bb5} FIXME *)
  835. END;
  836. END;
  837. CodeGen.InitCodeGenerator; (*{0bb7} *)
  838. IF Compiler.scopeSpare3 = NIL THEN (*{0bba-0bbd} *)
  839. Compiler.compilationActive := FALSE; (*{0bbf-0bc1} FIXME: group gated on l6 *)
  840. l4 := SymTab.currentScope; (*{0bc6-0bc9} FIXME pun *)
  841. WHILE l4 # NIL DO (*{0bca-0c43} export-emit walk *)
  842. IF Words(l4)^[4] = 6 THEN (*{0bd0-0bd2} *)
  843. l5 := Words(l4)^[6]; (*{0bd4-0bd6} FIXME pun *)
  844. WHILE l5 # NIL DO (*{0bd7-0be7} *)
  845. OpenScopeEmit(l5); (*{0be2-0be5} *)
  846. l5 := Words(l5)^[0]; (*{0be6-0be8} *)
  847. END;
  848. ELSIF Words(l4)^[2] = Compiler.charArrayDesc THEN (*{0beb-0bef} FIXME pun *)
  849. OpenScopeEmit(l4); (*{0bf2-0bf3} *)
  850. ELSIF (Words(l4)^[4] = 2) THEN (*{0bf6-0c03} FIXME: bit-66 conjunct TBD *)
  851. CodeGen.OpenFixup(1, Words(l4)^[5], 0); (*{0c05-0c09} FIXME arity *)
  852. Words(emitBase)^[Words(l4)^[5]] := CodeGen.nextEmitPos; (*{0c0c-0c11} FIXME *)
  853. ELSIF (Words(l4)^[4] = 4) AND (Words(l4)^[2] > 9) AND (Words(l4)^[3] = 0) THEN (*{0c22-0c33} *)
  854. PopTempMark(Words(l4)^[5], 0); (*{0c35-0c3f} FIXME: 8-cell grouping *)
  855. END;
  856. l4 := Words(l4)^[0]; (*{0c40-0c42} *)
  857. END;
  858. IF (Scanner.curSymbol # 23) AND (Scanner.curSymbol # 13) THEN (*{0c45-0c50} *)
  859. WHILE NOT TryParseDecl(0) DO END; (*{0c52-0c55} FIXME arg *)
  860. ELSE
  861. Statemen.GuardedStatSeq(BITSET{}); (*{0c59-0c5a} FIXME arg *)
  862. END;
  863. Words(emitBase)^[0] := Scanner.codeSize; (*{0c5c-0c61} FIXME shape *)
  864. END;
  865. RETURN TRUE; (*{0c62-0c63} *)
  866. (* guarded-recovery handler: *)
  867. IF Errors.savedEditPos > l10 THEN (*{0c65-0c69} FIXME: group wrote word2; l10 uninit here TBD *)
  868. Scanner.tokenPos := l10; Scanner.scanOptions := BITSET(l8); (*{0c6b-0c70} FIXME *)
  869. Scanner.CheckStackMark(l9); (*{0c72} *)
  870. Errors.RollbackToMark; (*{0c75} *)
  871. CodeGen.OpenEmitter; (*{0c77} *)
  872. RETURN FALSE; (*{0c7a-0c7b} *)
  873. END;
  874. Errors.DoError("X"); (*{0c84-0c86} FIXME: group saw proc17(69); unmapped *)
  875. END ParseMainModule;
  876. (*{0c93} proc33 — WriteMcdHeader. 0 params. *)
  877. PROCEDURE WriteMcdHeader;
  878. VAR l2: CARDINAL; l3: ADDRESS;
  879. BEGIN
  880. Scanner.Allocate(l3, 16); (*{0c95-0c98} FIXME: group wrote Reserve *)
  881. l2 := SymTab.moduleCount + 1; (*{0c99-0c9c} FIXME: group wrote word4 *)
  882. WHILE l2 # 0 DO (*{0c9d-0caa} *)
  883. DEC(l2);
  884. CodeGen.CloseFixup(Words(emitBase)^[l2], 0); (*{0ca4-0ca8} FIXME pun *)
  885. END;
  886. IF CodeGen.windowBase = 0 THEN (*{0cd2-0cd5} FIXME: group wrote word3 *)
  887. MOVE(Scanner.codeBuffer, l3, 16); (*{0cd7-0cdc} FIXME dst/src order *)
  888. END;
  889. IF Compiler.rangeCheckEnabled = FALSE THEN (*{0cef-0cf1} FIXME: group wrote word2 *)
  890. Texts.WriteString(3, "Compiled bytes:"); (* FIXME *)
  891. Texts.WriteCard(3, CodeGen.nextEmitPos - 16, 6); (* FIXME *)
  892. Texts.WriteLn(3); (* FIXME *)
  893. END;
  894. END WriteMcdHeader;
  895. (*{0d17} proc35 — EmitConstVal. 2 params: (buf, count) per frame rule. *)
  896. PROCEDURE EmitConstVal(buf: ADDRESS; count: CARDINAL);
  897. BEGIN
  898. WHILE count # 0 DO (*{0d19-0d1b} *)
  899. CodeGen.EmitString(buf); (*{0d1d-0d1f} FIXME-NYC: group saw Proc3 *)
  900. buf := buf + 2; (*{0d21-0d24} FIXME: ADDRESS arith *)
  901. count := count - 2; (*{0d25-0d28} *)
  902. END;
  903. END EmitConstVal;
  904. (*{0d2e} proc34 — EmitTypeDesc. 0 params. *)
  905. PROCEDURE EmitTypeDesc;
  906. VAR l2: ADDRESS; l3: ADDRESS;
  907. l4, l5, l6: CARDINAL;
  908. BEGIN
  909. Scanner.Allocate(l2, 84); (*{0d30-0d32} FIXME: group wrote Reserve *)
  910. Scanner.Allocate(l3, 508); (*{0d34-0d38} FIXME *)
  911. l5 := CodeGen.nextEmitPos - 18; (*{0d39-0d3d} *)
  912. l6 := 2 * (32 - SymTab.moduleCount); (*{0d70-0d76} FIXME: group wrote word3 *)
  913. EmitConstVal(l2 + l6, 84 - l6); (*{0d78-0d7f} FIXME arith *)
  914. LinkSymEntry(l3); (*{0d81-0d82} *)
  915. EmitConstVal(l3, SymTab.stringPoolPtr - 4); (*{0d83-0d88} FIXME: group wrote word5 *)
  916. l4 := SymTab.moduleCount; (*{0d8a-0d8c} FIXME *)
  917. WHILE l4 # 0 DO (*{0d8d-0da7} per-scope emit loop *)
  918. DEC(l4);
  919. EmitConstVal(SymTab.moduleTable + l4 * 10, 10); (*{0d94-0d9b} FIXME: word6 base? *)
  920. CodeGen.EmitString(l5 + (SymTab.moduleCount - l4) * 2); (*{0d9d-0da5} FIXME-NYC: group saw Proc3 *)
  921. END;
  922. CodeGen.EmitString(0); (*{0da9-0daa} FIXME *)
  923. CodeGen.EmitString(0); (*{0dac-0dad} FIXME *)
  924. END EmitTypeDesc;
  925. (*{0e93} proc36 — CheckForwardResolved: NO BODY (slot patched over by the
  926. COMPILE link stub's keyword-table search). Reconstruct from SymTab.CheckForwards
  927. or another MCD. *)
  928. PROCEDURE CheckForwardResolved; FORWARD;
  929. (*{1027} PASS1 — Pass1Main: NO bytes in pass1.txt (ends ~101a). *)
  930. PROCEDURE Pass1Main; FORWARD;
  931. (*{105b} 4NAZBA — module init: NO bytes. *)
  932. PROCEDURE InitPass1; FORWARD;
  933. (*{0db2} proc32 — WriteOutputFiles: file-output driver (.SYM via
  934. SymTab.SaveSymbolFile vs .MCD via WriteMcdHeader+EmitTypeDesc).
  935. 0 params. Refutes FRONTEND.md ~SkipToDeclStart (only the head loop
  936. skips input). Compiler.scopeSpare3/word2 flag roles TBD (no DEF slots). *)
  937. PROCEDURE WriteOutputFiles;
  938. BEGIN
  939. WHILE Scanner.curChar # CHR(255) DO (*{0db4-0db9} *)
  940. Scanner.NextChar; (*{0dbb} *)
  941. Express.CentralError((Scanner.curChar = CHR(255))
  942. OR (Scanner.curChar <= CHR(32)), 32); (*{0dbd-0dcb} *)
  943. END;
  944. IF 0 IN Scanner.scanOptions THEN (*{0dcf-0dd3} *)
  945. Texts.WriteLn(3); (*{0dd5-0dd6} FIXME channel roles TBD *)
  946. Texts.WriteString(3, "End of source reached."); (*{0dd8-0df3} *)
  947. Texts.WriteLn(3);
  948. END;
  949. Files.Close(Scanner.sourceFile); (*{0df8-0dfb} FIXME proc identity *)
  950. Texts.WriteLn(3);
  951. IF Compiler.scopeSpare3 THEN (*{0e00-0e02} FIXME: group read word3; TRUE = .SYM path *)
  952. SymTab.SaveSymbolFile; (*{0e04} *)
  953. Texts.WriteString(3, "Symbol"); (*{0e06-0e10} *)
  954. Scanner.ChangeFileExtension(ComLine.outName, "SYM", TRUE); (*{0e12-0e1c} FIXME ComLine slot *)
  955. ELSE
  956. WriteMcdHeader; (*{0e21} *)
  957. EmitTypeDesc; (*{0e23} *)
  958. Scanner.ChangeFileExtension(ComLine.outName, "MCD", TRUE); (*{0e25-0e2f} *)
  959. IF NOT Compiler.rangeCheckEnabled THEN (*{0e32-0e35} FIXME: group read word2; polarity TBD *)
  960. Files.SetPos(Scanner.codeFile, LONG(CodeGen.windowBase)); (*{0e37-0e3d} FIXME proc/arg order *)
  961. Files.WriteBytes(Scanner.codeFile, Scanner.codeBuffer,
  962. CodeGen.nextEmitPos - CodeGen.windowBase); (*{0e40-0e4a} FIXME proc identity *)
  963. Texts.WriteString(3, "M-code"); (*{0e4d-0e57} *)
  964. END;
  965. END;
  966. IF Compiler.scopeSpare3 OR NOT Compiler.rangeCheckEnabled THEN (*{0e59-0e60} FIXME same flags *)
  967. Texts.WriteString(3, " file "); (*{0e62-0e6b} *)
  968. Texts.WriteString(3, ComLine.outName); (*{0e6e-0e73} FIXME slot *)
  969. Texts.WriteString(3, " produced."); (*{0e75-0e83} *)
  970. Files.Close(Scanner.sourceFile); (*{0e85-0e8c} FIXME: finalizer identity TBD *)
  971. Texts.WriteLn(3);
  972. END;
  973. END WriteOutputFiles;
  974. END Pass1.