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>
This commit is contained in:
1 parent
d8a2e28fd5
commit
0b77c2ff3c
7 files changed
+999
-594
No files matched your search
+117
-73
@@ -2,21 +2,21 @@
|
||||
; Components: TextInput
|
||||
|
||||
; String constants
|
||||
@.str.0 = private unnamed_addr constant [4 x i8] c"div\00"
|
||||
@.str.1 = private unnamed_addr constant [6 x i8] c"class\00"
|
||||
@.str.2 = private unnamed_addr constant [10 x i8] c"container\00"
|
||||
@.str.3 = private unnamed_addr constant [3 x i8] c"h1\00"
|
||||
@.str.4 = private unnamed_addr constant [17 x i8] c"Reactive Counter\00"
|
||||
@.str.5 = private unnamed_addr constant [2 x i8] c"p\00"
|
||||
@.str.6 = private unnamed_addr constant [13 x i8] c"instructions\00"
|
||||
@.str.7 = private unnamed_addr constant [65 x i8] c"Click buttons to see reactive updates (text input coming soon!):\00"
|
||||
@.str.8 = private unnamed_addr constant [13 x i8] c"button-group\00"
|
||||
@.str.9 = private unnamed_addr constant [7 x i8] c"button\00"
|
||||
@.str.10 = private unnamed_addr constant [6 x i8] c"click\00"
|
||||
@.str.11 = private unnamed_addr constant [10 x i8] c"decrement\00"
|
||||
@.str.12 = private unnamed_addr constant [4 x i8] c"−\00"
|
||||
@.str.13 = private unnamed_addr constant [16 x i8] c"counter-display\00"
|
||||
@.str.14 = private unnamed_addr constant [2 x i8] c"0\00"
|
||||
@.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"
|
||||
@@ -32,17 +32,22 @@
|
||||
; 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:
|
||||
@@ -63,76 +68,115 @@ 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:
|
||||
%var2 = load i32, i32* @signal_TextInput_count
|
||||
%var3 = sub i32 %var2, 1
|
||||
store i32 %var3, i32* @signal_TextInput_count
|
||||
%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:
|
||||
%var4 = call i32 @js_create_element(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.0, i32 0, i32 0))
|
||||
call void @js_set_attribute(i32 %var4, i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str.1, i32 0, i32 0), i8* getelementptr inbounds ([10 x i8], [10 x i8]* @.str.2, i32 0, i32 0))
|
||||
%var5 = call i32 @js_create_element(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.3, i32 0, i32 0))
|
||||
%var6 = call i32 @js_create_text(i8* getelementptr inbounds ([17 x i8], [17 x i8]* @.str.4, i32 0, i32 0))
|
||||
call void @js_append_child(i32 %var5, i32 %var6)
|
||||
call void @js_append_child(i32 %var4, i32 %var5)
|
||||
%var7 = call i32 @js_create_element(i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.5, i32 0, i32 0))
|
||||
call void @js_set_attribute(i32 %var7, i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str.1, i32 0, i32 0), i8* getelementptr inbounds ([13 x i8], [13 x i8]* @.str.6, i32 0, i32 0))
|
||||
%var8 = call i32 @js_create_text(i8* getelementptr inbounds ([65 x i8], [65 x i8]* @.str.7, i32 0, i32 0))
|
||||
call void @js_append_child(i32 %var7, i32 %var8)
|
||||
call void @js_append_child(i32 %var4, i32 %var7)
|
||||
%var9 = call i32 @js_create_element(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.0, i32 0, i32 0))
|
||||
call void @js_set_attribute(i32 %var9, i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str.1, i32 0, i32 0), i8* getelementptr inbounds ([13 x i8], [13 x i8]* @.str.8, i32 0, i32 0))
|
||||
%var10 = call i32 @js_create_element(i8* getelementptr inbounds ([7 x i8], [7 x i8]* @.str.9, i32 0, i32 0))
|
||||
call void @js_bind_event(i32 %var10, i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str.10, i32 0, i32 0), i8* getelementptr inbounds ([10 x i8], [10 x i8]* @.str.11, i32 0, i32 0))
|
||||
%var11 = call i32 @js_create_text(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.12, i32 0, i32 0))
|
||||
call void @js_append_child(i32 %var10, i32 %var11)
|
||||
call void @js_append_child(i32 %var9, i32 %var10)
|
||||
%var12 = call i32 @js_create_element(i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.5, i32 0, i32 0))
|
||||
call void @js_set_attribute(i32 %var12, i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str.1, i32 0, i32 0), i8* getelementptr inbounds ([16 x i8], [16 x i8]* @.str.13, i32 0, i32 0))
|
||||
; TODO: Format f-string with signal count
|
||||
%var13 = call i32 @js_create_text(i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.14, i32 0, i32 0))
|
||||
call void @js_append_child(i32 %var12, i32 %var13)
|
||||
call void @js_append_child(i32 %var9, i32 %var12)
|
||||
%var14 = call i32 @js_create_element(i8* getelementptr inbounds ([7 x i8], [7 x i8]* @.str.9, i32 0, i32 0))
|
||||
call void @js_bind_event(i32 %var14, i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str.10, i32 0, i32 0), i8* getelementptr inbounds ([10 x i8], [10 x i8]* @.str.15, i32 0, i32 0))
|
||||
%var15 = 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 %var14, i32 %var15)
|
||||
call void @js_append_child(i32 %var9, i32 %var14)
|
||||
call void @js_append_child(i32 %var4, i32 %var9)
|
||||
%var16 = call i32 @js_create_element(i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.5, i32 0, i32 0))
|
||||
call void @js_set_attribute(i32 %var16, i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str.1, i32 0, i32 0), i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str.17, i32 0, i32 0))
|
||||
%var17 = 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 %var16, i32 %var17)
|
||||
call void @js_append_child(i32 %var4, i32 %var16)
|
||||
%var18 = call i32 @js_create_element(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.19, i32 0, i32 0))
|
||||
call void @js_set_attribute(i32 %var18, i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str.1, i32 0, i32 0), i8* getelementptr inbounds ([10 x i8], [10 x i8]* @.str.20, i32 0, i32 0))
|
||||
%var19 = call i32 @js_create_element(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.21, i32 0, i32 0))
|
||||
%var20 = 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 %var19, i32 %var20)
|
||||
call void @js_append_child(i32 %var18, i32 %var19)
|
||||
%var21 = call i32 @js_create_element(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.21, i32 0, i32 0))
|
||||
%var22 = 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 %var21, i32 %var22)
|
||||
call void @js_append_child(i32 %var18, i32 %var21)
|
||||
%var23 = call i32 @js_create_element(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.21, i32 0, i32 0))
|
||||
%var24 = 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 %var23, i32 %var24)
|
||||
call void @js_append_child(i32 %var18, i32 %var23)
|
||||
%var25 = call i32 @js_create_element(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.21, i32 0, i32 0))
|
||||
%var26 = 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 %var25, i32 %var26)
|
||||
call void @js_append_child(i32 %var18, i32 %var25)
|
||||
call void @js_append_child(i32 %var4, i32 %var18)
|
||||
ret i32 %var4
|
||||
%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
|
||||
|
||||
Reference in new issue
Block a user