Commit Graph
8 Commits
Author SHA1 Message Date
Aaron SinclairandClaude 44db8ff022 Integrate reactive rendering into _emit_if()
Modified _emit_if() to:
- Create marker node via js_create_marker()
- Append marker to parent element
- Store marker ID in global
- Call _init_conditional_X() to render and insert active branch

Branch render functions work correctly:
- Build element tree locally
- Return root element ID
- Called by init function to pre-render all branches

Fallback to _emit_if_static() if conditional not collected.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-15 03:53:38 -08:00
Aaron Sinclair 9f601b1787 Fix element appending in conditional branches
- Add parent_element_stack to track nesting context
- Elements inside if/match branches append to parent
- Fixes: Li elements inside if statements now append to Ul parent
- Tabs now render visibly!
- TODO: Fix duplicate appends
- All tests passing (30/30)
2025-11-15 03:43:06 -08:00
Aaron Sinclair cdddbf675a Add component parameter support and fix JS runtime
- Emit function parameters in component signature
- JS runtime passes props as positional arguments
- Remove incorrect return value handling (components call js_set_root internally)
- Enables: def Tabs(orientation=0)
- All tests passing (30/30)
2025-11-15 03:39:43 -08:00
Aaron Sinclair 41474aceda Add basic component composition support
- Handle yield_component statement type
- Call child component render function
- Enables: yield VerticalTabs()
- All tests passing (30/30)
- Tabs.wasm size: 3185 → 3205 bytes
2025-11-15 03:36:38 -08:00
Aaron Sinclair cd89f75c1c Implement match/case statement code generation
- Add _emit_match() using LLVM switch instruction
- Handle value patterns and wildcard (case _:) patterns
- Each case gets its own basic block with branch to end
- Wildcard case becomes default label in switch
- All tests passing (30/30)
- Tabs.wasm size: 1908 → 3185 bytes
2025-11-15 03:35:31 -08:00
Aaron Sinclair e18baf3106 Add direct signal assignment in event handlers
- Handle 'assign' type statements in _emit_handler_statement()
- Evaluate value expression and store to signal global
- Enables patterns like: setting_tab = 0
- All tests passing (30/30)
2025-11-15 03:33:45 -08:00
Aaron Sinclair 81d51d5617 Parser: Support multiple components in one file, change args to params with defaults 2025-11-15 03:25:13 -08:00
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