feat(tazjin/rlox): Implement variable depth resolver

Implements the first part of the resolver from
https://craftinginterpreters.com/resolving-and-binding.html

This is wired up to the execution paths in main, but not yet in the
tests. The resolved depth is also not actually used for variable
lookups (yet).

Change-Id: I3a8615252b7b9b12d5a290c5ddf85988f61b9184
Reviewed-on: https://cl.tvl.fyi/c/depot/+/2403
Reviewed-by: tazjin <mail@tazj.in>
Tested-by: BuildkiteCI
This commit is contained in:
Vincent Ambo 2021-01-16 15:11:36 +03:00 committed by tazjin
parent f472c82427
commit 29335a8b63
5 changed files with 217 additions and 16 deletions

View file

@ -15,6 +15,7 @@ use std::rc::Rc;
pub struct Assign {
pub name: Token,
pub value: Box<Expr>,
pub depth: Option<usize>,
}
#[derive(Debug)]
@ -57,7 +58,10 @@ pub struct Call {
// Not to be confused with `Var`, which is for assignment.
#[derive(Debug)]
pub struct Variable(pub Token);
pub struct Variable {
pub name: Token,
pub depth: Option<usize>,
}
#[derive(Debug)]
pub enum Expr {
@ -413,10 +417,11 @@ impl Parser {
let equals = self.previous().clone();
let value = self.assignment()?;
if let Expr::Variable(Variable(name)) = expr {
if let Expr::Variable(Variable { name, .. }) = expr {
return Ok(Expr::Assign(Assign {
name,
value: Box::new(value),
depth: None,
}));
}
@ -549,7 +554,12 @@ impl Parser {
return Ok(Expr::Grouping(Grouping(Box::new(expr))));
}
TokenKind::Identifier(_) => return Ok(Expr::Variable(Variable(next))),
TokenKind::Identifier(_) => {
return Ok(Expr::Variable(Variable {
name: next,
depth: None,
}))
}
unexpected => {
eprintln!("encountered {:?}", unexpected);