Skip to content

StalePixels/zxbasic-c

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

5,470 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Boriel ZX Basic

license C Build zxbpp tests zxbasm tests

ZX BASIC β€” C Port πŸš€

A C language port of the Boriel ZX BASIC compiler, originally written in Python by Jose Rodriguez-Rosa (a.k.a. Boriel).

🎯 What is this?

This is an agentic porting experiment β€” a test of whether an AI coding assistant can systematically port a non-trivial compiler (~38,500 lines of Python) to C, producing a drop-in replacement with byte-for-byte identical output.

The toolchain being ported β€” zxbc (compiler), zxbasm (assembler), and zxbpp (preprocessor) β€” is validated stage by stage against the original's comprehensive test suite of 1,285+ functional tests.

The practical end-goal: a C implementation of the compiler suitable for embedding on NextPi and similar resource-constrained platforms where a full modern Python runtime is undesirable.

πŸ“Š Current Status

Phase Component Tests Status
0 Infrastructure (arena, strbuf, vec, hashmap, CMake) β€” βœ… Complete
1 Preprocessor (zxbpp) 96/96 πŸŽ‰ βœ… Complete
2 Assembler (zxbasm) 61/61 πŸŽ‰ βœ… Complete
3 BASIC compiler frontend (lexer + parser + AST) β€” ⏳ Planned
4 Optimizer + IR generation (AST β†’ Quads) β€” ⏳ Planned
5 Z80 backend (Quads β†’ Assembly) β€” 1,175 ASM tests β€” ⏳ Planned
6 Full integration + all output formats β€” ⏳ Planned

πŸ”¬ Phase 2 β€” Assembler: Done!

The zxbasm C binary is a verified drop-in replacement for the Python original:

  • βœ… 61/61 tests passing β€” zero failures, byte-for-byte identical binary output
  • βœ… 61/61 Python comparison β€” confirmed by running both side-by-side
  • βœ… Full Z80 instruction set (827 opcodes) including ZX Next extensions
  • βœ… Two-pass assembly: labels, forward references, expressions, temporaries
  • βœ… PROC/ENDP scoping, LOCAL labels, PUSH/POP NAMESPACE
  • βœ… #init directive, EQU/DEFL, ORG, ALIGN, INCBIN
  • βœ… Hand-written recursive-descent parser (~1,750 lines of C)
  • βœ… Preprocessor integration (reuses the C zxbpp binary)

πŸ”¬ Phase 1 β€” Preprocessor: Done!

The zxbpp C binary is a verified drop-in replacement for the Python original:

  • βœ… 96/96 tests passing (91 normal + 5 error tests) β€” zero skipped
  • βœ… 91/91 outputs identical to Python β€” confirmed by running both side-by-side
  • βœ… All preprocessor features: #define, #include, #ifdef/#if, macro expansion, token pasting, stringizing, block comments, ASM mode, line continuation, #pragma/#require/#init/#error/#warning, architecture-specific includes
  • βœ… Hand-written recursive-descent parser (~1,600 lines of C)

πŸ§ͺ Try It Yourself

Building

git clone https://github.com/StalePixels/zxbasic-c.git
cd zxbasic-c
mkdir -p csrc/build && cd csrc/build
cmake ..
make -j4

This builds csrc/build/zxbpp/zxbpp and csrc/build/zxbasm/zxbasm.

Running the Tests

# Run all 96 preprocessor tests:
./csrc/tests/run_zxbpp_tests.sh ./csrc/build/zxbpp/zxbpp tests/functional/zxbpp

# Run all 61 assembler tests (binary-exact):
./csrc/tests/run_zxbasm_tests.sh ./csrc/build/zxbasm/zxbasm tests/functional/asm

🐍 Python Ground-Truth Comparison

Want to see for yourself that C matches Python? You'll need Python 3.11+:

# Install Python 3.12+ if you don't have it:
#   macOS:   brew install python@3.11  (or newer)
#   Ubuntu:  sudo apt install python3
#   Fedora:  sudo dnf install python3

# Run both Python and C on every test, diff the outputs:
./csrc/tests/compare_python_c.sh ./csrc/build/zxbpp/zxbpp tests/functional/zxbpp
./csrc/tests/compare_python_c_asm.sh ./csrc/build/zxbasm/zxbasm tests/functional/asm

This runs the original Python tools and the C ports on all test inputs and confirms their outputs are identical. 🀝

πŸ”§ Using the C Preprocessor Today

The C zxbpp binary accepts the exact same flags as the Python original. You can drop it into an existing Boriel ZX BASIC workflow right now for the preprocessing step:

# Instead of:
python3 zxbpp.py myfile.bas -o myfile.preprocessed.bas

# Use:
./csrc/build/zxbpp/zxbpp myfile.bas -o myfile.preprocessed.bas

Supported flags: -o, -d, -e, -D, -I, --arch, --expect-warnings

Supported flags: -d, -e, -o, -O (output format)

The zxbasm assembler is also available as a drop-in replacement:

# Instead of:
python3 zxbasm.py myfile.asm -o myfile.bin

# Use:
./csrc/build/zxbasm/zxbasm myfile.asm -o myfile.bin

The compiler frontend (zxbc) still requires Python β€” for now. 😏

πŸ—ΊοΈ The Road to NextPi

The big picture: a fully native C compiler toolchain that runs on the NextPi β€” a Raspberry Pi accelerator board for the ZX Spectrum Next. No Python runtime needed, just a single binary.

Here's how we get there, one step at a time:

 Phase 0  βœ…  Infrastructure β€” arena allocator, strings, vectors, hash maps
    β”‚
 Phase 1  βœ…  zxbpp β€” Preprocessor
    β”‚         96/96 tests, drop-in replacement for Python's zxbpp
    β”‚
 Phase 2  βœ…  zxbasm β€” Z80 Assembler (you are here! πŸ“)
    β”‚         61/61 binary-exact tests passing
    β”‚         zxbpp + zxbasm work without Python!
    β”‚
 Phase 3  ⏳  BASIC Frontend β€” Lexer, parser, AST, symbol table
    β”‚
 Phase 4  ⏳  Optimizer + IR β€” AST β†’ Quads intermediate code
    β”‚
 Phase 5  ⏳  Z80 Backend β€” Quads β†’ Assembly + peephole optimizer
    β”‚         1,175 ASM tests + 1,285 BASIC tests to pass
    β”‚
 Phase 6  ⏳  Integration β€” All output formats (.tap, .tzx, .sna, .z80)
    β”‚         Full CLI compatibility with zxbc
    β”‚
    🏁  Single static binary: zxbasic for NextPi and embedded platforms

Each phase is independently useful β€” you don't have to wait for the whole thing. After Phase 2, you can preprocess and assemble entirely in C. After Phase 6, Python is no longer needed at all. 🎯

πŸ€– Who is doing this?

This port is being developed by Claude (Anthropic's AI coding assistant, model Claude Opus 4.6), directed and supervised by @Xalior.

Claude is analysing the original Python codebase, designing the C architecture, writing the implementation, and verifying correctness against the existing test suite β€” with every commit pushed in real-time for full transparency.

Design Decisions

Aspect Python Original C Port
Parsing (zxbpp) PLY lex/yacc Hand-written recursive-descent
Parsing (zxbasm, zxbc) PLY lex/yacc flex + bison
AST nodes 50+ classes with inheritance Tagged union structs
Memory Python GC Arena allocator
Strings Python str (immutable) StrBuf (growable)
Dynamic arrays Python list VEC(T) macro
Hash tables Python dict HashMap (open addressing)
CLI argparse ya_getopt (BSD-2-Clause)
Path manipulation os.path cwalk (MIT)

See docs/c-port-plan.md for the full implementation plan with detailed breakdown.

πŸ”„ Upstream Sync

The src/ and tests/functional/ directories are a read-only mirror of the canonical Python source at boriel-basic/zxbasic. A weekly CI job checks for upstream changes and opens a PR automatically if anything has moved. You can also sync manually:

./csrc/scripts/sync-upstream.sh

This keeps our Python reference and test suite in lockstep with Boriel's latest, so the C port is always validated against the real thing. 🎯

πŸ“œ Original Project

Copyleft (K) 2008, Jose Rodriguez-Rosa (a.k.a. Boriel) http://www.boriel.com

All files in this project are covered under the AGPLv3 LICENSE except those placed in directories library/ and library-asm, which are licensed under MIT license unless otherwise specified in the files themselves.

About

ZX BASIC compiler - C port (byte-for-byte compatible with boriel/zxbasic)

Resources

License

Code of conduct

Stars

Watchers

Forks

Releases

No releases published

Sponsor this project

Packages

 
 
 

Contributors