Implemented SymTable optimization for efficient variable updates
This commit is contained in:
parent
dcb2969b0a
commit
381852b3bd
9 changed files with 122 additions and 23 deletions
59
src/sym.rs
59
src/sym.rs
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue