Files
Aaron SinclairandClaude 0b77c2ff3c Implement reactive text nodes & fix LLVM syntax for clang 20
**Reactive Text Nodes:**
- F-strings with signal dependencies now update automatically
- Added js_create_text_with_int() and js_update_text_with_int() for efficient "prefix{int}" pattern
- Text nodes stored in @reactive_text_N_node globals for updates
- Scan and track f-string dependencies during collection phase

**Binary Operations:**
- Implemented BinOp support in parser and codegen
- Maps Add → add i32, Sub → sub i32, Mult → mul i32, Div → sdiv i32, Mod → srem i32
- count = count + 1 now generates correct arithmetic instead of store i32 0

**LLVM Syntax Fixes (clang 20 compatibility):**
- Fixed getelementptr syntax: removed parentheses around type
- Before: getelementptr inbounds ([N x i8], [N x i8]* @str, ...)
- After:  getelementptr inbounds [N x i8], [N x i8]* @str, ...
- Created _emit_string_ptr() helper for consistent string pointer generation
- Fixed in: element creation, attribute setting, event binding, select instructions

**Runtime (ritz-runtime.js):**
- Added js_create_text_with_int(prefix, intValue) - creates text node with "prefix" + intValue
- Added js_update_text_with_int(node, prefix, intValue) - updates text content

**Result:**
✅ TextInput counter increments/decrements correctly
✅ Tabs example works (reactive attributes, conditionals)
✅ Both examples compile with clang 20

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-15 15:00:36 -08:00

189 lines
9.6 KiB
LLVM
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
; Generated by Ritz Framework with Signals
; Components: TextInput
; String constants
@.str.0 = private unnamed_addr constant [8 x i8] c"Count: \00"
@.str.1 = private unnamed_addr constant [4 x i8] c"div\00"
@.str.2 = private unnamed_addr constant [6 x i8] c"class\00"
@.str.3 = private unnamed_addr constant [10 x i8] c"container\00"
@.str.4 = private unnamed_addr constant [3 x i8] c"h1\00"
@.str.5 = private unnamed_addr constant [17 x i8] c"Reactive Counter\00"
@.str.6 = private unnamed_addr constant [2 x i8] c"p\00"
@.str.7 = private unnamed_addr constant [13 x i8] c"instructions\00"
@.str.8 = private unnamed_addr constant [65 x i8] c"Click buttons to see reactive updates (text input coming soon!):\00"
@.str.9 = private unnamed_addr constant [13 x i8] c"button-group\00"
@.str.10 = private unnamed_addr constant [7 x i8] c"button\00"
@.str.11 = private unnamed_addr constant [6 x i8] c"click\00"
@.str.12 = private unnamed_addr constant [10 x i8] c"decrement\00"
@.str.13 = private unnamed_addr constant [4 x i8] c"−\00"
@.str.14 = private unnamed_addr constant [16 x i8] c"counter-display\00"
@.str.15 = private unnamed_addr constant [10 x i8] c"increment\00"
@.str.16 = private unnamed_addr constant [2 x i8] c"+\00"
@.str.17 = private unnamed_addr constant [5 x i8] c"todo\00"
@.str.18 = private unnamed_addr constant [49 x i8] c"TODO: Replace with text input once we implement:\00"
@.str.19 = private unnamed_addr constant [3 x i8] c"ul\00"
@.str.20 = private unnamed_addr constant [10 x i8] c"todo-list\00"
@.str.21 = private unnamed_addr constant [3 x i8] c"li\00"
@.str.22 = private unnamed_addr constant [32 x i8] c"1. String signals (i8* not i32)\00"
@.str.23 = private unnamed_addr constant [25 x i8] c"2. oninput event handler\00"
@.str.24 = private unnamed_addr constant [23 x i8] c"3. Event value passing\00"
@.str.25 = private unnamed_addr constant [39 x i8] c"4. F-string interpolation with signals\00"
; JavaScript bridge function declarations
declare i32 @js_create_element(i8*)
declare i32 @js_create_text(i8*)
declare i32 @js_create_text_with_int(i8*, i32)
declare void @js_append_child(i32, i32)
declare void @js_set_attribute(i32, i8*, i8*)
declare void @js_set_root(i32)
declare void @js_bind_event(i32, i8*, i8*)
declare void @js_update_text_content(i32, i8*)
declare void @js_update_text_with_int(i32, i8*, i32)
declare i32 @js_create_marker()
declare void @js_replace_at_marker(i32, i32, i32)
; Signal storage for TextInput (reactive state in WASM memory)
@signal_TextInput_count = global i32 0
; Reactive text node storage
@reactive_text_0_node = global i32 0
; Signal helper functions
define i32 @get_count() {
entry:
%val = load i32, i32* @signal_TextInput_count
ret i32 %val
}
define void @set_count(i32 %newval) {
entry:
store i32 %newval, i32* @signal_TextInput_count
; TODO: Trigger DOM update callback
ret void
}
; Event handler: increment
define void @increment() {
entry:
%var0 = load i32, i32* @signal_TextInput_count
%var1 = add i32 %var0, 1
store i32 %var1, i32* @signal_TextInput_count
%var2 = load i32, i32* @reactive_text_0_node
%var3 = getelementptr inbounds [8 x i8], [8 x i8]* @.str.0, i32 0, i32 0
%var4 = load i32, i32* @signal_TextInput_count
call void @js_update_text_with_int(i32 %var2, i8* %var3, i32 %var4)
ret void
}
; Event handler: decrement
define void @decrement() {
entry:
%var5 = load i32, i32* @signal_TextInput_count
%var6 = sub i32 %var5, 1
store i32 %var6, i32* @signal_TextInput_count
%var7 = load i32, i32* @reactive_text_0_node
%var8 = getelementptr inbounds [8 x i8], [8 x i8]* @.str.0, i32 0, i32 0
%var9 = load i32, i32* @signal_TextInput_count
call void @js_update_text_with_int(i32 %var7, i8* %var8, i32 %var9)
ret void
}
; Component render function
define i32 @render_TextInput() {
entry:
%var11 = getelementptr inbounds [4 x i8], [4 x i8]* @.str.1, i32 0, i32 0
%var10 = call i32 @js_create_element(i8* %var11)
%var12 = getelementptr inbounds [6 x i8], [6 x i8]* @.str.2, i32 0, i32 0
%var13 = getelementptr inbounds [10 x i8], [10 x i8]* @.str.3, i32 0, i32 0
call void @js_set_attribute(i32 %var10, i8* %var12, i8* %var13)
%var15 = getelementptr inbounds [3 x i8], [3 x i8]* @.str.4, i32 0, i32 0
%var14 = call i32 @js_create_element(i8* %var15)
%var16 = call i32 @js_create_text(i8* getelementptr inbounds ([17 x i8], [17 x i8]* @.str.5, i32 0, i32 0))
call void @js_append_child(i32 %var14, i32 %var16)
call void @js_append_child(i32 %var10, i32 %var14)
%var18 = getelementptr inbounds [2 x i8], [2 x i8]* @.str.6, i32 0, i32 0
%var17 = call i32 @js_create_element(i8* %var18)
%var19 = getelementptr inbounds [6 x i8], [6 x i8]* @.str.2, i32 0, i32 0
%var20 = getelementptr inbounds [13 x i8], [13 x i8]* @.str.7, i32 0, i32 0
call void @js_set_attribute(i32 %var17, i8* %var19, i8* %var20)
%var21 = call i32 @js_create_text(i8* getelementptr inbounds ([65 x i8], [65 x i8]* @.str.8, i32 0, i32 0))
call void @js_append_child(i32 %var17, i32 %var21)
call void @js_append_child(i32 %var10, i32 %var17)
%var23 = getelementptr inbounds [4 x i8], [4 x i8]* @.str.1, i32 0, i32 0
%var22 = call i32 @js_create_element(i8* %var23)
%var24 = getelementptr inbounds [6 x i8], [6 x i8]* @.str.2, i32 0, i32 0
%var25 = getelementptr inbounds [13 x i8], [13 x i8]* @.str.9, i32 0, i32 0
call void @js_set_attribute(i32 %var22, i8* %var24, i8* %var25)
%var27 = getelementptr inbounds [7 x i8], [7 x i8]* @.str.10, i32 0, i32 0
%var26 = call i32 @js_create_element(i8* %var27)
%var28 = getelementptr inbounds [6 x i8], [6 x i8]* @.str.11, i32 0, i32 0
%var29 = getelementptr inbounds [10 x i8], [10 x i8]* @.str.12, i32 0, i32 0
call void @js_bind_event(i32 %var26, i8* %var28, i8* %var29)
%var30 = call i32 @js_create_text(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.13, i32 0, i32 0))
call void @js_append_child(i32 %var26, i32 %var30)
call void @js_append_child(i32 %var22, i32 %var26)
%var32 = getelementptr inbounds [2 x i8], [2 x i8]* @.str.6, i32 0, i32 0
%var31 = call i32 @js_create_element(i8* %var32)
%var33 = getelementptr inbounds [6 x i8], [6 x i8]* @.str.2, i32 0, i32 0
%var34 = getelementptr inbounds [16 x i8], [16 x i8]* @.str.14, i32 0, i32 0
call void @js_set_attribute(i32 %var31, i8* %var33, i8* %var34)
%var35 = getelementptr inbounds [8 x i8], [8 x i8]* @.str.0, i32 0, i32 0
%var36 = load i32, i32* @signal_TextInput_count
%var37 = call i32 @js_create_text_with_int(i8* %var35, i32 %var36)
store i32 %var37, i32* @reactive_text_0_node
call void @js_append_child(i32 %var31, i32 %var37)
call void @js_append_child(i32 %var22, i32 %var31)
%var39 = getelementptr inbounds [7 x i8], [7 x i8]* @.str.10, i32 0, i32 0
%var38 = call i32 @js_create_element(i8* %var39)
%var40 = getelementptr inbounds [6 x i8], [6 x i8]* @.str.11, i32 0, i32 0
%var41 = getelementptr inbounds [10 x i8], [10 x i8]* @.str.15, i32 0, i32 0
call void @js_bind_event(i32 %var38, i8* %var40, i8* %var41)
%var42 = call i32 @js_create_text(i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.16, i32 0, i32 0))
call void @js_append_child(i32 %var38, i32 %var42)
call void @js_append_child(i32 %var22, i32 %var38)
call void @js_append_child(i32 %var10, i32 %var22)
%var44 = getelementptr inbounds [2 x i8], [2 x i8]* @.str.6, i32 0, i32 0
%var43 = call i32 @js_create_element(i8* %var44)
%var45 = getelementptr inbounds [6 x i8], [6 x i8]* @.str.2, i32 0, i32 0
%var46 = getelementptr inbounds [5 x i8], [5 x i8]* @.str.17, i32 0, i32 0
call void @js_set_attribute(i32 %var43, i8* %var45, i8* %var46)
%var47 = call i32 @js_create_text(i8* getelementptr inbounds ([49 x i8], [49 x i8]* @.str.18, i32 0, i32 0))
call void @js_append_child(i32 %var43, i32 %var47)
call void @js_append_child(i32 %var10, i32 %var43)
%var49 = getelementptr inbounds [3 x i8], [3 x i8]* @.str.19, i32 0, i32 0
%var48 = call i32 @js_create_element(i8* %var49)
%var50 = getelementptr inbounds [6 x i8], [6 x i8]* @.str.2, i32 0, i32 0
%var51 = getelementptr inbounds [10 x i8], [10 x i8]* @.str.20, i32 0, i32 0
call void @js_set_attribute(i32 %var48, i8* %var50, i8* %var51)
%var53 = getelementptr inbounds [3 x i8], [3 x i8]* @.str.21, i32 0, i32 0
%var52 = call i32 @js_create_element(i8* %var53)
%var54 = call i32 @js_create_text(i8* getelementptr inbounds ([32 x i8], [32 x i8]* @.str.22, i32 0, i32 0))
call void @js_append_child(i32 %var52, i32 %var54)
call void @js_append_child(i32 %var48, i32 %var52)
%var56 = getelementptr inbounds [3 x i8], [3 x i8]* @.str.21, i32 0, i32 0
%var55 = call i32 @js_create_element(i8* %var56)
%var57 = call i32 @js_create_text(i8* getelementptr inbounds ([25 x i8], [25 x i8]* @.str.23, i32 0, i32 0))
call void @js_append_child(i32 %var55, i32 %var57)
call void @js_append_child(i32 %var48, i32 %var55)
%var59 = getelementptr inbounds [3 x i8], [3 x i8]* @.str.21, i32 0, i32 0
%var58 = call i32 @js_create_element(i8* %var59)
%var60 = call i32 @js_create_text(i8* getelementptr inbounds ([23 x i8], [23 x i8]* @.str.24, i32 0, i32 0))
call void @js_append_child(i32 %var58, i32 %var60)
call void @js_append_child(i32 %var48, i32 %var58)
%var62 = getelementptr inbounds [3 x i8], [3 x i8]* @.str.21, i32 0, i32 0
%var61 = call i32 @js_create_element(i8* %var62)
%var63 = call i32 @js_create_text(i8* getelementptr inbounds ([39 x i8], [39 x i8]* @.str.25, i32 0, i32 0))
call void @js_append_child(i32 %var61, i32 %var63)
call void @js_append_child(i32 %var48, i32 %var61)
call void @js_append_child(i32 %var10, i32 %var48)
ret i32 %var10
}
; Main entry point
define void @main() {
entry:
%root = call i32 @render_TextInput()
call void @js_set_root(i32 %root)
ret void
}