fix upvalue resolution for forward-declared functions
This commit is contained in:
parent
42a5f599f7
commit
772c56a6df
|
@ -1029,10 +1029,16 @@ box turtle_state = turtle_init
|
||||||
fn apply_command
|
fn apply_command
|
||||||
|
|
||||||
fn add_command! (command) -> {
|
fn add_command! (command) -> {
|
||||||
|
print! ("adding {command}")
|
||||||
update! (turtle_commands, append (_, command))
|
update! (turtle_commands, append (_, command))
|
||||||
|
print! ("added command to commands")
|
||||||
|
print! (turtle_commands)
|
||||||
let prev = unbox (turtle_state)
|
let prev = unbox (turtle_state)
|
||||||
|
print! ("previous state: {prev}")
|
||||||
let curr = apply_command (prev, command)
|
let curr = apply_command (prev, command)
|
||||||
|
print! ("new state: {curr}")
|
||||||
store! (turtle_state, curr)
|
store! (turtle_state, curr)
|
||||||
|
print! ("stored state: {turtle_state}")
|
||||||
:ok
|
:ok
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1146,38 +1152,40 @@ fn loadstate! {
|
||||||
|
|
||||||
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) -> {
|
||||||
(:goto, (x, y)) -> assoc (state, :position, (x, y))
|
print!("apply_command:\n{state}\n{command}")
|
||||||
(:home) -> do state >
|
match command with {
|
||||||
assoc (_, :position, (0, 0)) >
|
(:goto, (x, y)) -> assoc (state, :position, (x, y))
|
||||||
assoc (_, :heading, 0)
|
(:home) -> do state >
|
||||||
(:clear) -> do state >
|
assoc (_, :position, (0, 0)) >
|
||||||
assoc (state, :position, (0, 0)) >
|
assoc (_, :heading, 0)
|
||||||
assoc (_, :heading, 0)
|
& (:clear) -> do state >
|
||||||
(:right, turns) -> update (state, :heading, add (_, turns))
|
& assoc (state, :position, (0, 0)) >
|
||||||
(:left, turns) -> update (state, :heading, sub (_, turns))
|
& assoc (_, :heading, 0)
|
||||||
(:forward, steps) -> {
|
(:right, turns) -> update (state, :heading, add (_, turns))
|
||||||
let #{heading, position, ...} = state
|
(:left, turns) -> update (state, :heading, sub (_, turns))
|
||||||
let unit = heading/vector (heading)
|
(:forward, steps) -> {
|
||||||
let vect = mult (steps, unit)
|
let #{heading, position, ...} = state
|
||||||
update (state, :position, add (vect, _))
|
let unit = heading/vector (heading)
|
||||||
}
|
let vect = mult (steps, unit)
|
||||||
(:back, steps) -> {
|
update (state, :position, add (vect, _))
|
||||||
let #{heading, position, ...} = state
|
}
|
||||||
let unit = heading/vector (heading)
|
(:back, steps) -> {
|
||||||
let vect = mult (steps, unit)
|
let #{heading, position, ...} = state
|
||||||
update (state, :position, sub (_, vect))
|
let unit = heading/vector (heading)
|
||||||
}
|
let vect = mult (steps, unit)
|
||||||
(:penup) -> assoc (state, :pendown?, false)
|
update (state, :position, sub (_, vect))
|
||||||
(:pendown) -> assoc (state, :pendown?, true)
|
}
|
||||||
(:penwidth, pixels) -> assoc (state, :penwidth, pixels)
|
(:penup) -> assoc (state, :pendown?, false)
|
||||||
(:pencolor, color) -> assoc (state, :pencolor, color)
|
(:pendown) -> assoc (state, :pendown?, true)
|
||||||
(:setheading, heading) -> assoc (state, :heading, heading)
|
(:penwidth, pixels) -> assoc (state, :penwidth, pixels)
|
||||||
(:loadstate, position, heading, visible?, pendown?, penwidth, pencolor) -> #{position, heading, visible?, pendown?, penwidth, pencolor}
|
(:pencolor, color) -> assoc (state, :pencolor, color)
|
||||||
(:show) -> assoc (state, :visible?, true)
|
(:setheading, heading) -> assoc (state, :heading, heading)
|
||||||
(:hide) -> assoc (state, :visible?, false)
|
(:loadstate, position, heading, visible?, pendown?, penwidth, pencolor) -> #{position, heading, visible?, pendown?, penwidth, pencolor}
|
||||||
(:background, _) -> state
|
(:show) -> assoc (state, :visible?, true)
|
||||||
}
|
(:hide) -> assoc (state, :visible?, false)
|
||||||
|
(:background, _) -> state
|
||||||
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
& position () -> (x, y)
|
& position () -> (x, y)
|
||||||
|
|
39
sandbox.ld
39
sandbox.ld
|
@ -1,2 +1,37 @@
|
||||||
let state = unbox (turtle_state)
|
fn apply_command {
|
||||||
apply_command(state, (:penup))
|
"Takes a turtle state and a command and calculates a new state."
|
||||||
|
(state, command) -> 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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
apply_command (turtle_init, (:penup))
|
||||||
|
|
11
src/vm.rs
11
src/vm.rs
|
@ -606,8 +606,15 @@ impl Vm {
|
||||||
}
|
}
|
||||||
LoadDictValue => {
|
LoadDictValue => {
|
||||||
let dict_idx = self.chunk().bytecode[self.ip + 1] as usize;
|
let dict_idx = self.chunk().bytecode[self.ip + 1] as usize;
|
||||||
let Value::Dict(dict) = self.stack[dict_idx].clone() else {
|
let dict = match self.stack[dict_idx].clone() {
|
||||||
unreachable!("expected dict, got something else")
|
Value::Dict(dict) => dict,
|
||||||
|
value => {
|
||||||
|
println!(
|
||||||
|
"internal Ludus error in function {}",
|
||||||
|
self.frame.function.as_fn().name()
|
||||||
|
);
|
||||||
|
unreachable!("expected dict, got {value}")
|
||||||
|
}
|
||||||
};
|
};
|
||||||
let Value::Keyword(key) = self.pop() else {
|
let Value::Keyword(key) = self.pop() else {
|
||||||
unreachable!("expected keyword, got something else")
|
unreachable!("expected keyword, got something else")
|
||||||
|
|
Loading…
Reference in New Issue
Block a user