moar debugging: find issues with upvalues

This commit is contained in:
Scott Richmond 2025-06-23 18:59:12 -04:00
parent 24f57c1529
commit 987cc172c1
6 changed files with 172 additions and 205 deletions

View File

@ -1210,168 +1210,171 @@ fn penwidth {
box state = nil box state = nil
#{ #{
type apply_command
coll? add_command!
ordered?
assoc? abs
nil? abs
some? add
some angle
eq? any?
bool?
true?
false?
bool
not
tuple?
fn?
first
rest
inc
dec
count
empty?
any?
list?
list
first
fold
foldr
append append
map assert!
filter assoc
keep assoc?
concat at
contains? atan/2
print! back!
show background!
report! between?
doc! bg!
string bk!
string? bool
join bool?
split box?
trim butlast
upcase ceil
downcase
chars chars
chars/safe chars/safe
ws? clear!
strip coll?
words colors
sentence concat
to_number contains?
box? cos
unbox count
store! dec
update! deg/rad
add deg/turn
sub dict
mult dict?
dissoc
dist
div div
div/0 div/0
div/safe div/safe
doc!
downcase
each!
empty?
eq?
err
err?
even?
false?
fd!
filter
first
first
first
floor
fn?
fold
foldr
forward!
get
goto!
gt?
gte?
has?
heading
heading/vector
hideturtle!
home!
inc
inv inv
inv/0 inv/0
inv/safe inv/safe
abs join
neg keep
zero? keys
gt? keyword?
gte? last
left!
list
list?
loadstate!
lt!
lt? lt?
lte? lte?
between? map
neg?
pos?
abs
pi
tau
turn/deg
deg/turn
turn/rad
rad/turn
deg/rad
rad/deg
sin
cos
tan
rotate
atan/2
angle
mod mod
mod/0 mod/0
mod/safe mod/safe
even? mult
neg
neg?
nil?
not
odd? odd?
square
sqrt
sqrt/safe
dist
heading/vector
floor
ceil
round
range
at
first
second
last
butlast
slice
keyword?
assoc
dissoc
update
keys
values
get
has?
dict
dict?
each!
random
random_int
ok ok
ok? ok?
err ordered?
err? pc!
pd!
pencolor
pencolor!
pendown!
pendown?
penup!
penwidth
penwidth!
pi
pos?
position
print!
pu!
pw!
rad/deg
rad/turn
random
random_int
range
report!
rest
right!
rotate
round
rt!
second
sentence
setheading!
show
showturtle!
sin
slice
some
some?
split
sqrt
sqrt/safe
square
state
store!
string
string?
strip
sub
tan
tau
to_number
trim
true?
tuple?
turn/deg
turn/rad
turtle_commands
turtle_init
turtle_state
type
unbox
unwrap! unwrap!
unwrap_or unwrap_or
assert! upcase
colors update
turtle_init update!
turtle_commands values
turtle_state words
forward! ws?
fd! zero?
back!
bk!
left!
lt!
right!
rt!
penup!
pu!
pendown!
pd!
pencolor!
pc!
penwidth!
pw!
background!
bg!
home!
clear!
goto!
setheading!
showturtle!
hideturtle!
loadstate!
position
heading
pendown?
pencolor
penwidth
state
} }

View File

@ -1,46 +1,6 @@
let state = #{:position (0, 0), :heading 0, :pencolor :white} let add = :foo
let nil? = :bar
let command = (:forward, 10) fn baz () -> (add, nil?)
& 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) -> {
& print! ("matched forward")
& let #{heading, position, ...} = state
& print! ("extracted {heading} and {position} from state")
& let unit = heading/vector (heading)
& print! ("unit vector at {heading}: {unit}")
& let vect = mult (steps, unit)
& print! ("update vector: {vect}")
& let new_state = update (state, :position, add (vect, _))
& print! ("new state: {new_state}")
& new_state
& }
& & (: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
& }
let #{heading, position, ...x} = state
let unit = heading/vector (heading)
unit
baz()

View File

@ -393,10 +393,12 @@ impl<'a> Compiler<'a> {
} }
fn msg(&mut self, str: String) { fn msg(&mut self, str: String) {
self.emit_op(Op::Msg); if self.debug {
self.emit_byte(self.chunk.msgs.len()); self.emit_op(Op::Msg);
println!("{str}"); self.emit_byte(self.chunk.msgs.len());
self.chunk.msgs.push(str); println!("{str}");
self.chunk.msgs.push(str);
}
} }
fn report_depth(&mut self, label: &'static str) { fn report_depth(&mut self, label: &'static str) {
@ -750,18 +752,18 @@ impl<'a> Compiler<'a> {
} }
Splattern(patt) => self.visit(patt), Splattern(patt) => self.visit(patt),
InterpolatedPattern(parts, _) => { InterpolatedPattern(parts, _) => {
println!("An interpolated pattern of {} parts", parts.len()); // println!("An interpolated pattern of {} parts", parts.len());
let mut pattern = "".to_string(); let mut pattern = "".to_string();
let mut words = vec![]; let mut words = vec![];
for (part, _) in parts { for (part, _) in parts {
match part { match part {
StringPart::Word(word) => { StringPart::Word(word) => {
println!("wordpart: {word}"); // println!("wordpart: {word}");
words.push(word.clone()); words.push(word.clone());
pattern.push_str("(.*)"); pattern.push_str("(.*)");
} }
StringPart::Data(data) => { StringPart::Data(data) => {
println!("datapart: {data}"); // println!("datapart: {data}");
let data = regex::escape(data); let data = regex::escape(data);
pattern.push_str(data.as_str()); pattern.push_str(data.as_str());
} }

View File

@ -3,8 +3,8 @@ use imbl::HashMap;
use std::env; use std::env;
use std::fs; use std::fs;
const DEBUG_SCRIPT_COMPILE: bool = true; const DEBUG_SCRIPT_COMPILE: bool = false;
const DEBUG_SCRIPT_RUN: bool = true; const DEBUG_SCRIPT_RUN: bool = false;
const DEBUG_PRELUDE_COMPILE: bool = false; const DEBUG_PRELUDE_COMPILE: bool = false;
const DEBUG_PRELUDE_RUN: bool = false; const DEBUG_PRELUDE_RUN: bool = false;
@ -146,10 +146,12 @@ pub fn run(src: &'static str) {
let mut vm = Vm::new(vm_chunk, DEBUG_SCRIPT_RUN); let mut vm = Vm::new(vm_chunk, DEBUG_SCRIPT_RUN);
let result = vm.run(); let result = vm.run();
let output = match result { let output = match result {
Ok(val) => val.show(), Ok(val) => val.to_string(),
Err(panic) => format!("Ludus panicked! {panic}"), Err(panic) => format!("Ludus panicked! {panic}"),
}; };
vm.print_stack(); if DEBUG_SCRIPT_RUN {
vm.print_stack();
}
println!("{output}"); println!("{output}");
} }

View File

@ -26,8 +26,10 @@ impl LFn {
match self { match self {
LFn::Declared { .. } => unreachable!(), LFn::Declared { .. } => unreachable!(),
LFn::Defined { closed, .. } => { LFn::Defined { closed, .. } => {
println!("closing over in {}: {}", self.name(), value.show()); let shown = value.show();
closed.borrow_mut().push(value); closed.borrow_mut().push(value);
let pos = closed.borrow().len();
println!("closing over in {} at {pos}: {shown}", self.name(),);
} }
} }
} }

View File

@ -948,8 +948,6 @@ impl Vm {
frame.ip = self.ip; frame.ip = self.ip;
self.ip = 0; self.ip = 0;
if crate::DEBUG_SCRIPT_RUN {}
} }
Value::BaseFn(base_fn) => { Value::BaseFn(base_fn) => {
let value = match (arity, base_fn) { let value = match (arity, base_fn) {
@ -1014,7 +1012,7 @@ impl Vm {
let val = self.pop(); let val = self.pop();
if crate::DEBUG_SCRIPT_RUN { if self.debug {
println!("=== calling into {val}/{arity} ==="); println!("=== calling into {val}/{arity} ===");
} }
@ -1099,7 +1097,7 @@ impl Vm {
} }
} }
Return => { Return => {
if crate::DEBUG_SCRIPT_RUN { if self.debug {
println!("== returning from {} ==", self.frame.function.show()) println!("== returning from {} ==", self.frame.function.show())
} }
self.frame = self.call_stack.pop().unwrap(); self.frame = self.call_stack.pop().unwrap();