[fine] Different source locations
This commit is contained in:
parent
2d233244cf
commit
81a7b09555
2 changed files with 18 additions and 58 deletions
|
|
@ -47,10 +47,10 @@ pub enum BinaryOp {
|
||||||
Or,
|
Or,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum Expr {
|
pub enum Expr<'a> {
|
||||||
Literal(Literal),
|
Literal(Literal, Token<'a>),
|
||||||
Unary(UnaryOp, ExprRef),
|
Unary(UnaryOp, Token<'a>, ExprRef),
|
||||||
Binary(BinaryOp, ExprRef, ExprRef),
|
Binary(BinaryOp, Token<'a>, ExprRef, ExprRef),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ExprRef(Option<usize>);
|
pub struct ExprRef(Option<usize>);
|
||||||
|
|
@ -63,8 +63,7 @@ impl ExprRef {
|
||||||
|
|
||||||
pub struct SyntaxTree<'a> {
|
pub struct SyntaxTree<'a> {
|
||||||
pub errors: Vec<SyntaxError>,
|
pub errors: Vec<SyntaxError>,
|
||||||
expressions: Vec<Expr>,
|
expressions: Vec<Expr<'a>>,
|
||||||
spans: Vec<(Option<Token<'a>>, Option<Token<'a>>)>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> SyntaxTree<'a> {
|
impl<'a> SyntaxTree<'a> {
|
||||||
|
|
@ -72,7 +71,6 @@ impl<'a> SyntaxTree<'a> {
|
||||||
SyntaxTree {
|
SyntaxTree {
|
||||||
errors: Vec::new(),
|
errors: Vec::new(),
|
||||||
expressions: Vec::new(),
|
expressions: Vec::new(),
|
||||||
spans: Vec::new(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -80,51 +78,23 @@ impl<'a> SyntaxTree<'a> {
|
||||||
self.errors.push(error);
|
self.errors.push(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_expr(
|
pub fn add_expr(&mut self, expr: Expr<'a>) -> ExprRef {
|
||||||
&mut self,
|
|
||||||
expr: Expr,
|
|
||||||
start: Option<Token<'a>>,
|
|
||||||
end: Option<Token<'a>>,
|
|
||||||
) -> ExprRef {
|
|
||||||
let index = self.expressions.len();
|
let index = self.expressions.len();
|
||||||
self.expressions.push(expr);
|
self.expressions.push(expr);
|
||||||
self.spans.push((start, end));
|
|
||||||
ExprRef(Some(index))
|
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 {
|
pub fn dump_expr(&self, expr: &ExprRef) -> String {
|
||||||
match expr.0 {
|
match expr.0 {
|
||||||
Some(idx) => {
|
Some(idx) => {
|
||||||
let expr = &self.expressions[idx];
|
let expr = &self.expressions[idx];
|
||||||
match expr {
|
match expr {
|
||||||
Expr::Literal(lit) => match lit {
|
Expr::Literal(_, tok) => tok.to_string(),
|
||||||
Literal::Float64(f) => f.to_string(),
|
Expr::Unary(_, tok, e) => {
|
||||||
},
|
format!("({tok} {})", self.dump_expr(e))
|
||||||
Expr::Unary(op, e) => {
|
|
||||||
let op = match op {
|
|
||||||
UnaryOp::Negate => "-",
|
|
||||||
};
|
|
||||||
format!("({op} {})", self.dump_expr(e))
|
|
||||||
}
|
}
|
||||||
Expr::Binary(op, l, r) => {
|
Expr::Binary(_, tok, l, r) => {
|
||||||
let op = match op {
|
format!("({tok} {} {})", self.dump_expr(l), self.dump_expr(r))
|
||||||
BinaryOp::Add => "+",
|
|
||||||
BinaryOp::Subtract => "-",
|
|
||||||
BinaryOp::Mutiply => "*",
|
|
||||||
BinaryOp::Divide => "/",
|
|
||||||
BinaryOp::And => "and",
|
|
||||||
BinaryOp::Or => "or",
|
|
||||||
};
|
|
||||||
format!("({op} {} {})", self.dump_expr(l), self.dump_expr(r))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -263,11 +233,7 @@ impl<'a> Parser<'a> {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
self.tree.add_expr(
|
self.tree.add_expr(Expr::Literal(literal, token.clone()))
|
||||||
Expr::Literal(literal),
|
|
||||||
Some(token.clone()),
|
|
||||||
Some(token.clone()),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn grouping(&mut self) -> ExprRef {
|
fn grouping(&mut self) -> ExprRef {
|
||||||
|
|
@ -288,8 +254,7 @@ impl<'a> Parser<'a> {
|
||||||
_ => panic!("unsuitable unary: {:?}: no op", kind),
|
_ => panic!("unsuitable unary: {:?}: no op", kind),
|
||||||
};
|
};
|
||||||
|
|
||||||
self.tree
|
self.tree.add_expr(Expr::Unary(op, token, expr))
|
||||||
.add_expr(Expr::Unary(op, expr), Some(token), self.previous.clone())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn binary(&mut self, power: u8, left: ExprRef) -> ExprRef {
|
fn binary(&mut self, power: u8, left: ExprRef) -> ExprRef {
|
||||||
|
|
@ -304,12 +269,7 @@ impl<'a> Parser<'a> {
|
||||||
_ => panic!("unsuitable binary: {:?}: no op", self.previous),
|
_ => panic!("unsuitable binary: {:?}: no op", self.previous),
|
||||||
};
|
};
|
||||||
let right = self.expression_with_power(power + 1);
|
let right = self.expression_with_power(power + 1);
|
||||||
|
self.tree.add_expr(Expr::Binary(op, token, left, right))
|
||||||
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)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn advance(&mut self) {
|
fn advance(&mut self) {
|
||||||
|
|
@ -318,7 +278,7 @@ impl<'a> Parser<'a> {
|
||||||
self.current = self.tokens.next();
|
self.current = self.tokens.next();
|
||||||
match &self.current {
|
match &self.current {
|
||||||
Some(token) if token.kind() == TokenKind::Error => {
|
Some(token) if token.kind() == TokenKind::Error => {
|
||||||
self.error_at_current(token.clone())
|
self.error_at_current(token.to_string())
|
||||||
}
|
}
|
||||||
_ => break,
|
_ => break,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -89,9 +89,9 @@ impl<'a> Token<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Into<String> for Token<'a> {
|
impl<'a> std::fmt::Display for Token<'a> {
|
||||||
fn into(self) -> String {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
self.as_str().to_string()
|
write!(f, "{}", self.as_str())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue