Compare commits

..

No commits in common. "7a43d22b7757374670d162891a40f4303841e63c" and "129d03b74d74236327f299feb635b940717785eb" have entirely different histories.

2 changed files with 11 additions and 19 deletions

View File

@ -3,7 +3,7 @@ use std::{cell::RefCell, collections::HashMap, rc::Rc};
use crate::token::{LiteralType, Token};
pub struct Environment {
values: HashMap<String, Option<LiteralType>>,
values: HashMap<String, LiteralType>,
enclosing: Option<Rc<RefCell<Environment>>>,
}
@ -26,7 +26,7 @@ impl Environment {
}
}
pub fn define(&mut self, name: &str, val: Option<LiteralType>) {
pub fn define(&mut self, name: &str, val: LiteralType) {
// do not like this at all. String is allocated each time a variable is defined. Might be
// bad or might be good. I don't know :D
self.values.insert(name.to_string(), val);
@ -37,7 +37,7 @@ impl Environment {
let assigned = self
.values
.get_mut(&name.lexeme)
.map(|l| *l = Some(val))
.map(|l| *l = val)
.ok_or(EnvironmentError::AssignError);
if assigned.is_err() {
@ -49,7 +49,7 @@ impl Environment {
assigned
}
pub fn get(&self, name: &Token) -> Option<Option<LiteralType>> {
pub fn get(&self, name: &Token) -> Option<LiteralType> {
//self.values.get(&name.lexeme).cloned()
let value = self.values.get(&name.lexeme);

View File

@ -26,7 +26,7 @@ pub fn interpret(
environment: &Rc<RefCell<Environment>>,
) -> Result<(), RuntimeError> {
for statement in statements {
execute(statement, environment)?;
execute(statement, &environment)?;
}
Ok(())
@ -43,9 +43,9 @@ fn execute(statement: &Stmt, environment: &Rc<RefCell<Environment>>) -> Result<(
}
Stmt::Var { name, initializer } => {
let value = if let Some(initializer) = initializer {
Some(evaluate(initializer, &mut environment.borrow_mut())?)
evaluate(initializer, &mut environment.borrow_mut())?
} else {
None
LiteralType::Nil
};
environment.borrow_mut().define(&name.lexeme, value);
}
@ -85,18 +85,10 @@ fn evaluate(expr: &Expr, environment: &mut Environment) -> Result<LiteralType, R
Expr::Grouping { expression } => evaluate(expression, environment),
Expr::Literal { value } => Ok(value.clone()),
Expr::Unary { op, right } => Ok(unary(&evaluate(right, environment)?, op)),
Expr::Variable { name } => environment
.get(name)
.ok_or_else(|| RuntimeError {
token: name.clone(),
message: format!("Undefined variable {}.", name.lexeme),
})
.and_then(|x| {
x.ok_or_else(|| RuntimeError {
token: name.clone(),
message: format!("Uninitialized variable {}.", name.lexeme),
})
}),
Expr::Variable { name } => environment.get(name).ok_or_else(|| RuntimeError {
token: name.clone(),
message: format!("Undefined variable {}.", name.lexeme),
}),
Expr::Assign { name, value } => {
let value = evaluate(value, environment)?;
environment