use crate::ast::{Alias, Ast, AstMetadata, Value};
use crate::core::Environment;
use crate::error::Error;
use proc_macro2::Ident;
use std::cell::{Ref, RefCell};
use std::collections::HashMap;
use std::rc::Rc;
#[derive(Clone)]
pub enum Evaluated {
Value(Rc<Value>),
Bindings(HashMap<Rc<Alias>, Evaluated>),
}
#[derive(Default, Clone)]
pub struct Context {
context: HashMap<Ident, Evaluated>,
metadata: Rc<RefCell<AstMetadata>>,
}
impl Context {
pub fn new(metadata: Rc<RefCell<AstMetadata>>) -> Self {
Self {
context: HashMap::new(),
metadata,
}
}
pub fn add_variable(&mut self, name: &Ident, value: Evaluated) {
if !matches!(&value, Evaluated::Value(_)) {
panic!("Only Value can be added to the context");
}
self.context.insert(name.clone(), value);
}
pub fn get_variable(&self, name: &Ident) -> Option<&Evaluated> {
self.context.get(name)
}
pub fn metadata_rc(&self) -> Rc<RefCell<AstMetadata>> {
self.metadata.clone()
}
pub fn metadata(&self) -> Ref<'_, AstMetadata> {
self.metadata.borrow()
}
}
pub trait Eval: Ast {
fn eval(&self, environment: &Environment, context: &mut Context) -> Result<Evaluated, Error>;
}