Interpreter - Create and pass the environment when evaluating
This commit is contained in:
parent
8b44af08ba
commit
90557e6600
1 changed files with 19 additions and 15 deletions
|
@ -5,14 +5,17 @@ use crate::{
|
||||||
tokens::{Token, TokenType},
|
tokens::{Token, TokenType},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use super::Environment;
|
||||||
|
|
||||||
/// An Interpretable can be evaluated and will return a value.
|
/// An Interpretable can be evaluated and will return a value.
|
||||||
pub trait Interpretable {
|
pub trait Interpretable {
|
||||||
fn interprete(&self) -> Result<Value, InterpreterError>;
|
fn interprete(&self, environment: &mut Environment) -> Result<Value, InterpreterError>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Evaluate an interpretable, returning its value.
|
/// Evaluate an interpretable, returning its value.
|
||||||
pub fn evaluate(err_hdl: &mut ErrorHandler, ast: &dyn Interpretable) -> Option<Value> {
|
pub fn evaluate(err_hdl: &mut ErrorHandler, ast: &dyn Interpretable) -> Option<Value> {
|
||||||
match ast.interprete() {
|
let mut env = Environment::default();
|
||||||
|
match ast.interprete(&mut env) {
|
||||||
Ok(v) => Some(v),
|
Ok(v) => Some(v),
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
e.report(err_hdl);
|
e.report(err_hdl);
|
||||||
|
@ -26,9 +29,9 @@ pub fn evaluate(err_hdl: &mut ErrorHandler, ast: &dyn Interpretable) -> Option<V
|
||||||
* ----------------------------- */
|
* ----------------------------- */
|
||||||
|
|
||||||
impl Interpretable for ast::ProgramNode {
|
impl Interpretable for ast::ProgramNode {
|
||||||
fn interprete(&self) -> Result<Value, InterpreterError> {
|
fn interprete(&self, environment: &mut Environment) -> Result<Value, InterpreterError> {
|
||||||
for stmt in self.0.iter() {
|
for stmt in self.0.iter() {
|
||||||
stmt.interprete()?;
|
stmt.interprete(environment)?;
|
||||||
}
|
}
|
||||||
Ok(Value::Nil)
|
Ok(Value::Nil)
|
||||||
}
|
}
|
||||||
|
@ -39,11 +42,11 @@ impl Interpretable for ast::ProgramNode {
|
||||||
* ------------------------------- */
|
* ------------------------------- */
|
||||||
|
|
||||||
impl Interpretable for ast::StmtNode {
|
impl Interpretable for ast::StmtNode {
|
||||||
fn interprete(&self) -> Result<Value, InterpreterError> {
|
fn interprete(&self, environment: &mut Environment) -> Result<Value, InterpreterError> {
|
||||||
match self {
|
match self {
|
||||||
ast::StmtNode::Expression(expr) => expr.interprete(),
|
ast::StmtNode::Expression(expr) => expr.interprete(environment),
|
||||||
ast::StmtNode::Print(expr) => {
|
ast::StmtNode::Print(expr) => {
|
||||||
let value = expr.interprete()?;
|
let value = expr.interprete(environment)?;
|
||||||
let output = match value {
|
let output = match value {
|
||||||
Value::Nil => String::from("nil"),
|
Value::Nil => String::from("nil"),
|
||||||
Value::Boolean(true) => String::from("true"),
|
Value::Boolean(true) => String::from("true"),
|
||||||
|
@ -63,15 +66,15 @@ impl Interpretable for ast::StmtNode {
|
||||||
* -------------------------------- */
|
* -------------------------------- */
|
||||||
|
|
||||||
impl Interpretable for ast::ExprNode {
|
impl Interpretable for ast::ExprNode {
|
||||||
fn interprete(&self) -> Result<Value, InterpreterError> {
|
fn interprete(&self, environment: &mut Environment) -> Result<Value, InterpreterError> {
|
||||||
match self {
|
match self {
|
||||||
ast::ExprNode::Binary {
|
ast::ExprNode::Binary {
|
||||||
left,
|
left,
|
||||||
operator,
|
operator,
|
||||||
right,
|
right,
|
||||||
} => self.on_binary(left, operator, right),
|
} => self.on_binary(environment, left, operator, right),
|
||||||
ast::ExprNode::Unary { operator, right } => self.on_unary(operator, right),
|
ast::ExprNode::Unary { operator, right } => self.on_unary(environment, operator, right),
|
||||||
ast::ExprNode::Grouping { expression } => expression.interprete(),
|
ast::ExprNode::Grouping { expression } => expression.interprete(environment),
|
||||||
ast::ExprNode::Litteral { value } => self.on_litteral(value),
|
ast::ExprNode::Litteral { value } => self.on_litteral(value),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -81,12 +84,13 @@ impl ast::ExprNode {
|
||||||
/// Evaluate a binary operator.
|
/// Evaluate a binary operator.
|
||||||
fn on_binary(
|
fn on_binary(
|
||||||
&self,
|
&self,
|
||||||
|
environment: &mut Environment,
|
||||||
left: &ast::ExprNode,
|
left: &ast::ExprNode,
|
||||||
operator: &Token,
|
operator: &Token,
|
||||||
right: &ast::ExprNode,
|
right: &ast::ExprNode,
|
||||||
) -> Result<Value, InterpreterError> {
|
) -> Result<Value, InterpreterError> {
|
||||||
let left_value = left.interprete()?;
|
let left_value = left.interprete(environment)?;
|
||||||
let right_value = right.interprete()?;
|
let right_value = right.interprete(environment)?;
|
||||||
match operator.token_type {
|
match operator.token_type {
|
||||||
TokenType::Plus => match (left_value, right_value) {
|
TokenType::Plus => match (left_value, right_value) {
|
||||||
(Value::Number(a), Value::Number(b)) => Ok(Value::Number(a + b)),
|
(Value::Number(a), Value::Number(b)) => Ok(Value::Number(a + b)),
|
||||||
|
@ -147,8 +151,8 @@ impl ast::ExprNode {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Evaluate an unary operator.
|
/// Evaluate an unary operator.
|
||||||
fn on_unary(&self, operator: &Token, right: &ast::ExprNode) -> Result<Value, InterpreterError> {
|
fn on_unary(&self, environment: &mut Environment, operator: &Token, right: &ast::ExprNode) -> Result<Value, InterpreterError> {
|
||||||
let right_value = right.interprete()?;
|
let right_value = right.interprete(environment)?;
|
||||||
match operator.token_type {
|
match operator.token_type {
|
||||||
TokenType::Minus => {
|
TokenType::Minus => {
|
||||||
if let Value::Number(n) = right_value {
|
if let Value::Number(n) = right_value {
|
||||||
|
|
Loading…
Reference in a new issue