From b0e38db22ccd5d2fd1c1c832b58ae9645eadc0e1 Mon Sep 17 00:00:00 2001 From: Aaron Sinclair Date: Sat, 15 Nov 2025 11:16:23 -0800 Subject: [PATCH] Fix nested components - render functions now return i32 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Changes: - Component render functions return i32 (root element) instead of void - Nested components (yield SomeComponent()) now work correctly - Added main() entry point that calls top-level component and sets root - Updated runtime to call main() instead of render_ComponentName() Note: Active state in ternary expressions still needs reactive updates This commit fixes the nested component rendering issue All tests passing (51 passed, 2 skipped) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- examples/runtime/ritz-runtime.js | 12 +- examples/tabs/.Tabs.py.swp | Bin 0 -> 16384 bytes examples/tabs/Tabs.ll | 1589 ++++++----------- examples/tabs/Tabs.py | 64 +- examples/tabs/Tabs.wasm | Bin 8870 -> 5481 bytes examples/tabs/TabsClean.py | 70 + examples/tabs/TabsTernary.ll | 805 +++++++++ examples/tabs/TabsTernary.wasm | Bin 0 -> 4956 bytes examples/tabs/ritz-runtime.js | 354 ++++ examples/toggle/Toggle.ll | 227 +-- examples/toggle/Toggle.wasm | Bin 1733 -> 1779 bytes examples/toggle/ritz-runtime.js | 354 ++++ .../llvm_codegen_signals.cpython-313.pyc | Bin 49080 -> 56605 bytes ritz/__pycache__/parser.cpython-313.pyc | Bin 14662 -> 17853 bytes ritz/llvm_codegen_signals.py | 39 +- ...mponent_props.cpython-313-pytest-8.4.2.pyc | Bin 0 -> 14176 bytes ...mbda_handlers.cpython-313-pytest-8.4.2.pyc | Bin 0 -> 18460 bytes ...lambda_simple.cpython-313-pytest-8.4.2.pyc | Bin 0 -> 7371 bytes ..._llvm_codegen.cpython-313-pytest-8.4.2.pyc | Bin 19468 -> 20415 bytes ...n_conditional.cpython-313-pytest-8.4.2.pyc | Bin 7141 -> 8637 bytes ..._conditionals.cpython-313-pytest-8.4.2.pyc | Bin 0 -> 18778 bytes ...y_expressions.cpython-313-pytest-8.4.2.pyc | Bin 0 -> 6313 bytes ...er_components.cpython-313-pytest-8.4.2.pyc | Bin 0 -> 8429 bytes tests/test_component_props.py | 8 +- tests/test_llvm_codegen.py | 6 +- tests/test_wrapper_components.py | 4 +- 26 files changed, 2310 insertions(+), 1222 deletions(-) create mode 100644 examples/tabs/.Tabs.py.swp create mode 100644 examples/tabs/TabsClean.py create mode 100644 examples/tabs/TabsTernary.ll create mode 100755 examples/tabs/TabsTernary.wasm create mode 100644 examples/tabs/ritz-runtime.js create mode 100644 examples/toggle/ritz-runtime.js create mode 100644 tests/__pycache__/test_component_props.cpython-313-pytest-8.4.2.pyc create mode 100644 tests/__pycache__/test_lambda_handlers.cpython-313-pytest-8.4.2.pyc create mode 100644 tests/__pycache__/test_lambda_simple.cpython-313-pytest-8.4.2.pyc create mode 100644 tests/__pycache__/test_reactive_conditionals.cpython-313-pytest-8.4.2.pyc create mode 100644 tests/__pycache__/test_ternary_expressions.cpython-313-pytest-8.4.2.pyc create mode 100644 tests/__pycache__/test_wrapper_components.cpython-313-pytest-8.4.2.pyc diff --git a/examples/runtime/ritz-runtime.js b/examples/runtime/ritz-runtime.js index 3a23d1b..cb2f556 100644 --- a/examples/runtime/ritz-runtime.js +++ b/examples/runtime/ritz-runtime.js @@ -306,15 +306,13 @@ class RitzLoader { this.setStatus(`⏳ Rendering ${componentName}...`); - // Call the render function with props - const renderFn = instance.exports[`render_${componentName}`]; - if (!renderFn) { - throw new Error(`render_${componentName} not found in WASM exports`); + // Call the main entry point (which renders top-level component and sets root) + const mainFn = instance.exports.main; + if (!mainFn) { + throw new Error(`main function not found in WASM exports`); } - // Pass props as positional arguments - const propValues = Object.values(props); - renderFn(...propValues); + mainFn(); // Update signals runtime.updateSignals(); diff --git a/examples/tabs/.Tabs.py.swp b/examples/tabs/.Tabs.py.swp new file mode 100644 index 0000000000000000000000000000000000000000..9b5d79c645669c83c22b5cc542b2ec37f41ce343 GIT binary patch literal 16384 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 A+5i9m literal 8870 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 A6aWAK diff --git a/examples/tabs/TabsClean.py b/examples/tabs/TabsClean.py new file mode 100644 index 0000000..379bad6 --- /dev/null +++ b/examples/tabs/TabsClean.py @@ -0,0 +1,70 @@ +""" +Cleaner Tabs implementation using wrapper components to reduce repetition. +""" + +from ritz.syntax import * + + +@component +def VerticalTab(label, is_active, tab_value): + """Reusable vertical tab button with active state handling.""" + # Note: In current implementation, we still need the if/else for class + # But it's encapsulated in one place instead of repeated everywhere + if is_active: + with Button(class_="vertical-tab active"): + yield label + else: + with Button(class_="vertical-tab"): + yield label + + +@component +def VerticalTabs(): + """Vertical tabs for settings categories.""" + setting_tab = signal(0) + + def set_setting(value): + setting_tab = value + + with Div(class_="vertical-tabs"): + # Vertical tab menu + with Div(class_="vertical-tab-menu"): + # Now each tab is just one line instead of 6! + yield VerticalTab("⚙️ General", setting_tab == 0, 0) + yield VerticalTab("🔒 Privacy", setting_tab == 1, 1) + yield VerticalTab("🚀 Advanced", setting_tab == 2, 2) + + # Tab content (same as before) + with Div(class_="vertical-tab-content"): + match setting_tab: + case 0: + with Div(class_="setting-pane"): + with H3(): + yield "⚙️ General Settings" + with P(): + yield "Language: English" + with P(): + yield "Time Zone: UTC" + + case 1: + with Div(class_="setting-pane"): + with H3(): + yield "🔒 Privacy Settings" + with P(): + yield "Data Collection: Disabled" + with P(): + yield "Analytics: Opt-out" + + case 2: + with Div(class_="setting-pane"): + with H3(): + yield "🚀 Advanced Settings" + with P(): + yield "Debug Mode: Off" + with P(): + yield "Experimental Features: Disabled" + + case _: + with Div(class_="setting-pane"): + with P(): + yield "Invalid setting" diff --git a/examples/tabs/TabsTernary.ll b/examples/tabs/TabsTernary.ll new file mode 100644 index 0000000..b6eca62 --- /dev/null +++ b/examples/tabs/TabsTernary.ll @@ -0,0 +1,805 @@ +; Generated by Ritz Framework with Signals +; Components: VerticalTabs, Tabs + +; 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 [13 x i8] c"setting-pane\00" +@.str.3 = private unnamed_addr constant [3 x i8] c"h3\00" +@.str.4 = private unnamed_addr constant [24 x i8] c"⚙️ General Settings\00" +@.str.5 = private unnamed_addr constant [2 x i8] c"p\00" +@.str.6 = private unnamed_addr constant [18 x i8] c"Language: English\00" +@.str.7 = private unnamed_addr constant [15 x i8] c"Time Zone: UTC\00" +@.str.8 = private unnamed_addr constant [22 x i8] c"🔒 Privacy Settings\00" +@.str.9 = private unnamed_addr constant [26 x i8] c"Data Collection: Disabled\00" +@.str.10 = private unnamed_addr constant [19 x i8] c"Analytics: Opt-out\00" +@.str.11 = private unnamed_addr constant [23 x i8] c"🚀 Advanced Settings\00" +@.str.12 = private unnamed_addr constant [16 x i8] c"Debug Mode: Off\00" +@.str.13 = private unnamed_addr constant [32 x i8] c"Experimental Features: Disabled\00" +@.str.14 = private unnamed_addr constant [16 x i8] c"Invalid setting\00" +@.str.15 = private unnamed_addr constant [14 x i8] c"vertical-tabs\00" +@.str.16 = private unnamed_addr constant [18 x i8] c"vertical-tab-menu\00" +@.str.17 = private unnamed_addr constant [7 x i8] c"button\00" +@.str.18 = private unnamed_addr constant [20 x i8] c"vertical-tab active\00" +@.str.19 = private unnamed_addr constant [13 x i8] c"vertical-tab\00" +@.str.20 = private unnamed_addr constant [6 x i8] c"click\00" +@.str.21 = private unnamed_addr constant [23 x i8] c"_lambda_0_VerticalTabs\00" +@.str.22 = private unnamed_addr constant [15 x i8] c"⚙️ General\00" +@.str.23 = private unnamed_addr constant [23 x i8] c"_lambda_1_VerticalTabs\00" +@.str.24 = private unnamed_addr constant [13 x i8] c"🔒 Privacy\00" +@.str.25 = private unnamed_addr constant [23 x i8] c"_lambda_2_VerticalTabs\00" +@.str.26 = private unnamed_addr constant [14 x i8] c"🚀 Advanced\00" +@.str.27 = private unnamed_addr constant [21 x i8] c"vertical-tab-content\00" +@.str.28 = private unnamed_addr constant [14 x i8] c"tab-pane home\00" +@.str.29 = private unnamed_addr constant [3 x i8] c"h2\00" +@.str.30 = private unnamed_addr constant [18 x i8] c"🏠 Welcome Home\00" +@.str.31 = private unnamed_addr constant [29 x i8] c"This is your home dashboard.\00" +@.str.32 = private unnamed_addr constant [17 x i8] c"tab-pane profile\00" +@.str.33 = private unnamed_addr constant [18 x i8] c"👤 Your Profile\00" +@.str.34 = private unnamed_addr constant [30 x i8] c"Manage your account settings.\00" +@.str.35 = private unnamed_addr constant [18 x i8] c"tab-pane settings\00" +@.str.36 = private unnamed_addr constant [16 x i8] c"⚙️ Settings\00" +@.str.37 = private unnamed_addr constant [55 x i8] c"Configure your preferences using the categories below:\00" +@.str.38 = private unnamed_addr constant [15 x i8] c"tab-pane error\00" +@.str.39 = private unnamed_addr constant [28 x i8] c"⚠️ Invalid tab selected\00" +@.str.40 = private unnamed_addr constant [15 x i8] c"tabs-container\00" +@.str.41 = private unnamed_addr constant [3 x i8] c"h1\00" +@.str.42 = private unnamed_addr constant [19 x i8] c"Tab Component Demo\00" +@.str.43 = private unnamed_addr constant [9 x i8] c"subtitle\00" +@.str.44 = private unnamed_addr constant [47 x i8] c"Beautiful composition with ternary expressions\00" +@.str.45 = private unnamed_addr constant [3 x i8] c"ul\00" +@.str.46 = private unnamed_addr constant [9 x i8] c"tab-menu\00" +@.str.47 = private unnamed_addr constant [3 x i8] c"li\00" +@.str.48 = private unnamed_addr constant [11 x i8] c"tab active\00" +@.str.49 = private unnamed_addr constant [4 x i8] c"tab\00" +@.str.50 = private unnamed_addr constant [15 x i8] c"_lambda_0_Tabs\00" +@.str.51 = private unnamed_addr constant [10 x i8] c"🏠 Home\00" +@.str.52 = private unnamed_addr constant [15 x i8] c"_lambda_1_Tabs\00" +@.str.53 = private unnamed_addr constant [13 x i8] c"👤 Profile\00" +@.str.54 = private unnamed_addr constant [15 x i8] c"_lambda_2_Tabs\00" +@.str.55 = private unnamed_addr constant [12 x i8] c"tab-content\00" + +; JavaScript bridge function declarations +declare i32 @js_create_element(i8*) +declare i32 @js_create_text(i8*) +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 i32 @js_create_marker() +declare void @js_replace_at_marker(i32, i32, i32) + +; Signal storage for VerticalTabs (reactive state in WASM memory) +@signal_VerticalTabs_setting_tab = global i32 0 + +; Conditional rendering state +@cond_0_marker = global i32 0 +@cond_0_current = global i32 0 +@cond_0_case_0_root = global i32 0 +@cond_0_case_1_root = global i32 0 +@cond_0_case_2_root = global i32 0 +@cond_0_case_3_root = global i32 0 + +; Signal helper functions +define i32 @get_setting_tab() { +entry: + %val = load i32, i32* @signal_VerticalTabs_setting_tab + ret i32 %val +} + +define void @set_setting_tab(i32 %newval) { +entry: + store i32 %newval, i32* @signal_VerticalTabs_setting_tab + ; TODO: Trigger DOM update callback + ret void +} + +; Event handler: _lambda_0_VerticalTabs +define void @_lambda_0_VerticalTabs() { +entry: + call void @set_setting(i32 0) + ret void +} + +; Event handler: _lambda_1_VerticalTabs +define void @_lambda_1_VerticalTabs() { +entry: + call void @set_setting(i32 1) + ret void +} + +; Event handler: _lambda_2_VerticalTabs +define void @_lambda_2_VerticalTabs() { +entry: + call void @set_setting(i32 2) + ret void +} + +; Event handler: set_setting +define void @set_setting(i32 %value) { +entry: + store i32 %value, i32* @signal_VerticalTabs_setting_tab + call void @reevaluate_conditional_0() + ret void +} + +; Initialize conditional 0 (match) +define void @_init_conditional_0() { +entry: + ; Render all cases upfront + %var0 = call i32 @_render_cond_0_case_0() + store i32 %var0, i32* @cond_0_case_0_root + %var1 = call i32 @_render_cond_0_case_1() + store i32 %var1, i32* @cond_0_case_1_root + %var2 = call i32 @_render_cond_0_case_2() + store i32 %var2, i32* @cond_0_case_2_root + %var3 = call i32 @_render_cond_0_case_3() + store i32 %var3, i32* @cond_0_case_3_root + %var4 = load i32, i32* @signal_VerticalTabs_setting_tab + %var5 = load i32, i32* @cond_0_marker + switch i32 %var4, label %insert_case_3 [ + i32 0, label %insert_case_0 + i32 1, label %insert_case_1 + i32 2, label %insert_case_2 + ] +insert_case_0: + call void @js_replace_at_marker(i32 %var5, i32 0, i32 %var0) + store i32 0, i32* @cond_0_current + ret void +insert_case_1: + call void @js_replace_at_marker(i32 %var5, i32 0, i32 %var1) + store i32 1, i32* @cond_0_current + ret void +insert_case_2: + call void @js_replace_at_marker(i32 %var5, i32 0, i32 %var2) + store i32 2, i32* @cond_0_current + ret void +insert_case_3: + call void @js_replace_at_marker(i32 %var5, i32 0, i32 %var3) + store i32 3, i32* @cond_0_current + ret void +} + +; Re-evaluate conditional 0 (match) +define void @reevaluate_conditional_0() { +entry: + %var6 = load i32, i32* @signal_VerticalTabs_setting_tab + %var7 = load i32, i32* @cond_0_current + switch i32 %var6, label %case_3 [ + i32 0, label %case_0 + i32 1, label %case_1 + i32 2, label %case_2 + ] +case_0: + %var8 = icmp ne i32 %var7, 0 + br i1 %var8, label %swap_0, label %done +swap_0: + %var9 = load i32, i32* @cond_0_marker + %var10 = load i32, i32* @cond_0_case_0_root + switch i32 %var7, label %load_old_0_3 [ + i32 0, label %load_old_0_0 + i32 1, label %load_old_0_1 + i32 2, label %load_old_0_2 + i32 3, label %load_old_0_3 + ] +load_old_0_0: + %var12 = load i32, i32* @cond_0_case_0_root + br label %merge_0 +load_old_0_1: + %var13 = load i32, i32* @cond_0_case_1_root + br label %merge_0 +load_old_0_2: + %var14 = load i32, i32* @cond_0_case_2_root + br label %merge_0 +load_old_0_3: + %var15 = load i32, i32* @cond_0_case_3_root + br label %merge_0 +merge_0: + %var11 = phi i32 [ %var12, %load_old_0_0 ], [ %var13, %load_old_0_1 ], [ %var14, %load_old_0_2 ], [ %var15, %load_old_0_3 ] + call void @js_replace_at_marker(i32 %var9, i32 %var11, i32 %var10) + store i32 0, i32* @cond_0_current + br label %done +case_1: + %var16 = icmp ne i32 %var7, 1 + br i1 %var16, label %swap_1, label %done +swap_1: + %var17 = load i32, i32* @cond_0_marker + %var18 = load i32, i32* @cond_0_case_1_root + switch i32 %var7, label %load_old_1_3 [ + i32 0, label %load_old_1_0 + i32 1, label %load_old_1_1 + i32 2, label %load_old_1_2 + i32 3, label %load_old_1_3 + ] +load_old_1_0: + %var20 = load i32, i32* @cond_0_case_0_root + br label %merge_1 +load_old_1_1: + %var21 = load i32, i32* @cond_0_case_1_root + br label %merge_1 +load_old_1_2: + %var22 = load i32, i32* @cond_0_case_2_root + br label %merge_1 +load_old_1_3: + %var23 = load i32, i32* @cond_0_case_3_root + br label %merge_1 +merge_1: + %var19 = phi i32 [ %var20, %load_old_1_0 ], [ %var21, %load_old_1_1 ], [ %var22, %load_old_1_2 ], [ %var23, %load_old_1_3 ] + call void @js_replace_at_marker(i32 %var17, i32 %var19, i32 %var18) + store i32 1, i32* @cond_0_current + br label %done +case_2: + %var24 = icmp ne i32 %var7, 2 + br i1 %var24, label %swap_2, label %done +swap_2: + %var25 = load i32, i32* @cond_0_marker + %var26 = load i32, i32* @cond_0_case_2_root + switch i32 %var7, label %load_old_2_3 [ + i32 0, label %load_old_2_0 + i32 1, label %load_old_2_1 + i32 2, label %load_old_2_2 + i32 3, label %load_old_2_3 + ] +load_old_2_0: + %var28 = load i32, i32* @cond_0_case_0_root + br label %merge_2 +load_old_2_1: + %var29 = load i32, i32* @cond_0_case_1_root + br label %merge_2 +load_old_2_2: + %var30 = load i32, i32* @cond_0_case_2_root + br label %merge_2 +load_old_2_3: + %var31 = load i32, i32* @cond_0_case_3_root + br label %merge_2 +merge_2: + %var27 = phi i32 [ %var28, %load_old_2_0 ], [ %var29, %load_old_2_1 ], [ %var30, %load_old_2_2 ], [ %var31, %load_old_2_3 ] + call void @js_replace_at_marker(i32 %var25, i32 %var27, i32 %var26) + store i32 2, i32* @cond_0_current + br label %done +case_3: + %var32 = icmp ne i32 %var7, 3 + br i1 %var32, label %swap_3, label %done +swap_3: + %var33 = load i32, i32* @cond_0_marker + %var34 = load i32, i32* @cond_0_case_3_root + switch i32 %var7, label %load_old_3_3 [ + i32 0, label %load_old_3_0 + i32 1, label %load_old_3_1 + i32 2, label %load_old_3_2 + i32 3, label %load_old_3_3 + ] +load_old_3_0: + %var36 = load i32, i32* @cond_0_case_0_root + br label %merge_3 +load_old_3_1: + %var37 = load i32, i32* @cond_0_case_1_root + br label %merge_3 +load_old_3_2: + %var38 = load i32, i32* @cond_0_case_2_root + br label %merge_3 +load_old_3_3: + %var39 = load i32, i32* @cond_0_case_3_root + br label %merge_3 +merge_3: + %var35 = phi i32 [ %var36, %load_old_3_0 ], [ %var37, %load_old_3_1 ], [ %var38, %load_old_3_2 ], [ %var39, %load_old_3_3 ] + call void @js_replace_at_marker(i32 %var33, i32 %var35, i32 %var34) + store i32 3, i32* @cond_0_current + br label %done +done: + ret void +} + +define i32 @_render_cond_0_case_0() { +entry: + %var40 = call i32 @js_create_element(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.0, i32 0, i32 0)) + %var41 = 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 %var41, 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.2, i32 0, i32 0)) + %var42 = call i32 @js_create_element(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.3, i32 0, i32 0)) + %var43 = call i32 @js_create_text(i8* getelementptr inbounds ([24 x i8], [24 x i8]* @.str.4, i32 0, i32 0)) + call void @js_append_child(i32 %var42, i32 %var43) + call void @js_append_child(i32 %var41, i32 %var42) + call void @js_append_child(i32 %var41, i32 %var42) + %var44 = call i32 @js_create_element(i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.5, i32 0, i32 0)) + %var45 = call i32 @js_create_text(i8* getelementptr inbounds ([18 x i8], [18 x i8]* @.str.6, i32 0, i32 0)) + call void @js_append_child(i32 %var44, i32 %var45) + call void @js_append_child(i32 %var41, i32 %var44) + call void @js_append_child(i32 %var41, i32 %var44) + %var46 = call i32 @js_create_element(i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.5, i32 0, i32 0)) + %var47 = call i32 @js_create_text(i8* getelementptr inbounds ([15 x i8], [15 x i8]* @.str.7, i32 0, i32 0)) + call void @js_append_child(i32 %var46, i32 %var47) + call void @js_append_child(i32 %var41, i32 %var46) + call void @js_append_child(i32 %var41, i32 %var46) + call void @js_append_child(i32 %var40, i32 %var41) + ret i32 %var40 +} + +define i32 @_render_cond_0_case_1() { +entry: + %var48 = call i32 @js_create_element(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.0, i32 0, i32 0)) + %var49 = 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 %var49, 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.2, i32 0, i32 0)) + %var50 = call i32 @js_create_element(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.3, i32 0, i32 0)) + %var51 = call i32 @js_create_text(i8* getelementptr inbounds ([22 x i8], [22 x i8]* @.str.8, i32 0, i32 0)) + call void @js_append_child(i32 %var50, i32 %var51) + call void @js_append_child(i32 %var49, i32 %var50) + call void @js_append_child(i32 %var49, i32 %var50) + %var52 = call i32 @js_create_element(i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.5, i32 0, i32 0)) + %var53 = call i32 @js_create_text(i8* getelementptr inbounds ([26 x i8], [26 x i8]* @.str.9, i32 0, i32 0)) + call void @js_append_child(i32 %var52, i32 %var53) + call void @js_append_child(i32 %var49, i32 %var52) + call void @js_append_child(i32 %var49, i32 %var52) + %var54 = call i32 @js_create_element(i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.5, i32 0, i32 0)) + %var55 = call i32 @js_create_text(i8* getelementptr inbounds ([19 x i8], [19 x i8]* @.str.10, i32 0, i32 0)) + call void @js_append_child(i32 %var54, i32 %var55) + call void @js_append_child(i32 %var49, i32 %var54) + call void @js_append_child(i32 %var49, i32 %var54) + call void @js_append_child(i32 %var48, i32 %var49) + ret i32 %var48 +} + +define i32 @_render_cond_0_case_2() { +entry: + %var56 = call i32 @js_create_element(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.0, i32 0, i32 0)) + %var57 = 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 %var57, 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.2, i32 0, i32 0)) + %var58 = call i32 @js_create_element(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.3, i32 0, i32 0)) + %var59 = call i32 @js_create_text(i8* getelementptr inbounds ([23 x i8], [23 x i8]* @.str.11, i32 0, i32 0)) + call void @js_append_child(i32 %var58, i32 %var59) + call void @js_append_child(i32 %var57, i32 %var58) + call void @js_append_child(i32 %var57, i32 %var58) + %var60 = call i32 @js_create_element(i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.5, i32 0, i32 0)) + %var61 = call i32 @js_create_text(i8* getelementptr inbounds ([16 x i8], [16 x i8]* @.str.12, i32 0, i32 0)) + call void @js_append_child(i32 %var60, i32 %var61) + call void @js_append_child(i32 %var57, i32 %var60) + call void @js_append_child(i32 %var57, i32 %var60) + %var62 = call i32 @js_create_element(i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.5, i32 0, i32 0)) + %var63 = call i32 @js_create_text(i8* getelementptr inbounds ([32 x i8], [32 x i8]* @.str.13, i32 0, i32 0)) + call void @js_append_child(i32 %var62, i32 %var63) + call void @js_append_child(i32 %var57, i32 %var62) + call void @js_append_child(i32 %var57, i32 %var62) + call void @js_append_child(i32 %var56, i32 %var57) + ret i32 %var56 +} + +define i32 @_render_cond_0_case_3() { +entry: + %var64 = call i32 @js_create_element(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.0, i32 0, i32 0)) + %var65 = 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 %var65, 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.2, i32 0, i32 0)) + %var66 = call i32 @js_create_element(i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.5, i32 0, i32 0)) + %var67 = call i32 @js_create_text(i8* getelementptr inbounds ([16 x i8], [16 x i8]* @.str.14, i32 0, i32 0)) + call void @js_append_child(i32 %var66, i32 %var67) + call void @js_append_child(i32 %var65, i32 %var66) + call void @js_append_child(i32 %var65, i32 %var66) + call void @js_append_child(i32 %var64, i32 %var65) + ret i32 %var64 +} + +; Component render function +define void @render_VerticalTabs() { +entry: + %var68 = 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 %var68, i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str.1, i32 0, i32 0), i8* getelementptr inbounds ([14 x i8], [14 x i8]* @.str.15, i32 0, i32 0)) + %var69 = 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 %var69, i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str.1, i32 0, i32 0), i8* getelementptr inbounds ([18 x i8], [18 x i8]* @.str.16, i32 0, i32 0)) + %var70 = call i32 @js_create_element(i8* getelementptr inbounds ([7 x i8], [7 x i8]* @.str.17, i32 0, i32 0)) + %var71 = load i32, i32* @signal_VerticalTabs_setting_tab + %var72 = icmp eq i32 %var71, 0 + %var73 = zext i1 %var72 to i32 + %var74 = icmp ne i32 %var73, 0 + %var75 = select i1 %var74, i8* getelementptr inbounds ([20 x i8], [20 x i8]* @.str.18, i32 0, i32 0), i8* getelementptr inbounds ([13 x i8], [13 x i8]* @.str.19, i32 0, i32 0) + call void @js_set_attribute(i32 %var70, i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str.1, i32 0, i32 0), i8* %var75) + call void @js_bind_event(i32 %var70, i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str.20, i32 0, i32 0), i8* getelementptr inbounds ([23 x i8], [23 x i8]* @.str.21, i32 0, i32 0)) + %var76 = call i32 @js_create_text(i8* getelementptr inbounds ([15 x i8], [15 x i8]* @.str.22, i32 0, i32 0)) + call void @js_append_child(i32 %var70, i32 %var76) + call void @js_append_child(i32 %var69, i32 %var70) + call void @js_append_child(i32 %var69, i32 %var70) + %var77 = call i32 @js_create_element(i8* getelementptr inbounds ([7 x i8], [7 x i8]* @.str.17, i32 0, i32 0)) + %var78 = load i32, i32* @signal_VerticalTabs_setting_tab + %var79 = icmp eq i32 %var78, 1 + %var80 = zext i1 %var79 to i32 + %var81 = icmp ne i32 %var80, 0 + %var82 = select i1 %var81, i8* getelementptr inbounds ([20 x i8], [20 x i8]* @.str.18, i32 0, i32 0), i8* getelementptr inbounds ([13 x i8], [13 x i8]* @.str.19, i32 0, i32 0) + call void @js_set_attribute(i32 %var77, i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str.1, i32 0, i32 0), i8* %var82) + call void @js_bind_event(i32 %var77, i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str.20, i32 0, i32 0), i8* getelementptr inbounds ([23 x i8], [23 x i8]* @.str.23, i32 0, i32 0)) + %var83 = call i32 @js_create_text(i8* getelementptr inbounds ([13 x i8], [13 x i8]* @.str.24, i32 0, i32 0)) + call void @js_append_child(i32 %var77, i32 %var83) + call void @js_append_child(i32 %var69, i32 %var77) + call void @js_append_child(i32 %var69, i32 %var77) + %var84 = call i32 @js_create_element(i8* getelementptr inbounds ([7 x i8], [7 x i8]* @.str.17, i32 0, i32 0)) + %var85 = load i32, i32* @signal_VerticalTabs_setting_tab + %var86 = icmp eq i32 %var85, 2 + %var87 = zext i1 %var86 to i32 + %var88 = icmp ne i32 %var87, 0 + %var89 = select i1 %var88, i8* getelementptr inbounds ([20 x i8], [20 x i8]* @.str.18, i32 0, i32 0), i8* getelementptr inbounds ([13 x i8], [13 x i8]* @.str.19, i32 0, i32 0) + call void @js_set_attribute(i32 %var84, i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str.1, i32 0, i32 0), i8* %var89) + call void @js_bind_event(i32 %var84, i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str.20, i32 0, i32 0), i8* getelementptr inbounds ([23 x i8], [23 x i8]* @.str.25, i32 0, i32 0)) + %var90 = call i32 @js_create_text(i8* getelementptr inbounds ([14 x i8], [14 x i8]* @.str.26, i32 0, i32 0)) + call void @js_append_child(i32 %var84, i32 %var90) + call void @js_append_child(i32 %var69, i32 %var84) + call void @js_append_child(i32 %var69, i32 %var84) + call void @js_append_child(i32 %var68, i32 %var69) + call void @js_append_child(i32 %var68, i32 %var69) + %var91 = 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 %var91, i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str.1, i32 0, i32 0), i8* getelementptr inbounds ([21 x i8], [21 x i8]* @.str.27, i32 0, i32 0)) + %var92 = call i32 @js_create_marker() + call void @js_append_child(i32 %var91, i32 %var92) + store i32 %var92, i32* @cond_0_marker + call void @_init_conditional_0() + call void @js_append_child(i32 %var68, i32 %var91) + call void @js_append_child(i32 %var68, i32 %var91) + call void @js_set_root(i32 %var68) + ret void +} + +; Signal storage for Tabs (reactive state in WASM memory) +@signal_Tabs_tab_index = global i32 0 + +; Conditional rendering state +@cond_1_marker = global i32 0 +@cond_1_current = global i32 0 +@cond_1_case_0_root = global i32 0 +@cond_1_case_1_root = global i32 0 +@cond_1_case_2_root = global i32 0 +@cond_1_case_3_root = global i32 0 + +; Signal helper functions +define i32 @get_tab_index() { +entry: + %val = load i32, i32* @signal_Tabs_tab_index + ret i32 %val +} + +define void @set_tab_index(i32 %newval) { +entry: + store i32 %newval, i32* @signal_Tabs_tab_index + ; TODO: Trigger DOM update callback + ret void +} + +; Event handler: _lambda_0_Tabs +define void @_lambda_0_Tabs() { +entry: + call void @set_tab(i32 0) + ret void +} + +; Event handler: _lambda_1_Tabs +define void @_lambda_1_Tabs() { +entry: + call void @set_tab(i32 1) + ret void +} + +; Event handler: _lambda_2_Tabs +define void @_lambda_2_Tabs() { +entry: + call void @set_tab(i32 2) + ret void +} + +; Event handler: set_tab +define void @set_tab(i32 %value) { +entry: + store i32 %value, i32* @signal_Tabs_tab_index + call void @reevaluate_conditional_1() + ret void +} + +; Initialize conditional 1 (match) +define void @_init_conditional_1() { +entry: + ; Render all cases upfront + %var93 = call i32 @_render_cond_1_case_0() + store i32 %var93, i32* @cond_1_case_0_root + %var94 = call i32 @_render_cond_1_case_1() + store i32 %var94, i32* @cond_1_case_1_root + %var95 = call i32 @_render_cond_1_case_2() + store i32 %var95, i32* @cond_1_case_2_root + %var96 = call i32 @_render_cond_1_case_3() + store i32 %var96, i32* @cond_1_case_3_root + %var97 = load i32, i32* @signal_Tabs_tab_index + %var98 = load i32, i32* @cond_1_marker + switch i32 %var97, label %insert_case_3 [ + i32 0, label %insert_case_0 + i32 1, label %insert_case_1 + i32 2, label %insert_case_2 + ] +insert_case_0: + call void @js_replace_at_marker(i32 %var98, i32 0, i32 %var93) + store i32 0, i32* @cond_1_current + ret void +insert_case_1: + call void @js_replace_at_marker(i32 %var98, i32 0, i32 %var94) + store i32 1, i32* @cond_1_current + ret void +insert_case_2: + call void @js_replace_at_marker(i32 %var98, i32 0, i32 %var95) + store i32 2, i32* @cond_1_current + ret void +insert_case_3: + call void @js_replace_at_marker(i32 %var98, i32 0, i32 %var96) + store i32 3, i32* @cond_1_current + ret void +} + +; Re-evaluate conditional 1 (match) +define void @reevaluate_conditional_1() { +entry: + %var99 = load i32, i32* @signal_Tabs_tab_index + %var100 = load i32, i32* @cond_1_current + switch i32 %var99, label %case_3 [ + i32 0, label %case_0 + i32 1, label %case_1 + i32 2, label %case_2 + ] +case_0: + %var101 = icmp ne i32 %var100, 0 + br i1 %var101, label %swap_0, label %done +swap_0: + %var102 = load i32, i32* @cond_1_marker + %var103 = load i32, i32* @cond_1_case_0_root + switch i32 %var100, label %load_old_0_3 [ + i32 0, label %load_old_0_0 + i32 1, label %load_old_0_1 + i32 2, label %load_old_0_2 + i32 3, label %load_old_0_3 + ] +load_old_0_0: + %var105 = load i32, i32* @cond_1_case_0_root + br label %merge_0 +load_old_0_1: + %var106 = load i32, i32* @cond_1_case_1_root + br label %merge_0 +load_old_0_2: + %var107 = load i32, i32* @cond_1_case_2_root + br label %merge_0 +load_old_0_3: + %var108 = load i32, i32* @cond_1_case_3_root + br label %merge_0 +merge_0: + %var104 = phi i32 [ %var105, %load_old_0_0 ], [ %var106, %load_old_0_1 ], [ %var107, %load_old_0_2 ], [ %var108, %load_old_0_3 ] + call void @js_replace_at_marker(i32 %var102, i32 %var104, i32 %var103) + store i32 0, i32* @cond_1_current + br label %done +case_1: + %var109 = icmp ne i32 %var100, 1 + br i1 %var109, label %swap_1, label %done +swap_1: + %var110 = load i32, i32* @cond_1_marker + %var111 = load i32, i32* @cond_1_case_1_root + switch i32 %var100, label %load_old_1_3 [ + i32 0, label %load_old_1_0 + i32 1, label %load_old_1_1 + i32 2, label %load_old_1_2 + i32 3, label %load_old_1_3 + ] +load_old_1_0: + %var113 = load i32, i32* @cond_1_case_0_root + br label %merge_1 +load_old_1_1: + %var114 = load i32, i32* @cond_1_case_1_root + br label %merge_1 +load_old_1_2: + %var115 = load i32, i32* @cond_1_case_2_root + br label %merge_1 +load_old_1_3: + %var116 = load i32, i32* @cond_1_case_3_root + br label %merge_1 +merge_1: + %var112 = phi i32 [ %var113, %load_old_1_0 ], [ %var114, %load_old_1_1 ], [ %var115, %load_old_1_2 ], [ %var116, %load_old_1_3 ] + call void @js_replace_at_marker(i32 %var110, i32 %var112, i32 %var111) + store i32 1, i32* @cond_1_current + br label %done +case_2: + %var117 = icmp ne i32 %var100, 2 + br i1 %var117, label %swap_2, label %done +swap_2: + %var118 = load i32, i32* @cond_1_marker + %var119 = load i32, i32* @cond_1_case_2_root + switch i32 %var100, label %load_old_2_3 [ + i32 0, label %load_old_2_0 + i32 1, label %load_old_2_1 + i32 2, label %load_old_2_2 + i32 3, label %load_old_2_3 + ] +load_old_2_0: + %var121 = load i32, i32* @cond_1_case_0_root + br label %merge_2 +load_old_2_1: + %var122 = load i32, i32* @cond_1_case_1_root + br label %merge_2 +load_old_2_2: + %var123 = load i32, i32* @cond_1_case_2_root + br label %merge_2 +load_old_2_3: + %var124 = load i32, i32* @cond_1_case_3_root + br label %merge_2 +merge_2: + %var120 = phi i32 [ %var121, %load_old_2_0 ], [ %var122, %load_old_2_1 ], [ %var123, %load_old_2_2 ], [ %var124, %load_old_2_3 ] + call void @js_replace_at_marker(i32 %var118, i32 %var120, i32 %var119) + store i32 2, i32* @cond_1_current + br label %done +case_3: + %var125 = icmp ne i32 %var100, 3 + br i1 %var125, label %swap_3, label %done +swap_3: + %var126 = load i32, i32* @cond_1_marker + %var127 = load i32, i32* @cond_1_case_3_root + switch i32 %var100, label %load_old_3_3 [ + i32 0, label %load_old_3_0 + i32 1, label %load_old_3_1 + i32 2, label %load_old_3_2 + i32 3, label %load_old_3_3 + ] +load_old_3_0: + %var129 = load i32, i32* @cond_1_case_0_root + br label %merge_3 +load_old_3_1: + %var130 = load i32, i32* @cond_1_case_1_root + br label %merge_3 +load_old_3_2: + %var131 = load i32, i32* @cond_1_case_2_root + br label %merge_3 +load_old_3_3: + %var132 = load i32, i32* @cond_1_case_3_root + br label %merge_3 +merge_3: + %var128 = phi i32 [ %var129, %load_old_3_0 ], [ %var130, %load_old_3_1 ], [ %var131, %load_old_3_2 ], [ %var132, %load_old_3_3 ] + call void @js_replace_at_marker(i32 %var126, i32 %var128, i32 %var127) + store i32 3, i32* @cond_1_current + br label %done +done: + ret void +} + +define i32 @_render_cond_1_case_0() { +entry: + %var133 = call i32 @js_create_element(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.0, i32 0, i32 0)) + %var134 = 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 %var134, i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str.1, i32 0, i32 0), i8* getelementptr inbounds ([14 x i8], [14 x i8]* @.str.28, i32 0, i32 0)) + %var135 = call i32 @js_create_element(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.29, i32 0, i32 0)) + %var136 = call i32 @js_create_text(i8* getelementptr inbounds ([18 x i8], [18 x i8]* @.str.30, i32 0, i32 0)) + call void @js_append_child(i32 %var135, i32 %var136) + call void @js_append_child(i32 %var134, i32 %var135) + call void @js_append_child(i32 %var134, i32 %var135) + %var137 = call i32 @js_create_element(i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.5, i32 0, i32 0)) + %var138 = call i32 @js_create_text(i8* getelementptr inbounds ([29 x i8], [29 x i8]* @.str.31, i32 0, i32 0)) + call void @js_append_child(i32 %var137, i32 %var138) + call void @js_append_child(i32 %var134, i32 %var137) + call void @js_append_child(i32 %var134, i32 %var137) + call void @js_append_child(i32 %var133, i32 %var134) + ret i32 %var133 +} + +define i32 @_render_cond_1_case_1() { +entry: + %var139 = call i32 @js_create_element(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.0, i32 0, i32 0)) + %var140 = 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 %var140, i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str.1, i32 0, i32 0), i8* getelementptr inbounds ([17 x i8], [17 x i8]* @.str.32, i32 0, i32 0)) + %var141 = call i32 @js_create_element(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.29, i32 0, i32 0)) + %var142 = call i32 @js_create_text(i8* getelementptr inbounds ([18 x i8], [18 x i8]* @.str.33, i32 0, i32 0)) + call void @js_append_child(i32 %var141, i32 %var142) + call void @js_append_child(i32 %var140, i32 %var141) + call void @js_append_child(i32 %var140, i32 %var141) + %var143 = call i32 @js_create_element(i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.5, i32 0, i32 0)) + %var144 = call i32 @js_create_text(i8* getelementptr inbounds ([30 x i8], [30 x i8]* @.str.34, i32 0, i32 0)) + call void @js_append_child(i32 %var143, i32 %var144) + call void @js_append_child(i32 %var140, i32 %var143) + call void @js_append_child(i32 %var140, i32 %var143) + call void @js_append_child(i32 %var139, i32 %var140) + ret i32 %var139 +} + +define i32 @_render_cond_1_case_2() { +entry: + %var145 = call i32 @js_create_element(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.0, i32 0, i32 0)) + %var146 = 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 %var146, i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str.1, i32 0, i32 0), i8* getelementptr inbounds ([18 x i8], [18 x i8]* @.str.35, i32 0, i32 0)) + %var147 = call i32 @js_create_element(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.29, i32 0, i32 0)) + %var148 = call i32 @js_create_text(i8* getelementptr inbounds ([16 x i8], [16 x i8]* @.str.36, i32 0, i32 0)) + call void @js_append_child(i32 %var147, i32 %var148) + call void @js_append_child(i32 %var146, i32 %var147) + call void @js_append_child(i32 %var146, i32 %var147) + %var149 = call i32 @js_create_element(i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.5, i32 0, i32 0)) + %var150 = call i32 @js_create_text(i8* getelementptr inbounds ([55 x i8], [55 x i8]* @.str.37, i32 0, i32 0)) + call void @js_append_child(i32 %var149, i32 %var150) + call void @js_append_child(i32 %var146, i32 %var149) + call void @js_append_child(i32 %var146, i32 %var149) + call void @render_VerticalTabs() + call void @js_append_child(i32 %var145, i32 %var146) + ret i32 %var145 +} + +define i32 @_render_cond_1_case_3() { +entry: + %var151 = call i32 @js_create_element(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.0, i32 0, i32 0)) + %var152 = 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 %var152, i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str.1, i32 0, i32 0), i8* getelementptr inbounds ([15 x i8], [15 x i8]* @.str.38, i32 0, i32 0)) + %var153 = call i32 @js_create_element(i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.5, i32 0, i32 0)) + %var154 = call i32 @js_create_text(i8* getelementptr inbounds ([28 x i8], [28 x i8]* @.str.39, i32 0, i32 0)) + call void @js_append_child(i32 %var153, i32 %var154) + call void @js_append_child(i32 %var152, i32 %var153) + call void @js_append_child(i32 %var152, i32 %var153) + call void @js_append_child(i32 %var151, i32 %var152) + ret i32 %var151 +} + +; Component render function +define void @render_Tabs() { +entry: + %var155 = 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 %var155, i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str.1, i32 0, i32 0), i8* getelementptr inbounds ([15 x i8], [15 x i8]* @.str.40, i32 0, i32 0)) + %var156 = call i32 @js_create_element(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.41, i32 0, i32 0)) + %var157 = call i32 @js_create_text(i8* getelementptr inbounds ([19 x i8], [19 x i8]* @.str.42, i32 0, i32 0)) + call void @js_append_child(i32 %var156, i32 %var157) + call void @js_append_child(i32 %var155, i32 %var156) + call void @js_append_child(i32 %var155, i32 %var156) + %var158 = 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 %var158, i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str.1, i32 0, i32 0), i8* getelementptr inbounds ([9 x i8], [9 x i8]* @.str.43, i32 0, i32 0)) + %var159 = call i32 @js_create_text(i8* getelementptr inbounds ([47 x i8], [47 x i8]* @.str.44, i32 0, i32 0)) + call void @js_append_child(i32 %var158, i32 %var159) + call void @js_append_child(i32 %var155, i32 %var158) + call void @js_append_child(i32 %var155, i32 %var158) + %var160 = call i32 @js_create_element(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.45, i32 0, i32 0)) + call void @js_set_attribute(i32 %var160, i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str.1, i32 0, i32 0), i8* getelementptr inbounds ([9 x i8], [9 x i8]* @.str.46, i32 0, i32 0)) + %var161 = call i32 @js_create_element(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.47, i32 0, i32 0)) + %var162 = load i32, i32* @signal_Tabs_tab_index + %var163 = icmp eq i32 %var162, 0 + %var164 = zext i1 %var163 to i32 + %var165 = icmp ne i32 %var164, 0 + %var166 = select i1 %var165, i8* getelementptr inbounds ([11 x i8], [11 x i8]* @.str.48, i32 0, i32 0), i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.49, i32 0, i32 0) + call void @js_set_attribute(i32 %var161, i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str.1, i32 0, i32 0), i8* %var166) + %var167 = call i32 @js_create_element(i8* getelementptr inbounds ([7 x i8], [7 x i8]* @.str.17, i32 0, i32 0)) + call void @js_bind_event(i32 %var167, i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str.20, i32 0, i32 0), i8* getelementptr inbounds ([15 x i8], [15 x i8]* @.str.50, i32 0, i32 0)) + %var168 = call i32 @js_create_text(i8* getelementptr inbounds ([10 x i8], [10 x i8]* @.str.51, i32 0, i32 0)) + call void @js_append_child(i32 %var167, i32 %var168) + call void @js_append_child(i32 %var161, i32 %var167) + call void @js_append_child(i32 %var161, i32 %var167) + call void @js_append_child(i32 %var160, i32 %var161) + call void @js_append_child(i32 %var160, i32 %var161) + %var169 = call i32 @js_create_element(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.47, i32 0, i32 0)) + %var170 = load i32, i32* @signal_Tabs_tab_index + %var171 = icmp eq i32 %var170, 1 + %var172 = zext i1 %var171 to i32 + %var173 = icmp ne i32 %var172, 0 + %var174 = select i1 %var173, i8* getelementptr inbounds ([11 x i8], [11 x i8]* @.str.48, i32 0, i32 0), i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.49, i32 0, i32 0) + call void @js_set_attribute(i32 %var169, i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str.1, i32 0, i32 0), i8* %var174) + %var175 = call i32 @js_create_element(i8* getelementptr inbounds ([7 x i8], [7 x i8]* @.str.17, i32 0, i32 0)) + call void @js_bind_event(i32 %var175, i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str.20, i32 0, i32 0), i8* getelementptr inbounds ([15 x i8], [15 x i8]* @.str.52, i32 0, i32 0)) + %var176 = call i32 @js_create_text(i8* getelementptr inbounds ([13 x i8], [13 x i8]* @.str.53, i32 0, i32 0)) + call void @js_append_child(i32 %var175, i32 %var176) + call void @js_append_child(i32 %var169, i32 %var175) + call void @js_append_child(i32 %var169, i32 %var175) + call void @js_append_child(i32 %var160, i32 %var169) + call void @js_append_child(i32 %var160, i32 %var169) + %var177 = call i32 @js_create_element(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.47, i32 0, i32 0)) + %var178 = load i32, i32* @signal_Tabs_tab_index + %var179 = icmp eq i32 %var178, 2 + %var180 = zext i1 %var179 to i32 + %var181 = icmp ne i32 %var180, 0 + %var182 = select i1 %var181, i8* getelementptr inbounds ([11 x i8], [11 x i8]* @.str.48, i32 0, i32 0), i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.49, i32 0, i32 0) + call void @js_set_attribute(i32 %var177, i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str.1, i32 0, i32 0), i8* %var182) + %var183 = call i32 @js_create_element(i8* getelementptr inbounds ([7 x i8], [7 x i8]* @.str.17, i32 0, i32 0)) + call void @js_bind_event(i32 %var183, i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str.20, i32 0, i32 0), i8* getelementptr inbounds ([15 x i8], [15 x i8]* @.str.54, i32 0, i32 0)) + %var184 = call i32 @js_create_text(i8* getelementptr inbounds ([16 x i8], [16 x i8]* @.str.36, i32 0, i32 0)) + call void @js_append_child(i32 %var183, i32 %var184) + call void @js_append_child(i32 %var177, i32 %var183) + call void @js_append_child(i32 %var177, i32 %var183) + call void @js_append_child(i32 %var160, i32 %var177) + call void @js_append_child(i32 %var160, i32 %var177) + call void @js_append_child(i32 %var155, i32 %var160) + call void @js_append_child(i32 %var155, i32 %var160) + %var185 = 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 %var185, i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str.1, i32 0, i32 0), i8* getelementptr inbounds ([12 x i8], [12 x i8]* @.str.55, i32 0, i32 0)) + %var186 = call i32 @js_create_marker() + call void @js_append_child(i32 %var185, i32 %var186) + store i32 %var186, i32* @cond_1_marker + call void @_init_conditional_1() + call void @js_append_child(i32 %var155, i32 %var185) + call void @js_append_child(i32 %var155, i32 %var185) + call void @js_set_root(i32 %var155) + ret void +} diff --git a/examples/tabs/TabsTernary.wasm b/examples/tabs/TabsTernary.wasm new file mode 100755 index 0000000000000000000000000000000000000000..b2897b49213bd386f544d1ddd987c5ed6234134b GIT binary patch literal 4956 zcmb7IO=uj+6|U~q&uD5!)2*@Wb>v;w%qbwWcqG_^$srxvN&;CDh_d;)w0mYsGadDG z58XYobO>bwgm;TyjNA-)1w)& zyOJo?&wH=ld*7?CyPCLhPa}kAR~Bv)a+_#}x3xoZ+c-RgRy%~D4n6&MTEXDKzV+kS zX+_*kxWj$k<3U2^aNdOZm?w^#B$3w~B%ByHy*w6A_+2Gifl0UD=Rw# zpUJ_zp%H!INV{}M?B^zh_EXUgE$rVD?VF-~A?803?U9&yDB8!O9f|g-Xzz>mShT|e z+WEEUKa=f)Ih>LU&(uJU2rg)J@o$S;3q9ToqXV5-j&ldlaaykLJFO&)Vp6DdAUcRJ z@q&(%xJ|NjHTF7z>pO4oDDgma$8Cxnq!I?HU`Fyf#fy&b_L^sDg zfLmeE_7X2daO8xxaTa&oS$e2@iZ%rB=t4I*$lF&1WSu|+Oa zRZMwE$Z8p(1IQo`ZGM+rTvfmcz_NK`v5aZU#^loS7%UVeFP#TcgIvyJ8;+3uQZ}(E zC)O5~b#i3}APw^JWK4||kXK}e(y`1?VWx0{T%8bBfGo`v-Xv^7SOHR;m{fpJ2}nbc zgHe)zfKLjL^2{x^NR28$L{91@$7#o*({+Qk&yD3G4BfljFtntCPHkN%=-XvoDdct- zE8J5G8u()y+ht7(*L3g(Ox2B=mio_#@?5%A(@L<5*burJg&;to28MK|F~gj*L6<@r zn1&frDZ)OaNajn=4MZMcQWmIS2^!67b`&56L+ybQ{y5r%Ov z-6l+fpdcQBcwaLPr6am@M9Um`zX*;H`?M$=0ocGD(MlH~CVJk=AE$IMo1m}L&)#r! zuGy1wS5Bu^zQBgV(s^;bFF}|Q`)Eoh+wdz{O100At=fXVrKj3Z15grwDnLnKq0|L1 zCnXsE94kZ=%x{bKX-Oi#W`YU(*^)ghoAc27)wJtlJx~Hwas2V5rm7>UIxI}(W40=s z*;MsJsy;avc!WO}$Y~igHFKekCH+DcqiLo&l(k|mB1s+Lc|?*rvNDo7vLs1eRwQ*S z&MZmK0{)kJ6C`yXrRimINkNJPNnJ*gf`K3@HIO8AS&`I3 z%X~$W)MLxMDoJW&nd}^r`ZrdjBB`M%DrK6aAX|c@RDfw%5|qzPQV@?IsW;Ly0jUya zK@|T#kuCp%B&FHIW#tHx3^JS{UDWK+)Cv?CQkhO?n>|?`n?0RUPR$N0XE)5u{$QrJ zqsrLqZ{z_JeolIOGG*3W%?!^bme0T=C6@n+r@6?UfyD9?%-#o*;ztrj@qA(ODI)+D zY5r-^L}odemicAILl3Yf-ov3_srQQZM@tfGAPC76 zG+)jO!&}56rT4-zzf<2TxkcQ1Mm6?-Zopl8^`41 zN5A;T@84$Ml^3s=?5oSx2I#~jeL+|6*y&KcgQvr5@(mn!>AL}EJc_~y_lh@gGuI2? z!rLcsdrrcD4E%J{uX9*%eelFSxD+~mzchrJ%Q`E~Z~-CZ=v z+*ac4bD~7Vh9WGnb2sd9^8Cr$BlZpK#e-(zB|c6)cnTQ_cRew9G-P&r-wj&4JrOY3 z@p_#7C=6h~@9o?m-7V7HB;5wSq|i$$Rm$se%HTbPTHkVm&cN+};;o?LdvO;Y1eC7k zp~z{RP`Y^&Ud`E!(Dyk+6b9GXO)th5={Au+He62+;NlxY?EPdT93%j5iC%pEBGX@a{{mgP6U0D(Ee5cj?bedpz&eQAyeC9T7k8*2gZq4>d zZtcv)**-1P3;E4NePA&H!BR^A_kHfS06PgFuq(Z`)AeEoe+S_pVu&znyK%P}x>5U8 zOjTBQeFd<6DvSZ-KSY%jcY9c&jn~}(P?EOXRx2C?Nm_0(TFZ>70*ir}D)hA*VX*6U zAe&ONAMsrdSFaY2*&v2eWl5K_7JOXjgpmi6O%B(r>kyVnH$Q$f!XuUzHx_XW-y_RBcJuj$yxhg>)d0?81mCE@<&E8b5_&8pU3OP-oS^m2Om-R{{dYdqs0IK literal 0 HcmV?d00001 diff --git a/examples/tabs/ritz-runtime.js b/examples/tabs/ritz-runtime.js new file mode 100644 index 0000000..3a23d1b --- /dev/null +++ b/examples/tabs/ritz-runtime.js @@ -0,0 +1,354 @@ +/** + * Ritz Runtime - WebAssembly DOM Bridge + * + * Provides the runtime environment for Ritz components compiled to WASM. + */ + +class RitzRuntime { + constructor(rootElement) { + this.rootElement = rootElement || document.getElementById('app'); + this.nodes = new Map(); + this.nextNodeId = 1; + this.log = []; + this.wasmInstance = null; + this.debugEnabled = true; + } + + // ===== DOM Manipulation Bridge ===== + + js_create_element(tagPtr) { + const tag = this.readString(tagPtr); + const element = document.createElement(tag); + const id = this.nextNodeId++; + this.nodes.set(id, element); + this._log(`createElement("${tag}") = ${id}`); + return id; + } + + js_create_text(textPtr) { + const text = this.readString(textPtr); + const textNode = document.createTextNode(text); + const id = this.nextNodeId++; + this.nodes.set(id, textNode); + this._log(`createTextNode("${text}") = ${id}`); + return id; + } + + js_append_child(parentId, childId) { + const parent = this.nodes.get(parentId); + const child = this.nodes.get(childId); + if (parent && child) { + parent.appendChild(child); + this._log(`appendChild(${parentId}, ${childId})`); + } + } + + js_set_attribute(elemId, namePtr, valuePtr) { + const element = this.nodes.get(elemId); + const name = this.readString(namePtr); + const value = this.readString(valuePtr); + if (element) { + if (name === 'class') { + element.className = value; + } else { + element.setAttribute(name, value); + } + this._log(`setAttribute(${elemId}, "${name}", "${value}")`); + } + } + + js_bind_event(elemId, eventNamePtr, handlerNamePtr) { + const element = this.nodes.get(elemId); + const eventName = this.readString(eventNamePtr); + const handlerName = this.readString(handlerNamePtr); + + if (element && this.wasmInstance) { + const handler = this.wasmInstance.exports[handlerName]; + if (handler) { + element.addEventListener(eventName, () => { + this._log(`[Event] ${eventName} → ${handlerName}()`); + handler(); + this.updateSignals(); + }); + this._log(`bindEvent(${elemId}, "${eventName}", "${handlerName}")`); + } else { + console.error(`Handler ${handlerName} not found in WASM exports`); + } + } + } + + js_set_root(elemId) { + const element = this.nodes.get(elemId); + if (element) { + this.rootElement.innerHTML = ''; + this.rootElement.appendChild(element); + this._log(`setRoot(${elemId})`); + } + } + + js_update_text_content(nodeId, textPtr) { + const node = this.nodes.get(nodeId); + const text = this.readString(textPtr); + if (node) { + node.textContent = text; + this._log(`updateTextContent(${nodeId}, "${text}")`); + } + } + + // ===== Signal Management ===== + + updateSignals() { + // Discover and update all signals + if (!this.wasmInstance) return; + + const exports = this.wasmInstance.exports; + + // Find all get_* functions (signal getters) + for (const [name, fn] of Object.entries(exports)) { + if (name.startsWith('get_') && typeof fn === 'function') { + const signalName = name.substring(4); // Remove 'get_' prefix + const value = fn(); + this._log(`[Signal] ${signalName} = ${value}`); + + // Update DOM elements bound to this signal + // TODO: Track signal-to-DOM bindings during render for efficiency + this.updateSignalDisplay(signalName, value); + } + } + + // Re-evaluate all reactive conditionals + for (const [name, fn] of Object.entries(exports)) { + if (name.startsWith('reevaluate_conditional_') && typeof fn === 'function') { + fn(); + this._log(`[Reactive] ${name}()`); + } + } + + // Re-evaluate all reactive match statements + for (const [name, fn] of Object.entries(exports)) { + if (name.startsWith('reevaluate_match_') && typeof fn === 'function') { + fn(); + this._log(`[Reactive] ${name}()`); + } + } + } + + updateSignalDisplay(signalName, value) { + // Find DOM elements that should display this signal + // For now, update any element with class matching signal name or data-signal attribute + const selectors = [ + `[data-signal="${signalName}"]`, + `.${signalName}`, + '.count', // Hardcoded for demo - TODO: track bindings properly + ]; + + selectors.forEach(selector => { + const elements = document.querySelectorAll(selector); + elements.forEach(el => { + // Check if text contains the signal name or looks like a counter + const text = el.textContent; + if (text.includes(signalName) || text.match(/\d+/)) { + // Replace the number in the text + el.textContent = text.replace(/\d+/, value); + } + }); + }); + } + + // ===== Reactive Conditional Rendering ===== + + js_create_marker() { + // Create a comment node as a marker for conditional insertion + const marker = document.createComment('conditional-marker'); + const id = this.nextNodeId++; + this.nodes.set(id, marker); + this._log(`Created marker node ${id}`); + return id; + } + + js_replace_at_marker(markerId, oldNodeId, newNodeId) { + // Replace DOM node at marker position + const marker = this.nodes.get(markerId); + if (!marker) { + console.error(`[replace_at_marker] Marker ${markerId} not found`); + return; + } + + const parent = marker.parentNode; + if (!parent) { + console.error(`[replace_at_marker] Marker ${markerId} has no parent`); + return; + } + + this._log(`[replace_at_marker] marker=${markerId}, old=${oldNodeId}, new=${newNodeId}`); + + // Remove old node if it exists (0 means no old node to remove) + if (oldNodeId !== 0) { + const oldNode = this.nodes.get(oldNodeId); + if (!oldNode) { + console.warn(`[replace_at_marker] Old node ${oldNodeId} not found in registry`); + } else if (!oldNode.parentNode) { + console.warn(`[replace_at_marker] Old node ${oldNodeId} not in DOM`); + } else if (oldNode.parentNode !== parent) { + console.warn(`[replace_at_marker] Old node ${oldNodeId} in wrong parent`); + oldNode.parentNode.removeChild(oldNode); + this._log(`[replace_at_marker] Removed ${oldNodeId} from wrong parent`); + } else { + // Remove from correct parent + parent.removeChild(oldNode); + this._log(`[replace_at_marker] Removed ${oldNodeId} from correct parent`); + } + } + + // Insert new node after marker (only if newNodeId is not 0) + if (newNodeId !== 0) { + const newNode = this.nodes.get(newNodeId); + if (!newNode) { + console.error(`[replace_at_marker] New node ${newNodeId} not found`); + return; + } + + // Insert right after the marker + // If newNode is already in DOM elsewhere, this will move it + const nextSibling = marker.nextSibling; + if (nextSibling) { + parent.insertBefore(newNode, nextSibling); + this._log(`[replace_at_marker] Inserted ${newNodeId} before sibling`); + } else { + parent.appendChild(newNode); + this._log(`[replace_at_marker] Appended ${newNodeId} (no sibling)`); + } + } + } + + // ===== Memory & String Utilities ===== + + readString(ptr) { + if (!this.memory) return ''; + const bytes = new Uint8Array(this.memory.buffer, ptr); + let length = 0; + while (bytes[length] !== 0) length++; + return new TextDecoder().decode(bytes.slice(0, length)); + } + + setMemory(memory) { + this.memory = memory; + } + + setWasmInstance(instance) { + this.wasmInstance = instance; + } + + // ===== Logging & Debug ===== + + _log(message) { + if (this.debugEnabled) { + this.log.push(message); + } + } + + getLog() { + return this.log; + } + + clearLog() { + this.log = []; + } +} + + +/** + * RitzLoader - Simplified WASM loading + */ +class RitzLoader { + constructor(options = {}) { + this.rootElement = options.rootElement || document.getElementById('app'); + this.statusElement = options.statusElement || document.getElementById('status'); + this.onLoad = options.onLoad || (() => {}); + this.onError = options.onError || ((err) => console.error(err)); + } + + async load(wasmPath, componentName, props = {}) { + try { + this.setStatus('⏳ Creating runtime...'); + const runtime = new RitzRuntime(this.rootElement); + + this.setStatus(`⏳ Loading ${wasmPath}...`); + const response = await fetch(wasmPath); + if (!response.ok) { + throw new Error(`Failed to load ${wasmPath}: ${response.status}`); + } + + const wasmBytes = await response.arrayBuffer(); + + this.setStatus('⏳ Instantiating WASM...'); + + // Create imports for WASM + const imports = { + env: { + js_create_element: (ptr) => runtime.js_create_element(ptr), + js_create_text: (ptr) => runtime.js_create_text(ptr), + js_append_child: (p, c) => runtime.js_append_child(p, c), + js_set_attribute: (e, n, v) => runtime.js_set_attribute(e, n, v), + js_set_root: (e) => runtime.js_set_root(e), + js_bind_event: (e, n, h) => runtime.js_bind_event(e, n, h), + js_update_text_content: (n, t) => runtime.js_update_text_content(n, t), + js_create_marker: () => runtime.js_create_marker(), + js_replace_at_marker: (m, o, n) => runtime.js_replace_at_marker(m, o, n), + } + }; + + const { instance } = await WebAssembly.instantiate(wasmBytes, imports); + + // Setup runtime + runtime.setMemory(instance.exports.memory); + runtime.setWasmInstance(instance); + + this.setStatus(`⏳ Rendering ${componentName}...`); + + // Call the render function with props + const renderFn = instance.exports[`render_${componentName}`]; + if (!renderFn) { + throw new Error(`render_${componentName} not found in WASM exports`); + } + + // Pass props as positional arguments + const propValues = Object.values(props); + renderFn(...propValues); + + // Update signals + runtime.updateSignals(); + + this.setStatus(`✅ ${componentName} loaded!`, 'success'); + + // Make runtime globally available for debugging + window.ritzRuntime = runtime; + window.ritzInstance = instance; + + this.onLoad(runtime, instance); + + return { runtime, instance }; + + } catch (error) { + this.setStatus(`❌ Error: ${error.message}`, 'error'); + this.onError(error); + throw error; + } + } + + setStatus(message, type = '') { + if (this.statusElement) { + this.statusElement.textContent = message; + this.statusElement.className = 'status ' + type; + } + } +} + + +// Export for use in modules or global scope +if (typeof module !== 'undefined' && module.exports) { + module.exports = { RitzRuntime, RitzLoader }; +} else { + window.RitzRuntime = RitzRuntime; + window.RitzLoader = RitzLoader; +} diff --git a/examples/toggle/Toggle.ll b/examples/toggle/Toggle.ll index 07b7167..011b0cd 100644 --- a/examples/toggle/Toggle.ll +++ b/examples/toggle/Toggle.ll @@ -1,5 +1,5 @@ ; Generated by Ritz Framework with Signals -; Component: Toggle +; Components: Toggle ; String constants @.str.0 = private unnamed_addr constant [4 x i8] c"div\00" @@ -23,16 +23,6 @@ @.str.18 = private unnamed_addr constant [18 x i8] c"Increment Counter\00" @.str.19 = private unnamed_addr constant [8 x i8] c"display\00" -; Signal storage (reactive state in WASM memory) -@signal_count = global i32 0 - -; Conditional rendering state -@cond_0_parent = global i32 0 -@cond_0_marker = global i32 0 -@cond_0_current = global i32 0 -@cond_0_then_root = global i32 0 -@cond_0_else_root = global i32 0 - ; JavaScript bridge function declarations declare i32 @js_create_element(i8*) declare i32 @js_create_text(i8*) @@ -44,16 +34,25 @@ declare void @js_update_text_content(i32, i8*) declare i32 @js_create_marker() declare void @js_replace_at_marker(i32, i32, i32) +; Signal storage for Toggle (reactive state in WASM memory) +@signal_Toggle_count = global i32 0 + +; Conditional rendering state +@cond_0_marker = global i32 0 +@cond_0_current = global i32 0 +@cond_0_then_root = global i32 0 +@cond_0_else_root = global i32 0 + ; Signal helper functions define i32 @get_count() { entry: - %val = load i32, i32* @signal_count + %val = load i32, i32* @signal_Toggle_count ret i32 %val } define void @set_count(i32 %newval) { entry: - store i32 %newval, i32* @signal_count + store i32 %newval, i32* @signal_Toggle_count ; TODO: Trigger DOM update callback ret void } @@ -61,65 +60,33 @@ entry: ; Event handler: increment define void @increment() { entry: - %var0 = load i32, i32* @signal_count + %var0 = load i32, i32* @signal_Toggle_count %var1 = add i32 %var0, 1 - store i32 %var1, i32* @signal_count + store i32 %var1, i32* @signal_Toggle_count call void @reevaluate_conditional_0() ret void } -; Conditional 0 - then branch -define i32 @_render_cond_0_then() { -entry: - %var2 = 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 %var2, 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.2, i32 0, i32 0)) - %var3 = call i32 @js_create_element(i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.3, i32 0, i32 0)) - %var4 = call i32 @js_create_text(i8* getelementptr inbounds ([24 x i8], [24 x i8]* @.str.4, i32 0, i32 0)) - call void @js_append_child(i32 %var3, i32 %var4) - call void @js_append_child(i32 %var2, i32 %var3) - %var5 = call i32 @js_create_element(i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.3, i32 0, i32 0)) - call void @js_set_attribute(i32 %var5, i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str.1, i32 0, i32 0), i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str.5, i32 0, i32 0)) - ; TODO: Format f-string with signal count - %var6 = call i32 @js_create_text(i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.6, i32 0, i32 0)) - call void @js_append_child(i32 %var5, i32 %var6) - call void @js_append_child(i32 %var2, i32 %var5) - ret i32 %var2 -} - -; Conditional 0 - else branch -define i32 @_render_cond_0_else() { -entry: - %var7 = 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 %var7, i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str.1, i32 0, i32 0), i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.7, i32 0, i32 0)) - %var8 = call i32 @js_create_element(i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.3, i32 0, i32 0)) - %var9 = call i32 @js_create_text(i8* getelementptr inbounds ([25 x i8], [25 x i8]* @.str.8, i32 0, i32 0)) - call void @js_append_child(i32 %var8, i32 %var9) - call void @js_append_child(i32 %var7, i32 %var8) - %var10 = call i32 @js_create_element(i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.3, i32 0, i32 0)) - call void @js_set_attribute(i32 %var10, i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str.1, i32 0, i32 0), i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str.5, i32 0, i32 0)) - ; TODO: Format f-string with signal count - %var11 = call i32 @js_create_text(i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.6, i32 0, i32 0)) - call void @js_append_child(i32 %var10, i32 %var11) - call void @js_append_child(i32 %var7, i32 %var10) - ret i32 %var7 -} - -; Initialize conditional 0 - render both branches -define void @_init_conditional_0(i1 %cond) { +; Initialize conditional 0 +define void @_init_conditional_0() { entry: ; Render both branches upfront - %then_root = call i32 @_render_cond_0_then() - %else_root = call i32 @_render_cond_0_else() - store i32 %then_root, i32* @cond_0_then_root - store i32 %else_root, i32* @cond_0_else_root - %marker = load i32, i32* @cond_0_marker - br i1 %cond, label %insert_then, label %insert_else + %var2 = call i32 @_render_cond_0_then() + %var3 = call i32 @_render_cond_0_else() + store i32 %var2, i32* @cond_0_then_root + store i32 %var3, i32* @cond_0_else_root + %var4 = load i32, i32* @signal_Toggle_count + %var5 = icmp sgt i32 %var4, 5 + %var6 = zext i1 %var5 to i32 + %var7 = icmp ne i32 %var6, 0 + %var8 = load i32, i32* @cond_0_marker + br i1 %var7, label %insert_then, label %insert_else insert_then: - call void @js_replace_at_marker(i32 %marker, i32 0, i32 %then_root) + call void @js_replace_at_marker(i32 %var8, i32 0, i32 %var2) store i32 1, i32* @cond_0_current ret void insert_else: - call void @js_replace_at_marker(i32 %marker, i32 0, i32 %else_root) + call void @js_replace_at_marker(i32 %var8, i32 0, i32 %var3) store i32 0, i32* @cond_0_current ret void } @@ -127,66 +94,110 @@ insert_else: ; Re-evaluate conditional 0 define void @reevaluate_conditional_0() { entry: - %var12 = load i32, i32* @signal_count - %var13 = icmp sgt i32 %var12, 5 - %var15 = load i32, i32* @cond_0_current - %var16 = zext i1 %var13 to i32 - %var17 = icmp ne i32 %var15, %var16 - br i1 %var17, label %swap, label %done + %var9 = load i32, i32* @signal_Toggle_count + %var10 = icmp sgt i32 %var9, 5 + %var11 = zext i1 %var10 to i32 + %var12 = icmp ne i32 %var11, 0 + %var13 = zext i1 %var12 to i32 + %var14 = load i32, i32* @cond_0_current + %var15 = icmp ne i32 %var14, %var13 + br i1 %var15, label %swap, label %done swap: - br i1 %var13, label %swap_to_then, label %swap_to_else + br i1 %var12, label %swap_to_then, label %swap_to_else swap_to_then: - %var18 = load i32, i32* @cond_0_else_root - %var19 = load i32, i32* @cond_0_then_root - %var20 = load i32, i32* @cond_0_marker - call void @js_replace_at_marker(i32 %var20, i32 %var18, i32 %var19) + %var16 = load i32, i32* @cond_0_else_root + %var17 = load i32, i32* @cond_0_then_root + %var18 = load i32, i32* @cond_0_marker + call void @js_replace_at_marker(i32 %var18, i32 %var16, i32 %var17) store i32 1, i32* @cond_0_current br label %done swap_to_else: - %var21 = load i32, i32* @cond_0_then_root - %var22 = load i32, i32* @cond_0_else_root - %var23 = load i32, i32* @cond_0_marker - call void @js_replace_at_marker(i32 %var23, i32 %var21, i32 %var22) + %var19 = load i32, i32* @cond_0_then_root + %var20 = load i32, i32* @cond_0_else_root + %var21 = load i32, i32* @cond_0_marker + call void @js_replace_at_marker(i32 %var21, i32 %var19, i32 %var20) store i32 0, i32* @cond_0_current br label %done done: ret void } +define i32 @_render_cond_0_then() { +entry: + %var22 = call i32 @js_create_element(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.0, i32 0, i32 0)) + %var23 = 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 %var23, 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.2, i32 0, i32 0)) + %var24 = call i32 @js_create_element(i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.3, i32 0, i32 0)) + %var25 = call i32 @js_create_text(i8* getelementptr inbounds ([24 x i8], [24 x i8]* @.str.4, i32 0, i32 0)) + call void @js_append_child(i32 %var24, i32 %var25) + call void @js_append_child(i32 %var23, i32 %var24) + call void @js_append_child(i32 %var23, i32 %var24) + %var26 = call i32 @js_create_element(i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.3, i32 0, i32 0)) + call void @js_set_attribute(i32 %var26, i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str.1, i32 0, i32 0), i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str.5, i32 0, i32 0)) + ; TODO: Format f-string with signal count + %var27 = call i32 @js_create_text(i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.6, i32 0, i32 0)) + call void @js_append_child(i32 %var26, i32 %var27) + call void @js_append_child(i32 %var23, i32 %var26) + call void @js_append_child(i32 %var23, i32 %var26) + call void @js_append_child(i32 %var22, i32 %var23) + ret i32 %var22 +} + +define i32 @_render_cond_0_else() { +entry: + %var28 = call i32 @js_create_element(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.0, i32 0, i32 0)) + %var29 = 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 %var29, i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str.1, i32 0, i32 0), i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.7, i32 0, i32 0)) + %var30 = call i32 @js_create_element(i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.3, i32 0, i32 0)) + %var31 = call i32 @js_create_text(i8* getelementptr inbounds ([25 x i8], [25 x i8]* @.str.8, i32 0, i32 0)) + call void @js_append_child(i32 %var30, i32 %var31) + call void @js_append_child(i32 %var29, i32 %var30) + call void @js_append_child(i32 %var29, i32 %var30) + %var32 = call i32 @js_create_element(i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.3, i32 0, i32 0)) + call void @js_set_attribute(i32 %var32, i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str.1, i32 0, i32 0), i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str.5, i32 0, i32 0)) + ; TODO: Format f-string with signal count + %var33 = call i32 @js_create_text(i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.6, i32 0, i32 0)) + call void @js_append_child(i32 %var32, i32 %var33) + call void @js_append_child(i32 %var29, i32 %var32) + call void @js_append_child(i32 %var29, i32 %var32) + call void @js_append_child(i32 %var28, i32 %var29) + ret i32 %var28 +} + ; Component render function define void @render_Toggle() { entry: - %var24 = 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 %var24, i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str.1, i32 0, i32 0), i8* getelementptr inbounds ([11 x i8], [11 x i8]* @.str.9, i32 0, i32 0)) - %var25 = call i32 @js_create_element(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.10, i32 0, i32 0)) - %var26 = call i32 @js_create_text(i8* getelementptr inbounds ([27 x i8], [27 x i8]* @.str.11, i32 0, i32 0)) - call void @js_append_child(i32 %var25, i32 %var26) - call void @js_append_child(i32 %var24, i32 %var25) - %var27 = call i32 @js_create_element(i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.3, i32 0, i32 0)) - call void @js_set_attribute(i32 %var27, 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.12, i32 0, i32 0)) - %var28 = call i32 @js_create_text(i8* getelementptr inbounds ([44 x i8], [44 x i8]* @.str.13, i32 0, i32 0)) - call void @js_append_child(i32 %var27, i32 %var28) - call void @js_append_child(i32 %var24, i32 %var27) - %var29 = 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 %var29, i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str.1, i32 0, i32 0), i8* getelementptr inbounds ([9 x i8], [9 x i8]* @.str.14, i32 0, i32 0)) - %var30 = call i32 @js_create_element(i8* getelementptr inbounds ([7 x i8], [7 x i8]* @.str.15, i32 0, i32 0)) - call void @js_bind_event(i32 %var30, i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str.16, i32 0, i32 0), i8* getelementptr inbounds ([10 x i8], [10 x i8]* @.str.17, i32 0, i32 0)) - %var31 = call i32 @js_create_text(i8* getelementptr inbounds ([18 x i8], [18 x i8]* @.str.18, i32 0, i32 0)) - call void @js_append_child(i32 %var30, i32 %var31) - call void @js_append_child(i32 %var29, i32 %var30) - call void @js_append_child(i32 %var24, i32 %var29) - %var32 = 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 %var32, i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str.1, i32 0, i32 0), i8* getelementptr inbounds ([8 x i8], [8 x i8]* @.str.19, i32 0, i32 0)) - %var33 = call i32 @js_create_element(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.0, i32 0, i32 0)) - %var34 = call i32 @js_create_marker() - call void @js_append_child(i32 %var33, i32 %var34) - store i32 %var34, i32* @cond_0_marker - store i32 %var33, i32* @cond_0_parent - %var35 = load i32, i32* @signal_count - %var36 = icmp sgt i32 %var35, 5 - call void @_init_conditional_0(i1 %var36) - call void @js_append_child(i32 %var32, i32 %var33) - call void @js_append_child(i32 %var24, i32 %var32) - call void @js_set_root(i32 %var24) + %var34 = 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 %var34, i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str.1, i32 0, i32 0), i8* getelementptr inbounds ([11 x i8], [11 x i8]* @.str.9, i32 0, i32 0)) + %var35 = call i32 @js_create_element(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.10, i32 0, i32 0)) + %var36 = call i32 @js_create_text(i8* getelementptr inbounds ([27 x i8], [27 x i8]* @.str.11, i32 0, i32 0)) + call void @js_append_child(i32 %var35, i32 %var36) + call void @js_append_child(i32 %var34, i32 %var35) + call void @js_append_child(i32 %var34, i32 %var35) + %var37 = call i32 @js_create_element(i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.3, i32 0, i32 0)) + call void @js_set_attribute(i32 %var37, 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.12, i32 0, i32 0)) + %var38 = call i32 @js_create_text(i8* getelementptr inbounds ([44 x i8], [44 x i8]* @.str.13, i32 0, i32 0)) + call void @js_append_child(i32 %var37, i32 %var38) + call void @js_append_child(i32 %var34, i32 %var37) + call void @js_append_child(i32 %var34, i32 %var37) + %var39 = 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 %var39, i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str.1, i32 0, i32 0), i8* getelementptr inbounds ([9 x i8], [9 x i8]* @.str.14, i32 0, i32 0)) + %var40 = call i32 @js_create_element(i8* getelementptr inbounds ([7 x i8], [7 x i8]* @.str.15, i32 0, i32 0)) + call void @js_bind_event(i32 %var40, i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str.16, i32 0, i32 0), i8* getelementptr inbounds ([10 x i8], [10 x i8]* @.str.17, i32 0, i32 0)) + %var41 = call i32 @js_create_text(i8* getelementptr inbounds ([18 x i8], [18 x i8]* @.str.18, i32 0, i32 0)) + call void @js_append_child(i32 %var40, i32 %var41) + call void @js_append_child(i32 %var39, i32 %var40) + call void @js_append_child(i32 %var39, i32 %var40) + call void @js_append_child(i32 %var34, i32 %var39) + call void @js_append_child(i32 %var34, i32 %var39) + %var42 = 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 %var42, i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str.1, i32 0, i32 0), i8* getelementptr inbounds ([8 x i8], [8 x i8]* @.str.19, i32 0, i32 0)) + %var43 = call i32 @js_create_marker() + call void @js_append_child(i32 %var42, i32 %var43) + store i32 %var43, i32* @cond_0_marker + call void @_init_conditional_0() + call void @js_append_child(i32 %var34, i32 %var42) + call void @js_append_child(i32 %var34, i32 %var42) + call void @js_set_root(i32 %var34) ret void } diff --git a/examples/toggle/Toggle.wasm b/examples/toggle/Toggle.wasm index 69ac79b6ee21611f19972f3a0c7adddfded43e97..30325dd5151d04d9fbf765d134c27ae4d183deff 100755 GIT binary patch delta 857 zcmb7BF^kkd6n-z0tl4CD30&cUBH0LsBFZ&hqsR>wg3TcuRvwe=?U0RT6WIh0tGUAB zgaz-&A(mR`AFvS%wb5T=Az0Y@X0pfL+1Y$EZ{GL5_ue<(`@j1`NUA9U0AB3G05PD7 znNkX3RCGlJN5fmlj&`mQyxiPECW~kO<4RPr7PGRf!De0;&?W_vaTtQtc{otOUwA&@ z+~9%1V}pkV_g$TR(_F$E>=j#Ww(#m;rOMJG$;Eb=rnzhsW_Pk8tHo|vjI%l`b#5Jc zD`F;#v7DKAu`cR~ETI4ItIR9etXbDpPl$0({lE_P4-BsPDZ(;(4*3R z51IGgX?|Ka)!e&c!99DEALt7|))*l_G^Z89h0qF-jzD`C!iELDe;X|o&{q*V7(_^K z#5cKx3WN|MIj$9*`_Y-|7@6X8H^8AqNArk<%@?+|8bV;}RvP_NoaP<7tO+}32zRx} zQlCcq|1JI?+U+Ef)fD!5McbMg2>B-(FarM8<)7Vv68u{?U?*9cQ*-nZE$0Jq_*Wew z|Kal2Zs5@VzuFSAf(lza-C|k3Z(3{zorsuZVW=%7gRwQ3EetkBx8Fo+AzK=Ni|^5l McDNJ#_`s?0FF5_M-T(jq delta 855 zcmb7Bzi-n(7`^Y#P8|OLOI^y3;SvTwsHh955)$f(p@O{|=;G9;#E{q}wm?i5B!(hI z(8?9cz|e`6fd#R^0y}>II~$ew2l(zBP&+dCefRF(_rAO5-_h5oOOkQ|gb=vc>J!j? zLi$W=P5NLz&2_BZRRF#|-MMW6%J3ttEFaQ@TZQVbsiFn}$ zi2D}j78e!|E$&&Ic}DZLUWMyy!Oqop;c7c9vtgc$>ltLXrz%g?RPGdcD%WK-QaK4% zv+qI9Ar#q^mRoHyDC zt*T@&R*m>f2+aTK)IaErjeY+LC0ov>n45)I80>*Kw3Tvlfm04xViP4NHz^5%Eugx7 z#V*yW4tE>&t6@6Wz_U2)0y@P}kD?yEIGEZ@AZUla0v`8Hx!wV$@t>JXxc7Qy+W%kd zSOc`Qn0qnc8;(5j-ixXDZYU8)otVXrc}(nxkIOwzd_oCc=gY}cYk(b|cxMbg8!;8% zJn_bhT~5VuBPN{wGi+M4>6w`x%W2%|;Y_jTbDPB6=gcHwpV@UVC)VWTE_1S{e{*8o h<&Fu%S*Guxik}$DA#Ml3bIJ(L47Ss({P5aM;SVUWw*LSC diff --git a/examples/toggle/ritz-runtime.js b/examples/toggle/ritz-runtime.js new file mode 100644 index 0000000..3a23d1b --- /dev/null +++ b/examples/toggle/ritz-runtime.js @@ -0,0 +1,354 @@ +/** + * Ritz Runtime - WebAssembly DOM Bridge + * + * Provides the runtime environment for Ritz components compiled to WASM. + */ + +class RitzRuntime { + constructor(rootElement) { + this.rootElement = rootElement || document.getElementById('app'); + this.nodes = new Map(); + this.nextNodeId = 1; + this.log = []; + this.wasmInstance = null; + this.debugEnabled = true; + } + + // ===== DOM Manipulation Bridge ===== + + js_create_element(tagPtr) { + const tag = this.readString(tagPtr); + const element = document.createElement(tag); + const id = this.nextNodeId++; + this.nodes.set(id, element); + this._log(`createElement("${tag}") = ${id}`); + return id; + } + + js_create_text(textPtr) { + const text = this.readString(textPtr); + const textNode = document.createTextNode(text); + const id = this.nextNodeId++; + this.nodes.set(id, textNode); + this._log(`createTextNode("${text}") = ${id}`); + return id; + } + + js_append_child(parentId, childId) { + const parent = this.nodes.get(parentId); + const child = this.nodes.get(childId); + if (parent && child) { + parent.appendChild(child); + this._log(`appendChild(${parentId}, ${childId})`); + } + } + + js_set_attribute(elemId, namePtr, valuePtr) { + const element = this.nodes.get(elemId); + const name = this.readString(namePtr); + const value = this.readString(valuePtr); + if (element) { + if (name === 'class') { + element.className = value; + } else { + element.setAttribute(name, value); + } + this._log(`setAttribute(${elemId}, "${name}", "${value}")`); + } + } + + js_bind_event(elemId, eventNamePtr, handlerNamePtr) { + const element = this.nodes.get(elemId); + const eventName = this.readString(eventNamePtr); + const handlerName = this.readString(handlerNamePtr); + + if (element && this.wasmInstance) { + const handler = this.wasmInstance.exports[handlerName]; + if (handler) { + element.addEventListener(eventName, () => { + this._log(`[Event] ${eventName} → ${handlerName}()`); + handler(); + this.updateSignals(); + }); + this._log(`bindEvent(${elemId}, "${eventName}", "${handlerName}")`); + } else { + console.error(`Handler ${handlerName} not found in WASM exports`); + } + } + } + + js_set_root(elemId) { + const element = this.nodes.get(elemId); + if (element) { + this.rootElement.innerHTML = ''; + this.rootElement.appendChild(element); + this._log(`setRoot(${elemId})`); + } + } + + js_update_text_content(nodeId, textPtr) { + const node = this.nodes.get(nodeId); + const text = this.readString(textPtr); + if (node) { + node.textContent = text; + this._log(`updateTextContent(${nodeId}, "${text}")`); + } + } + + // ===== Signal Management ===== + + updateSignals() { + // Discover and update all signals + if (!this.wasmInstance) return; + + const exports = this.wasmInstance.exports; + + // Find all get_* functions (signal getters) + for (const [name, fn] of Object.entries(exports)) { + if (name.startsWith('get_') && typeof fn === 'function') { + const signalName = name.substring(4); // Remove 'get_' prefix + const value = fn(); + this._log(`[Signal] ${signalName} = ${value}`); + + // Update DOM elements bound to this signal + // TODO: Track signal-to-DOM bindings during render for efficiency + this.updateSignalDisplay(signalName, value); + } + } + + // Re-evaluate all reactive conditionals + for (const [name, fn] of Object.entries(exports)) { + if (name.startsWith('reevaluate_conditional_') && typeof fn === 'function') { + fn(); + this._log(`[Reactive] ${name}()`); + } + } + + // Re-evaluate all reactive match statements + for (const [name, fn] of Object.entries(exports)) { + if (name.startsWith('reevaluate_match_') && typeof fn === 'function') { + fn(); + this._log(`[Reactive] ${name}()`); + } + } + } + + updateSignalDisplay(signalName, value) { + // Find DOM elements that should display this signal + // For now, update any element with class matching signal name or data-signal attribute + const selectors = [ + `[data-signal="${signalName}"]`, + `.${signalName}`, + '.count', // Hardcoded for demo - TODO: track bindings properly + ]; + + selectors.forEach(selector => { + const elements = document.querySelectorAll(selector); + elements.forEach(el => { + // Check if text contains the signal name or looks like a counter + const text = el.textContent; + if (text.includes(signalName) || text.match(/\d+/)) { + // Replace the number in the text + el.textContent = text.replace(/\d+/, value); + } + }); + }); + } + + // ===== Reactive Conditional Rendering ===== + + js_create_marker() { + // Create a comment node as a marker for conditional insertion + const marker = document.createComment('conditional-marker'); + const id = this.nextNodeId++; + this.nodes.set(id, marker); + this._log(`Created marker node ${id}`); + return id; + } + + js_replace_at_marker(markerId, oldNodeId, newNodeId) { + // Replace DOM node at marker position + const marker = this.nodes.get(markerId); + if (!marker) { + console.error(`[replace_at_marker] Marker ${markerId} not found`); + return; + } + + const parent = marker.parentNode; + if (!parent) { + console.error(`[replace_at_marker] Marker ${markerId} has no parent`); + return; + } + + this._log(`[replace_at_marker] marker=${markerId}, old=${oldNodeId}, new=${newNodeId}`); + + // Remove old node if it exists (0 means no old node to remove) + if (oldNodeId !== 0) { + const oldNode = this.nodes.get(oldNodeId); + if (!oldNode) { + console.warn(`[replace_at_marker] Old node ${oldNodeId} not found in registry`); + } else if (!oldNode.parentNode) { + console.warn(`[replace_at_marker] Old node ${oldNodeId} not in DOM`); + } else if (oldNode.parentNode !== parent) { + console.warn(`[replace_at_marker] Old node ${oldNodeId} in wrong parent`); + oldNode.parentNode.removeChild(oldNode); + this._log(`[replace_at_marker] Removed ${oldNodeId} from wrong parent`); + } else { + // Remove from correct parent + parent.removeChild(oldNode); + this._log(`[replace_at_marker] Removed ${oldNodeId} from correct parent`); + } + } + + // Insert new node after marker (only if newNodeId is not 0) + if (newNodeId !== 0) { + const newNode = this.nodes.get(newNodeId); + if (!newNode) { + console.error(`[replace_at_marker] New node ${newNodeId} not found`); + return; + } + + // Insert right after the marker + // If newNode is already in DOM elsewhere, this will move it + const nextSibling = marker.nextSibling; + if (nextSibling) { + parent.insertBefore(newNode, nextSibling); + this._log(`[replace_at_marker] Inserted ${newNodeId} before sibling`); + } else { + parent.appendChild(newNode); + this._log(`[replace_at_marker] Appended ${newNodeId} (no sibling)`); + } + } + } + + // ===== Memory & String Utilities ===== + + readString(ptr) { + if (!this.memory) return ''; + const bytes = new Uint8Array(this.memory.buffer, ptr); + let length = 0; + while (bytes[length] !== 0) length++; + return new TextDecoder().decode(bytes.slice(0, length)); + } + + setMemory(memory) { + this.memory = memory; + } + + setWasmInstance(instance) { + this.wasmInstance = instance; + } + + // ===== Logging & Debug ===== + + _log(message) { + if (this.debugEnabled) { + this.log.push(message); + } + } + + getLog() { + return this.log; + } + + clearLog() { + this.log = []; + } +} + + +/** + * RitzLoader - Simplified WASM loading + */ +class RitzLoader { + constructor(options = {}) { + this.rootElement = options.rootElement || document.getElementById('app'); + this.statusElement = options.statusElement || document.getElementById('status'); + this.onLoad = options.onLoad || (() => {}); + this.onError = options.onError || ((err) => console.error(err)); + } + + async load(wasmPath, componentName, props = {}) { + try { + this.setStatus('⏳ Creating runtime...'); + const runtime = new RitzRuntime(this.rootElement); + + this.setStatus(`⏳ Loading ${wasmPath}...`); + const response = await fetch(wasmPath); + if (!response.ok) { + throw new Error(`Failed to load ${wasmPath}: ${response.status}`); + } + + const wasmBytes = await response.arrayBuffer(); + + this.setStatus('⏳ Instantiating WASM...'); + + // Create imports for WASM + const imports = { + env: { + js_create_element: (ptr) => runtime.js_create_element(ptr), + js_create_text: (ptr) => runtime.js_create_text(ptr), + js_append_child: (p, c) => runtime.js_append_child(p, c), + js_set_attribute: (e, n, v) => runtime.js_set_attribute(e, n, v), + js_set_root: (e) => runtime.js_set_root(e), + js_bind_event: (e, n, h) => runtime.js_bind_event(e, n, h), + js_update_text_content: (n, t) => runtime.js_update_text_content(n, t), + js_create_marker: () => runtime.js_create_marker(), + js_replace_at_marker: (m, o, n) => runtime.js_replace_at_marker(m, o, n), + } + }; + + const { instance } = await WebAssembly.instantiate(wasmBytes, imports); + + // Setup runtime + runtime.setMemory(instance.exports.memory); + runtime.setWasmInstance(instance); + + this.setStatus(`⏳ Rendering ${componentName}...`); + + // Call the render function with props + const renderFn = instance.exports[`render_${componentName}`]; + if (!renderFn) { + throw new Error(`render_${componentName} not found in WASM exports`); + } + + // Pass props as positional arguments + const propValues = Object.values(props); + renderFn(...propValues); + + // Update signals + runtime.updateSignals(); + + this.setStatus(`✅ ${componentName} loaded!`, 'success'); + + // Make runtime globally available for debugging + window.ritzRuntime = runtime; + window.ritzInstance = instance; + + this.onLoad(runtime, instance); + + return { runtime, instance }; + + } catch (error) { + this.setStatus(`❌ Error: ${error.message}`, 'error'); + this.onError(error); + throw error; + } + } + + setStatus(message, type = '') { + if (this.statusElement) { + this.statusElement.textContent = message; + this.statusElement.className = 'status ' + type; + } + } +} + + +// Export for use in modules or global scope +if (typeof module !== 'undefined' && module.exports) { + module.exports = { RitzRuntime, RitzLoader }; +} else { + window.RitzRuntime = RitzRuntime; + window.RitzLoader = RitzLoader; +} diff --git a/ritz/__pycache__/llvm_codegen_signals.cpython-313.pyc b/ritz/__pycache__/llvm_codegen_signals.cpython-313.pyc index ba36d0bb03acf62fb565f993a365aeacd31e1bc9..5908adab86c878b15384863ea8ea6e5524f09f4c 100644 GIT binary patch delta 12986 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 GMf!hWQG?U~ delta 8052 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 maelV`M)O?r{J$U^&bF2l{~iq delta 2960 zcmZt{TW}j!b?<7WmE@OPd1cE|rpFk4{ zgo&Y-1eQU-AiR(8i_Gx0B988fcUeSlquWDtdk47N2_GT6TQ&4}#sKqUgg*~>BGU@^ z1mSN1-dT0;KWe%mO7^=*134U8(je+~B6puv)3M4K&s*M(9K)PdzX1Gu;CJ^IKz&IW zR7#@Q-6r1mge$khai(T8@sE~>XMrtsJi+2DbeQPE+i#Er4rGrv4`B_`~tNb=^MxKCGS}$7MbS&AF zb+}owSIfMZwZ6EPI9Bi@c&Y>X?-@ee{Rmjc^?4<2X}`9%Ccz+3Oz zRlHu`zwY>z<{4)Dfc+*jW@14;AYM&GD?e+EcvzRX-9DmA?}k}ew?ruR-G{n>Px`Z2 z%v&~_W_$qcU}ZX82hc7@@L1*j*xy-7YMXiI3uzB0N!=<~MXThv`SeO}-m!|d`167O zev|<=%EjZTgfwG~Aw*aAFp?2`Rvb?(`=o{`7G1-U$~%cqvZ(Z~@$#CT4)8i;^aGIE zj9Dm%_RjcJ57G`I7y*#h_$;2EL~sg#)X!PxH_Lp*)&Rq-x;9TD0|KkE*=c(M*Hwyy zkBGk}e>Z?ZQP=P!oTTsECRQq4Pd4`4;HQyqPJEbZJ%fy{AD_Y#x|Q})*fOxXUdmBw zW#hS0d9#$QrpqQash-=kaVMa6Rrf|w2ZD{tXC9pJY*CiA90bkhfGT}<{%pxCxbFFL z<&y1~CFe9>fXix8+(y^)rM#0j3({xWC{wGL&w+?6#|`LVlnO}QrP=!ejKK{=H3<;Y zE47t;&XFFJjH6JsuwO$qWU&9IuwzI@aIrFVCme=-~4!Rae3znCYSv24l z7g0sM?n9tWu$g* zc#GhcB0e0NV=q=F4o$N0myvu40qMBsAvpIUQa|RLKq`ViDB_*NIrcJblB2^()`2yr zrgQgze=}cL$(ekGV@vTNasEjBgj+MfrG5%ynzA{$KsCau!n#3%%>Y#U|1umofTTtdBA~a}-r$<9# zI~o@8WHVFom2F(aed-FU^FA?`?D47@9UhKbZBa2b8WwZWW*vGY<6ksH;#j&B+wi_G z6BzIi|J~74APu}hFxW{3U+E5k4?pVeR5Nwr)<{fj9!u$Mz*0}@4vI5l2gLV}k(u!4 zf!?ssA!Ys`IMl8#rp2|fL@3jUTj2<%1-|({@n%a{{B{i7dL&%87ltM#2aUs8rfEP+ zDVfkBIOKi{`($ghz5h(Jm>%zE4~Vt#RQ4-Cck75l1D!y{p$Ysl5~>r0yT_fV4LHew z={P*UyzW@ForC=VuPKnFz6x`ZFP%kY;@{(a)g4x_RvnH5E$edSB0j@TncLNV0dl%+ zZ~aLBOm(xl%VKXWoCZ$*6oNgMsL$>#Um2LHImfS}Iq~lCzWLWs1Y?sPcv9S*@&iC& zX6fCa4e%wrXB#k4;Nbn6nXDkV13&vOOw3IzRc=o#GO;lkW&Ps9WGwN^9%DA?zggch z+Z()@N&)=UabvdM_v;~J_E3;swm(j`ve_rlvVSk$eS7bRaODPwDWwSbH__t0A))vY zw22eb&#8Y#}>{BjWcaIei%`DY$;ZH0*@jM9~yoP0d4F@@PwO{ zmL8wL6D_DoJWTu6`b%l6f+ zD_gq?9B&Nocy=;7{x>H+LUebm5_{BSQ%UwHyPUk*d!_f_j|Du}#u f(no~vKFNH{xG;0+FS7T diff --git a/ritz/llvm_codegen_signals.py b/ritz/llvm_codegen_signals.py index 5d346f9..e277607 100644 --- a/ritz/llvm_codegen_signals.py +++ b/ritz/llvm_codegen_signals.py @@ -87,6 +87,10 @@ class SignalLLVMIRGenerator: self._emit_conditional_functions() self._emit_component(component) + # Emit main entry point for the last (top-level) component + if self.components: + self._emit_main_entry(self.components[-1]["name"]) + # Prepend string constants return self._finalize_with_strings() @@ -641,6 +645,17 @@ class SignalLLVMIRGenerator: self.lines.append("}") self.lines.append("") + def _emit_main_entry(self, component_name: str) -> None: + """Emit main entry point that renders top-level component and sets root.""" + self.lines.append("; Main entry point") + self.lines.append("define void @main() {") + self.lines.append("entry:") + self.lines.append(f" %root = call i32 @render_{component_name}()") + self.lines.append(" call void @js_set_root(i32 %root)") + self.lines.append(" ret void") + self.lines.append("}") + self.lines.append("") + def _emit_component(self, ir: dict[str, Any]) -> None: """Emit component render function.""" component_name = ir["name"] @@ -654,7 +669,7 @@ class SignalLLVMIRGenerator: param_str = ", ".join(param_list) if param_list else "" self.lines.append("; Component render function") - self.lines.append(f"define void @render_{component_name}({param_str}) {{") + self.lines.append(f"define i32 @render_{component_name}({param_str}) {{") self.lines.append("entry:") # Process component body (skip signals and functions, already handled) @@ -666,11 +681,13 @@ class SignalLLVMIRGenerator: if root_var is None and var: root_var = var - # Set root element + # Return root element (caller decides whether to set as root or append) if root_var: - self.lines.append(f" call void @js_set_root(i32 %{root_var})") + self.lines.append(f" ret i32 %{root_var}") + else: + # No root element - return 0 + self.lines.append(" ret i32 0") - self.lines.append(" ret void") self.lines.append("}") self.lines.append("") @@ -767,14 +784,20 @@ class SignalLLVMIRGenerator: arg_var = self._emit_expr(arg) arg_values.append(f"i32 {arg_var}") - # Build argument list and call + # Call component render function and capture returned root element + elem_var = self._new_var() if arg_values: arg_list = ", ".join(arg_values) - self.lines.append(f" call void @render_{component_name}({arg_list})") + self.lines.append(f" %{elem_var} = call i32 @render_{component_name}({arg_list})") else: - self.lines.append(f" call void @render_{component_name}()") + self.lines.append(f" %{elem_var} = call i32 @render_{component_name}()") - return None + # Append to parent if we have one + if self.parent_element_stack: + parent_var = self.parent_element_stack[-1] + self.lines.append(f" call void @js_append_child(i32 %{parent_var}, i32 %{elem_var})") + + return elem_var def _emit_match(self, stmt: dict[str, Any]) -> str | None: """Emit a match/case statement with reactive rendering.""" diff --git a/tests/__pycache__/test_component_props.cpython-313-pytest-8.4.2.pyc b/tests/__pycache__/test_component_props.cpython-313-pytest-8.4.2.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7b189d0c4011cd571598b8fdafc54ddb017b92fb GIT binary patch literal 14176 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 literal 0 HcmV?d00001 diff --git a/tests/__pycache__/test_lambda_handlers.cpython-313-pytest-8.4.2.pyc b/tests/__pycache__/test_lambda_handlers.cpython-313-pytest-8.4.2.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9afd7d024a74f5bdd92174f4a7d6a2e88074bc46 GIT binary patch literal 18460 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 literal 0 HcmV?d00001 diff --git a/tests/__pycache__/test_lambda_simple.cpython-313-pytest-8.4.2.pyc b/tests/__pycache__/test_lambda_simple.cpython-313-pytest-8.4.2.pyc new file mode 100644 index 0000000000000000000000000000000000000000..46f34d5ceb470ba59532df8ce02d6e1e82d2df1b GIT binary patch literal 7371 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 delta 1043 zcmZ{iO-vI}5XX6R+p60VRHPq(B`seoP^c7XDP*A~5tfPxH?>CjZX+#Z`AGbT#>A+J zCWcI6%0CKbH0;ZP@gbRdv=$6iQH<4^6co3^b)xk@KazZQN z5}}RYL(CWvmFg!4VX3TvNy@jfEyjAlQDRdzD#Ch8FM0PJ_qMp4Y*1-;&6D?fm96lj z5h_~4inV&uXqYG!9QQgv^q0eYQ&cZIF&_4tHux&aR!yjZcg>Hcaw+hDny=T4YMnBpyxk|6AZz@S`OH z(2~;ca5h=(aarpE$1W>t{z7)bh1Vt6WdSzZU)j~CMR$3$3vfH&uxo9|8s-v{vBVw0 zly3(t1|0Q%3T!8g5a_kZoroC|BLC!a1HQZcKplIam^v0s%%!~Vbu%WwZr`~3|0keq zPYKTm>QNvj)iN(ENX~Qr+#J425o~mIe=S>6uJo_ySR)(^w1jfI+^0N`5n1E(&}?)v sHZ1GN6e383K|+-9g75~hS|In34np*5sKmnT2VOU`9S*Z@#vHk&Ur*f&Jpcdz diff --git a/tests/__pycache__/test_llvm_codegen_conditional.cpython-313-pytest-8.4.2.pyc b/tests/__pycache__/test_llvm_codegen_conditional.cpython-313-pytest-8.4.2.pyc index b45fb961b6e877696627b18d3d5dee2f432d61c4..e81afb261abef28f0a4a9cb75e078a6a1ef5f67c 100644 GIT binary patch delta 1168 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 literal 0 HcmV?d00001 diff --git a/tests/__pycache__/test_ternary_expressions.cpython-313-pytest-8.4.2.pyc b/tests/__pycache__/test_ternary_expressions.cpython-313-pytest-8.4.2.pyc new file mode 100644 index 0000000000000000000000000000000000000000..915b6bfb3d688496e595bccf0277a740f4d158cb GIT binary patch literal 6313 zcmeHLOK;rP6~5%$c~Wm#j%~>?JFa3)oX+U&#Wz7O5l3WHHH7 zvfq+sX=q8@&ManGmiy@K+@i!J(32Mk>rzr6yOlJ^o|;(5Y!vV7PScT>Z6-H$W@&6) z)}J((?l^{R$MUtLc``w5G0_ z=2~4fSS46L|4D;Pz~A9tDc_7>ktHDvD3h5$w}dimF$oQW zxR1wzWmIiKmcpcyd$7*qPo5~ba(Y@&q=yft#hD-?)+cqm2O)V^ zpTTHWM(I|1%9(M2TiK;-I74hK{t1PC{}*P>hGT`lx}fyV3087WXskgd`gmsgd1jKz zz^Ts%|LT;%ARlK=eLjZx_Yvmf?CH)&trw44JYkke;f;-PJT_%K0}ZQo(#Z)Yrf%wW zI2rlLS$z4&+%mK4GBcVRMQ7b=YENVX&Q3U7-_GUUi_XzpRbQ6x+qIghj}@-xWO%en z(^%8xIoUC4mS&Dk6ms1E*l4cE@2@tSwl!8UHOEost~_d5LHrfjSPr}DrlZT)b|n}R zhg~;xvnuC5FpbJ@@;Q$_va9PJZLT+TkK)h_PeLyp?7~a(0^p_mnY^U240U2xcqz`! z?Ft(MqhpQriGm}~&B>@v7o1(uOMnl>^vfPto(_A(w%LM%&e^*#8)VTFjjEUOH|ZtU zG;>vdnd|JsOW6$9?MI@+?19m^NNwpFU?Yb8rx(@n!E;a5_^4LV$^ zL21TC2c_95HrBlhJO_Ry4nqt}#kH~$Oa*{~IA23$-6YRxwuf$h{O>a)cYgb9J1cL# z|2#!5UfN#!a3|0B9xb(`%f7iE)7uywMMVm@qd{w~^j3?`?!3c=E6pCz;N7FME$J=a z+>hyPjE893iYr}umWCa-=)}%PT)5K20S(?gI?=*xpt&E@+ZY{1MGAy`|Du=l z|B`@IQnGwYD!^7rC9P!2$pBlWmHNiY;)1D-I9QnR!NSa4b^+Si2#7+Cg8+u75PK8FB@{9UuL~>m zqgBIf8kXawOdGI)qApuxLGho8>))_zBgn!&fV5LxaKD{@27AtaBS zTo(TXWe@I1USBIs6$VdtK911nGaF;Pu!I+n zoY49l&T!!NvBP$X8{7W{eg42+wP4JUKUdJ~(C6_ueg4o`i@5WOQCs1x+3zqf&j5u- z;%wTFPaw_@kg4W#3~K;G)XDH_j6GBNC9_5{(MGx^;xq;LAcV@0~)-0^eShRXzs`KHU>sfkpdy# zzv%Apw1olSX&?%{URqVFc12aaOb9;MEacxiulg4iMgP_SE*pwWe+={?!9Rdq!fv3>fl1~@-L9^h`aHW0 wKKLq#gLvn8LJ)+%lj-jW`5pOf_qXKAw`BH3>Z~yNVsc0rIUFAn-r=MC2a_G6YXATM literal 0 HcmV?d00001 diff --git a/tests/__pycache__/test_wrapper_components.cpython-313-pytest-8.4.2.pyc b/tests/__pycache__/test_wrapper_components.cpython-313-pytest-8.4.2.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4c044881b933c092fe9bca3c00024631ced3e374 GIT binary patch literal 8429 zcmeGhO>f)Sk(8e#TeO{z-Na7PtQoD-h#Rjhf5=YK)ovPOn;=QkB8;{Hd?09vc8JoX z@JKtciy{HK2OHgkQJ{bid&s4Ldo9qv(6eMaaZ7AYJrubG&7OMd%p)I3IZAA!E!tuu z(C^I*XXeeDH}Cn)@KsMwPJmyz*>7I$5`@1Z!hfj{cy$|q-wLWg1yxj2H$|Faea8*r zrextpnr7tSO_pZiO~=j78(p-E(a6o*4T(wsr%wvBTg^b*GnZ1b%NOq&uII|L4wWBJ zy-jR?sRe}?(;$^M1BB$Z9ovFnctCkr#pO==<>oe_kLs*A5%ZsBHf!1 z3&D2MKY?{o$$_jq)iO?7D=Q-RS!CVu7OA$@#Zq7uQPT&qYCpb-s@-AyWYr$Ew~{T2ESfqG5KWz27w<8e%A!rmV%?~S>Y+3& zka`$fyGuRdD3uh8rmK9NYRv{ded3^p=O+CEL><$|hu!)RRBT zCD?c#3`=Pw-dXRq(gBTMxXG40R4K*_6(1NO^yRKHwqq1Q9d}Khm)escL-;!xq zHJO>tMldYb*i-p|wC;A83a+#aaGP5QodV`+%xiL4cFj3kw+cli$IL+wyN0I$OJPyB z7K~5?O;3ukcYz3V$W?Q(knqOG^M<{UPsj$-1|vex<*z&Q2286slvG)clk>v!;cbMt5lfe7C02w`o!h&x0s+LDkqUReUCf27J~MO-eTx^X@d0I!b(1IXoI{7J?2J1oOi2!-m9K(T0nTF0@OT<%R+ ze*szROBW~(=M!6>H~g;1%`o!Oa3WkcOjk)UjTCDOEy`eAiplc}%-{W79DjZWYCihB z`vQ|!KApEXF7Ov0atekFXCi?-8yAh9Y8m`uFq4aZn(Z+^%>v!e1l#ikmWKQ+-aY=;GolV>i28zeP_X{X;9Om+MMOg=$01v zOLO&E1Id2x4_RP9z3X#I9qPZQ!I3ksdz$gEZt1p;l`wh;2Rx#|2o_U@$DB?LrPt56 z&H}9(6f0i7geC<`H69>=u2S;NSQ2S@Gm(^;N+K7NGQ}h^nnWg(G8Y051s04JUCf(t zU&cSbJaQkl_K2=i#~!H}izBwNXh4LI;ORbsZgg3zg@wbo0_YCcm;5u#(RkDZ|0-T* zqmwWwu9o{8R`0R!lJxhI$3OaZOvs&BKfcu^Kfdy9M(94iHuLr1mNd{H1J9&^9n$hN z$-q~aB3dgJke`u(wV5PG0*g4l9!zp@>?s*&v>Wjosdt6`da6PC)^ygaezHUQf@h2L ztxQE&06ZmqUyVn!W(yXOpMexja&QbpxjN9irbj#x0OUVQJuCWZY3=xGxk1jY-(*cw zI=4f@XOo;;DF@hg3~nKB#1jEPZc$iRzttenG^N5037<_;K!u2H$KV#SMLZDzQ{dH86pC1yF$OPI9tAJ9 z5`q9f8IAZO0J!<&`d2?&hjCA@&o-sA4N~0bV@*>k?vU`=B*lhwHbA!%@D_4MToC}| z|Az9>js6CKrYXUM!)KF>GRqO&PQY8p7;!}akl$eW*v5$lfu<>q?U3-2mqE>u*-!iHvAWT1R${Y;j_lRJ_7KR844dMXS|ZaGQJa+%YFxikEm>XC;Ak? zhZF=Ty>?WvTt@DV#f6WA44y{2e#x?MO98rVDZb?c1D5V%d)k*Kqap+^-{@GnkEPmM z6iH!G97^3mX)dj1)y_&fEJ|b&MTuBn`@(mIdzSZ5l)$pwgqnNjXAFq{w4dj?6luB0 zlCWF1zW6bGgsU0w5$)|C=7#k@!OiSnNx9nRTJMsjM8bnN7@lLbOO_I>Z_14lD&CkF zEuV&r&9n{K93PV}Qv-5gszn#~0(?|WnRfF2ZrUsrf!x8*hF@9vMgA}ZY|CA`6x^jt zx0g@hE%i-f6Vo4f^JS6k1Ntd&jl-Y&92&eT9%EO+( z@6;A7<5PMa-eY#?%Fw**5JmAX!e@UIgfE3(^*k5OJr^ebo+*gquf7lm#0jS1p9&Q% ASO5S3 literal 0 HcmV?d00001 diff --git a/tests/test_component_props.py b/tests/test_component_props.py index aab3d71..09f8205 100644 --- a/tests/test_component_props.py +++ b/tests/test_component_props.py @@ -57,7 +57,7 @@ def Button(label): llvm_ir = generate_llvm_ir(ir) # Should generate render function with parameter - assert "define void @render_Button(i32 %label)" in llvm_ir + assert "define i32 @render_Button(i32 %label)" in llvm_ir def test_parse_yield_component_with_args(): @@ -111,8 +111,8 @@ def Parent(): components = parse_component(source) llvm_ir = generate_llvm_ir(components) - # Should call render_Child with argument - assert "call void @render_Child(i32 42)" in llvm_ir + # Should call render_Child with argument and capture return value + assert "call i32 @render_Child(i32 42)" in llvm_ir def test_component_with_default_param(): @@ -180,7 +180,7 @@ def Counter(initial_count): llvm_ir = generate_llvm_ir(ir) # Should accept parameter - assert "define void @render_Counter(i32 %initial_count)" in llvm_ir + assert "define i32 @render_Counter(i32 %initial_count)" in llvm_ir # Signal should be initialized with parameter value # This will require storing the param value to the signal global diff --git a/tests/test_llvm_codegen.py b/tests/test_llvm_codegen.py index 7bedae0..9a9e0a7 100644 --- a/tests/test_llvm_codegen.py +++ b/tests/test_llvm_codegen.py @@ -25,7 +25,7 @@ def test_llvm_hello_world_structure(): llvm_ir = generate_llvm_ir(ir_dict) # Check basic LLVM IR structure - assert "define void @render_HelloWorld()" in llvm_ir + assert "define i32 @render_HelloWorld()" in llvm_ir assert "ret void" in llvm_ir # Should have string constants @@ -115,10 +115,12 @@ def test_llvm_ir_syntax_valid(): llvm_ir = generate_llvm_ir(ir_dict) # Basic syntax checks - assert llvm_ir.count("define") == llvm_ir.count("ret void") # All functions return + assert llvm_ir.count("define") == llvm_ir.count("ret") # All functions have returns assert "%" in llvm_ir # Has SSA variables assert "call" in llvm_ir # Has function calls assert "@" in llvm_ir # Has global symbols + assert "define void @main()" in llvm_ir # Has main entry point + assert "define i32 @render_" in llvm_ir # Component functions return i32 def test_llvm_ir_compiles_with_llc(): diff --git a/tests/test_wrapper_components.py b/tests/test_wrapper_components.py index 220a355..73bf358 100644 --- a/tests/test_wrapper_components.py +++ b/tests/test_wrapper_components.py @@ -76,7 +76,7 @@ def SimpleTabs(): llvm_ir = generate_llvm_ir(ir) # Should generate render function for TabButton with parameters - assert "define void @render_TabButton(" in llvm_ir + assert "define i32 @render_TabButton(" in llvm_ir # Should call TabButton from SimpleTabs with arguments - assert "call void @render_TabButton(" in llvm_ir + assert "call i32 @render_TabButton(" in llvm_ir