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.
| 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. |
| 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 .. |
| D122 | init returns no value (as type is E151), like destroy. |
Spec 6.3 says new Class(args) yields the object, so an init result could never be observed. Spec 6.3 already gives destroy no parameters and no result (E152, E151). Implemented by E03-S02. |
| D123 | Inside a method an unqualified name is a parameter or local, else a field of the enclosing class; methods are always called through an expression such as self.tick(). |
Spec 9 lets a local “shadow a field”, which implies fields are in scope unqualified, but no fixture used one. Spec 7 defines calls only as expression.method(arguments), so a bare tick() is an unknown name. Implemented by E03-S02. |
| D124 | Numeric literals are constants that adopt the type of the place or operand they meet when the value fits, and literal-only arithmetic folds at compile time. and/or take booleans; + - * / take byte, word, or integer; < <= > >= take numbers or chars; = <> also take booleans and references (identity). byte widens to word/integer, but word and integer do not mix. |
Spec 3.4 names the conversions but not literal types or the operator table. Out-of-range folded results are E084, division by zero E086, and a constant that does not fit E085. Implemented by types.s; changing it changes only that module and the semantic goldens. |
| D125 | An array index may be an integer or a value assignable to word; a constant index is also checked against the declared length. | Spec 3.3 gives arrays but not the index type. Byte indexes widen; an out-of-range constant is E089 at compile time. Implemented by check_index in parser.s. |
| D126 | Arrays are fields or locals only: never parameters, results, or whole values. A bare array is E088, and a parameter or result declaring one is E094. | Keeps array storage and copying out of the ABI (D108); indexing is the only way to read or write one. Implemented by no_array_sig and ty_assign. |
| D127 | return with a value in a program is E151. A method that declares a result must end every path in return; an if satisfies this only when both branches do, a while never does, and a missing return is reported at end as E150. |
Spec 7 permits return but does not say what a program return means; a program has no caller or result. Deterministic and observable, and lets E04 emit a single exit path. Implemented by close_block and set_ret. |
:make and error-navigation commandsPowered by TurnKey Linux.