From e4b385d2fb03b25e84ae1457775bd3c6777a6006 Mon Sep 17 00:00:00 2001 From: Scott Richmond Date: Mon, 23 Jun 2025 00:27:50 -0400 Subject: [PATCH] fix tail position in collection forms --- sandbox.ld | 38 ++++++++++++++++++++++++++++++++++++-- src/compiler.rs | 7 +++++-- src/vm.rs | 14 +++++++------- 3 files changed, 48 insertions(+), 11 deletions(-) diff --git a/sandbox.ld b/sandbox.ld index 927e835..243f9c0 100644 --- a/sandbox.ld +++ b/sandbox.ld @@ -1,3 +1,37 @@ -let #{a, b, ...} = #{:a 1, :b 2, :c 3} +& let state = #{:position (0, 0), :heading 0, :pencolor :white} + +& let command = (:forward, 10) + +& match command with { +& (:goto, (x, y)) -> assoc (state, :position, (x, y)) +& & (:home) -> do state > +& & assoc (_, :position, (0, 0)) > +& & assoc (_, :heading, 0) +& & (:clear) -> do state > +& & assoc (state, :position, (0, 0)) > +& & assoc (_, :heading, 0) +& (:right, turns) -> update (state, :heading, add (_, turns)) +& (:left, turns) -> update (state, :heading, sub (_, turns)) +& (:forward, steps) -> { +& let #{heading, position, ...} = state +& let unit = heading/vector (heading) +& let vect = mult (steps, unit) +& update (state, :position, add (vect, _)) +& } +& (:back, steps) -> { +& let #{heading, position, ...} = state +& let unit = heading/vector (heading) +& let vect = mult (steps, unit) +& update (state, :position, sub (_, vect)) +& } +& & (:penup) -> assoc (state, :pendown?, false) +& & (:pendown) -> assoc (state, :pendown?, true) +& & (:penwidth, pixels) -> assoc (state, :penwidth, pixels) +& & (:pencolor, color) -> assoc (state, :pencolor, color) +& & (:setheading, heading) -> assoc (state, :heading, heading) +& & (:loadstate, position, heading, visible?, pendown?, penwidth, pencolor) -> #{position, heading, visible?, pendown?, penwidth, pencolor} +& & (:show) -> assoc (state, :visible?, true) +& & (:hide) -> assoc (state, :visible?, false) +& & (:background, _) -> state +& } -(a, b) diff --git a/src/compiler.rs b/src/compiler.rs index 3442df8..affaa8e 100644 --- a/src/compiler.rs +++ b/src/compiler.rs @@ -740,8 +740,6 @@ impl<'a> Compiler<'a> { } self.pop_n(pairs.len()); - // self.emit_op(Op::PopN); - // 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); @@ -796,6 +794,7 @@ impl<'a> Compiler<'a> { } PairPattern(_, _) => unreachable!(), Tuple(members) => { + self.tail_pos = false; for member in members { self.visit(member); } @@ -804,6 +803,7 @@ impl<'a> Compiler<'a> { self.stack_depth = self.stack_depth + 1 - members.len(); } List(members) => { + self.tail_pos = false; self.emit_op(Op::PushList); self.stack_depth += 1; for member in members { @@ -817,11 +817,13 @@ impl<'a> Compiler<'a> { } } LBox(name, expr) => { + self.tail_pos = false; self.visit(expr); self.emit_op(Op::PushBox); self.bind(name); } Dict(pairs) => { + self.tail_pos = false; self.emit_op(Op::PushDict); self.stack_depth += 1; for pair in pairs.iter().rev() { @@ -836,6 +838,7 @@ impl<'a> Compiler<'a> { } } Pair(key, value) => { + self.tail_pos = false; self.emit_constant(Value::Keyword(key)); self.visit(value); } diff --git a/src/vm.rs b/src/vm.rs index 3c725f7..b442d0a 100644 --- a/src/vm.rs +++ b/src/vm.rs @@ -968,13 +968,13 @@ impl Vm { } _ => return self.panic("internal ludus error"), }; - // algo: - // clear the stack - self.stack.truncate(self.frame.stack_base); - // then pop back out to the enclosing stack frame - self.frame = self.call_stack.pop().unwrap(); - self.ip = self.frame.ip; - // finally, throw the value on the stack + // // algo: + // // clear the stack + // self.stack.truncate(self.frame.stack_base); + // // then pop back out to the enclosing stack frame + // self.frame = self.call_stack.pop().unwrap(); + // self.ip = self.frame.ip; + // // finally, throw the value on the stack self.push(value); println!( "=== returning to {} ===",