1use std::{collections::BTreeMap, sync::Arc};
2
3use crate::{error::Diagnostic, id::Symbol, value::Value};
4
5#[derive(Clone, Debug, Default)]
10pub struct Env {
11 frame: BTreeMap<Symbol, Value>,
12 parent: Option<Arc<Env>>,
13}
14
15impl Env {
16 pub fn child(parent: Arc<Env>) -> Self {
18 Self {
19 frame: BTreeMap::new(),
20 parent: Some(parent),
21 }
22 }
23
24 pub fn define(&mut self, name: Symbol, value: Value) -> Option<Value> {
26 self.frame.insert(name, value)
27 }
28
29 pub fn get(&self, name: &Symbol) -> Option<Value> {
31 self.frame
32 .get(name)
33 .cloned()
34 .or_else(|| self.parent.as_ref().and_then(|parent| parent.get(name)))
35 }
36}
37
38#[derive(Clone, Debug, Default)]
40pub struct Diagnostics {
41 messages: Vec<Diagnostic>,
42}
43
44impl Diagnostics {
45 pub fn push(&mut self, message: impl Into<String>) {
47 self.messages.push(Diagnostic::error(message));
48 }
49
50 pub fn push_diagnostic(&mut self, diagnostic: Diagnostic) {
52 self.messages.push(diagnostic);
53 }
54
55 pub fn push_info(&mut self, message: impl Into<String>) {
57 self.messages.push(Diagnostic::info(message));
58 }
59
60 pub fn messages(&self) -> &[Diagnostic] {
62 &self.messages
63 }
64
65 pub fn take(&mut self) -> Vec<Diagnostic> {
67 std::mem::take(&mut self.messages)
68 }
69}