Scope?
This commit is contained in:
parent
247cf593ca
commit
e4bf43dc6d
|
|
@ -1 +1,2 @@
|
||||||
|
pub mod scope;
|
||||||
pub mod types;
|
pub mod types;
|
||||||
|
|
|
||||||
63
src/scope.rs
Normal file
63
src/scope.rs
Normal file
|
|
@ -0,0 +1,63 @@
|
||||||
|
use std::{
|
||||||
|
cell::RefCell,
|
||||||
|
collections::{hash_map::Entry, HashMap},
|
||||||
|
rc::Rc,
|
||||||
|
};
|
||||||
|
|
||||||
|
use crate::types::Value;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Default)]
|
||||||
|
pub struct Variable(Rc<RefCell<Value>>);
|
||||||
|
|
||||||
|
impl Variable {
|
||||||
|
pub fn get(&self) -> Value {
|
||||||
|
self.0.borrow().clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set(&self, value: Value) {
|
||||||
|
*self.0.borrow_mut() = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Default)]
|
||||||
|
struct ScopeInner {
|
||||||
|
parent: Option<Scope>,
|
||||||
|
locals: HashMap<String, Variable>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Default)]
|
||||||
|
pub struct Scope(Rc<RefCell<ScopeInner>>);
|
||||||
|
|
||||||
|
impl Scope {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self::default()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn nested(&self) -> Self {
|
||||||
|
Self(Rc::new(RefCell::new(ScopeInner {
|
||||||
|
parent: Some(self.clone()),
|
||||||
|
..Default::default()
|
||||||
|
})))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add(&self, name: String) {
|
||||||
|
self.0.borrow_mut().locals.insert(name, Variable::default());
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get(&self, name: String) -> Variable {
|
||||||
|
let mut this = self.0.borrow_mut();
|
||||||
|
let parent = this.parent.clone();
|
||||||
|
match this.locals.entry(name) {
|
||||||
|
Entry::Occupied(var) => var.get().clone(),
|
||||||
|
Entry::Vacant(var) => {
|
||||||
|
if let Some(parent) = parent {
|
||||||
|
let name = var.into_key();
|
||||||
|
drop(this);
|
||||||
|
parent.get(name)
|
||||||
|
} else {
|
||||||
|
var.insert(Variable::default()).clone()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user