Skip to content

Releases: jackwthake/C02

v1.0.0

Choose a tag to compare

@jackwthake jackwthake released this 01 Jul 19:45
f201919

C02 v1.0.0: Complete Single-File Language

C02 has reached its v1.0 milestone. Per the goal set out in docs/roadmap.md:
someone can sit down and write a non-trivial 65C02 program without hitting an
"unimplemented" wall. Every must-have and should-have feature on the v1.0
checklist is now implemented and tested.

Highlights

  • break and continue now work inside while and for loops.
  • Local string literal initializers: u8 *p = "..."; works inside
    function bodies, not just at global scope.
  • 16-bit multiply, divide, and modulo (__mul16, __div16, __sdiv16).
  • __heap_start and __memory_top implicit globals for bump allocators
    and RAM top queries, injected automatically into every translation unit.
  • Embedded ROM symbol table: compiled binaries now carry function names,
    so c02-objdump shows real labels instead of auto-generated ones.

Correctness fixes

  • Variable shadowing is now a semantic error instead of a silent miscompile.
    Codegen identifies variables by name only, with no scope qualifier, so a
    shadowed inner declaration could alias the same storage as its outer
    namesake (this is what caused a break bug fixed this cycle). Shadowing an
    enclosing scope is now rejected at analysis time.
  • Signed 8-bit division and modulo (i8) previously routed through the
    unsigned helper and produced wrong results for negative operands. Fixed
    with a new __sdiv8 wrapper.
  • Binary operations with mixed width or mixed signedness (u8 + u16,
    i8 < u8) derived their result type from the left operand only, silently
    dropping high bytes or producing inconsistent comparisons depending on
    operand order. Both operands now normalize to a common type first.

Safety and robustness

  • ROM writes are now bounds checked. A program that exceeds the 32 KB ROM
    fails with a clear diagnostic instead of silently corrupting the output.
  • Zero page exhaustion now fails codegen cleanly instead of warning and
    continuing.

Testing

285 tests passing: golden tests, smoke tests, emulator tests, and valgrind
leak checks, all under make test. New coverage this cycle includes
emulator tests for break, continue (in both loop forms), 16-bit
multiply/divide, and mixed-width/mixed-sign binary operations.

What's not in v1.0

A short, deliberate list of nice-to-haves the roadmap explicitly allows v1.0
to ship without: short-circuit &&/|| evaluation outside a boolean
context, and the bitwise/shift compound assignment operators (&=, |=,
^=, <<=, >>=). Arrays and multi-file linking are scoped for later
milestones (v1.2+).

What's next

v1.1 is planned to bring interrupt handlers and inline assembly. See
docs/roadmap.md for the full plan through v2.0.

Functional code generation

Pre-release

Choose a tag to compare

@jackwthake jackwthake released this 27 Jun 04:18
1b26049

What's Changed

  • Implement IR generation by @jackwthake in #3
  • Code generation for 65C02 target by @jackwthake in #4
  • Enhance label printing and add section boundaries to binary by @jackwthake in #5
  • Added arithmetic operators, comparisons for all types by @jackwthake in #6
  • Codegen: Operators, Structs, and Function Calls by @jackwthake in #7

Full Changelog: v0.2.0...v0.2.15

v0.2.0 - Compiler Frontend

Pre-release

Choose a tag to compare

@jackwthake jackwthake released this 21 Jun 12:42
159ee80

Complete, tested compiler frontend - tokenizer, parser, and semantic analyzer.

Highlights

  • Two-pass semantic analyzer - type checking, scoped symbol tables, redeclaration
    detection, struct validation, and function signature enforcement
  • Analyzer hardening - lvalue checks, literal range validation, void/unknown type
    rejection, global initializer checking, missing-return detection, and TYPE_INVALID
    poisoning to prevent cascading diagnostics
  • Struct pointer auto-deref - ptr.field works on Struct* (no -> operator)
  • Struct-typed globals - Point p; at file scope
  • Bug fixes - arena allocator segfault, string escape truncation, lexer error
    recovery for malformed literals
  • Negative-test corpus - 10 new bad-path tests with golden files covering every
    analyzer error path

Full Changelog: v0.1.1...v0.2.0

v0.1.1 - Licensing & Project Docs

Pre-release

Choose a tag to compare

@jackwthake jackwthake released this 20 Jun 08:19

No code changes - this release adds the project's LICENSE (GPLv3, with a
compiler-output exception), and a CONTRIBUTING guide.

Full Changelog: v0.1.0...v0.1.1

v0.1.0 - Parser Frontend

Pre-release

Choose a tag to compare

@jackwthake jackwthake released this 20 Jun 07:21

v0.1.0 - Parser Frontend

First public release of C02. This is a frontend-only milestone: the tokenizer, recursive descent parser, and AST printer are complete and tested. Semantic analysis and code generation are not implemented yet - see Known Limitations below before you go looking for working binaries.

If you're new here: C02 is a strongly-typed, C-like systems language targeting the 65C02, built around an Ben Eater-style breadboard computer. The goal is a real (if small) compiler toolchain - tokenizer → parser → semantic analysis → 65C02 codegen - built from scratch.

Highlights

  • Full expression grammar, precedence-correct: || && | ^ & == != < > <= >= << >> + - * / %, plus unary ! - & ~ ++ -- * @.
  • Structs: field declarations, chained field access (a.b.c), designated-initializer literals (Point { .x = 0, .y = 0 }).
  • Generalized assignment: any lvalue - identifier, field access, or dereference - works as an assignment target, including compound assignment (+= -= *= /= %=).
  • Hardware registers as a first-class construct: reg u8 PORTB @ 0x6000; pins a declaration directly to an absolute memory address.
  • if / else if / else chains, while, for with optional clauses, function calls - the usual control-flow surface.
  • Clang-style diagnostics: colorized, caret-span error output with expected/context messages on every parse error.
  • --ast-dump: prints a readable tree view of any parsed program - the easiest way to explore what the parser actually produces.
  • Golden-file test suite with CI, covering bitwise ops, conditionals, registers, globals, and structs.
  • c02-objdump, a companion disassembler that decodes compiled .bin files back into annotated, label-resolved 65C02 assembly - ready for when codegen lands.

Known Limitations

  • No semantic analysis. The parser will happily accept syntactically valid but semantically meaningless programs - undeclared struct types, unknown fields, type mismatches - without complaint.
  • No code generation. cc02 does not yet produce a working 65C02 binary. The zero-page register layout documented in the README is a design target, not a current reality.
  • No arrays. No array type, no subscript syntax (a[i]) yet. Strings are u8* in the meantime.
  • No -> operator. Field access through a pointer uses . uniformly; auto-dereferencing is intended to happen during semantic analysis, which doesn't exist yet.

Trying it out

git clone https://github.com/jackwthake/C02.git
cd C02
make

cc02 --ast-dump examples/lcd_hello_world.c02

What's next

Semantic analysis - a lexically-scoped symbol table, type checking, and struct/field validation - is the immediate next milestone, followed by 65C02 code generation.


Full Changelog: see CHANGELOG.md