2018-05-10 22:23:42 -07:00
|
|
|
use std::collections::HashMap;
|
|
|
|
use std::hash::Hash;
|
|
|
|
use std::cmp::Eq;
|
2019-10-10 14:38:48 -07:00
|
|
|
use std::ops::Deref;
|
|
|
|
|
|
|
|
pub fn deref_optional_box<T>(x: &Option<Box<T>>) -> Option<&T> {
|
|
|
|
x.as_ref().map(|b: &Box<T>| Deref::deref(b))
|
|
|
|
}
|
2018-05-10 22:23:42 -07:00
|
|
|
|
|
|
|
#[derive(Default, Debug)]
|
2018-08-19 21:31:28 -07:00
|
|
|
pub struct ScopeStack<'a, T: 'a, V: 'a> where T: Hash + Eq {
|
|
|
|
parent: Option<&'a ScopeStack<'a, T, V>>,
|
2018-05-10 22:32:36 -07:00
|
|
|
values: HashMap<T, V>,
|
|
|
|
scope_name: Option<String>
|
2018-05-10 22:23:42 -07:00
|
|
|
}
|
|
|
|
|
2018-08-19 21:31:28 -07:00
|
|
|
impl<'a, T, V> ScopeStack<'a, T, V> where T: Hash + Eq {
|
|
|
|
pub fn new(name: Option<String>) -> ScopeStack<'a, T, V> where T: Hash + Eq {
|
|
|
|
ScopeStack {
|
2018-05-11 01:56:12 -07:00
|
|
|
parent: None,
|
|
|
|
values: HashMap::new(),
|
|
|
|
scope_name: name
|
|
|
|
}
|
|
|
|
}
|
2018-05-10 22:23:42 -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-09-22 00:26:38 -07:00
|
|
|
|
2018-08-19 21:31:28 -07:00
|
|
|
pub fn new_scope(&'a self, name: Option<String>) -> ScopeStack<'a, T, V> where T: Hash + Eq {
|
|
|
|
ScopeStack {
|
2018-05-10 22:28:25 -07:00
|
|
|
parent: Some(self),
|
2018-05-10 22:32:36 -07:00
|
|
|
values: HashMap::default(),
|
|
|
|
scope_name: name,
|
2018-05-10 22:28:25 -07:00
|
|
|
}
|
|
|
|
}
|
2018-10-20 00:55:37 -07:00
|
|
|
#[allow(dead_code)]
|
2018-05-10 22:32:36 -07:00
|
|
|
pub fn get_name(&self) -> Option<&String> {
|
|
|
|
self.scope_name.as_ref()
|
|
|
|
}
|
2018-05-10 22:23:42 -07:00
|
|
|
}
|
|
|
|
|
2019-03-07 23:51:31 -08:00
|
|
|
/// this is intended for use in tests, and does no error-handling whatsoever
|
2019-03-08 03:57:32 -08:00
|
|
|
#[allow(dead_code)]
|
2019-03-07 23:51:31 -08:00
|
|
|
pub fn quick_ast(input: &str) -> crate::ast::AST {
|
|
|
|
let tokens = crate::tokenizing::tokenize(input);
|
|
|
|
let mut parser = crate::parsing::Parser::new(tokens);
|
|
|
|
parser.parse().unwrap()
|
|
|
|
}
|
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 {
|
|
|
|
($string:tt) => { Rc::new(stringify!($string).to_string()) }
|
|
|
|
}
|