mirror of
https://github.com/TheM1Stery/izanami.git
synced 2025-04-20 08:51:12 +00:00
Compare commits
2 Commits
129d03b74d
...
7a43d22b77
Author | SHA1 | Date | |
---|---|---|---|
7a43d22b77 | |||
dd0b2880df |
@ -3,7 +3,7 @@ use std::{cell::RefCell, collections::HashMap, rc::Rc};
|
|||||||
use crate::token::{LiteralType, Token};
|
use crate::token::{LiteralType, Token};
|
||||||
|
|
||||||
pub struct Environment {
|
pub struct Environment {
|
||||||
values: HashMap<String, LiteralType>,
|
values: HashMap<String, Option<LiteralType>>,
|
||||||
enclosing: Option<Rc<RefCell<Environment>>>,
|
enclosing: Option<Rc<RefCell<Environment>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -26,7 +26,7 @@ impl Environment {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn define(&mut self, name: &str, val: LiteralType) {
|
pub fn define(&mut self, name: &str, val: Option<LiteralType>) {
|
||||||
// do not like this at all. String is allocated each time a variable is defined. Might be
|
// 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
|
// bad or might be good. I don't know :D
|
||||||
self.values.insert(name.to_string(), val);
|
self.values.insert(name.to_string(), val);
|
||||||
@ -37,7 +37,7 @@ impl Environment {
|
|||||||
let assigned = self
|
let assigned = self
|
||||||
.values
|
.values
|
||||||
.get_mut(&name.lexeme)
|
.get_mut(&name.lexeme)
|
||||||
.map(|l| *l = val)
|
.map(|l| *l = Some(val))
|
||||||
.ok_or(EnvironmentError::AssignError);
|
.ok_or(EnvironmentError::AssignError);
|
||||||
|
|
||||||
if assigned.is_err() {
|
if assigned.is_err() {
|
||||||
@ -49,7 +49,7 @@ impl Environment {
|
|||||||
assigned
|
assigned
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get(&self, name: &Token) -> Option<LiteralType> {
|
pub fn get(&self, name: &Token) -> Option<Option<LiteralType>> {
|
||||||
//self.values.get(&name.lexeme).cloned()
|
//self.values.get(&name.lexeme).cloned()
|
||||||
|
|
||||||
let value = self.values.get(&name.lexeme);
|
let value = self.values.get(&name.lexeme);
|
||||||
|
@ -26,7 +26,7 @@ pub fn interpret(
|
|||||||
environment: &Rc<RefCell<Environment>>,
|
environment: &Rc<RefCell<Environment>>,
|
||||||
) -> Result<(), RuntimeError> {
|
) -> Result<(), RuntimeError> {
|
||||||
for statement in statements {
|
for statement in statements {
|
||||||
execute(statement, &environment)?;
|
execute(statement, environment)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -43,9 +43,9 @@ fn execute(statement: &Stmt, environment: &Rc<RefCell<Environment>>) -> Result<(
|
|||||||
}
|
}
|
||||||
Stmt::Var { name, initializer } => {
|
Stmt::Var { name, initializer } => {
|
||||||
let value = if let Some(initializer) = initializer {
|
let value = if let Some(initializer) = initializer {
|
||||||
evaluate(initializer, &mut environment.borrow_mut())?
|
Some(evaluate(initializer, &mut environment.borrow_mut())?)
|
||||||
} else {
|
} else {
|
||||||
LiteralType::Nil
|
None
|
||||||
};
|
};
|
||||||
environment.borrow_mut().define(&name.lexeme, value);
|
environment.borrow_mut().define(&name.lexeme, value);
|
||||||
}
|
}
|
||||||
@ -85,9 +85,17 @@ fn evaluate(expr: &Expr, environment: &mut Environment) -> Result<LiteralType, R
|
|||||||
Expr::Grouping { expression } => evaluate(expression, environment),
|
Expr::Grouping { expression } => evaluate(expression, environment),
|
||||||
Expr::Literal { value } => Ok(value.clone()),
|
Expr::Literal { value } => Ok(value.clone()),
|
||||||
Expr::Unary { op, right } => Ok(unary(&evaluate(right, environment)?, op)),
|
Expr::Unary { op, right } => Ok(unary(&evaluate(right, environment)?, op)),
|
||||||
Expr::Variable { name } => environment.get(name).ok_or_else(|| RuntimeError {
|
Expr::Variable { name } => environment
|
||||||
|
.get(name)
|
||||||
|
.ok_or_else(|| RuntimeError {
|
||||||
token: name.clone(),
|
token: name.clone(),
|
||||||
message: format!("Undefined variable {}.", name.lexeme),
|
message: format!("Undefined variable {}.", name.lexeme),
|
||||||
|
})
|
||||||
|
.and_then(|x| {
|
||||||
|
x.ok_or_else(|| RuntimeError {
|
||||||
|
token: name.clone(),
|
||||||
|
message: format!("Uninitialized variable {}.", name.lexeme),
|
||||||
|
})
|
||||||
}),
|
}),
|
||||||
Expr::Assign { name, value } => {
|
Expr::Assign { name, value } => {
|
||||||
let value = evaluate(value, environment)?;
|
let value = evaluate(value, environment)?;
|
||||||
|
Loading…
Reference in New Issue
Block a user