From 7def05274945cca10468538eca378af57568f830 Mon Sep 17 00:00:00 2001 From: Jakub Doka Date: Mon, 11 Nov 2024 21:55:18 +0100 Subject: [PATCH] preventing dangling nodes due to cycles in loop phys --- lang/README.md | 45 ++++++++++++++++++++++ lang/src/son.rs | 19 ++++++--- lang/tests/son_tests_very_nested_loops.txt | 6 +++ 3 files changed, 65 insertions(+), 5 deletions(-) create mode 100644 lang/tests/son_tests_very_nested_loops.txt diff --git a/lang/README.md b/lang/README.md index 695d936c..f57453a5 100644 --- a/lang/README.md +++ b/lang/README.md @@ -615,6 +615,51 @@ main := fn(): uint { ### Purely Testing Examples +#### very_nested_loops +```hb +$W := 200 +$H := 200 +$MAX_ITER := 20 +$ZOOM := 0.5 + +main := fn(): int { + mv_x := 0.5 + mv_y := 0.0 + + y := 0 + loop if y < H break else { + x := 0 + loop if x < W break else { + i := MAX_ITER - 1 + + c_i := (2.0 * @floatcast(@itf(@as(i32, @intcast(x)))) - @floatcast(@itf(@as(i32, @intcast(W))))) / (W * ZOOM) + mv_x + c_r := (2.0 * @floatcast(@itf(@as(i32, @intcast(y)))) - @floatcast(@itf(@as(i32, @intcast(H))))) / (H * ZOOM) + mv_y + + z_i := c_i + z_r := c_r + + // iteration + loop if (z_r + z_i) * (z_r + z_i) >= 4 | i == 0 break else { + // z = z * z + c + z_i = z_i * z_i + c_i + z_r = z_r * z_r + c_r + i -= 1 + } + // b g r + put_pixel(.(x, y), .(@as(u8, @intcast(i)), @as(u8, @intcast(i)), @as(u8, @intcast(i)), 255)) + } + } + + return 0 +} + +Color := struct {r: u8, g: u8, b: u8, a: u8} +Vec := struct {x: uint, y: uint} + +put_pixel := fn(pos: Vec, color: Color): void { +} +``` + #### generic_type_mishap ```hb opaque := fn($Expr: type, ptr: ^?Expr): void { diff --git a/lang/src/son.rs b/lang/src/son.rs index cd8f6847..13f538f6 100644 --- a/lang/src/son.rs +++ b/lang/src/son.rs @@ -1298,14 +1298,21 @@ impl Nodes { } } K::Loop => { - if self[target].inputs[0] == NEVER { - return Some(NEVER); - } - - if self[target].inputs[1] == NEVER { + if self[target].inputs[1] == NEVER || self[target].inputs[0] == NEVER { self.lock(target); for o in self[target].outputs.clone() { if self[o].kind == Kind::Phi { + self.remove_node_lookup(target); + + let prev = self[o].inputs[2]; + self[o].inputs[2] = VOID; + self[VOID].outputs.push(o); + let index = self[prev].outputs.iter().position(|&n| n == o).unwrap(); + self[prev].outputs.swap_remove(index); + self.lock(o); + self.remove(prev); + self.unlock(o); + self.replace(o, self[o].inputs[1]); } } @@ -3398,6 +3405,7 @@ impl<'a> Codegen<'a> { ), &mut self.ci.nodes, ); + self.ci.loops.push(Loop { node: self.ci.ctrl.get(), ctrl: [StrongRef::DEFAULT; 2], @@ -4749,6 +4757,7 @@ mod tests { fb_driver; // Purely Testing Examples; + very_nested_loops; generic_type_mishap; storing_into_nullable_struct; scheduling_block_did_dirty; diff --git a/lang/tests/son_tests_very_nested_loops.txt b/lang/tests/son_tests_very_nested_loops.txt new file mode 100644 index 00000000..e10b4213 --- /dev/null +++ b/lang/tests/son_tests_very_nested_loops.txt @@ -0,0 +1,6 @@ +main: + LI64 r1, 0d + JALA r0, r31, 0a +code size: 29 +ret: 0 +status: Ok(())