diff --git a/may_2025_thoughts.md b/may_2025_thoughts.md index 938700e..3d008c4 100644 --- a/may_2025_thoughts.md +++ b/may_2025_thoughts.md @@ -492,4 +492,7 @@ Here's a list of things that need doing: * [ ] Original implementation of `butlast` is breaking stack discipline; I don't know why. It ends up returning from evaluating one of the arguments straight into a `load` instruction. Something about tail calls and ternary synthetic expressions and base functions. (For now, I can call `slice` instead of `base :slice` and it works.) - Original version of `update` also had this same problem with `assoc`; fixed it by calling the Ludus, rather than Rust, function. - I need this fixed for optimization reasons. + - I _think_ I just fixed this by fixing tail position tracking in collections + - [ ] test this +* [ ] Dict patterns are giving me stack discipline grief. Why is stack discipline so hard? diff --git a/sandbox.ld b/sandbox.ld index 243f9c0..fd745a2 100644 --- a/sandbox.ld +++ b/sandbox.ld @@ -35,3 +35,6 @@ & & (:background, _) -> state & } +let foo = #{:a 1, :b 2, :c 3} +let #{a, b, ...c} = foo + diff --git a/src/compiler.rs b/src/compiler.rs index affaa8e..0ca91bc 100644 --- a/src/compiler.rs +++ b/src/compiler.rs @@ -739,7 +739,9 @@ impl<'a> Compiler<'a> { self.patch_jump(idx, self.len() - idx - 3); } - self.pop_n(pairs.len()); + // do this explicitly to keep compiler & vm stacks in sync + self.emit_op(Op::Pop); + self.emit_byte(pairs.len()); self.patch_jump(before_load_dict_idx, self.len() - before_load_dict_idx - 3); self.patch_jump(jump_idx, self.len() - jump_idx - 3);