chapter 9 in rust
This commit is contained in:
parent
1a485ebcb1
commit
f82919414e
5 changed files with 271 additions and 35 deletions
|
@ -1,4 +1,4 @@
|
|||
use std::collections::HashMap;
|
||||
use std::{cell::RefCell, collections::HashMap, rc::Rc};
|
||||
|
||||
use thiserror::Error;
|
||||
|
||||
|
@ -15,14 +15,15 @@ pub enum EnvironmentError {
|
|||
#[derive(Default, Debug, Clone)]
|
||||
pub struct Environment {
|
||||
values: HashMap<String, Value>,
|
||||
enclosing: Option<Box<Environment>>,
|
||||
enclosing: Option<Rc<RefCell<Environment>>>,
|
||||
}
|
||||
|
||||
impl Environment {
|
||||
pub fn with_enclosing(enclosing: Environment) -> Self {
|
||||
/// Initialize a new environment with an enclosing one.
|
||||
pub fn with_enclosing(enclosing: Rc<RefCell<Environment>>) -> Self {
|
||||
Self {
|
||||
values: HashMap::default(),
|
||||
enclosing: Some(Box::new(enclosing)),
|
||||
enclosing: Some(enclosing),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -40,7 +41,7 @@ impl Environment {
|
|||
self.values.insert(token.lexeme.clone(), value);
|
||||
Ok(())
|
||||
} else if let Some(enclosing) = &mut self.enclosing {
|
||||
enclosing.assign(token, value)
|
||||
enclosing.borrow_mut().assign(token, value)
|
||||
} else {
|
||||
Err(EnvironmentError::UndefinedVariable(
|
||||
token.line,
|
||||
|
@ -55,7 +56,7 @@ impl Environment {
|
|||
if let Some(v) = self.values.get(token.lexeme.as_str()) {
|
||||
Ok(v.clone())
|
||||
} else if let Some(enclosing) = &self.enclosing {
|
||||
enclosing.get(token)
|
||||
enclosing.borrow().get(token)
|
||||
} else {
|
||||
Err(EnvironmentError::UndefinedVariable(
|
||||
token.line,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue