mirror of
https://github.com/roc-lang/roc.git
synced 2025-12-23 08:48:03 +00:00
fix infinite recursion bug (again)
This commit is contained in:
parent
0016bb1a04
commit
4e4eef2d04
5 changed files with 704 additions and 510 deletions
|
|
@ -1,9 +1,11 @@
|
|||
app [main] { pf: platform "./platform/main.roc" }
|
||||
|
||||
import pf.Simple
|
||||
|
||||
Model : { value: I64 }
|
||||
|
||||
main = {
|
||||
init: |{}| { value: 0 },
|
||||
update: |m, delta| { value: m.value + delta },
|
||||
render: |m| m.value,
|
||||
render: |_m| Simple.leaf("hello"),
|
||||
}
|
||||
|
|
|
|||
|
|
@ -127,18 +127,15 @@ fn platform_main() !void {
|
|||
try stdout.print("\x1b[32mSUCCESS\x1b[0m: init completed!\n", .{});
|
||||
success_count += 1;
|
||||
|
||||
// Test 2: render takes Box(model), returns I64
|
||||
try stdout.print("\n=== Test 2: render(Box(model)) -> I64 ===\n", .{});
|
||||
var render_result: i64 = undefined;
|
||||
// Test 2: render takes Box(model), returns Simple(Model) - an opaque type
|
||||
// Simple(Model) is a tag union, so it has a discriminant + payload
|
||||
// For now, just treat it as a blob and check we can call without crashing
|
||||
try stdout.print("\n=== Test 2: render(Box(model)) -> Simple(Model) ===\n", .{});
|
||||
var render_result: [64]u8 = undefined; // Buffer for opaque result
|
||||
roc__render(&roc_ops, @as(*anyopaque, @ptrCast(&render_result)), @as(*anyopaque, @ptrCast(&boxed_model)));
|
||||
try stdout.print("render returned: {}\n", .{render_result});
|
||||
|
||||
if (render_result == 0) {
|
||||
try stdout.print("\x1b[32mSUCCESS\x1b[0m: render returned expected value 0!\n", .{});
|
||||
success_count += 1;
|
||||
} else {
|
||||
try stdout.print("\x1b[31mFAIL\x1b[0m: render returned {} but expected 0!\n", .{render_result});
|
||||
}
|
||||
try stdout.print("render completed without crash\n", .{});
|
||||
try stdout.print("\x1b[32mSUCCESS\x1b[0m: render returned Simple(Model)!\n", .{});
|
||||
success_count += 1;
|
||||
|
||||
// Test 3: update takes (Box(model), I64), returns Box(model)
|
||||
try stdout.print("\n=== Test 3: update(Box(model), 42) -> Box(model) ===\n", .{});
|
||||
|
|
@ -151,17 +148,12 @@ fn platform_main() !void {
|
|||
success_count += 1;
|
||||
|
||||
// Test 4: render the updated model
|
||||
try stdout.print("\n=== Test 4: render(updated Box(model)) -> I64 ===\n", .{});
|
||||
var final_result: i64 = undefined;
|
||||
try stdout.print("\n=== Test 4: render(updated Box(model)) -> Simple(Model) ===\n", .{});
|
||||
var final_result: [64]u8 = undefined;
|
||||
roc__render(&roc_ops, @as(*anyopaque, @ptrCast(&final_result)), @as(*anyopaque, @ptrCast(&new_boxed_model)));
|
||||
try stdout.print("render returned: {}\n", .{final_result});
|
||||
|
||||
if (final_result == 42) {
|
||||
try stdout.print("\x1b[32mSUCCESS\x1b[0m: render returned expected value 42!\n", .{});
|
||||
success_count += 1;
|
||||
} else {
|
||||
try stdout.print("\x1b[31mFAIL\x1b[0m: render returned {} but expected 42!\n", .{final_result});
|
||||
}
|
||||
try stdout.print("render completed without crash\n", .{});
|
||||
try stdout.print("\x1b[32mSUCCESS\x1b[0m: render returned Simple(Model)!\n", .{});
|
||||
success_count += 1;
|
||||
|
||||
// Final summary
|
||||
try stdout.print("\n=== FINAL RESULT ===\n", .{});
|
||||
|
|
|
|||
|
|
@ -3,10 +3,10 @@ platform ""
|
|||
[Model : model] for main : {
|
||||
init : {} -> model,
|
||||
update : model, I64 -> model,
|
||||
render : model -> I64
|
||||
render : model -> Simple(model)
|
||||
}
|
||||
}
|
||||
exposes []
|
||||
exposes [Simple]
|
||||
packages {}
|
||||
provides { init_for_host: "init", update_for_host: "update", render_for_host: "render" }
|
||||
targets: {
|
||||
|
|
@ -21,6 +21,8 @@ platform ""
|
|||
}
|
||||
}
|
||||
|
||||
import Simple exposing [Simple]
|
||||
|
||||
# Explicit type annotations for host-facing functions
|
||||
# Note: Use uppercase Model here - it's a type alias introduced by the for-clause [Model : model]
|
||||
# that gets unified with the app's concrete type during type checking.
|
||||
|
|
@ -38,7 +40,8 @@ update_for_host = |boxed_model, value| {
|
|||
Box.box(update_fn(m, value))
|
||||
}
|
||||
|
||||
render_for_host : Box(Model) -> I64
|
||||
# This now returns Simple(Model) - an opaque type from an imported module
|
||||
render_for_host : Box(Model) -> Simple(Model)
|
||||
render_for_host = |boxed_model| {
|
||||
m = Box.unbox(boxed_model)
|
||||
render_fn = main.render
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue