add location info for errors

This commit is contained in:
wires 2025-07-11 12:33:08 -04:00
parent d7ceafc0f0
commit 89082a3750
Signed by: wires
SSH key fingerprint: SHA256:9GtP+M3O2IivPDlw1UY872UPUuJH2gI0yG6ExBxaaiM

View file

@ -120,23 +120,23 @@ impl<'a> ParseIter<'a> {
} }
} }
fn parse_list(&mut self) -> Result<Expr, Error> { fn parse_list(&mut self, start: usize) -> Result<Expr, (Error, usize)> {
let mut res = vec![]; let mut res = vec![];
while let Some(term) = self.parse_list_helper() { while let Some(term) = self.parse_list_helper(start) {
res.push(term?); res.push(term?);
} }
Ok(Expr::List(res)) Ok(Expr::List(res))
} }
fn parse_list_helper(&mut self) -> Option<Result<Expr, Error>> { fn parse_list_helper(&mut self, start: usize) -> Option<Result<Expr, (Error, usize)>> {
let Self { src, cursor } = self; let Self { src, cursor } = self;
let Token { let Token {
kind, kind,
span: Span { start, len }, span: Span { start, len },
} = match cursor.next_token() { } = match cursor.next_token() {
None => return Some(Err(Error::Incomplete)), None => return Some(Err((Error::Incomplete, start))),
Some(t) => t, Some(t) => t,
}; };
let end = start + len; let end = start + len;
@ -145,15 +145,15 @@ impl<'a> ParseIter<'a> {
match kind { match kind {
TokenKind::Atom => Some(Ok(Expr::atom(src_str))), TokenKind::Atom => Some(Ok(Expr::atom(src_str))),
TokenKind::Number => Some(Expr::parse_int(src_str).map_err(Into::into)), TokenKind::Number => Some(Expr::parse_int(src_str).map_err(|e| (e.into(), start))),
TokenKind::OpenParen => Some(self.parse_list()), TokenKind::OpenParen => Some(self.parse_list(start)),
TokenKind::CloseParen => None, TokenKind::CloseParen => None,
} }
} }
} }
impl<'a> Iterator for ParseIter<'a> { impl<'a> Iterator for ParseIter<'a> {
type Item = Result<Expr, Error>; type Item = Result<Expr, (Error, usize)>;
fn next(&mut self) -> Option<Self::Item> { fn next(&mut self) -> Option<Self::Item> {
let Self { src, cursor } = self; let Self { src, cursor } = self;
@ -167,9 +167,9 @@ impl<'a> Iterator for ParseIter<'a> {
Some(match kind { Some(match kind {
TokenKind::Atom => Ok(Expr::atom(src_str)), TokenKind::Atom => Ok(Expr::atom(src_str)),
TokenKind::Number => Expr::parse_int(src_str).map_err(Into::into), TokenKind::Number => Expr::parse_int(src_str).map_err(|e| (e.into(), start)),
TokenKind::OpenParen => self.parse_list(), TokenKind::OpenParen => self.parse_list(start),
_ => Err(Error::Unexpected), _ => Err((Error::Unexpected, start)),
}) })
} }
} }