Last active
August 1, 2020 16:40
-
-
Save nviennot/0aca77cbc27256ddd18c187d9c520c9f to your computer and use it in GitHub Desktop.
sym.rs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use std::collections::HashMap; | |
type Value = i32; | |
struct SymbolTable { | |
// We wish to own the parent SymbolTable, but we need a level of indirection | |
// with box, otherwise it would create an unallocatable recursive structure. | |
parent: Option<Box<SymbolTable>>, | |
values: HashMap<String, Value>, | |
} | |
impl SymbolTable { | |
pub fn default() -> SymbolTable { | |
SymbolTable {values: HashMap::default(), parent: None } | |
} | |
pub fn child(parent: SymbolTable) -> SymbolTable { | |
SymbolTable {values: HashMap::default(), parent: Some(Box::new(parent)) } | |
} | |
pub fn get_parent(&self) -> Option<&SymbolTable> { | |
// as_ref() is needed to avoid consuming the option | |
// the &** deref dance gets a reference of the boxed value | |
self.parent.as_ref().map(|p| &**p) | |
} | |
fn get_on_parent(&self, symbol: &str) -> Option<&Value> { | |
self.parent.as_ref().map(|p| p.get(symbol)).flatten() | |
} | |
pub fn get(&self, symbol: &str) -> Option<&Value> { | |
self.values.get(symbol).or_else(|| self.get_on_parent(symbol)) | |
} | |
pub fn put(&mut self, symbol: String, value: Value) { | |
// XXX This has bad complexity: O(n!) | |
if self.get_on_parent(&symbol).is_some() { | |
self.parent.as_mut().unwrap().put(symbol, value); | |
} else { | |
self.values.insert(symbol, value); | |
} | |
} | |
} | |
fn main() { | |
let mut parent = SymbolTable::default(); | |
parent.put("x".into(), 10); | |
let mut child = SymbolTable::child(parent); | |
child.put("x".into(), 20); | |
child.get_parent().unwrap().get("x"); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment