crftng-intrprtrs/src/interpreter/world.rs

63 lines
1.3 KiB
Rust

use std::{cell::RefCell, collections::HashMap};
use gc::{allocator::GCAllocator, gc_ref::GcRef, trace::GCTrace};
use crate::ast::statement::Statement;
use super::{
ast_walker::{Interpret, RuntimeError},
types::Primitive,
};
#[derive(Default, GCTrace)]
pub struct Environment {
variables: HashMap<String, Primitive>,
parent: Option<GcRef<RefCell<Environment>>>,
}
impl Environment {
pub fn set_var(&mut self, name: String, v: Primitive) -> Option<Primitive> {
self.variables.insert(name, v)
}
pub fn get_var(&self, name: &str) -> Option<Primitive> {
self.variables
.get(name)
.cloned()
.or_else(|| self.parent.as_ref().and_then(|v| v.borrow().get_var(name)))
}
}
pub struct World {
env: GcRef<Environment>,
_gc: GCAllocator,
}
impl World {
pub fn set_var(&mut self, _name: String, _v: Primitive) -> Option<Primitive> {
todo!()
// self.env.set_var(name, v)
}
pub fn get_var(&self, name: &str) -> Option<Primitive> {
self.env.get_var(name)
}
}
impl World {
pub fn new() -> Self {
Self::default()
}
pub fn exec(&mut self, nodes: Vec<Statement>) -> Result<Primitive, RuntimeError> {
nodes
.into_iter()
.try_fold(Primitive::Nil, |_, stmnt| stmnt.interpret(self))
}
}
impl Default for World {
fn default() -> Self {
let mut gc = GCAllocator::default();
let env = gc.alloc(Environment::default());
Self { env, _gc: gc }
}
}