Files
ritz/ritz/syntax.py
T
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

180 lines
2.2 KiB
Python

"""
Ritz syntax placeholders for writing components.
These are runtime placeholders that allow components to be valid Python.
The compiler ignores imports and uses AST parsing instead.
"""
def component(func):
"""Component decorator - marks a function as a Ritz component."""
return func
def signal(initial_value):
"""Create a reactive signal with an initial value."""
pass
# HTML Elements - Context managers for building DOM
class _Element:
"""Base element class."""
def __init__(self, *children, **props):
self.children = children
self.props = props
def __enter__(self):
return self
def __exit__(self, *args):
pass
# Standard HTML elements
class Div(_Element):
"""<div> element."""
pass
class P(_Element):
"""<p> element."""
pass
class Button(_Element):
"""<button> element."""
pass
class Span(_Element):
"""<span> element."""
pass
class H1(_Element):
"""<h1> element."""
pass
class H2(_Element):
"""<h2> element."""
pass
class H3(_Element):
"""<h3> element."""
pass
class Label(_Element):
"""<label> element."""
pass
class Input(_Element):
"""<input> element."""
pass
class Form(_Element):
"""<form> element."""
pass
class Section(_Element):
"""<section> element."""
pass
class Article(_Element):
"""<article> element."""
pass
class Header(_Element):
"""<header> element."""
pass
class Footer(_Element):
"""<footer> element."""
pass
class Nav(_Element):
"""<nav> element."""
pass
class Ul(_Element):
"""<ul> element."""
pass
class Ol(_Element):
"""<ol> element."""
pass
class Li(_Element):
"""<li> element."""
pass
class A(_Element):
"""<a> element."""
pass
class Img(_Element):
"""<img> element."""
pass
# Export all for convenience
__all__ = [
"component",
"signal",
"Div",
"P",
"Button",
"Span",
"H1",
"H2",
"H3",
"Label",
"Input",
"Form",
"Section",
"Article",
"Header",
"Footer",
"Nav",
"Ul",
"Ol",
"Li",
"A",
"Img",
]