Records the initialisation order the parser fixture establishes and the three
output paths output.s already provides, so the driver is wiring rather than new
file handling; no driver source has landed yet.
Generated with Codebuff
Co-Authored-By: Codebuff <noreply@codebuff.com>
Analysis shows the type checker already models class/interface references, so
the work is emitter-side: four-byte slots, member transfers and if_call sites.
E04-S07 becomes a dependency because argument push/discard is its work.
Generated with Codebuff
Co-Authored-By: Codebuff <noreply@codebuff.com>
E07-S05 specifies the on-machine n128c driver that prepare-disk and the
compiler launcher already expect; E06-S07 specifies emitting interface
conversions, storage and calls from source. E07-S04 now depends on both, so the
walkthrough cannot be claimed before them.
Generated with Codebuff
Co-Authored-By: Codebuff <noreply@codebuff.com>
Suites run from a manifest into fresh build directories with time limits,
captured logs, JSON results and SHA-256 comparisons; source, lexer and parser
artifacts are pinned, and self-tests cover timeout, failure signature and
changed-artifact detection.
Generated with Codebuff
Co-Authored-By: Codebuff <noreply@codebuff.com>
The editor launcher now copies the Vim disk, injects vim128.prg into the copy,
and autostarts that disk copy in x128 80-column mode; host-loaded editor
sessions reported success without writing to the image.
E07-S03 adds a C128 tokenizer fixture and a two-session test that creates a
source in Vim, reopens it, and tokenizes the disk file without host conversion.
Generated with Codebuff
Co-Authored-By: Codebuff <noreply@codebuff.com>
E06-S06 routes deletion through a fat reference to obj_delete behind the heap's
always-on validation, so a stale value is refused with IF_ERR_FREED instead of
reading a freed destructor, and adds the objects.n8 parser fixture.
E07-S02 shares one launcher implementation that locks the writable image and
waits for the emulator exit and image flush, with x64sc for the editor and x128
for the compiler.
Generated with Codebuff
Co-Authored-By: Codebuff <noreply@codebuff.com>
iface_slot reads the declaration slot assign_slots recorded, so a call site
emits an offset the class table actually has and refuses a method the interface
does not declare. The x128 fixture proves one call site reaching two classes,
one object reaching two interface tables, a nested call with a one-byte result,
and byte/word arguments returning a word with the frame stack restored, while
self stays the underlying object.
Generated with Codebuff
Co-Authored-By: Codebuff <noreply@codebuff.com>
it_find selects the table a class emitted for an interface, refusing a pair the
class does not implement, and if_assign, if_arg_push, if_elem_store, and
if_elem_load give assignment, argument passing, field, and array storage one
API that keeps all four value bytes. Two x128 fixtures prove the class and null
conversions, verbatim copies, array stride, argument layout, and the result
area, while the semantic suite still rejects an invalid conversion.
Generated with Codebuff
Co-Authored-By: Codebuff <noreply@codebuff.com>
Classes now build one table per implemented interface, in implements order with
one two-byte entry per interface slot, and a failed class rolls back so a
missing method address is refused instead of dispatching to zero. The MAP gains
one TABLE record per table, and the x128 fixture checks table contents, distinct
per-class tables, both rollback paths, and the exact MAP text.
Generated with Codebuff
Co-Authored-By: Codebuff <noreply@codebuff.com>
Give interface calls one audited entry point that resolves the slot, refuses
null/table/entry/stack faults before executing anything, and returns through a
single synthetic address so nested and recursive calls unwind.
Generated with Codebuff
Co-Authored-By: Codebuff <noreply@codebuff.com>
Freeze the four-byte fat reference, canonical null, slot/table layout,
and the IF_RESULT return area so interface dispatch and table emission can
build on one documented contract.
Generated with Codebuff
Co-Authored-By: Codebuff <noreply@codebuff.com>
Lets pass 2 resolve absolute flow targets against a final CODE base and verifies a source program through deterministic PRG/MAP output and a real x128 run. Count-mode sizing, method/class MAP records, and unresolved-reference diagnostics remain in-progress.
Adds control flow, field access, forward self calls, method/program entry tracking, and E227 emission-failure reporting. Print vectors now live in safe zero-page cells to avoid the 6502 indirect-JMP page bug.
Statement emission now runs from parser pass 2: assignment, byte + and -, and
print reach codegen.s through emit.s, and the statements fixture executes the
emitted bytes in x128. Restoring the parser trace fixture's length arithmetic
(it emitted between the two halves of the subtraction, which clears carry)
brings the 41-fixture parser verification back to green after emit.s joined
the link.
Also check in the vim clone's improved C128 build and the Power C
reverse-engineering notes and tools.
Generated with Codebuff
Co-Authored-By: Codebuff <noreply@codebuff.com>
Generated methods can now store and load fields through a zero-page receiver,
pass self to direct JSR calls, and keep byte or word results across argument
cleanup. The backlog gains the parser-to-codegen and pass-3 address assignment
stories the next backend work needs.
🤖 Generated with Codebuff
Co-Authored-By: Codebuff <noreply@codebuff.com>
Generated programs now have control-flow emission, text and fault output, a
free-list heap, class descriptors, and object construction/deletion. Each
story lands with an x128 fixture and verifier so the runtime stays proven
before the parser drives code generation.
🤖 Generated with Codebuff
Co-Authored-By: Codebuff <noreply@codebuff.com>
Emit bounded documented instructions for scalar assignments, word and integer
arithmetic, comparisons, and short-circuit booleans, with checked forward
branch fixups. Add multiply and signed/unsigned divide helpers with a stable
divide-by-zero result, plus a reviewed golden byte stream and disassembly.
Generated with Codebuff 🤖
Co-Authored-By: Codebuff <noreply@codebuff.com>
Implement transactional frame entry/leave, right-to-left arguments, one- and
two-byte returns, and guards for both the software stack and the 6502 hardware
stack. Add a recursive x128 ABI fixture covering bounded success and overflow
unwind.
Generated with Codebuff 🤖
Co-Authored-By: Codebuff <noreply@codebuff.com>
Emit a BASIC-stub PRG with ordered sections and a MAP entry/section table,
refuse existing output names, and scratch partial files on failure. Include
a runnable startup that reports through the test mailbox.
Generated with Codebuff 🤖
Co-Authored-By: Codebuff <noreply@codebuff.com>
Number interface methods in source order and check each class against every
implemented interface, reporting missing, private, mismatched, conflicting,
and non-interface implementations at the class declaration.
Generated with Codebuff 🤖
Co-Authored-By: Codebuff <noreply@codebuff.com>
Compute sizes and offsets after the declaration pass so forward references
have a kind, report E096 for instances over 65535 bytes, and record the
layout in the parser harness so declaration order is fixture-checked.
Generated with Codebuff 🤖
Co-Authored-By: Codebuff <noreply@codebuff.com>
types.s gives every expression a type and applies the spec 3.4/8
conversions, operator table, constant folding and diagnostic spellings.
parser.s records implements lists and init rows in pass 1, carries types
through member chains, groups, calls and indexing in pass 2, and checks
assignments, arguments, returns, conditions, for, print, delete and member
access. A method that declares a result must end in return; a missing one
is E150 at end, and a program return value is E151.
Three older parser fixtures gain true diagnostics. The lexer's host
reference formatter now spells bytes such as {0D} correctly, and the demo
tolerates a missing ERR file.
Verified in x128: 37 parser fixtures, 10 lexer fixtures, the 67-entry
diagnostic catalog, and the Vim-to-N8CHECK demo (good.n8 clean, bad.n8's
four diagnostics).
Generated with Codebuff 🤖
Co-Authored-By: Codebuff <noreply@codebuff.com>
parse_statement parses every spec 7 form (assignment, call, if/else,
while, for/to/step, return, print, delete) and requires the line to end
after it. Expressions use precedence climbing over spec 8's levels: binary
operators left associative, unary not and - nesting rightwards, postfix
member access, calls, and indexing tightest. A syntax error is reported in
pass 1, unwinds to the statement, and skips the line; E03-S02's name,
member, and access checks now run from the parser in pass 2, replacing the
token scan. Expression nesting is bounded at 16 levels (E225).
Verified in x128: 31 fixtures, including the two statement fixtures that
were pending since E03-S01, a postfix trace golden for precedence and
associativity (both mutations caught), every statement form, and 15
independent syntax errors with recovery. Lowest stack pointer $A7. New
diagnostics E038-E042 and E225. The demo passes; its Vim typing is slowed
to 200 ms per key after one doubled keystroke.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Pass 1 now records every field and method signature (access, type,
parameter types) in bank-1 member and parameter tables, rejects duplicate
fields or methods per type, invalid init/destroy shapes (E151/E152, D122),
and `var` after a method statement or inside a block. Each signature and the
program open a typed local scope. Pass 2 scans statement lines: unqualified
names must be locals, parameters, or fields of the enclosing class (D123),
and member chains through locals, fields, self, new, calls, and indexing
report unknown members (E061) and private access (E120) at the member.
The parser test PRG grew past $4000 and crashed: mmu_init copies the COMMON
load image in the system mapping, where BASIC ROM hides $4000+. COMMON now
loads right after STARTUP and mmu.s asserts both stay below $4000.
Verified in x128: 28 fixtures, member tables against a source-derived
oracle, privacy and scope mutations caught; map, source, lexer, names, and
diagnostics suites pass on the new layout.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
parser.s runs two passes over the cached source. Pass 1 parses interfaces,
classes (implements lists, fields, method headers), and the one program,
records top-level types in a bank-1 table, tracks method/program/if/while/
for blocks, checks duplicate locals, and reports syntax, ordering, and
duplicate errors with line-level recovery. Pass 2 reports type references
that name no declared type, so forward references are legal.
Verified in x128 against 24 fixtures through the real ERR files: 7/7
accepted, 10/12 rejected grammar fixtures at their sidecar positions
(line_cont and multi_stmt are statement-level, pending E03-S03), and five
parser fixtures matching their complete diagnostic lists. A pass-order
mutation is caught. D121 (proposed): method names may be keywords, as
spec 5.1's `method print()` requires.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
diagcat.inc is the single catalog: one line per diagnostic with a stable
number in a per-category range. Included by errors.inc it gives E_*
constants; included by diagnostics.s it gives the message table.
docs/diagnostics.md is generated from it. The build rejects out-of-range
or duplicate numbers and any grammar .expect symbol missing from it.
diagnostics.s prints a two-line, 40-column-safe screen form and appends
full lines to NAME.ERR. NAME.ERR is scratched at the start and created
only when needed. After 20 errors, E221 replaces the next one and the
caller must stop. diskio.s gains output-file and DOS-command wrappers.
Verified in x128: screen RAM rows, diag.err and limit.err read back from
the D81, stale-file scratching, an unwritable ERR name (DOS 33 -> E201
once), and no open files after any phase. A counting mutation is caught.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
names.s gives each distinct identifier a 1-byte ID (1-255), comparing
case-insensitively across both PETSCII letter ranges. The table lives in
bank 1: 64 hash-chain heads plus 20-byte records holding the original
spelling. name_declare replaces the first-use spelling with the first
declaration's spelling, so forward references keep the declared form.
A full table returns NAMES_ERR_FULL and writes nothing.
Verified in x128: the C128 dump equals a host model byte for byte across
case variants, an 8-name collision chain with an identical-hash pair, and
a 260-name overflow, with a guard after the table intact. A mutation that
skips the text compare is caught. D120 (proposed): 255-name limit.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
lexer.s turns cached source lines into tokens with stable kinds and error
codes (tokens.inc): 32 keywords, identifiers folded across both PETSCII
letter ranges, decimal/hex/binary numbers to 65535, strings and character
literals with escapes, all operators, and comments. An error reports its
exact column, then the rest of the line is skipped.
An independent host reference lexer and the C128 lexer in x128 both
reproduce the reviewed golden token files: 10 fixtures, 1,119 tokens,
including one fixture per error kind. A case-folding mutation is caught.
Spec 2.2 now lists <= and >=, matching section 8. D119 (proposed): the \n
and \r escapes both produce $0D. The monitor helper now reads RAM bank 0,
because BASIC ROM hides $4000+ after a program returns.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
src_load reads a SEQ file from device 8 once into a bank-1 cache (D118).
It enforces the 80-byte line, 599-line, and 18,999-byte limits as bytes
arrive and reports stable codes with exact positions. src_rewind and
src_next_line replay the cache one logical line at a time for every pass.
diskio.s wraps the KERNAL file calls; channels close on every path.
Verified in x128 with a 1581: eight fixtures, including the exact limits,
each limit error, a missing file (DOS 62), and a missing final $0D, all
match host-computed line counts, Fletcher-16 checksums, and positions.
Adds a shared PowerShell test library for x128 scripts.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Add cfg/compiler.cfg, the production mmu.s, c128.inc, and the test mailbox,
proven by a capacity-checking skeleton in x128:
- 8K bottom common RAM, shared code at $1300, private zero page at bank 0
page $1A via P0, bank-1 tables at $2000-$BFFF, test mailbox at $1BF0
- ld65 rejects overflows of the ZP, COMMON, MAIN, SWSTACK, and TABLES areas
- a CIA #2 timer NMI taken under bank 1 with the private zero page returns
cleanly through the NMI guard (closes the E01-S03 NMI risk)
- decision D117 records the map; RESTORE is ignored while compiling
Also pin newLang/ to LF in .gitattributes. A branch switch under
core.autocrlf had rewritten the byte-exact fixtures with CRLF.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Nova128 is an object-oriented language with an on-machine C128 compiler.
This adds the spec, decisions, architecture, backlog, and story claims,
plus the grammar fixtures (E00-S02), disk-image builder (E07-S01), and
the x128-verified platform probes:
- E01-S01 minimal native PRG
- E01-S02 MMU/common-RAM probe. With bottom common on, a P0/P1 pointer
aimed at bank 1 lands in bank 0 at the translated page. The verifier
traces every MMU write in the probe window.
- E01-S03 KERNAL wrapper (kcall). CHROUT, drive status, and a
device-not-present failure work from bank 0 and bank 1 mappings.
A/X/Y/C/ST are preserved and the MMU state is restored exactly.
- E01-S04 40/80-column display and clock probe
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>