Complete the parser's pass-2 emission path for byte procedural code: numeric
and char expressions, assignments, comparisons, if/else, while, for,
return, print, self.field, and concrete self calls. Each method stores
its incoming self before any statement, and a program body's offset is
recorded so a fixture can execute it after class methods. Emitter failures
become a stable diagnostic.
src/compiler/emit.s, src/common/emit.incsrc/compiler/flow.s, src/common/flow.incsrc/compiler/parser.s (pass-2 hooks and long-branch dispatch)src/compiler/codegen.s (cg_cmp_zp)src/common/diagcat.inc (E227)tests/compiler/statements.n8, tests/compiler/statements-test.stests/compiler/calls.n8, tests/compiler/calls-test.sscripts/build-statements-test.ps1, scripts/verify-statements-test.ps1scripts/build-calls-test.ps1, scripts/verify-calls-test.ps1flow.s, members.s, and
emit.s where needed)docs/decisions.md, docs/architecture.md, docs/memory-map.mdcodegen.s/flow.s:
assignment, byte +/-, comparisons, if/else, while, for,
return, and print. Byte control-flow fixture executes in x128.EM_TMP combines it, parameters use FP+2, and locals use FP-1.
Concrete calls use the existing zero-byte discard path; argument pushing
is not emitted in this claim.self.field loads/stores the parser's field offset through members.s.
Forward zero-argument calls through self emit a stable method label and
direct JSR; self is stored at method entry.em_bad and become E_RES_EMIT_FAILED (E227)
after pass 2. A failed emit writes no output file.calls.n8 leaves Counter.n = 2 after both() and a forward tick().return is emitted, including an explicit return in the called
method.a=10, b=7, recorded
SUM 0D FF 0A 0D.flow.s: labels grew to 64 and fixups
to 128. fl_release is intentionally a no-op because releasing a label can
strand unresolved fixups; closed-block labels therefore remain allocated
until the pass ends.if/else, while, positive-step for
with a constant byte end, and return. The fixture's for a = 1 to 1
leaves a = 2, which is the documented one-past-end behavior.mb_self_store at method
entry, self.field loads/stores, and zero-argument concrete self calls.
em_entry records the program body's offset so the fixture does not run a
class method by accident.E_RES_EMIT_FAILED (227) and the post-pass-2 em_bad check.calls-test initially failed because its fl_err success check jumped on a
nonzero value; corrected to jump on zero. It then passed with 53 bytes.em_ctx was set, even when em_on
was off. em_expr_name, em_expr_const, em_push_left, and em_bin now
return immediately when em_on is zero, and the parser fixture disables
emission explicitly. The 41-fixture parser suite passed afterward.verify-hello-test initially missed the PRG output because it polled screen
memory without resuming the emulator. The verifier now sends x each poll;
hello passes with the text on row 13.statements-test.s; diag_screen is
off again.statements-test then hit
the linker's indirect-JMP page assertion. Moved the three vectors to
absolute zero-page cells $C0-$C5 and reserved six BSS bytes so the existing
emitter-state layout is unchanged. The assertion and address-size warning
are gone; statements and calls both pass.a=2, b=3, no diagnostics, no recorded print.em_bad=0, cg_err=0, fl_err=0,
Counter.n=2.HELLO FROM NOVA128 displayed on row 13.$A7.for
requires a constant byte end and step 1. return is a bare RTS until the
emitted frame prologue exists. The code buffer is still 255 bytes, and E227
is reported at the end of the parse rather than at the failing source line.
The print vectors occupy $C0-$C5; anything added there must preserve their
non-$FF low bytes and the reserved six-byte BSS gap.E04-S07 owns sizing, pass-3 section addresses, emitted frame_enter, word
results, and argument push/discard, followed by the complete counter.n8
end-to-end fixture.
Powered by TurnKey Linux.