diff --git a/src/main.rs b/src/main.rs index b07fd09..800b338 100644 --- a/src/main.rs +++ b/src/main.rs @@ -75,14 +75,12 @@ pub fn run(src: &'static str) { pub fn main() { env::set_var("RUST_BACKTRACE", "1"); let src = " -fn nope () -> nil -fn foo (_, _, _) -> { - nope () - :foo +fn recursive { + (0) -> :done + (n) -> recursive (0) } -fn bar () -> foo (1, 2, 3) -bar () +recursive (1) "; run(src); } diff --git a/src/vm.rs b/src/vm.rs index c824d50..017908e 100644 --- a/src/vm.rs +++ b/src/vm.rs @@ -164,21 +164,28 @@ impl Vm { self.result.as_ref().unwrap() } - pub fn print_call_stack(&mut self) { - println!("in {}", self.frame.function.as_fn().name()); - for frame in self.call_stack.iter() { - println!(" in {}", frame.function.as_fn().name()); + pub fn call_stack(&mut self) -> String { + let mut stack = format!(" calling {}", self.frame.function.show()); + for frame in self.call_stack.iter().rev() { + let mut name = frame.function.show(); + name = if name == "fn user script" { + "user script".to_string() + } else { + name + }; + stack = format!("{stack}\n from {name}"); } + stack } pub fn panic(&mut self, msg: &'static str) { - self.result = Some(Err(Panic::Str(msg))); - self.print_call_stack(); + let msg = format!("{msg}\nPanic traceback:\n{}", self.call_stack()); + self.result = Some(Err(Panic::String(msg))); } pub fn panic_with(&mut self, msg: String) { + let msg = format!("{msg}\nPanic traceback:\n{}", self.call_stack()); self.result = Some(Err(Panic::String(msg))); - self.print_call_stack(); } pub fn interpret(&mut self) { @@ -539,21 +546,6 @@ impl Vm { self.push(splatted); self.ip += 2; } - // PushDict => { - // let dict_len = self.chunk().bytecode[self.ip + 1] as usize * 2; - // let dict_members = self.stack.split_off(self.stack.len() - dict_len); - // let mut dict = HashMap::new(); - // let mut dict_iter = dict_members.iter(); - // while let Some(kw) = dict_iter.next() { - // let Value::Keyword(key) = kw else { - // unreachable!() - // }; - // let value = dict_iter.next().unwrap(); - // dict.insert(*key, value.clone()); - // } - // self.push(Value::Dict(Box::new(dict))); - // self.ip += 2; - // } PushDict => { self.push(Value::Dict(Box::new(HashMap::new()))); self.ip += 1; @@ -657,7 +649,6 @@ impl Vm { let high = self.chunk().bytecode[self.ip + 1]; let low = self.chunk().bytecode[self.ip + 2]; let jump_len = combine_bytes(high, low); - // let jump_len = self.chunk().bytecode[self.ip + 1] as usize; if self.matches { self.ip += jump_len + 3; } else {