update (fix?) partial function application stack discipline

This commit is contained in:
Scott Richmond 2025-06-23 21:22:28 -04:00
parent 772c56a6df
commit 0290bb3bf2
4 changed files with 44 additions and 40 deletions

View File

@ -1,37 +1,41 @@
fn apply_command { & fn apply_command {
"Takes a turtle state and a command and calculates a new state." & "Takes a turtle state and a command and calculates a new state."
(state, command) -> match command with { & (state, command) -> match command with {
(:goto, (x, y)) -> assoc (state, :position, (x, y)) & (:goto, (x, y)) -> assoc (state, :position, (x, y))
(:home) -> do state > & (:home) -> do state >
assoc (_, :position, (0, 0)) > & assoc (_, :position, (0, 0)) >
assoc (_, :heading, 0) & assoc (_, :heading, 0)
(:clear) -> do state > & (:clear) -> do state >
assoc (state, :position, (0, 0)) > & assoc (state, :position, (0, 0)) >
assoc (_, :heading, 0) & assoc (_, :heading, 0)
(:right, turns) -> update (state, :heading, add (_, turns)) & (:right, turns) -> update (state, :heading, add (_, turns))
(:left, turns) -> update (state, :heading, sub (_, turns)) & (:left, turns) -> update (state, :heading, sub (_, turns))
(:forward, steps) -> { & (:forward, steps) -> {
let #{heading, position, ...} = state & let #{heading, position, ...} = state
let unit = heading/vector (heading) & let unit = heading/vector (heading)
let vect = mult (steps, unit) & let vect = mult (steps, unit)
update (state, :position, add (vect, _)) & update (state, :position, add (vect, _))
} & }
(:back, steps) -> { & (:back, steps) -> {
let #{heading, position, ...} = state & let #{heading, position, ...} = state
let unit = heading/vector (heading) & let unit = heading/vector (heading)
let vect = mult (steps, unit) & let vect = mult (steps, unit)
update (state, :position, sub (_, vect)) & update (state, :position, sub (_, vect))
} & }
(:penup) -> assoc (state, :pendown?, false) & (:penup) -> assoc (state, :pendown?, false)
(:pendown) -> assoc (state, :pendown?, true) & (:pendown) -> assoc (state, :pendown?, true)
(:penwidth, pixels) -> assoc (state, :penwidth, pixels) & (:penwidth, pixels) -> assoc (state, :penwidth, pixels)
(:pencolor, color) -> assoc (state, :pencolor, color) & (:pencolor, color) -> assoc (state, :pencolor, color)
(:setheading, heading) -> assoc (state, :heading, heading) & (:setheading, heading) -> assoc (state, :heading, heading)
(:loadstate, position, heading, visible?, pendown?, penwidth, pencolor) -> #{position, heading, visible?, pendown?, penwidth, pencolor} & (:loadstate, position, heading, visible?, pendown?, penwidth, pencolor) -> #{position, heading, visible?, pendown?, penwidth, pencolor}
(:show) -> assoc (state, :visible?, true) & (:show) -> assoc (state, :visible?, true)
(:hide) -> assoc (state, :visible?, false) & (:hide) -> assoc (state, :visible?, false)
(:background, _) -> state & (:background, _) -> state
} & }
} & }
apply_command (turtle_init, (:penup)) fn many_args (_, _, x, _) -> x
let fewer_args = many_args (:foo, :bar, _, :baz)
fewer_args(:quux)

View File

@ -917,7 +917,7 @@ impl Compiler {
self.resolve_binding(fn_name); self.resolve_binding(fn_name);
self.emit_op(Op::Partial); self.emit_op(Op::Partial);
self.emit_byte(arity); self.emit_byte(arity);
self.stack_depth -= 1; self.stack_depth -= args.len() - 1;
} else { } else {
match get_builtin(fn_name, args.len()) { match get_builtin(fn_name, args.len()) {
Some(code) => { Some(code) => {

View File

@ -4,7 +4,7 @@ use std::env;
use std::fs; use std::fs;
const DEBUG_SCRIPT_COMPILE: bool = false; const DEBUG_SCRIPT_COMPILE: bool = false;
const DEBUG_SCRIPT_RUN: bool = false; const DEBUG_SCRIPT_RUN: bool = true;
const DEBUG_PRELUDE_COMPILE: bool = false; const DEBUG_PRELUDE_COMPILE: bool = false;
const DEBUG_PRELUDE_RUN: bool = false; const DEBUG_PRELUDE_RUN: bool = false;

View File

@ -1000,7 +1000,7 @@ impl Vm {
let mut frame = CallFrame { let mut frame = CallFrame {
function: the_fn, function: the_fn,
arity: args.len() as u8, arity: args.len() as u8,
stack_base: self.stack.len() - arity as usize - 1, stack_base: self.stack.len() - args.len(),
ip: 0, ip: 0,
}; };
@ -1090,7 +1090,7 @@ impl Vm {
let mut frame = CallFrame { let mut frame = CallFrame {
function: the_fn, function: the_fn,
arity: args.len() as u8, arity: args.len() as u8,
stack_base: self.stack.len() - arity as usize - 1, stack_base: self.stack.len() - args.len(),
ip: 0, ip: 0,
}; };