mirror of
https://github.com/imjasonh/nescript
synced 2026-07-09 09:18:01 +00:00
No description
Issues found by systematic review of all compiler modules. Each fix includes a regression test. Parser fixes: - Add EOF checks to function call arg parsing loops (lines 984, 1269) to prevent infinite loops on unterminated call expressions - Fix span end positions: use .end instead of .start for 9 declaration span computations (var, const, fun, state, bank, sprite, palette, background, block) - Add missing compound assignment operators (&= |= ^=) to parse_assign_op() for array element assignments Codegen fix: - Fix NOT operator: old code used EOR #$FF + AND #$01 which produced wrong results for non-boolean inputs (e.g., NOT 0x42 returned 1 instead of 0). New code uses BEQ/branch to properly map any nonzero value to 0 and zero to 1. Assembler fixes: - Add branch offset range validation: assert offset is in -128..127 range instead of silently wrapping on overflow - Panic on unresolved labels instead of silently leaving placeholder 0x00 bytes in the output Verified non-issues (reviewer false positives): - NMI P register: 6502 hardware pushes P automatically on NMI entry; RTI restores it. PHP/PLP not needed. - Controller read buffer: 8 iterations of LSR+ROL fully replace all 8 bits, so prior contents don't matter. - advance() panic: tokens always has at least Eof from lexer. 4 new regression tests, 225 total. https://claude.ai/code/session_01W6eQFStA66EuMKHUFo2rx3 |
||
|---|---|---|
| .github/workflows | ||
| docs | ||
| examples | ||
| fuzz | ||
| scripts | ||
| src | ||
| tests | ||
| .gitignore | ||
| Cargo.lock | ||
| Cargo.toml | ||
| LICENSE | ||
| plan.md | ||
| README.md | ||
| spec.md | ||
NEScript
A statically-typed, compiled programming language for NES game development.
NEScript compiles .ne source files directly into playable iNES ROM files, with no external assembler or linker dependencies. The compiler handles everything from source text to a ROM you can run in any NES emulator.
Quick Start
# Build the compiler
cargo build --release
# Compile an example
cargo run -- build examples/hello_sprite.ne
# Run the output ROM in an emulator
# (produces examples/hello_sprite.nes)
Hello World
game "Hello" {
mapper: NROM
}
var px: u8 = 128
var py: u8 = 120
on frame {
if button.right { px += 2 }
if button.left { px -= 2 }
if button.down { py += 2 }
if button.up { py -= 2 }
draw Smiley at: (px, py)
}
start Main
Features
- Game-aware syntax -- states, sprites, palettes, and input are first-class constructs
- Full type system --
u8,i8,u16,bool, fixed-size arrays (u8[N]) - Functions -- with parameters, return types,
inlinehint, recursion detection - State machines --
statewithon enter,on exit,on framehandlers - Compile-time safety -- call depth limits, recursion detection, type checking
- Optimizer -- constant folding, dead code elimination, strength reduction
- Multiple mappers -- NROM, MMC1, UxROM, MMC3
- Asset pipeline -- PNG-to-CHR conversion, palette definitions, inline tile data
- Debug support --
--debugflag, source maps, Mesen-compatible symbol export - Single binary -- no dependencies on ca65, Python, or any external tools
Documentation
- Language Guide -- complete reference for every language feature
- Architecture -- compiler internals and module overview
- NES Reference -- hardware quick reference for contributors
- Examples README -- how to build and run examples
Examples
| Example | Features demonstrated |
|---|---|
hello_sprite.ne |
D-pad input, sprite drawing |
bouncing_ball.ne |
Automatic movement, edge detection |
coin_cavern.ne |
Multi-state game, functions, constants, gravity |
arrays_and_functions.ne |
Arrays, functions, while loops, inline functions |
state_machine.ne |
State transitions, on enter/exit, timers |
sprites_and_palettes.ne |
Inline CHR data, palettes, scroll, type casting |
mmc1_banked.ne |
MMC1 mapper, bank declarations, multiply |
Compiler Commands
# Compile to ROM
nescript build game.ne
# Compile with custom output path
nescript build game.ne --output my_game.nes
# Type-check only (no ROM output)
nescript check game.ne
# View generated 6502 assembly
nescript build game.ne --asm-dump
# Enable debug mode
nescript build game.ne --debug
Emulator Compatibility
Output ROMs are standard iNES format and work with any NES emulator:
Project Status
NEScript implements all five planned milestones:
| Milestone | Status | Key Features |
|---|---|---|
| M1: Hello Sprite | Done | Full compiler pipeline, assembler, ROM builder |
| M2: Game Loop | Done | Functions, arrays, IR, optimizer, call graph analysis |
| M3: Asset Pipeline | Done | PNG-to-CHR, sprites, palettes, debug symbols |
| M4: Optimization | Done | Strength reduction, ZP promotion, type casting, asm-dump |
| M5: Bank Switching | Done | MMC1/UxROM/MMC3, bank declarations, software mul/div |
210 tests across 14 modules, with CI running fmt, clippy, test, and example compilation on every push.