about summary refs log tree commit diff
path: root/users/tazjin/rlox/src/resolver.rs
diff options
context:
space:
mode:
authorVincent Ambo <mail@tazj.in>2021-01-17T09·13+0300
committertazjin <mail@tazj.in>2021-01-17T09·34+0000
commitf8b3e2a100fdb28cad24948703439d2964c31580 (patch)
treefdd7b13f4a359532f6acaa183d78e7d777f5c32d /users/tazjin/rlox/src/resolver.rs
parent052f8976bb3273d16fb0e1c4643de5abcaf0f135 (diff)
refactor(tazjin/rlox): Move treewalk interpreter into subdirectory r/2120
Change-Id: I9163f75db5a1ff75e1b1f81bad78fd9d8ddb104a
Reviewed-on: https://cl.tvl.fyi/c/depot/+/2409
Reviewed-by: tazjin <mail@tazj.in>
Tested-by: BuildkiteCI
Diffstat (limited to 'users/tazjin/rlox/src/resolver.rs')
-rw-r--r--users/tazjin/rlox/src/resolver.rs199
1 files changed, 0 insertions, 199 deletions
diff --git a/users/tazjin/rlox/src/resolver.rs b/users/tazjin/rlox/src/resolver.rs
deleted file mode 100644
index 5e15d386c73f..000000000000
--- a/users/tazjin/rlox/src/resolver.rs
+++ /dev/null
@@ -1,199 +0,0 @@
-// Resolves variable access to their specific instances in the
-// environment chain.
-//
-// https://craftinginterpreters.com/resolving-and-binding.html
-
-use std::collections::HashMap;
-use std::rc::Rc;
-
-use crate::errors::{Error, ErrorKind};
-use crate::parser::{self, Expr, Statement};
-use crate::scanner::Token;
-
-#[derive(Default)]
-struct Resolver<'a> {
-    scopes: Vec<HashMap<&'a str, bool>>,
-}
-
-impl<'a> Resolver<'a> {
-    // AST traversal
-    fn resolve(&mut self, program: &'a mut parser::Block) -> Result<(), Error> {
-        self.begin_scope();
-        for stmt in program {
-            self.resolve_stmt(stmt)?;
-        }
-        self.end_scope();
-
-        Ok(())
-    }
-
-    fn resolve_stmt(&mut self, stmt: &'a mut Statement) -> Result<(), Error> {
-        match stmt {
-            Statement::Expr(expr) => self.resolve_expr(expr),
-            Statement::Print(expr) => self.resolve_expr(expr),
-            Statement::Var(var) => self.resolve_var(var),
-            Statement::Return(ret) => self.resolve_expr(&mut ret.value),
-            Statement::Block(block) => self.resolve(block),
-
-            Statement::If(if_stmt) => {
-                self.resolve_expr(&mut if_stmt.condition)?;
-                self.resolve_stmt(&mut if_stmt.then_branch)?;
-
-                if let Some(branch) = if_stmt.else_branch.as_mut() {
-                    self.resolve_stmt(branch)?;
-                }
-
-                Ok(())
-            }
-
-            Statement::While(while_stmt) => {
-                self.resolve_expr(&mut while_stmt.condition)?;
-                self.resolve_stmt(&mut while_stmt.body)
-            }
-
-            Statement::Function(func) => match Rc::get_mut(func) {
-                Some(func) => self.resolve_function(func),
-                // The resolver does not clone references, so unless
-                // the interpreter is called before the resolver this
-                // case should never happen.
-                None => {
-                    return Err(Error {
-                        line: 0,
-                        kind: ErrorKind::InternalError(
-                            "multiple function references before interpretation".into(),
-                        ),
-                    })
-                }
-            },
-        }
-    }
-
-    fn resolve_var(&mut self, var: &'a mut parser::Var) -> Result<(), Error> {
-        self.declare(&var.name.lexeme);
-
-        if let Some(init) = &mut var.initialiser {
-            self.resolve_expr(init)?;
-        }
-
-        self.define(&var.name.lexeme);
-
-        Ok(())
-    }
-
-    fn resolve_function(&mut self, func: &'a mut parser::Function) -> Result<(), Error> {
-        self.declare(&func.name.lexeme);
-        self.define(&func.name.lexeme);
-
-        self.begin_scope();
-
-        for param in &func.params {
-            self.declare(&param.lexeme);
-            self.define(&param.lexeme);
-        }
-
-        for stmt in &mut func.body {
-            self.resolve_stmt(stmt)?;
-        }
-
-        self.end_scope();
-
-        Ok(())
-    }
-
-    fn resolve_expr(&mut self, expr: &'a mut Expr) -> Result<(), Error> {
-        match expr {
-            Expr::Variable(var) => self.resolve_variable(var),
-            Expr::Assign(assign) => self.resolve_assign(assign),
-            Expr::Grouping(grouping) => self.resolve_expr(&mut grouping.0),
-            Expr::Call(call) => self.resolve_call(call),
-            Expr::Literal(_) => Ok(()),
-            Expr::Unary(unary) => self.resolve_expr(&mut unary.right),
-
-            Expr::Logical(log) => {
-                self.resolve_expr(&mut log.left)?;
-                self.resolve_expr(&mut log.right)
-            }
-
-            Expr::Binary(binary) => {
-                self.resolve_expr(&mut binary.left)?;
-                self.resolve_expr(&mut binary.right)
-            }
-        }
-    }
-
-    fn resolve_variable(&mut self, var: &'a mut parser::Variable) -> Result<(), Error> {
-        if let Some(scope) = self.scopes.last_mut() {
-            if let Some(false) = scope.get(var.name.lexeme.as_str()) {
-                return Err(Error {
-                    line: var.name.line,
-                    kind: ErrorKind::StaticError(
-                        "can't read local variable in its own initialiser".into(),
-                    ),
-                });
-            }
-        }
-
-        var.depth = self.resolve_local(&var.name);
-        Ok(())
-    }
-
-    fn resolve_assign(&mut self, assign: &'a mut parser::Assign) -> Result<(), Error> {
-        self.resolve_expr(&mut assign.value)?;
-        assign.depth = self.resolve_local(&assign.name);
-        Ok(())
-    }
-
-    fn resolve_local(&mut self, name: &'a Token) -> Option<usize> {
-        for (c, scope) in self.scopes.iter().rev().enumerate() {
-            if scope.contains_key(name.lexeme.as_str()) {
-                return Some(c);
-            }
-        }
-
-        None
-    }
-
-    fn resolve_call(&mut self, call: &'a mut parser::Call) -> Result<(), Error> {
-        self.resolve_expr(&mut call.callee)?;
-
-        for arg in call.args.iter_mut() {
-            self.resolve_expr(arg)?;
-        }
-
-        Ok(())
-    }
-
-    // Internal helpers
-
-    fn declare(&mut self, name: &'a str) {
-        if let Some(scope) = self.scopes.last_mut() {
-            scope.insert(&name, false);
-        }
-    }
-
-    fn define(&mut self, name: &'a str) {
-        if let Some(scope) = self.scopes.last_mut() {
-            scope.insert(&name, true);
-        }
-    }
-
-    fn begin_scope(&mut self) {
-        self.scopes.push(Default::default());
-    }
-
-    fn end_scope(&mut self) {
-        self.scopes.pop();
-    }
-}
-
-pub fn resolve(globals: &[String], block: &mut parser::Block) -> Result<(), Error> {
-    let mut resolver: Resolver = Default::default();
-
-    // Scope for static globals only starts, never ends.
-    resolver.begin_scope();
-    for global in globals {
-        resolver.define(global);
-    }
-
-    resolver.resolve(block)
-}