improve (but not fully fix?) reported line numbers in tracebacks

This commit is contained in:
Scott Richmond 2025-07-06 18:27:43 -04:00
parent 05792d631a
commit 6eb28888ca
5 changed files with 35 additions and 13 deletions

Binary file not shown.

View File

@ -44,20 +44,24 @@ impl Chunk {
| UnconditionalMatch | Print | AppendList | ConcatList | PushList | PushDict
| AppendDict | ConcatDict | Nothing | PushGlobal | SetUpvalue | LoadMessage
| NextMessage | MatchMessage | ClearMessage | SendMethod | LoadScrutinee | Spawn => {
console_log!("{i:04}: {op}")
console_log!("{} | {i:04}: {op}", self.spans[*i])
}
Constant | MatchConstant => {
let high = self.bytecode[*i + 1];
let low = self.bytecode[*i + 2];
let idx = ((high as usize) << 8) + low as usize;
let value = &self.constants[idx].show();
console_log!("{i:04}: {:16} {idx:05}: {value}", op.to_string());
console_log!(
"{} | {i:04}: {:16} {idx:05}: {value}",
self.spans[*i],
op.to_string()
);
*i += 2;
}
Msg => {
let msg_idx = self.bytecode[*i + 1];
let msg = &self.msgs[msg_idx as usize];
console_log!("{i:04}: {msg}");
console_log!("{} | {i:04}: {msg}", self.spans[*i]);
*i += 1;
}
PushBinding | MatchTuple | MatchSplattedTuple | LoadSplattedTuple | MatchList
@ -65,7 +69,11 @@ impl Chunk {
| DropDictEntry | LoadDictValue | PushTuple | PushBox | MatchDepth | PopN | StoreN
| Call | GetUpvalue | Partial | MatchString | PushStringMatches | TailCall | LoadN => {
let next = self.bytecode[*i + 1];
console_log!("{i:04}: {:16} {next:03}", op.to_string());
console_log!(
"{} | {i:04}: {:16} {next:03}",
self.spans[*i],
op.to_string()
);
*i += 1;
}
Jump | JumpIfFalse | JumpIfTrue | JumpIfNoMatch | JumpIfMatch | JumpBack
@ -73,7 +81,11 @@ impl Chunk {
let high = self.bytecode[*i + 1];
let low = self.bytecode[*i + 2];
let len = ((high as u16) << 8) + low as u16;
console_log!("{i:04}: {:16} {len:05}", op.to_string());
console_log!(
"{} | {i:04}: {:16} {len:05}",
self.spans[*i],
op.to_string()
);
*i += 2;
}
}

View File

@ -1,5 +1,6 @@
use crate::ast::{Ast, StringPart};
use crate::chunk::{Chunk, StrPattern};
use crate::errors::line_number;
use crate::op::Op;
use crate::spans::Spanned;
use crate::value::*;
@ -71,6 +72,8 @@ pub struct Compiler {
pub stack_depth: usize,
pub ast: &'static Ast,
pub span: SimpleSpan,
pub line: usize,
pub lines: Vec<usize>,
pub src: &'static str,
pub input: &'static str,
pub depth: usize,
@ -123,6 +126,8 @@ impl Compiler {
stack_depth: 0,
ast: &ast.0,
span: ast.1,
line: 0,
lines: vec![],
loop_info: vec![],
upvalues: vec![],
src,

View File

@ -8,7 +8,7 @@ use chumsky::prelude::*;
const SEPARATOR: &str = "\n\n";
fn line_number(src: &'static str, span: SimpleSpan) -> usize {
pub fn line_number(src: &'static str, span: SimpleSpan) -> usize {
src.chars().take(span.start).filter(|c| *c == '\n').count()
}
@ -127,7 +127,11 @@ pub fn panic(panic: Panic) -> String {
let traceback = traceback(&panic);
format!("no match in `let` form against `{scrutinee}`\n{traceback}")
}
_ => String::from("no match"),
PanicMsg::NoMatch => {
let scrutinee = scrutinee.as_ref().unwrap();
let traceback = traceback(&panic);
format!("no match in `match` form against `{scrutinee}`\n{traceback}")
}
}
}
@ -150,12 +154,9 @@ fn traceback(panic: &Panic) -> String {
}
fn frame_info(frame: &CallFrame) -> String {
let span = frame.chunk().spans[if frame.ip == 0 {
frame.ip
} else {
frame.ip - 1
}];
let span = frame.chunk().spans[if frame.ip == 0 { 0 } else { frame.ip - 1 }];
let line_number = line_number(frame.chunk().src, span);
console_log!("ip: {} | span: {span} | line: {line_number}", frame.ip);
let line = get_line(frame.chunk().src, line_number);
let line = line.trim_start();
let name = frame.function.as_fn().name();

View File

@ -196,7 +196,7 @@ impl Creature {
fn panic(&mut self, msg: PanicMsg) {
// first prep the current frame for parsing
let mut frame = self.frame.clone();
frame.ip = self.last_code;
frame.ip = self.ip;
// add it to our cloned stack
let mut call_stack = self.call_stack.clone();
call_stack.push(frame);
@ -550,16 +550,20 @@ impl Creature {
}
PanicNoMatch => {
if !self.matches {
self.ip -= 1;
return self.panic(PanicMsg::NoMatch);
}
}
PanicNoLetMatch => {
if !self.matches {
self.ip -= 2;
console_log!("panic at bytecode {}", self.ip);
return self.panic(PanicMsg::NoLetMatch);
}
}
PanicNoFnMatch => {
if !self.matches {
self.ip -= 2;
return self.panic(PanicMsg::NoFnMatch);
}
}