--- type: project-decisions source-path: user conversation and repository inspection ingested-at: 2026-11-07 --- # Project Decisions This file prevents later agents from silently changing the approved product. `Accepted` means the user explicitly requested, confirmed, or approved the documented default. `Proposed` means a later change still needs approval. ## Accepted | ID | Decision | Consequence | |---|---|---| | D001 | Create an object-oriented language for the Commodore 128. | C128 behavior and limits define the platform contract. | | D002 | Write the compiler in assembly. | Compiler implementation uses documented 8502/6502 instructions and ca65 source. | | D003 | Source creation must work with the repository's new Vim clone. | The compiler accepts the editor's PETSCII SEQ output directly. | | D004 | Put project programs and supporting material under `newLang/`. | Existing `vim/` and reference assets remain external inputs. | | D005 | Plan and obtain approval before implementation. | The user approved continuation on 2026-11-07; implementation stories may now be claimed in dependency order. | | D006 | Support interfaces. | Interfaces and dynamic interface dispatch are version 1 work, not an optional extension. | | D007 | Create a specification and epics/stories suitable for other agents. | Work is divided into claimable, testable stories with durable context. | | D100 | Use `Nova128` as the language name and `.n8` as the source suffix. | Short, recognizable, and compatible with 16-character disk filenames. | | D101 | Run the compiler in C128 native 8502 mode. | Gives access to both RAM banks, the MMU, 80-column facilities, and 2 MHz operation where safe. | | D102 | Use host `ca65`/`ld65` only to build the on-machine compiler. | The resulting compiler still runs entirely on the C128. | | D103 | Keep the existing Vim binary in C64 mode for version 1. | A native C128 editor port is a separate large project. | | D104 | Exchange source through a copied D81 image. | It works with the current editor without inventing an editor API. | | D105 | Use explicit `new`/`delete` and a deterministic free-list heap. | Avoids the size and timing cost of garbage collection. | | D106 | Permit multiple interfaces but no class inheritance in version 1. | Delivers polymorphism while limiting layout and dispatch complexity. | | D107 | Use statically dispatched concrete method calls and dynamically dispatched interface calls. | Keeps ordinary calls fast while preserving interface polymorphism. | | D108 | Represent interface values as a four-byte pair: object pointer plus interface-table pointer. | Makes interface invocation constant-time without searching class metadata on every call. | | D109 | Compile one source file into one PRG in version 1. | Separate compilation and object linking can follow a proven compiler. | | D110 | Use KERNAL-compatible output so the compiler can operate on 40- or 80-column displays. | Avoids coupling the first compiler UI directly to one video chip. | | D111 | Physical C128 testing is P2 validation, not a version 1 release blocker when hardware is unavailable. | VICE x128 remains the mandatory automated acceptance environment. | | D112 | Compiler diagnostics use the active C128 display and do not force 80-column mode. | The compiler remains usable with either display; safe clock acceleration is opportunistic. | | D113 | Version 1 integer overflow always wraps in the destination representation. | Debug overflow trapping is deferred, keeping semantics identical between builds. | | D114 | Version 1 has no interface-to-class down-cast operation. | Programs express polymorphism through interfaces without runtime type reflection. | | D115 | Character literals use single quotes and contain exactly one PETSCII character or supported escape. | The `char` type has a direct, unambiguous literal form while `//` remains the comment syntax. | | D116 | Runtime faults report a stable code and the best available map-resolvable program address. | Rich stack traces are deferred; faults remain diagnosable within the runtime budget. | | D117 | Freeze the compiler memory map in `cfg/compiler.cfg`: 8K bottom common RAM, COMMON at `$1300`, private zero page at bank 0 page `$1A` via P0, bank-1 tables at `$2000-$BFFF`, IRQs masked and NMIs guarded in compiler states, test mailbox at `$1BF0`. | Internal contract backed by E01-S05 x128 evidence (`docs/memory-map.md`); no user-visible behavior except that RESTORE is ignored while compiling. Generated-program maps remain open. | | D118 | The compiler loads the whole source file once into a bank-1 cache (`$2000-$6AFF`) and replays it for every pass, instead of re-reading the disk. | Rewind is exact by construction and avoids reading a slow disk three times. Compiler tables get the remaining 21,760 bytes of bank 1 (`$6B00-$BFFF`). Internal; no user-visible behavior. | ## Proposed | ID | Proposal | Consequence | |---|---|---| | D119 | The string and character escapes `\n` and `\r` both produce PETSCII `$0D`. | Commodore output has one line-end character, so both escapes start a new line. Implemented as `ESC_N_VALUE`/`ESC_R_VALUE` in `src/common/tokens.inc`; changing them later affects only those constants and the lexer golden files. | | D120 | A program may use at most 255 distinct identifiers (names are 1-byte IDs). | Covers well beyond a 599-line program's typical vocabulary at 5,164 bytes of bank 1. Exceeding it is a resource diagnostic; raising it means 2-byte name IDs in every later record. | | D121 | A method name may be any identifier or reserved word, as in spec 5.1's `method print()`. | Spec 5.1 and the accepted fixtures declare `method print()` although `print` is a statement keyword. The parser accepts a keyword after `method`; E03-S03 must accept the same member names after `.`. | ## Deferred - Native C128/80-column Vim port - Vim `:make` and error-navigation commands - Class inheritance and virtual class methods - Interface inheritance and default methods - Separate compilation and relocatable Nova128 object files - Garbage collection or reference counting - Exceptions, generics, closures, reflection, and method overloading - Floating point - C64 and Z80 code-generation targets - Bank 1 heaps for generated programs ## Open Questions 1. What generated-program memory map should E04-S01/E04-S02 adopt? (The compiler map is D117.) 2. What compiler table capacities fit in the 21,760-byte bank-1 table window and 254-byte zero page (D117, D118)?