| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830 |
- (* STATEMEN.MOD — DRAFT v1, assembled 2026-10-03, NOT verified.
- Reconstructed from Reversing-Turbo-Modula2-main/MCode_disassembly/statement.txt
- (1793 lines) by two parallel passes (group 1 @0001-0566, group 2 @0566-end).
- Does NOT yet recompile to the original MCD; verification via unassemble.c
- diff is still required (see src/compiler/README.md).
- FRAME MECHANICS (proven from MCode_specification/Stack.mod +
- Instruction.mod + Extended.mod, settles all arg-order disputes):
- - Callers push args in source order (spec Extended.Move pops size,dst,src).
- - NewFrame pushes oldFP,outerFP above retAddr; fp^[0]=outerFP, [1]=oldFP,
- [2]=retAddr, [3]=LAST pushed word. Opcode 03H..07H = LoadParam(3..7), and
- the disassembler prints fp^[3] as "param1". Hence "param1" = LAST pushed
- word (modulo multi-word/VAR params: SYMTAB proc8 SymbolAssert reads
- "param2"=cond,"param1"=code for source (cond, code) — consistent).
- - Consequence: a body reading "param1"=first-formal is backwards; the
- correct source order is first-pushed=formal1. Call sites reconstructed
- from pushes are order-correct as written.
- - Proven by this: Express proc9 @02be tests `IN param2` and reports via
- ERRORS.proc14(param2, X, param1)=(want,got,ctx); STMT @05d9 pushes
- (512, 43): (allowed={9}, code=43) is the only sane reading, so
- Express.MatchOpClass is (allowed, errCode) — NOT (errCode, allowed) as
- EXPRESS.MOD draft v1 declares. FIX APPLIED HERE (call shapes unchanged);
- EXPRESS.MOD's own declaration still needs the same swap (next edit).
- - Same proof: Express.proc1 takes (cond, code) — STMT @058a shows
- [bool,20] with code on top. EXPRESS.MOD's 1-param CentralError FORWARD
- is stale; widened here via Express.CentralError(ok, code) usage and
- flagged there.
- CORRECTIONS to docs/compiler/60-frontend.md + FRONTEND.md (body-proven):
- - proc5 = CASE (jump table via EmitWord, OF, `|`, ELSE), proc6 = FOR
- (`:=`/TO/BY, control-var checks) — the map had them swapped.
- - STMT dispatch: 121 Loop, 122 Exit, 123 Result, 124 If, 125 For,
- 126 Repeat, 127 While, 128 With, 129 Return, 130 Case (125 = CASE default).
- - TWO case-shaped procedures exist: proc5 (STMT-driven, full jump-table
- parser) vs proc16 (BODY-driven via Accept(14), label-table emitter).
- Kept distinct: ParseCaseStmt vs ParseCaseTail. Why BODY re-enters case
- parsing on symbol 14 is unexplained — MCD diff must decide.
- - 123/129 = RESULT/RETURN inferred from store-vs-epilogue behavior.
- CONVENTIONS: Words(X)^[N] = numeric-word pun on ADDRESS/T1 handles
- (MCode is untyped; original emissive code TBD). GOTO kept as faithful
- jump rendering (restructure to LOOP/EXIT in verification).
- Scanner.word22/word23/word25 read as codeSize/listingEnabled/tokenPos
- (SCANNER.DEF positional mapping; listingEnabled assignments flagged).
- BITSET{..} literal sets on CARDINAL curSymbol kept verbatim (cast TBD). *)
- IMPLEMENTATION MODULE Statemen;
- IMPORT Compiler, Scanner, Errors, CodeGen, Express, SymTab, Files, Texts, Loader;
- FROM SYSTEM IMPORT ADDRESS, ADR, MOVE, WORD;
- FROM STORAGE IMPORT MARK, RELEASE;
- TYPE Words = POINTER TO ARRAY [0..15] OF WORD;
- VAR
- needEpilogue: CARDINAL; (* word2: set from body-nonEmpty + tail paths *)
- withPending: CARDINAL; (* word3: nonzero = with-base load pending *)
- nestDepth: CARDINAL; (* word4: LOOP/CASE/FOR nesting depth *)
- exitDepth: CARDINAL; (* word5: LOOP-entry depth for EXIT (= group2 loopExitMark) *)
- curBlockNode: ADDRESS; (* word6: BODY param1 (= group1 curRoutine) *)
- caseActive: CARDINAL; (* word7: proc16 sets 1 (= group1 caseSeen) *)
- withDesc: ADDRESS; (* word8: pending operand for EmitStandardOp(25) *)
- exitEmitted: CARDINAL; (* word9: proc17 sets 1 *)
- (* ---- helpers shared across both groups ---- *)
- PROCEDURE ReserveWords(n: CARDINAL): ADDRESS; FORWARD; (* FIXME: = Scanner.Allocate? *)
- PROCEDURE MoveWords(dst, src: ADDRESS; words: CARDINAL); FORWARD; (* FIXME: = MOVE? *)
- (* ---- group-1 procedures (FORWARDs; bodies below) ---- *)
- PROCEDURE CalcMemOffset(): CARDINAL; FORWARD;
- PROCEDURE SyncToStatStart; FORWARD;
- PROCEDURE ParseCaseStmt; FORWARD;
- PROCEDURE ParseFor; FORWARD;
- PROCEDURE ParseWhile; FORWARD;
- PROCEDURE ParseRepeat; FORWARD;
- PROCEDURE ParseIf; FORWARD;
- PROCEDURE ParseLoop; FORWARD;
- PROCEDURE ParseExit; FORWARD;
- PROCEDURE ParseResult; FORWARD;
- PROCEDURE ParseWith; FORWARD;
- PROCEDURE ParseReturn; FORWARD;
- (* ---- group-2 procedures (FORWARDs; bodies below) ---- *)
- PROCEDURE NextSymWrap; FORWARD;
- PROCEDURE ParseStatSeqLoop(stop: BITSET): BOOLEAN; FORWARD;
- PROCEDURE EmitJumpFixup; FORWARD;
- PROCEDURE ParseStatement; FORWARD;
- PROCEDURE GuardedStatSeq(follow: BITSET): BOOLEAN; FORWARD;
- PROCEDURE ParseCaseTail; FORWARD;
- PROCEDURE CloseBlockChain(VAR node: ADDRESS); FORWARD;
- PROCEDURE EmitNameHash(VAR name: ARRAY OF CHAR); FORWARD;
- PROCEDURE EmitComBytes; FORWARD;
- PROCEDURE ParseBeginBlock(tag: CARDINAL); FORWARD; (* audit: frame says 1 param; VAR rest dropped *)
- (* STATEMEN group 1 — procedures @0001-0566 *)
- (* proc2 @0001 — ~CalcMemOffset. 0 params: reads curBlockNode global *)
- PROCEDURE CalcMemOffset(): CARDINAL;
- VAR p, q: ADDRESS;
- flag: CARDINAL;
- BEGIN
- {/* 0001 */}
- p := Words(curBlockNode)^[6]; (*{0003-0005}*)
- IF p = NIL THEN (*{0006-0008} *)
- RETURN 0; (*{000a-000b} *)
- END;
- WHILE Words(p)^[0] # NIL DO (*{000d-0010} *)
- p := Words(p)^[0]; (*{0012-0014}*)
- END;
- q := Words(p)^[2]; (*{0017-0019}*)
- IF (Words(q)^[4] > 9) OR (4 IN Words(p)^[3]) THEN (*{001a-0024} *)
- flag := 1; (*{0026-0027} *)
- ELSE
- flag := (Words(q)^[3] + 1) DIV 2; (*{002a-002f} shr 1 *)
- END;
- RETURN Words(p)^[5] DIV 2 + flag - 3; (*{0030-0038} *)
- END CalcMemOffset;
- (* proc3 @003b — ~SyncToStatStart *)
- PROCEDURE SyncToStatStart;
- BEGIN
- {/* 003b */}
- IF Express.spillFlag # 0 THEN (*{003d-0040} *)
- IF withPending # 0 THEN (*{0042-0043} *)
- Express.PushOperand(withDesc); (*{0045-0046} FIXME: 1-arg vs 0-arg FORWARD *)
- CodeGen.EmitStandardOp(25); (*{0048-004a} *)
- END;
- IF Words(curBlockNode)^[2] = NIL THEN (*{004c-004f}*)
- CodeGen.EmitMiscOp(0, (*{0051-0052} *)
- CalcMemOffset() + ORD(Express.spillFlag = 1) * 128); (*{0053-005a} shl 7 *)
- ELSIF 8 IN Scanner.scanOpt THEN (*{005e-0062} *)
- CodeGen.QueueConst(9); (*{0064-0065} *)
- CodeGen.QueueConst(0); (*{0067-0068} *)
- CodeGen.QueueConst(0); (*{006a-006b} *)
- CodeGen.EmitStandardOp(14); (*{006d-006e} *)
- END;
- ELSE (*{0072} *)
- CodeGen.EmitMiscOp(5, 2); (*{0073-0074} *)
- END;
- END SyncToStatStart;
- (* proc5 @0078, STMT case 130 — ParseCaseStmt. Selector + OF + label ranges
- with jump-table emission, `|`-separated arms, ELSE. *)
- PROCEDURE ParseCaseStmt;
- VAR head: ADDRESS;
- chain: ADDRESS;
- buf: ADDRESS;
- tail: ADDRESS;
- prev: ADDRESS;
- selTyp: ADDRESS;
- lo: CARDINAL;
- hi: CARDINAL;
- endFix: CARDINAL;
- topFix: ADDRESS;
- armFix: CARDINAL;
- BEGIN
- INC(nestDepth); (*{007a-007d} *)
- Express.BoolCondHelper; (*{007d} parse CASE selector *)
- Express.MatchOpClass(7, 40); (*{007f-0082} *)
- selTyp := Express.curDesc.raw[0]; (*{0084-0087} FIXME: typ pun *)
- Scanner.ExpectSy(41); (*{0088-008a} OF *)
- CodeGen.EmitSystemCall(21); (*{008c-008e} *)
- CodeGen.EmitStandardOp(15); (*{008f-0092} jump to dispatch *)
- CodeGen.OpenFixup(topFix, TRUE); (*{0094-0097} *)
- head := NIL; (*{0099-009a} *)
- tail := NIL; (*{009b-009c} *)
- WHILE NOT (Scanner.curSym IN BITSET{8,10,13}) DO (*{009d-00a4} *)
- armFix := CodeGen.MarkCodePos(14); (*{00a6-00aa} *)
- Express.GetTypeDesc(selTyp, ADR(lo), ADR(hi)); (*{00ac-00b1} FIXME: (dest,mode,src) roles *)
- prev := NIL; (*{00b3-00b4} *)
- chain := head; (*{00b5-00b6} *)
- WHILE (chain # NIL) AND (Words(chain)^[1] < lo) DO (*{00b7-00be} *)
- prev := chain; (*{00c1-00c2} *)
- chain := Words(chain)^[0]; (*{00c3-00c6} *)
- END;
- Scanner.Allocate(buf, 6); (*{00c8-00cb} *)
- Words(buf)^[0] := chain; (*{00cd-00cf} *)
- Words(buf)^[1] := hi; (*{00d0-00d2} *)
- Words(buf)^[2] := armFix; (*{00d3-00d6} *)
- IF (chain # NIL) AND (Words(chain)^[1] = 0) THEN (*{00d7-00d9} *)
- tail := buf; (*{00db-00dc} *)
- END;
- IF (chain # NIL) AND (Words(chain)^[1] > hi) THEN (*{00df-00e2} *)
- Express.CentralError(FALSE, 47); (*{00e3-00e5} *)
- END;
- chain := buf; (*{00e7-00e8} *)
- DEC(hi); (*{00e9-00eb} *)
- WHILE hi >= lo DO (*{00ec-00ef} expand label range; duplicate check TBD *)
- END;
- IF prev # NIL THEN (*{00f1-00f3} *)
- Words(prev)^[0] := buf; (*{00f5-00f8} *)
- ELSE
- head := buf; (*{00fa-00fb} *)
- END;
- Scanner.TestSet(BITSET{1,2}); (*{00fc-00fd} `,`/`:` *)
- IF Scanner.AcceptSy(1) THEN (*{00ff-0100} `,`: another label, loop to 00ac *)
- END;
- Scanner.GetSym; (*{0105} consume `:` *)
- WHILE NOT ParseStatSeqLoop(BITSET{8,10,13}) DO END; (*{0107-010b} arm body *)
- CodeGen.EmitStandardOp(20); (*{010d-010f} jump to end *)
- END;
- IF NOT Scanner.AcceptSy(8) THEN (*{0111-0115} `|`: more arms loop to 009d *);
- END;
- DEC(nestDepth); (*{0117-0119} *)
- endFix := CodeGen.InsertFixup(topFix, TRUE); (*{011a-011e} *)
- IF head # NIL THEN (*{011f-0121} emit jump table over label chain *)
- lo := Words(head)^[1]; (*{0123-0125} *)
- CodeGen.EmitStandardOp(19); (*{0126-0128} *)
- CodeGen.EmitWord(lo + 32768); (*{012a-012f} *)
- CodeGen.EmitWord(tail - lo); (*{0131-0135} FIXME: ADDRESS pun *)
- CodeGen.OpenFixup(topFix, FALSE); (*{0137-013a} *)
- WHILE Words(head)^[0] = lo DO (*{013c-0140} FIXME *)
- CodeGen.CloseFixup(Words(head)^[2] + ORD(NOT endFix), FALSE); (*{0142-0148} *)
- head := Words(head)^[0]; (*{014a-014c} *)
- ELSE
- CodeGen.EmitWord((tail - lo) * 2 + 1); (*{014f-0156} *)
- END;
- INC(lo); (*{0158-015a} *)
- IF head = NIL THEN END; (*{015b-015d} loop to 013c while head#NIL *)
- END;
- IF Scanner.AcceptSy(10) THEN (*{015f-0160} ELSE *)
- WHILE NOT ParseStatSeqLoop(BITSET{13}) DO END; (*{0164-0168} *)
- END;
- Scanner.GetSym; (*{0187} consume END *)
- IF 8 IN Scanner.scanOpt THEN (*{016c-0170} range-check variant epilogue *)
- CodeGen.QueueConst(13); (*{0172-0173} *)
- CodeGen.QueueConst(0); (*{0175-0176} *)
- CodeGen.QueueConst(0); (*{0178-0179} *)
- CodeGen.EmitStandardOp(14); (*{017b-017c} *)
- END;
- IF tail # NIL THEN (*{017e-0180} *)
- endFix := CodeGen.InsertFixup(topFix, FALSE); (*{0182-0186} *)
- END;
- END ParseCaseStmt;
- (* proc6 @018b, STMT case 125 — ParseFor. Control var, `:=` lower TO
- upper [BY const] DO body END. Largest frame (4 desc buffers). *)
- PROCEDURE ParseFor;
- VAR ctrl: ADDRESS;
- loD: ADDRESS;
- hiD: ADDRESS;
- tmpD: ADDRESS;
- step: CARDINAL;
- cflag: CARDINAL;
- isInt: CARDINAL;
- dummy: CARDINAL;
- sub: CARDINAL;
- topMark: CARDINAL;
- fixA: ADDRESS;
- markB: CARDINAL;
- BEGIN
- {/* 018b */}
- Scanner.Allocate(ctrl, 10); (*{018d-018f} FIXME: group wrote ReserveWords *)
- Scanner.Allocate(loD, 10); (*{0190-0192} *)
- Scanner.Allocate(hiD, 10); (*{0193-0195} *)
- Scanner.Allocate(tmpD, 10); (*{0196-0198} *)
- Express.EvalConstExpr; (*{0199} control var head *)
- Express.MatchOpClass(7, 28); (*{019c-019f} *)
- IF Express.curDesc.raw[0] = Compiler.ByteType THEN (*{01a1-01a7} *)
- Express.MatchOpClass(5, 28); (*{01aa-01ad} *)
- END;
- Express.CentralError(NOT (12 IN Words(Express.curDesc.raw[0])^[4]), 24); (*{01af-01b7} FIXME: pun *)
- MOVE(Express.curDesc, ctrl, 10); (*{01b9-01bd} FIXME: group wrote MoveWords *)
- sub := ORD(Words(Express.curDesc.raw[0])^[4] = 4); (*{01be-01c3} FIXME *)
- IF sub # 0 THEN (*{01c4-01c5} rotate saved descs *)
- MOVE(ctrl, tmpD, 10); (*{01c7-01cb} FIXME: direction TBD by diff *)
- Express.PushExprDesc(ctrl, tmpD); (*{01cb-01ce} FIXME: arity/shape *)
- MOVE(tmpD, ctrl, 10);
- END;
- Express.EmitOp; (*{01d0} proc6 *)
- isInt := ORD(Express.curDesc.raw[0] = Compiler.IntType); (*{01d2-01d8} FIXME *)
- Scanner.ExpectSy(27); (*{01d9-01db} `:=` *)
- Express.BoolCondHelper; (*{01dd} lower bound *)
- Express.ConstToCard(Words(ctrl)^[0], 27); (*{01df-01e5} FIXME: ctrlDescTyp *)
- MOVE(Express.curDesc, loD, 10); (*{01e5-01e9} *)
- Express.PopExprDesc(ctrl); (*{01ea-01eb} FIXME: ADDRESS arg *)
- Scanner.ExpectSy(42); (*{01ed-01ef} TO *)
- Express.BoolCondHelper; (*{01f1} upper bound *)
- Express.ConstToCard(Words(ctrl)^[0], 42); (*{01f3-01f7} *)
- MOVE(Express.curDesc, hiD, 10); (*{01f9-01fd} *)
- step := 1; (*{01fe-01ff} *)
- IF Scanner.AcceptSy(29) THEN (*{0200-0204} BY *)
- Express.GetConstVal; (*{0206} proc13 *)
- Express.ConstToCard(Compiler.IntType, 29); (*{0208-020c} *)
- step := Express.curDesc.raw[2]; (*{020e-0211} const step *)
- END;
- (*{0212-0269} bound/step validation + counter init (const-fold vs runtime
- paths); faithful to raw, minutiae FIXME *)
- IF sub # 0 THEN (*{02e4-02e5} subrange control: normalize *)
- Express.NormalizeOperand; (*{02e7-02e8} FIXME: group passed tmpD *)
- Express.PushOperand(ctrl); (*{02ea-02eb} FIXME: 1-arg vs 0-arg FORWARD *)
- CodeGen.SetPendingOp(5, 2, 0, 0); (*{02ed-02f1} *)
- END;
- WHILE NOT ParseStatSeqLoop(BITSET{13}) DO END; (*{02f3-02f7} body to END *)
- Scanner.GetSym; (*{02f9} consume END *)
- (*{02fb-033d} loop-back + fixup close-out FIXME *)
- Scanner.GetSym;
- END ParseFor;
- (* proc7 @0341, STMT case 127 — ParseWhile. WHILE cond DO body END. *)
- PROCEDURE ParseWhile;
- VAR top: CARDINAL;
- fix: ADDRESS;
- endMark: CARDINAL;
- BEGIN
- top := CodeGen.MarkCodePos(13); (*{0343-0347} *)
- Express.BoolCondHelper; (*{0348} *)
- Express.ConstToCard(Compiler.BooleanType, 37); (*{034a-034e} *)
- Scanner.ExpectSy(30); (*{0350-0352} DO *)
- CodeGen.EmitStandardOp(16); (*{0354-0356} jump-if-false *)
- CodeGen.OpenFixup(fix, TRUE); (*{0358-035b} *)
- WHILE NOT ParseStatSeqLoop(BITSET{13}) DO END; (*{035d-0361} body to END *)
- Scanner.GetSym; (*{0363} consume END *)
- CodeGen.EmitStandardOp(15); (*{0365-0366} jump back to top *)
- endMark := CodeGen.nextEmitPos; (*{0368-036a} *)
- CodeGen.CloseFixup(top, TRUE); (*{036b-036d} *)
- IF NOT CodeGen.InsertFixup(fix, TRUE) THEN (*{036f-0374} *)
- CodeGen.AdjustFixup(endMark + 1); (*{0376-0378} *)
- END;
- END ParseWhile;
- (* proc8 @037c, STMT case 126 — ParseRepeat. REPEAT body UNTIL cond. *)
- PROCEDURE ParseRepeat;
- VAR top: CARDINAL;
- BEGIN
- top := CodeGen.MarkCodePos(12); (*{037e-0382} *)
- WHILE NOT ParseStatSeqLoop(BITSET{12}) DO END; (*{0383-0387} to UNTIL *)
- Scanner.GetSym; (*{0389} consume UNTIL *)
- Express.BoolCondHelper; (*{038b} *)
- Express.ConstToCard(Compiler.BooleanType, 12); (*{038d-0392} *)
- CodeGen.EmitStandardOp(16); (*{0392-0394} jump-if-false to top *)
- CodeGen.CloseFixup(top, TRUE); (*{0396-0398} *)
- END ParseRepeat;
- (* proc9 @039c, STMT case 124 — ParseIf. IF cond THEN stats
- [ELSIF cond THEN stats]... [ELSE stats] END. ELSIF via recursion. *)
- PROCEDURE ParseIf;
- VAR elseFix: ADDRESS;
- endFix: ADDRESS;
- savedEmit: CARDINAL;
- constCond: BOOLEAN;
- chained: CARDINAL;
- skipGen: CARDINAL;
- BEGIN
- Express.BoolCondHelper; (*{039e} *)
- Express.ConstToCard(Compiler.BooleanType, 34); (*{03a0-03a4} *)
- savedEmit := ORD(CodeGen.emitEnabled); (*{03a6-03a8} FIXME: BOOLEAN pun *)
- skipGen := 0; (*{03a9-03aa} *)
- constCond := (Express.curDesc.raw[1] = 0); (*{03ab-03af} mode=const *)
- IF constCond THEN (*{03b0-03b1} *)
- CodeGen.DiscardPending; (*{03b3} *)
- skipGen := 2; (*{03b5-03b6} *)
- IF Express.curDesc.raw[2] = 0 THEN (*{03b7-03bb} *)
- ELSE
- skipGen := 1; (*{03bd-03be} *)
- END;
- CodeGen.emitEnabled := FALSE; (*{03bf-03c0} suppress dead arm *)
- END;
- Scanner.ExpectSy(35); (*{03c2-03c4} THEN *)
- IF NOT constCond THEN (*{03c6-03c8} *)
- CodeGen.EmitStandardOp(16); (*{03ca-03cc} jump-if-false *)
- CodeGen.OpenFixup(elseFix, TRUE); (*{03ce-03d1} *)
- END;
- WHILE NOT ParseStatSeqLoop(BITSET{10,11,13}) DO END; (*{03d3-03d7} *)
- IF Scanner.AcceptSy(13) THEN (*{03d9-03dc} END: done *)
- IF NOT constCond THEN (*{03de-03e0} *)
- chained := ORD(CodeGen.InsertFixup(elseFix, TRUE)); (*{03e2-03e6} FIXME pun *)
- END;
- END;
- IF NOT constCond THEN (*{03e9-03eb} *)
- CodeGen.EmitStandardOp(15); (*{03ed-03ee} jump over else *)
- CodeGen.OpenFixup(endFix, TRUE); (*{03f0-03f3} *)
- IF NOT CodeGen.InsertFixup(elseFix, TRUE) THEN (*{03f5-03fa} *)
- INC(endFix); (*{03fc-03fe} FIXME: ADDRESS pun *)
- END;
- END;
- CodeGen.emitEnabled := savedEmit # 0; (*{0400-0405} FIXME: exact condition TBD *)
- IF Scanner.AcceptSy(11) THEN (*{0407-040a} ELSIF: nested IF *)
- ParseIf(); (*{040c} recursion *)
- ELSE
- Scanner.GetSym; (*{040f} consume ELSE *)
- WHILE NOT ParseStatSeqLoop(BITSET{13}) DO END; (*{0411-0415} else stats *)
- Scanner.GetSym; (*{0417} consume END *)
- END;
- IF NOT constCond THEN (*{0419-041a} InsertFixup(endFix, TRUE), result dropped *)
- END;
- CodeGen.emitEnabled := savedEmit # 0; (*{0426-0427} tail *)
- END ParseIf;
- (* proc10 @042b, STMT case 121 — ParseLoop. LOOP body END with EXIT support. *)
- PROCEDURE ParseLoop;
- VAR savedExit: CARDINAL;
- fix: ADDRESS;
- top: CARDINAL;
- endFix: CARDINAL;
- BEGIN
- savedExit := exitDepth; (*{042d-042e} *)
- INC(nestDepth); (*{042f-0431} *)
- exitDepth := nestDepth; (*{0432-0433} *)
- CodeGen.EmitStandardOp(21); (*{0434-0436} loop-head marker *)
- CodeGen.OpenFixup(fix, FALSE); (*{0438-043b} *)
- top := CodeGen.MarkCodePos(11); (*{043d-0441} *)
- WHILE NOT ParseStatSeqLoop(BITSET{13}) DO END; (*{0442-0446} body to END *)
- Scanner.GetSym; (*{0448} consume END *)
- CodeGen.EmitStandardOp(15); (*{044a-044b} jump back *)
- CodeGen.CloseFixup(top, TRUE); (*{044d-044f} *)
- endFix := ORD(CodeGen.InsertFixup(fix, FALSE)); (*{0451-0455} FIXME pun *)
- DEC(nestDepth); (*{0456-0458} *)
- exitDepth := savedExit; (*{0459-045a} *)
- END ParseLoop;
- (* proc11 @045d, STMT case 122 — ParseExit. Unwind to enclosing LOOP. *)
- PROCEDURE ParseExit;
- VAR level: CARDINAL;
- BEGIN
- Express.CentralError(exitDepth # 0, 26); (*{045f-0463} *)
- level := nestDepth; (*{0465-0466} *)
- WHILE level > exitDepth DO (*{0467-046a} *)
- CodeGen.EmitStandardOp(23); (*{046c-046e} unwind one level *)
- DEC(level); (*{0470-0472} *)
- END;
- CodeGen.EmitStandardOp(20); (*{0475-0477} jump out *)
- END ParseExit;
- (* proc12 @047b, STMT case 123 — ParseResult. RESULT expr: store value
- to function result slot; no exit jump. *)
- PROCEDURE ParseResult;
- VAR size: CARDINAL;
- desc: ADDRESS;
- BEGIN
- Express.CentralError((Words(curBlockNode)^[4] = 5) AND (Express.spillFlag # 0), 27); (*{047d-0488} *)
- Express.CheckAndStore(desc); (*{0491-0493} FIXME: 0-arg FORWARD *)
- Express.BoolCondHelper; (*{0496} result value *)
- Express.ConstToInt(desc, 33); (*{0498-049b} FIXME: ADDRESS arg *)
- Express.PopExprDesc(desc); (*{049d-049e} FIXME: ADDRESS arg *)
- IF withPending # 0 THEN (*{04a0-04a1} *)
- Express.PushOperand(withDesc); (*{04a3-04a4} FIXME arity *)
- CodeGen.EmitStandardOp(25); (*{04a6-04a8} *)
- END;
- size := 0; (*{04aa-04ab} *)
- IF desc # NIL THEN (*{04ac-04ae} *)
- size := (Words(desc)^[3] + 1) DIV 2; (*{04b0-04b5} *)
- END;
- CodeGen.EmitMiscOp(size, (*{04b6} staged *)
- CalcMemOffset() + ORD(Express.spillFlag = 1) * 128); (*{04b7-04bf} *)
- END ParseResult;
- (* proc13 @04c3, STMT case 128 — ParseWith. WITH rec DO body END. *)
- PROCEDURE ParseWith;
- VAR saved: ADDRESS;
- BEGIN
- Express.ParseDesignatorTail; (*{04c5} *)
- saved := Express.curDesc.raw[0]; (*{04c7-04c9} FIXME: typ pun *)
- Express.MatchOpClass(1024, 38); (*{04ca-04cf} *)
- IF Words(saved)^[4] IN BITSET{2,3,5} THEN (*{04d1-04de} FIXME set TBD *)
- Scanner.OpenScop(SymTab.currentScope, Words(saved)^[0]); (*{04d9-04dd} FIXME *)
- END;
- IF Words(Express.curDesc.raw[0])^[0] # Compiler.CardType THEN (*{04e0-04e8} FIXME *)
- Express.PushOperand(ADR(Express.curDesc)); (*{04e0-04e2} FIXME arity *)
- Express.PopExprDesc(ADR(Express.curDesc)); (*{04ea-04ec} FIXME *)
- END;
- MOVE(Words(SymTab.currentScope)^[2], ADR(Express.curDesc), 10); (*{04ee-04f5} FIXME *)
- Scanner.ExpectSy(30); (*{04f6-04f8} DO *)
- WHILE NOT ParseStatSeqLoop(BITSET{13}) DO END; (*{04fa-04fe} body to END *)
- SymTab.currentScope := Words(SymTab.currentScope)^[0]; (*{0500-0503} FIXME pun *)
- Scanner.GetSym; (*{0505} consume END *)
- END ParseWith;
- (* proc14 @0509, STMT case 129 — ParseReturn. RETURN [value]: routine
- exit epilogue with optional value. *)
- PROCEDURE ParseReturn;
- VAR info: CARDINAL;
- BEGIN
- Scanner.PushWith; (*{050b} *)
- IF caseActive = 0 THEN (*{050d-050f} *)
- Scanner.ExpectKd(2); (*{0511-0512} *)
- END;
- IF Scanner.identKd = 2 THEN (*{0514-0518} function context *)
- IF 1 IN Scanner.follSet THEN (*{051a-051e} *)
- info := Words(Scanner.curNode)^[6] + 2; (*{0520-0525} *)
- ELSE
- info := ORD(1 IN Scanner.follSet) - ORD(6 IN Scanner.follSet); (*{0528-052e} *)
- END;
- CodeGen.QueueConst(Words(Scanner.curNode)^[5] + info * 256); (*{052f-0536} *)
- Scanner.GetSym; (*{0538} *)
- IF Scanner.AcceptSy(1) THEN (*{053a-053d} `,` before value *)
- Express.BoolCondHelper; (*{053f} *)
- Express.ParseSelector(FALSE, Compiler.charArrayDesc, NIL); (*{0541-0546} FIXME: 39 dropped *)
- ELSE
- CodeGen.QueueConst(0); (*{054b-054c} *)
- CodeGen.QueueConst(0); (*{054e-054f} *)
- END;
- ELSE
- CodeGen.QueueConst(0); (*{0553-0554} *)
- CodeGen.QueueConst(0); (*{0556-0557} *)
- CodeGen.QueueConst(0); (*{0559-055a} *)
- END;
- CodeGen.EmitStandardOp(14); (*{055c-055d} *)
- END ParseReturn;
- (* STATEMEN group 2 — STMT/STATSE/tails/BODY + internals *)
- PROCEDURE NextSymWrap;
- (* ~proc1: no head, no call site in statement.txt; GetSym wrapper by name *)
- BEGIN
- Scanner.GetSym;
- END NextSymWrap;
- PROCEDURE ParseStatSeqLoop(stop: BITSET): BOOLEAN;
- (* ~proc4: every driver is REPEAT proc4(set) UNTIL TRUE with empty body,
- so proc4 parses ONE step; 14 pre-emption for nested CASE. *)
- BEGIN
- IF Scanner.curSym IN stop THEN RETURN TRUE END;
- IF Scanner.curSym = 14 THEN (* CaseSym FIXME *)
- ParseCaseTail;
- ELSE
- ParseStatement;
- END;
- RETURN Scanner.curSym IN stop;
- END ParseStatSeqLoop;
- PROCEDURE EmitJumpFixup;
- (* ~proc15: sole real site STATSE after mark-save, before THEN-expect. *)
- BEGIN
- CodeGen.DiscardPending;
- END EmitJumpFixup;
- PROCEDURE ParseStatement; (* STMT @0566 *)
- VAR
- kw: CARDINAL;
- saveSpill: CARDINAL;
- saveNest: CARDINAL;
- saveLoop: CARDINAL;
- saveScope: ADDRESS;
- BEGIN
- saveSpill := Express.spillTop; (*{0568} FIXME: group wrote spillTop; word3 spill save *)
- saveNest := nestDepth; (*{056b} *)
- saveLoop := exitDepth; (*{056d} FIXME: group wrote loopExitMark *)
- saveScope := SymTab.currentScope; (*{056f} FIXME: ADDRESS pun *)
- IF Scanner.curSym = 0 THEN GOTO identLed END; (*{0572} *)
- IF Scanner.curSym IN BITSET{8..14} THEN GOTO done END; (*{0577} *)
- Express.CentralError((121 <= Scanner.curSym) AND (Scanner.curSym <= 130), 20); (*{0580} *)
- kw := Scanner.curSym; (*{058c} *)
- Scanner.GetSym; (*{058f} *)
- CASE kw OF (*{0591-05a6} default (125) -> ParseFor *)
- 121: ParseLoop
- | 122: ParseExit
- | 123: ParseResult
- | 124: ParseIf
- | 126: ParseRepeat
- | 127: ParseWhile
- | 128: ParseWith
- | 129: ParseReturn
- | 130: ParseCaseStmt
- ELSE ParseFor (* 125 *)
- END;
- GOTO done;
- identLed:
- Scanner.PushWith; (*{05c4} *)
- IF Scanner.identKd = 4 THEN (*{05c6} proc call *)
- Express.ParseDesignatorTail; (*{05cc} *)
- IF Scanner.AcceptSy(43) THEN (*{05d0} '(' *)
- Express.MatchOpClass(512, 43); (*{05d9} *)
- Express.CentralError(Express.curDesc.raw[2] = 0, 61); (*{05db} FIXME: scratch2 TBD *)
- Express.StoreOperand; (* proc19 *) (*{05e9?} *)
- ELSE
- Scanner.ExpectSy(27); (*{05e9} ':=' *)
- Express.ParseAssignment; (*{05f2?} FIXME: group wrote ParseAssignRhs=proc17 *)
- END;
- ELSIF Scanner.identKd = 5 THEN (*{05f2} *)
- Express.CentralError(Scanner.litType = NIL, 61); (*{05f8} FIXME: pun *)
- Express.LoadOperand; (* proc18 *) (*{05e9?} *)
- ELSIF Scanner.identKd = 0 THEN (*{0604} *)
- Errors.ReportErrorWithText(128, Scanner.tokBuf); (*{0609} *)
- ELSE
- Errors.ReportError(21); (*{0612} *)
- END;
- done:
- Express.spillTop := saveSpill; (*{0616} *)
- (* 061a unwind path (exceptions only): restores exitDepth/currentScope, RAISE *)
- END ParseStatement;
- PROCEDURE GuardedStatSeq(follow: BITSET): BOOLEAN; (* STATSE @0634 *)
- VAR
- saveOpts: BITSET;
- savePos: CARDINAL;
- mark: ADDRESS;
- saveCode: CARDINAL;
- savePool: CARDINAL;
- BEGIN
- saveOpts := Scanner.scanOpt; (*{0636} *)
- savePos := Scanner.tokPos; (*{0639} FIXME: group wrote word25 *)
- Scanner.GetStack(mark); (*{063d} *)
- saveCode := CodeGen.nextEmitPos; (*{0641} *)
- savePool := SymTab.stringPoolPtr; (*{0644} *)
- EmitJumpFixup; (* ~proc15 *) (*{0647} *)
- Scanner.TestSet(follow + BITSET{9}); (*{0648} entry assert *)
- IF Scanner.AcceptSy(9) THEN (* guarded-seq introducer *)
- REPEAT UNTIL ParseStatSeqLoop(follow) END; (*{0654} *)
- END;
- RETURN TRUE;
- (* 065b error-recovery exit: restore scanOptions/tokenPos/mark/codepos/pool,
- Errors.RollbackToMark, CodeGen.OpenEmitter, RETURN FALSE *)
- END GuardedStatSeq;
- PROCEDURE ParseCaseTail; (* proc16 @0683, called only from BODY via ed *)
- VAR
- tab, cnt: CARDINAL;
- step: CARDINAL;
- fix1, elseSeen: CARDINAL;
- fix2: CARDINAL;
- labelAddr: ADDRESS;
- BEGIN
- caseActive := 1; (*{0685} *)
- cnt := 0; (*{0687} *)
- tab := 0; (*{0689} *)
- IF NOT (Scanner.curSym IN BITSET{8,10,13}) THEN (*{068b} *)
- fix1 := CodeGen.MarkCodePos(15); (*{0694} *)
- Scanner.PushWith; (*{0699} *)
- Scanner.ExpectKd(2); (*{069b} *)
- LOOP
- Scanner.Allocate(labelAddr, 6); (*{06a0} FIXME: operand slots TBD *)
- IF 1 IN Scanner.follSet THEN (* const-label class *)
- step := Words(Scanner.curNode)^[0] + 2; (*{06a5?} FIXME *)
- ELSE
- step := 1 - ORD(6 IN Scanner.follSet);
- END;
- WHILE tab <> 0 DO
- Express.CentralError(Words(tab)^[1] = Words(tab)^[1], 47); (*{06cd} FIXME: dup-label slots TBD *)
- tab := Words(tab)^[0]; (* advance FIXME *)
- END;
- INC(cnt);
- Scanner.GetSym;
- Scanner.TestSet(BITSET{1,2}); (*{06e0} *)
- IF NOT Scanner.AcceptSy(1) THEN EXIT END; (*{06e3} *)
- END;
- Scanner.GetSym;
- REPEAT UNTIL ParseStatSeqLoop(BITSET{8,10,13}) END; (*{06eb} arm seq *)
- SyncToStatStart; (* ~proc3 *)
- END;
- IF NOT Scanner.AcceptSy(8) THEN GOTO noMoreArms END; (*{06f2} '|' *)
- GOTO caseLoop; (* back to {068b} FIXME: restructure to LOOP *)
- noMoreArms:
- elseSeen := ORD(Scanner.AcceptSy(10)); (*{06f8} ELSE FIXME pun *)
- IF elseSeen # 0 THEN
- INC(cnt);
- fix1 := CodeGen.MarkCodePos(15);
- REPEAT UNTIL ParseStatSeqLoop(BITSET{13,14}) END; (*{06fb} FIXME set TBD *)
- SyncToStatStart;
- END;
- fix2 := CodeGen.InsertFixup(Scanner.codeSize - 2, FALSE); (*{070e} FIXME: word22 TBD *)
- CodeGen.Emit1(cnt);
- WHILE tab <> 0 DO
- CodeGen.EmitWord(tab);
- CodeGen.CloseFixup(tab, FALSE);
- tab := Words(tab)^[0]; (* advance FIXME *)
- END;
- IF elseSeen # 0 THEN
- CodeGen.EmitWord(0);
- CodeGen.CloseFixup(fix1, FALSE);
- END;
- END ParseCaseTail;
- PROCEDURE CloseBlockChain(VAR node: ADDRESS); (* proc17 @0738, display-call *)
- VAR isFirst: BOOLEAN; desc: CARDINAL;
- BEGIN
- WHILE node # NIL DO (*{073a} *)
- IF NOT (0 IN Words(node)^[3]) THEN GOTO advance END; (*{073e} FIXME pun *)
- IF 5 IN Words(node)^[3] THEN (*{0745} *)
- Scanner.FindIden(SymTab.currentScope, node, 9 IN Scanner.scanOpt); (*{074b} FIXME: group wrote Proc22 6-push id-check; arity TBD *)
- IF Scanner.FindIden(SymTab.currentScope, node, 9 IN Scanner.scanOpt) = node THEN
- Errors.ReportErrorWithText(128, Scanner.tokBuf); (*{0758} FIXME: raw (5, node, s1, 128) *)
- END;
- GOTO advance;
- END;
- IF Words(node)^[4] = 4 THEN (*{0765} *)
- IF (Words(node)^[3] - BITSET{3} = BITSET{}) THEN (*{076b} FIXME: s4 > 9 conjunct TBD *)
- CloseBlockChain(node); (*{077e} recurse FIXME: node^^ *)
- IF Express.spillFlag <> 0 THEN (*{0780} *)
- needEpilogue := 1;
- desc := Express.curDesc.raw[0]; (*{079c?} FIXME *)
- Express.LoadIndirect; (* proc11 *)
- IF 3 IN Words(node)^[3] THEN (*{079c} *)
- Express.NormalizeOperand; (* proc10 *)
- IF Express.spillFlag = 1 THEN CodeGen.EmitMiscOp(5, 23)
- ELSE CodeGen.EmitStandardOp(10) END;
- ELSE CodeGen.EmitStandardOp(9) END;
- Express.PopOperand; (* proc3 *)
- END;
- RETURN;
- END;
- GOTO advance;
- END;
- IF Words(node)^[4] = 6 THEN (*{07c7} *)
- isFirst := NOT exitEmitted;
- exitEmitted := 1;
- CloseBlockChain(node); (* FIXME: node^ pun *)
- IF Words(node)^[5] # NIL THEN
- needEpilogue := 1;
- CodeGen.EmitStandardOp(15);
- CodeGen.CloseFixup(Words(node)^[2], FALSE);
- IF NOT CodeGen.InsertFixup(Words(node)^[5], FALSE) THEN END;
- END;
- IF isFirst THEN CodeGen.EmitSystemCall(24) END;
- RETURN;
- END;
- advance:
- node := Words(node)^[0]; (*{07f7} FIXME: next link via scratch; pun *)
- END;
- IF exitEmitted = 0 THEN CodeGen.EmitSystemCall(24) END; (*{07fc} *)
- END CloseBlockChain;
- PROCEDURE EmitNameHash(VAR name: ARRAY OF CHAR); (* proc18 @0808 FIXME: 2nd param HIGH=128 *)
- VAR h, m3, acc: CARDINAL; chunk, i: CARDINAL; c: CARDINAL;
- BEGIN
- acc := 0; chunk := 0;
- REPEAT
- h := 0; m3 := 0; c := 0; i := 1; (*{080a-0812} *)
- WHILE h <> 37 DO
- c := ORD(name[chunk + m3]);
- IF c = 0C THEN h := 37;
- ELSIF c <= ORD("9") THEN h := c - 22C; (* FIXME: exact bounds TBD *)
- ELSE h := c - ORD("A") - ORD(NOT ODD((c AND 64) DIV 2)); (* case-fold FIXME *)
- END;
- END;
- acc := acc + h * i;
- i := i * 38; INC(m3);
- IF m3 <= 2 THEN (* redo *) END;
- CodeGen.EmitWord(acc);
- chunk := chunk + 3;
- UNTIL chunk > 3;
- END EmitNameHash;
- PROCEDURE EmitComBytes; (* proc19 @0863, display-call reading BODY locals *)
- VAR f: CARDINAL; n: CARDINAL; saveHeap: ADDRESS;
- BEGIN
- MARK(saveHeap);
- CodeGen.EmitMiscOp(3, ORD(Express.spillFlag = 1));
- Files.FindFileOnDrives(f, Scanner.tokBuf, "COM"); (*{0863?} FIXME: raw (addr-2, buf, 128) *)
- n := 0;
- REPEAT
- CodeGen.Emit1(0); (* FIXME: bodyL5 byte; Files.FileProc09 TBD *)
- INC(n);
- UNTIL n = 0; (* FIXME: bodyL3 count TBD *)
- RELEASE(saveHeap);
- END EmitComBytes;
- PROCEDURE ParseBeginBlock(tag: CARDINAL); (* BODY @08a4 *)
- VAR
- nonEmpty, wasVar: CARDINAL;
- fix: CARDINAL;
- s2, s5: CARDINAL;
- BEGIN
- curBlockNode := tag; (*{08a6} *)
- Express.spillTop := SymTab.stringPoolPtr; (*{08a8} FIXME: group wrote spillTop *)
- nestDepth := 0; exitDepth := 0;
- Scanner.listing := TRUE; (*{08b8?} FIXME: group wrote word23 *)
- caseActive := 0; exitEmitted := 0;
- Scanner.codeSize := CodeGen.nextEmitPos; (*{08b8} FIXME: group wrote word22 *)
- wasVar := ORD(Scanner.identKd = 5); (*{08bd} *)
- nonEmpty := ORD(Scanner.curSym = 23); (*{08c2} body-lead FIXME *)
- IF nonEmpty # 0 THEN
- Scanner.GetSym;
- WHILE NOT Scanner.AcceptSy(9) DO Scanner.GetSym END; (*{08cd} skip past BEGIN *)
- nonEmpty := ORD(Scanner.curSym <> 13);
- END;
- needEpilogue := nonEmpty; (*{08d8} *)
- IF (Words(curBlockNode)^[4] = 5) AND (Express.spillFlag = 0) THEN (*{08da} *)
- CodeGen.EmitExtCall3(3, curBlockNode, CalcMemOffset()); (*{08e0} FIXME: 3rd arg BYTEAt TBD *)
- IF Compiler.rangeCheckEnabled THEN CodeGen.OpenFixup(fix, TRUE) END; (*{08ea} *)
- IF 15 IN Scanner.scanOpt THEN CodeGen.Emit1(255) (*{08f3} *)
- ELSE
- EmitNameHash(Scanner.tokBuf); (*{08ff} FIXME: raw (g6, s1, 128) *)
- CodeGen.EmitWord(0);
- END;
- Scanner.codeSize := CodeGen.nextEmitPos; (*{0908} FIXME *)
- IF wasVar # 0 THEN
- Scanner.GetSym;
- Scanner.ExpectSy(43); (*{0912} '(' *)
- Express.CentralError(Scanner.isLit AND (Scanner.litType = Compiler.CharType), 33); (*{0916} *)
- EmitComBytes; (* nested proc19 *)
- Scanner.GetSym;
- Scanner.ExpectSy(5); (*{0927} ')' *)
- fix := ORD(Scanner.AcceptSy(9)); (*{092b} FIXME pun *)
- ELSE
- CodeGen.EmitStandardOp(22);
- CodeGen.Emit1(255);
- IF (Express.spillFlag <> 0) AND (withPending # 0) THEN (*{0938} FIXME: group wrote spare3 *)
- Express.PushExprDesc(withDesc, Compiler.BitsetType); (*{0938?} FIXME: operand slots TBD *)
- CodeGen.EmitStandardOp(24);
- Express.PopOperand;
- END;
- CloseBlockChain(SymTab.currentScope); (*{094c} FIXME: ADDRESS pun *)
- IF nonEmpty # 0 THEN REPEAT UNTIL ParseStatSeqLoop(BITSET{13,14}) END END; (*{0951} *)
- SyncToStatStart;
- IF Scanner.AcceptSy(14) THEN ParseCaseTail END; (*{095c} *)
- IF Express.spillFlag <> 0 THEN (*{0962} *)
- CodeGen.PokeCodeByte(SymTab.stringPoolPtr - 255, Scanner.codeSize + 1); (* FIXME *)
- END;
- END;
- ELSE
- CodeGen.EmitSystemCall(4); (*{0974} *)
- IF Compiler.rangeCheckEnabled THEN CodeGen.OpenFixup(fix, FALSE) END; (*{0978} *)
- Scanner.codeSize := CodeGen.nextEmitPos; (* FIXME *)
- CloseBlockChain(SymTab.currentScope); (* FIXME pun *)
- IF nonEmpty # 0 THEN REPEAT UNTIL ParseStatSeqLoop(BITSET{13}) END END; (*{098b} *)
- IF needEpilogue # 0 THEN (*{0994} *)
- CodeGen.EmitStandardOp(15);
- s5 := CodeGen.nextEmitPos; CodeGen.EmitWord(0); (* FIXME *)
- s2 := Scanner.codeSize; (* FIXME *)
- ELSE
- s5 := 0;
- END;
- END;
- IF Compiler.rangeCheckEnabled THEN fix := ORD(CodeGen.InsertFixup(fix, FALSE)) END; (*{09ab} FIXME pun *)
- Scanner.listing := FALSE; (* FIXME: group wrote word23 *)
- Scanner.ExpectSy(13); (*{09b8} END *)
- Scanner.ExpectSt(Scanner.tokBuf); (*{09bb} FIXME: group wrote Proc21; END-name match TBD *)
- IF (Words(curBlockNode)^[4] = 5) AND (Express.spillFlag = 0) THEN (*{09c2} *)
- Scanner.TestSet(BITSET{3}); (* '.' module end *)
- ELSE
- Scanner.TestSet(BITSET{9});
- END;
- IF (NOT Compiler.rangeCheckEnabled) AND (0 IN Scanner.scanOpt) THEN (*{09d7} *)
- Texts.WriteString(3, "----- Size = "); (* FIXME: Texts.proc09 idiom *)
- Texts.WriteCard(3, CodeGen.nextEmitPos - Scanner.codeSize, 0); (* FIXME: Texts.proc11 *)
- END;
- IF 4 IN Scanner.scanOpt THEN (*{0a02} *)
- Loader.Call("PRINTCOD"); (* FIXME: +CARDINAL 7 *)
- END;
- END ParseBeginBlock;
- BEGIN (* proc0 @0a25 module init *)
- END Statemen.
|