crftng-intrprtrs/src/interpreter/ast_walker/expression_interpreter.rs

75 lines
2.2 KiB
Rust

use super::Interpret;
use super::{types::Primitive, RuntimeError};
use crate::ast::expression::{
self,
operator::{Operator, UnaryOperator},
};
use crate::interpreter::world::World;
impl Interpret for expression::ExpressionNode {
fn interpret(&self, w: &mut World) -> Result<Primitive, RuntimeError> {
expression::all_variants!(self, n => n.interpret(w))
}
}
impl Interpret for expression::Literal {
fn interpret(&self, _: &mut World) -> Result<Primitive, RuntimeError> {
Ok(self.clone().into())
}
}
impl Interpret for expression::BinaryExpr {
fn interpret(&self, w: &mut World) -> Result<Primitive, RuntimeError> {
let left_val = self.left.interpret(w).expect("expected lval");
let right_val = self.right.interpret(w).expect("expected rval");
match self.operator {
Operator::Plus => todo!(),
Operator::Minus => todo!(),
Operator::BangEqual => Ok((left_val != right_val).into()),
Operator::Less => Ok((left_val < right_val).into()),
Operator::LessEqual => Ok((left_val <= right_val).into()),
Operator::Greater => Ok((left_val > right_val).into()),
Operator::GreaterEqual => Ok((left_val >= right_val).into()),
Operator::EqualEqual => Ok((left_val == right_val).into()),
}
}
}
impl Interpret for expression::UnaryExpr {
fn interpret(&self, w: &mut World) -> Result<Primitive, RuntimeError> {
let val = self.right.interpret(w)?;
match self.operator {
UnaryOperator::Bang => Ok(Primitive::Bool(!val.truthy())),
UnaryOperator::Minus => match val {
Primitive::Int(i) => Ok(Primitive::Int(-i)),
Primitive::Float(f) => Ok(Primitive::Float(-f)),
_ => Err(RuntimeError),
},
}
}
}
impl Interpret for expression::GroupingExpr {
fn interpret(&self, w: &mut World) -> Result<Primitive, RuntimeError> {
self.0.interpret(w)
}
}
impl Interpret for expression::VariableExpr {
fn interpret(&self, world: &mut World) -> Result<Primitive, RuntimeError> {
match world.get_var(&self.var_name) {
Some(v) => Ok(v),
None => Err(RuntimeError),
}
}
}
impl Interpret for expression::BlockExpr {
fn interpret(&self, world: &mut World) -> Result<Primitive, RuntimeError> {
for stmnt in self.statements.iter() {
stmnt.interpret(world)?;
}
Ok(Primitive::Nil)
}
}