use std::{collections::BTreeMap, sync::Arc};
use crate::{error::Diagnostic, id::Symbol, value::Value};
#[derive(Clone, Debug, Default)]
pub struct Env {
frame: BTreeMap<Symbol, Value>,
parent: Option<Arc<Env>>,
}
impl Env {
pub fn child(parent: Arc<Env>) -> Self {
Self {
frame: BTreeMap::new(),
parent: Some(parent),
}
}
pub fn define(&mut self, name: Symbol, value: Value) -> Option<Value> {
self.frame.insert(name, value)
}
pub fn get(&self, name: &Symbol) -> Option<Value> {
self.frame
.get(name)
.cloned()
.or_else(|| self.parent.as_ref().and_then(|parent| parent.get(name)))
}
}
#[derive(Clone, Debug, Default)]
pub struct Diagnostics {
messages: Vec<Diagnostic>,
}
impl Diagnostics {
pub fn push(&mut self, message: impl Into<String>) {
self.messages.push(Diagnostic::error(message));
}
pub fn push_diagnostic(&mut self, diagnostic: Diagnostic) {
self.messages.push(diagnostic);
}
pub fn push_info(&mut self, message: impl Into<String>) {
self.messages.push(Diagnostic::info(message));
}
pub fn messages(&self) -> &[Diagnostic] {
&self.messages
}
pub fn take(&mut self) -> Vec<Diagnostic> {
std::mem::take(&mut self.messages)
}
}