From 26ed836e1d12ce7a3205bdfbe20e4e5a59f5062b Mon Sep 17 00:00:00 2001 From: Vincent Ambo Date: Thu, 31 Dec 2020 17:31:09 +0300 Subject: feat(tazjin/rlox): Add support for scoped environments Adds scoped environments using a sophisticated structure known as an SRPT, which stands for "shitty parent pointer tree". Change-Id: I62f66aabe6eb32ea01c4cabcca5b03cfefcc28ee Reviewed-on: https://cl.tvl.fyi/c/depot/+/2301 Reviewed-by: tazjin Tested-by: BuildkiteCI --- users/tazjin/rlox/src/interpreter.rs | 34 ++++++++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 8 deletions(-) (limited to 'users/tazjin/rlox/src') diff --git a/users/tazjin/rlox/src/interpreter.rs b/users/tazjin/rlox/src/interpreter.rs index 8d968a1f20dd..c0af7d047652 100644 --- a/users/tazjin/rlox/src/interpreter.rs +++ b/users/tazjin/rlox/src/interpreter.rs @@ -2,11 +2,14 @@ use crate::errors::{Error, ErrorKind}; use crate::parser::{self, Declaration, Expr, Literal, Program, Statement}; use crate::scanner::{self, TokenKind}; use std::collections::HashMap; +use std::rc::Rc; +use std::sync::RwLock; // Tree-walk interpreter #[derive(Debug, Default)] struct Environment { + enclosing: Option>>, values: HashMap, } @@ -27,19 +30,34 @@ impl Environment { line: name.0.line, kind: ErrorKind::UndefinedVariable(ident.into()), }) + .or_else(|err| { + if let Some(parent) = &self.enclosing { + parent.read().unwrap().get(name) + } else { + Err(err) + } + }) } fn assign(&mut self, name: &scanner::Token, value: Literal) -> Result<(), Error> { let ident = identifier_str(name)?; - let target = self.values - .get_mut(ident) - .ok_or_else(|| Error { - line: name.line, - kind: ErrorKind::UndefinedVariable(ident.into()), - })?; - *target = value; - Ok(()) + match self.values.get_mut(ident) { + Some(target) => { + *target = value; + Ok(()) + } + None => { + if let Some(parent) = &self.enclosing { + return parent.write().unwrap().assign(name, value); + } + + Err(Error { + line: name.line, + kind: ErrorKind::UndefinedVariable(ident.into()), + }) + } + } } } -- cgit 1.4.1