2021-10-27 01:11:46 -07:00
|
|
|
use std::{cmp::Eq, collections::HashMap, hash::Hash};
|
2018-05-10 22:23:42 -07:00
|
|
|
|
|
|
|
#[derive(Default, Debug)]
|
2021-10-27 00:40:21 -07:00
|
|
|
pub struct ScopeStack<'a, T: 'a, V: 'a, N = String>
|
|
|
|
where T: Hash + Eq
|
|
|
|
{
|
|
|
|
parent: Option<&'a ScopeStack<'a, T, V, N>>,
|
|
|
|
values: HashMap<T, V>,
|
|
|
|
scope_name: Option<N>,
|
2018-05-10 22:23:42 -07:00
|
|
|
}
|
|
|
|
|
2021-10-27 00:40:21 -07:00
|
|
|
impl<'a, T, V, N> ScopeStack<'a, T, V, N>
|
|
|
|
where T: Hash + Eq
|
|
|
|
{
|
|
|
|
pub fn new(scope_name: Option<N>) -> Self
|
|
|
|
where T: Hash + Eq {
|
|
|
|
ScopeStack { parent: None, values: HashMap::new(), scope_name }
|
2018-05-11 01:56:12 -07:00
|
|
|
}
|
2021-10-27 00:40:21 -07:00
|
|
|
pub fn insert(&mut self, key: T, value: V)
|
|
|
|
where T: Hash + Eq {
|
|
|
|
self.values.insert(key, value);
|
|
|
|
}
|
|
|
|
pub fn lookup(&self, key: &T) -> Option<&V>
|
|
|
|
where T: Hash + Eq {
|
|
|
|
match (self.values.get(key), self.parent) {
|
|
|
|
(None, None) => None,
|
|
|
|
(None, Some(parent)) => parent.lookup(key),
|
|
|
|
(Some(value), _) => Some(value),
|
|
|
|
}
|
2018-05-10 22:23:42 -07:00
|
|
|
}
|
2018-09-22 00:26:38 -07:00
|
|
|
|
2021-10-27 00:40:21 -07:00
|
|
|
pub fn new_scope(&'a self, scope_name: Option<N>) -> Self
|
|
|
|
where T: Hash + Eq {
|
|
|
|
ScopeStack { parent: Some(self), values: HashMap::default(), scope_name }
|
2018-05-10 22:28:25 -07:00
|
|
|
}
|
2021-10-21 19:22:11 -07:00
|
|
|
|
2021-10-27 00:40:21 -07:00
|
|
|
#[allow(dead_code)]
|
|
|
|
pub fn lookup_with_scope(&self, key: &T) -> Option<(&V, Option<&N>)>
|
|
|
|
where T: Hash + Eq {
|
|
|
|
match (self.values.get(key), self.parent) {
|
|
|
|
(None, None) => None,
|
|
|
|
(None, Some(parent)) => parent.lookup_with_scope(key),
|
|
|
|
(Some(value), _) => Some((value, self.scope_name.as_ref())),
|
|
|
|
}
|
|
|
|
}
|
2021-10-21 19:22:11 -07:00
|
|
|
|
2021-10-27 00:40:21 -07:00
|
|
|
pub fn get_name(&self) -> Option<&N> {
|
|
|
|
self.scope_name.as_ref()
|
|
|
|
}
|
2018-05-10 22:23:42 -07:00
|
|
|
}
|
|
|
|
|
2021-10-14 06:33:47 -07:00
|
|
|
/// Quickly create an AST from a string, with no error checking. For test use only
|
|
|
|
#[cfg(test)]
|
2021-10-14 06:18:17 -07:00
|
|
|
pub fn quick_ast(input: &str) -> crate::ast::AST {
|
2021-11-14 03:55:35 -08:00
|
|
|
let mut parser = crate::parsing::Parser::new();
|
2021-11-14 02:15:08 -08:00
|
|
|
let output = parser.parse(input);
|
2021-11-20 11:04:56 -08:00
|
|
|
match output {
|
|
|
|
Ok(output) => output,
|
|
|
|
Err(err) => {
|
|
|
|
println!("Parse error: {}", err.msg);
|
|
|
|
panic!();
|
|
|
|
}
|
|
|
|
}
|
2019-03-07 23:51:31 -08:00
|
|
|
}
|
2019-03-08 01:15:19 -08:00
|
|
|
|
2019-05-14 10:51:32 -07:00
|
|
|
#[allow(unused_macros)]
|
2019-03-08 01:15:19 -08:00
|
|
|
macro_rules! rc {
|
2021-10-27 00:40:21 -07:00
|
|
|
($string:tt) => {
|
|
|
|
Rc::new(stringify!($string).to_string())
|
|
|
|
};
|
2019-03-08 01:15:19 -08:00
|
|
|
}
|