[fine] Different source locations

This commit is contained in:
John Doty 2024-01-01 09:05:13 -08:00
parent 2d233244cf
commit 81a7b09555
2 changed files with 18 additions and 58 deletions

View file

@ -47,10 +47,10 @@ pub enum BinaryOp {
Or,
}
pub enum Expr {
Literal(Literal),
Unary(UnaryOp, ExprRef),
Binary(BinaryOp, ExprRef, ExprRef),
pub enum Expr<'a> {
Literal(Literal, Token<'a>),
Unary(UnaryOp, Token<'a>, ExprRef),
Binary(BinaryOp, Token<'a>, ExprRef, ExprRef),
}
pub struct ExprRef(Option<usize>);
@ -63,8 +63,7 @@ impl ExprRef {
pub struct SyntaxTree<'a> {
pub errors: Vec<SyntaxError>,
expressions: Vec<Expr>,
spans: Vec<(Option<Token<'a>>, Option<Token<'a>>)>,
expressions: Vec<Expr<'a>>,
}
impl<'a> SyntaxTree<'a> {
@ -72,7 +71,6 @@ impl<'a> SyntaxTree<'a> {
SyntaxTree {
errors: Vec::new(),
expressions: Vec::new(),
spans: Vec::new(),
}
}
@ -80,51 +78,23 @@ impl<'a> SyntaxTree<'a> {
self.errors.push(error);
}
pub fn add_expr(
&mut self,
expr: Expr,
start: Option<Token<'a>>,
end: Option<Token<'a>>,
) -> ExprRef {
pub fn add_expr(&mut self, expr: Expr<'a>) -> ExprRef {
let index = self.expressions.len();
self.expressions.push(expr);
self.spans.push((start, end));
ExprRef(Some(index))
}
pub fn span(&self, expr: &ExprRef) -> (Option<Token<'a>>, Option<Token<'a>>) {
if let ExprRef(Some(idx)) = expr {
let (start, end) = &self.spans[*idx];
(start.clone(), end.clone())
} else {
(None, None)
}
}
pub fn dump_expr(&self, expr: &ExprRef) -> String {
match expr.0 {
Some(idx) => {
let expr = &self.expressions[idx];
match expr {
Expr::Literal(lit) => match lit {
Literal::Float64(f) => f.to_string(),
},
Expr::Unary(op, e) => {
let op = match op {
UnaryOp::Negate => "-",
};
format!("({op} {})", self.dump_expr(e))
Expr::Literal(_, tok) => tok.to_string(),
Expr::Unary(_, tok, e) => {
format!("({tok} {})", self.dump_expr(e))
}
Expr::Binary(op, l, r) => {
let op = match op {
BinaryOp::Add => "+",
BinaryOp::Subtract => "-",
BinaryOp::Mutiply => "*",
BinaryOp::Divide => "/",
BinaryOp::And => "and",
BinaryOp::Or => "or",
};
format!("({op} {} {})", self.dump_expr(l), self.dump_expr(r))
Expr::Binary(_, tok, l, r) => {
format!("({tok} {} {})", self.dump_expr(l), self.dump_expr(r))
}
}
}
@ -263,11 +233,7 @@ impl<'a> Parser<'a> {
}
};
self.tree.add_expr(
Expr::Literal(literal),
Some(token.clone()),
Some(token.clone()),
)
self.tree.add_expr(Expr::Literal(literal, token.clone()))
}
fn grouping(&mut self) -> ExprRef {
@ -288,8 +254,7 @@ impl<'a> Parser<'a> {
_ => panic!("unsuitable unary: {:?}: no op", kind),
};
self.tree
.add_expr(Expr::Unary(op, expr), Some(token), self.previous.clone())
self.tree.add_expr(Expr::Unary(op, token, expr))
}
fn binary(&mut self, power: u8, left: ExprRef) -> ExprRef {
@ -304,12 +269,7 @@ impl<'a> Parser<'a> {
_ => panic!("unsuitable binary: {:?}: no op", self.previous),
};
let right = self.expression_with_power(power + 1);
let (left_start, _) = self.tree.span(&left);
let (_, right_end) = self.tree.span(&right);
self.tree
.add_expr(Expr::Binary(op, left, right), left_start, right_end)
self.tree.add_expr(Expr::Binary(op, token, left, right))
}
fn advance(&mut self) {
@ -318,7 +278,7 @@ impl<'a> Parser<'a> {
self.current = self.tokens.next();
match &self.current {
Some(token) if token.kind() == TokenKind::Error => {
self.error_at_current(token.clone())
self.error_at_current(token.to_string())
}
_ => break,
}

View file

@ -89,9 +89,9 @@ impl<'a> Token<'a> {
}
}
impl<'a> Into<String> for Token<'a> {
fn into(self) -> String {
self.as_str().to_string()
impl<'a> std::fmt::Display for Token<'a> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.as_str())
}
}