Files
Aaron Sinclair 635d466874 Implement Python → LLVM IR → WASM reactive framework
MAJOR ACHIEVEMENT: Full working reactive framework!

## What's Working

✅ Python → AST → Ritz IR → LLVM IR → WASM pipeline
✅ Reactive signals stored in WASM memory (@signal_name = global i32)
✅ Event handlers exported from WASM and callable from JS
✅ Clean runtime with RitzLoader and debug tools
✅ Two working examples: HelloWorld and HighFive counter

## Core Components

### Parser (ritz/parser.py)
- Uses Python's ast module to parse components
- Handles @component decorator, signals, event handlers
- Supports yield, with statements, f-strings, augmented assignment (+=)
- Clean syntax: from ritz.syntax import *

### LLVM IR Code Generator (ritz/llvm_codegen_signals.py)
- Generates LLVM IR directly (not C!)
- Signals as global variables in WASM memory
- Exports getter/setter functions for each signal
- Exports event handler functions for JS to call
- UTF-8 string handling

### Build System (ritz/build.py)
- Python → AST → IR → LLVM IR → clang --target=wasm32 → WASM
- Saves intermediate .ll files for inspection
- Debug symbols support (-g flag)

### Runtime (runtime/ritz-runtime.js)
- RitzRuntime class: DOM bridge for WASM
- RitzLoader class: Simplified component loading
- Debug bar with Ctrl+` toggle
- Signal updates trigger DOM updates

## Examples

### HelloWorld.py
Simple static content - renders <p>Hello World</p>

### HighFive.py
Reactive counter with:
- Signal in WASM memory (high_fives = signal(0))
- Event handler (increment function)
- DOM updates on signal change

## Test Coverage

- 4 parser tests (all passing)
- 4 LLVM codegen tests (all passing)
- 4 signal parsing tests (all passing)
- Code formatted with black and ruff

## Next Steps

- <script type="text/ritz"> in-browser compilation
- Better signal-to-DOM binding tracking
- More complex examples (TodoMVC, forms, lists)
- Playwright browser tests

---

This is a genuinely innovative framework: write Python, compile to WASM,
run with reactive signals in WASM memory. No virtual DOM, no transpilation,
just compiled Python with fine-grained reactivity.

🎉 Python → WASM → Reactive UI is REAL!
2025-11-15 01:50:40 -08:00

3.4 KiB

Ritz Framework TODO

✅ COMPLETED: Phase 1 & 2 - Working Reactive Framework!

Phase 1: Hello World (Static Content) ✅

  • Set up project structure (pyproject.toml, ruff, black, pytest)
  • Write AST parser tests using Python's ast module
  • Implement AST parser (HelloWorld, props, nesting, augassign)
  • All parser tests passing (4/4)
  • Write LLVM IR codegen tests
  • Implement LLVM IR code generator (NOT C - direct LLVM!)
  • All codegen tests passing (4/4)
  • Create JavaScript DOM bridge/runtime (ritz-runtime.js)
  • Create build script (Python → AST → IR → LLVM → clang → WASM)
  • Write HelloWorld.py component
  • ✅ MILESTONE: HelloWorld.wasm renders in browser!

Phase 2: Reactive Signals ✅

  • Parse signal declarations and augmented assignment (+=)
  • Parse event handlers (onclick)
  • Parse f-strings with signal references
  • Implement signals in WASM memory (@signal_name = global i32)
  • Generate signal getter/setter functions
  • Generate exported event handler functions
  • Bind events in JS runtime to WASM functions
  • Update DOM when signals change
  • Write HighFive.py counter component
  • ✅ MILESTONE: Reactive counter working!

Phase 3: Developer Experience ✅

  • Clean runtime architecture (RitzRuntime + RitzLoader classes)
  • Debug bar with Ctrl+` toggle
  • Clean HTML examples with minimal boilerplate
  • Dev server with port reuse
  • Run black and ruff formatters
  • from ritz.syntax import * for clean component syntax

🚀 Current State

WORKING:

  • Python → AST → Ritz IR → LLVM IR → WASM pipeline
  • Reactive signals stored in WASM memory
  • Event handlers exported from WASM
  • Clean runtime with debug tools
  • Two working examples (HelloWorld, HighFive)

Architecture:

Python Component
    ↓ ast.parse()
Ritz IR
    ↓ LLVM IR Generator (llvm_codegen_signals.py)
LLVM IR (.ll file)
    ↓ clang --target=wasm32
WebAssembly
    ↓ RitzRuntime (JavaScript)
Live Reactive UI

Phase 4: Next Steps

In-Browser Compilation (THE BIG ONE)

  • Research: Compile Ritz compiler to WASM (Pyodide vs Rust rewrite)
  • Implement <script type="text/ritz"> loader
  • Parse inline Ritz code in browser
  • Compile to WASM on-the-fly
  • ✅ MILESTONE: Zero build step - write Python in HTML!

More Examples

  • TodoMVC example
  • Form with multiple inputs
  • Nested components example
  • List rendering with iteration

Better Signal-DOM Binding

  • Track signal-to-DOM bindings during render
  • Efficient updates (only update bound elements)
  • Proper f-string interpolation with signals

Testing

  • Playwright browser tests
  • Test HelloWorld renders correctly
  • Test HighFive counter increments
  • CI/CD pipeline

Advanced Features

  • Component props/args
  • Computed values (derived signals)
  • Conditional rendering (if/else)
  • List rendering (for loops with keys)
  • Nested components (yield from)
  • DWARF debug symbols for Python debugging
  • Source maps (WASM → Python lines)

Current Focus

JUST COMPLETED: Full reactive framework with signals in WASM!

NEXT UP: Commit current work, then explore:

  1. More complex examples
  2. <script type="text/ritz"> in-browser compilation
  3. Better signal tracking and f-string support