Scope?
This commit is contained in:
parent
247cf593ca
commit
e4bf43dc6d
|
|
@ -1 +1,2 @@
|
|||
pub mod scope;
|
||||
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