[fine] Tracking source locations
This commit is contained in:
parent
24d056b198
commit
2d233244cf
1 changed files with 44 additions and 13 deletions
|
|
@ -61,16 +61,18 @@ impl ExprRef {
|
|||
}
|
||||
}
|
||||
|
||||
pub struct SyntaxTree {
|
||||
pub struct SyntaxTree<'a> {
|
||||
pub errors: Vec<SyntaxError>,
|
||||
expressions: Vec<Expr>,
|
||||
spans: Vec<(Option<Token<'a>>, Option<Token<'a>>)>,
|
||||
}
|
||||
|
||||
impl SyntaxTree {
|
||||
impl<'a> SyntaxTree<'a> {
|
||||
pub fn new() -> Self {
|
||||
SyntaxTree {
|
||||
errors: Vec::new(),
|
||||
expressions: Vec::new(),
|
||||
spans: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -78,12 +80,27 @@ impl SyntaxTree {
|
|||
self.errors.push(error);
|
||||
}
|
||||
|
||||
pub fn add_expr(&mut self, expr: Expr) -> ExprRef {
|
||||
pub fn add_expr(
|
||||
&mut self,
|
||||
expr: Expr,
|
||||
start: Option<Token<'a>>,
|
||||
end: Option<Token<'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) => {
|
||||
|
|
@ -153,7 +170,7 @@ fn token_power<'a>(token: &Option<Token<'a>>) -> Option<u8> {
|
|||
|
||||
pub struct Parser<'a> {
|
||||
tokens: Tokens<'a>,
|
||||
tree: SyntaxTree,
|
||||
tree: SyntaxTree<'a>,
|
||||
current: Option<Token<'a>>,
|
||||
previous: Option<Token<'a>>,
|
||||
|
||||
|
|
@ -173,7 +190,7 @@ impl<'a> Parser<'a> {
|
|||
parser
|
||||
}
|
||||
|
||||
pub fn parse(mut self) -> (SyntaxTree, ExprRef) {
|
||||
pub fn parse(mut self) -> (SyntaxTree<'a>, ExprRef) {
|
||||
let expr = self.expression();
|
||||
self.consume(None, "expected end of expression");
|
||||
(self.tree, expr)
|
||||
|
|
@ -238,13 +255,19 @@ impl<'a> Parser<'a> {
|
|||
let token = self.previous.as_ref().unwrap();
|
||||
// What kind is it? For now let's just ... make it good.
|
||||
|
||||
match token.as_str().parse::<f64>() {
|
||||
Ok(v) => self.tree.add_expr(Expr::Literal(Literal::Float64(v))),
|
||||
let literal = match token.as_str().parse::<f64>() {
|
||||
Ok(v) => Literal::Float64(v),
|
||||
Err(e) => {
|
||||
self.error(format!("invalid f64: {e}"));
|
||||
ExprRef::error()
|
||||
return ExprRef::error();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
self.tree.add_expr(
|
||||
Expr::Literal(literal),
|
||||
Some(token.clone()),
|
||||
Some(token.clone()),
|
||||
)
|
||||
}
|
||||
|
||||
fn grouping(&mut self) -> ExprRef {
|
||||
|
|
@ -257,17 +280,21 @@ impl<'a> Parser<'a> {
|
|||
}
|
||||
|
||||
fn unary(&mut self) -> ExprRef {
|
||||
let kind = self.previous.as_ref().unwrap().kind();
|
||||
let token = self.previous.as_ref().unwrap().clone();
|
||||
let kind = token.kind();
|
||||
let expr = self.expression_with_power(UNARY_POWER);
|
||||
let op = match kind {
|
||||
TokenKind::Minus => UnaryOp::Negate,
|
||||
_ => panic!("unsuitable unary: {:?}: no op", kind),
|
||||
};
|
||||
self.tree.add_expr(Expr::Unary(op, expr))
|
||||
|
||||
self.tree
|
||||
.add_expr(Expr::Unary(op, expr), Some(token), self.previous.clone())
|
||||
}
|
||||
|
||||
fn binary(&mut self, power: u8, left: ExprRef) -> ExprRef {
|
||||
let op = match self.previous.as_ref().unwrap().kind() {
|
||||
let token = self.previous.as_ref().unwrap().clone();
|
||||
let op = match token.kind() {
|
||||
TokenKind::Plus => BinaryOp::Add,
|
||||
TokenKind::Minus => BinaryOp::Subtract,
|
||||
TokenKind::Star => BinaryOp::Mutiply,
|
||||
|
|
@ -278,7 +305,11 @@ impl<'a> Parser<'a> {
|
|||
};
|
||||
let right = self.expression_with_power(power + 1);
|
||||
|
||||
self.tree.add_expr(Expr::Binary(op, 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) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue