schala/schala-lang/language/src/util.rs

71 lines
1.9 KiB
Rust
Raw Normal View History

use std::collections::HashMap;
use std::hash::Hash;
use std::cmp::Eq;
use std::ops::Deref;
pub fn deref_optional_box<T>(x: &Option<Box<T>>) -> Option<&T> {
x.as_ref().map(Deref::deref)
}
#[derive(Default, Debug)]
pub struct ScopeStack<'a, T: 'a, V: 'a, N=String> where T: Hash + Eq {
parent: Option<&'a ScopeStack<'a, T, V, N>>,
2018-05-10 22:32:36 -07:00
values: HashMap<T, V>,
scope_name: Option<N>
}
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 {
2018-08-19 21:31:28 -07:00
ScopeStack {
2018-05-11 01:56:12 -07:00
parent: None,
values: HashMap::new(),
scope_name,
2018-05-11 01:56:12 -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
pub fn new_scope(&'a self, scope_name: Option<N>) -> Self where T: Hash + Eq {
2018-08-19 21:31:28 -07:00
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,
2018-05-10 22:28:25 -07:00
}
}
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()))
}
}
pub fn get_name(&self) -> Option<&N> {
2018-05-10 22:32:36 -07:00
self.scope_name.as_ref()
}
}
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)]
pub fn quick_ast(input: &str) -> crate::ast::AST {
2019-03-07 23:51:31 -08:00
let tokens = crate::tokenizing::tokenize(input);
let mut parser = crate::parsing::Parser::new();
parser.add_new_tokens(tokens);
let output = parser.parse();
output.unwrap()
2019-03-07 23:51:31 -08:00
}
2019-05-14 10:51:32 -07:00
#[allow(unused_macros)]
macro_rules! rc {
($string:tt) => { Rc::new(stringify!($string).to_string()) }
}