Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

5.6KB


story: E04-S06 owner: codebuff status: done started: 2026-11-09 completed: 2026-11-09 depends-on: [E04-S04, E04-S05, E05-S04, E03-S04]

E04-S06 Claim

Intended change

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.

File area

  • src/compiler/emit.s, src/common/emit.inc
  • src/compiler/flow.s, src/common/flow.inc
  • src/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.s
  • tests/compiler/calls.n8, tests/compiler/calls-test.s
  • scripts/build-statements-test.ps1, scripts/verify-statements-test.ps1
  • scripts/build-calls-test.ps1, scripts/verify-calls-test.ps1
  • parser/hello/statements build scripts (link flow.s, members.s, and emit.s where needed)
  • docs/decisions.md, docs/architecture.md, docs/memory-map.md

Acceptance evidence

  • Statements and expressions emit through codegen.s/flow.s: assignment, byte +/-, comparisons, if/else, while, for, return, and print. Byte control-flow fixture executes in x128.
  • Byte temporaries follow D129: the left operand is on the hardware stack, 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.
  • Emitter failures set em_bad and become E_RES_EMIT_FAILED (E227) after pass 2. A failed emit writes no output file.
  • A source program with statements and one concrete call executes in x128: calls.n8 leaves Counter.n = 2 after both() and a forward tick().
  • return is emitted, including an explicit return in the called method.
  • Full D129 argument emission and word results are not implemented; they remain E04-S07 work, along with arrays and the emitted frame prologue.

Work log

  • Baseline statements fixture: PASS — 138 bytes, a=10, b=7, recorded SUM 0D FF 0A 0D.
  • Added control-flow emission through 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.
  • Added comparison-flag lowering, 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.
  • Added method entry labels allocated by member row, 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.
  • Added 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.
  • Parser regression initially reported E227 for type-only fixtures because the expression helpers emitted whenever 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.
  • Removed temporary stage markers from statements-test.s; diag_screen is off again.
  • The expanded code shifted the BSS print vectors; 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.

Completion

  • Tests run: statements, calls, member, control, scalar, hello, and parser fixtures in x128. All pass with the current code.
  • Results:
    • statements: 244 bytes, a=2, b=3, no diagnostics, no recorded print.
    • calls: 53 bytes, diagnostics 0, em_bad=0, cg_err=0, fl_err=0, Counter.n=2.
    • hello: 118-byte PRG, HELLO FROM NOVA128 displayed on row 13.
    • parser: 41 fixtures, lowest expression stack pointer $A7.
  • Files changed: as listed above.
  • Remaining risks: only byte expressions and assignments emit; word values, call arguments, arrays, and method result forwarding are deferred. 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.

Next step

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.