Implemented SymTable optimization for efficient variable updates

This commit is contained in:
Ava Apples Affine 2023-03-20 17:16:44 -07:00
parent dcb2969b0a
commit 381852b3bd
Signed by: affine
GPG key ID: 3A4645B8CF806069
9 changed files with 122 additions and 23 deletions

View file

@ -22,7 +22,7 @@ use std::fmt;
use std::rc::Rc;
#[derive(Clone)]
pub struct SymTable(HashMap<String, Symbol>);
pub struct SymTable(HashMap<String, Symbol>, usize);
#[derive(Debug, Clone)]
pub struct UserFn {
@ -68,11 +68,14 @@ pub struct Symbol {
// eval() will not eval the args
pub conditional_branches: bool,
pub docs: String,
// see SymTable::Insert
// (only pub begrudgingly
pub __generation: usize,
}
impl SymTable {
pub fn new() -> SymTable {
SymTable(HashMap::<String, Symbol>::new())
SymTable(HashMap::<String, Symbol>::new(), 0)
}
pub fn get(&self, arg: &String) -> Option<&Symbol> {
@ -83,7 +86,9 @@ impl SymTable {
self.0.contains_key(arg)
}
pub fn insert(&mut self, k: String, v: Symbol) -> Option<Symbol> {
pub fn insert(&mut self, k: String, mut v: Symbol) -> Option<Symbol> {
self.1 += 1;
v.__generation = self.1;
self.0.insert(k, v)
}
@ -95,16 +100,40 @@ impl SymTable {
self.0.iter()
}
pub fn update(&mut self, other: &mut SymTable) {
/* updates self with all syms in other that match the following cases:
* * sym is not in self
* * sym has a newer generation than the entry in self
*/
for i in other.iter() {
self.0.entry(i.0.to_string())
.and_modify(|inner: &mut Symbol| {
if inner.__generation < i.1.__generation {
inner.__generation = i.1.__generation;
inner.value = i.1.value.clone();
inner.args = i.1.args.clone();
inner.docs = i.1.docs.clone();
inner.conditional_branches = i.1.conditional_branches;
inner.name = i.1.name.clone();
}
})
.or_insert(i.1.clone());
}
}
pub fn call_symbol(
&mut self,
name: &String,
args: &Seg,
call_func: bool,
) -> Result<Box<Ctr>, String> {
let symbol = match self.remove(name) {
let mut symbol = match self.remove(name) {
Some(s) => s,
None => return Err(format!("undefined symbol: {}", name)),
};
// will re-increment when inserted
// but we dont want to increment it
symbol.__generation -= 1;
self.insert(name.to_string(), symbol.clone());
let cond_args: &Seg;
@ -338,6 +367,7 @@ impl Symbol {
args: Args::None,
docs: format!("local argument to {}", f.arg_syms[n].clone()),
conditional_branches: false,
..Default::default()
},
) {
holding_table.insert(f.arg_syms[n].clone(), old);
@ -412,6 +442,26 @@ impl Symbol {
docs: doc.clone(),
conditional_branches: false,
args, value,
..Default::default()
}
}
}
impl Default for Symbol {
fn default() -> Symbol {
Symbol {
value: ValueType::Internal(
Rc::new(
|_: &Seg, _: &mut SymTable| -> Result<Ctr, String> {
unimplemented!()
}
)
),
name: String::new(),
docs: String::new(),
args: Args::None,
conditional_branches: false,
__generation: 0,
}
}
}
@ -427,6 +477,7 @@ pub fn call_lambda(
docs: String::from("user defined lambda"),
args: Args::Lazy(lam.arg_syms.len() as u128),
value: ValueType::FuncForm(lam.clone()),
..Default::default()
};
let args: &Seg;