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

@ -477,7 +477,6 @@ Note: this section will not show the status of each item unless you are viewing
Note: this section only tracks the state of incomplete TODO items. Having everything on here would be cluttered. Note: this section only tracks the state of incomplete TODO items. Having everything on here would be cluttered.
** TODO Pre-alpha tasks ** TODO Pre-alpha tasks
- SYMTABLE-LET OPTIMIZATION COUNTERS
- Load (load a script) function - Load (load a script) function
- Pull/Refactor the logic out of the configure functions. - Pull/Refactor the logic out of the configure functions.
- Optionally return a list of new variables and/or functions? - Optionally return a list of new variables and/or functions?

View file

@ -28,7 +28,7 @@
'prints if a test has failed' 'prints if a test has failed'
(test) (test)
(echo (concat "FAILED: " test))) (echo (concat "FAILED: " test)))
(def test-cases 'all test cases' (def test-cases 'all test cases'
(('set updates var' (('set updates var'
(quote (quote
@ -61,4 +61,4 @@
(if (eval test-body) (if (eval test-body)
(passed test-name) (passed test-name)
(failed test-name)) (failed test-name))
(set (q test-iter) (pop remaining))))) (set (q test-iter) (pop remaining)))))

View file

@ -50,7 +50,7 @@ WARNING: abandon hope all ye who declare and then modify global variables!
(let ((doc (get-doc var))) (let ((doc (get-doc var)))
(def (eval var) doc val))) (def (eval var) doc val)))
(def map (def map
'Takes two arguments: a function and a list. 'Takes two arguments: a function and a list.
for each element in the list, the function is applied and the for each element in the list, the function is applied and the
result is added to a new list. Returns the new list.' result is added to a new list. Returns the new list.'

View file

@ -40,6 +40,7 @@ pub fn configure(filename: String, syms: &mut SymTable) -> Result<(), String> {
default value: false".to_string(), default value: false".to_string(),
value: ValueType::VarForm(Box::new(Ctr::Bool(false))), value: ValueType::VarForm(Box::new(Ctr::Bool(false))),
..Default::default()
}, },
); );
@ -56,6 +57,7 @@ checked at shell startup by configuration daemon. not used afterwards.
default value: 1 (set) default value: 1 (set)
".to_string(), ".to_string(),
value: ValueType::VarForm(Box::new(Ctr::Bool(true))), value: ValueType::VarForm(Box::new(Ctr::Bool(true))),
..Default::default()
}, },
); );
@ -69,6 +71,7 @@ default value: 1 (set)
default value (<lambda>)" default value (<lambda>)"
.to_string(), .to_string(),
value: ValueType::Internal(Rc::new(prompt_default_callback)), value: ValueType::Internal(Rc::new(prompt_default_callback)),
..Default::default()
}, },
); );

View file

@ -38,6 +38,7 @@ pub fn static_stdlib(syms: &mut SymTable) -> Result<(), String> {
conditional_branches: false, conditional_branches: false,
docs: append::CONS_DOCSTRING.to_string(), docs: append::CONS_DOCSTRING.to_string(),
value: ValueType::Internal(Rc::new(append::cons_callback)), value: ValueType::Internal(Rc::new(append::cons_callback)),
..Default::default()
}, },
); );
@ -49,6 +50,7 @@ pub fn static_stdlib(syms: &mut SymTable) -> Result<(), String> {
conditional_branches: false, conditional_branches: false,
docs: strings::ECHO_DOCSTRING.to_string(), docs: strings::ECHO_DOCSTRING.to_string(),
value: ValueType::Internal(Rc::new(strings::echo_callback)), value: ValueType::Internal(Rc::new(strings::echo_callback)),
..Default::default()
}, },
); );
@ -60,6 +62,7 @@ pub fn static_stdlib(syms: &mut SymTable) -> Result<(), String> {
conditional_branches: false, conditional_branches: false,
docs: strings::CONCAT_DOCSTRING.to_string(), docs: strings::CONCAT_DOCSTRING.to_string(),
value: ValueType::Internal(Rc::new(strings::concat_callback)), value: ValueType::Internal(Rc::new(strings::concat_callback)),
..Default::default()
}, },
); );
@ -71,6 +74,7 @@ pub fn static_stdlib(syms: &mut SymTable) -> Result<(), String> {
conditional_branches: false, conditional_branches: false,
docs: strings::CONTAINS_DOCSTRING.to_string(), docs: strings::CONTAINS_DOCSTRING.to_string(),
value: ValueType::Internal(Rc::new(strings::contains_callback)), value: ValueType::Internal(Rc::new(strings::contains_callback)),
..Default::default()
}, },
); );
@ -82,6 +86,7 @@ pub fn static_stdlib(syms: &mut SymTable) -> Result<(), String> {
conditional_branches: false, conditional_branches: false,
docs: strings::SPLIT_DOCSTRING.to_string(), docs: strings::SPLIT_DOCSTRING.to_string(),
value: ValueType::Internal(Rc::new(strings::split_callback)), value: ValueType::Internal(Rc::new(strings::split_callback)),
..Default::default()
}, },
); );
@ -93,6 +98,7 @@ pub fn static_stdlib(syms: &mut SymTable) -> Result<(), String> {
conditional_branches: false, conditional_branches: false,
docs: strings::STRLEN_DOCSTRING.to_string(), docs: strings::STRLEN_DOCSTRING.to_string(),
value: ValueType::Internal(Rc::new(strings::strlen_callback)), value: ValueType::Internal(Rc::new(strings::strlen_callback)),
..Default::default()
}, },
); );
@ -104,6 +110,7 @@ pub fn static_stdlib(syms: &mut SymTable) -> Result<(), String> {
conditional_branches: false, conditional_branches: false,
docs: strings::STRCAST_DOCSTRING.to_string(), docs: strings::STRCAST_DOCSTRING.to_string(),
value: ValueType::Internal(Rc::new(strings::strcast_callback)), value: ValueType::Internal(Rc::new(strings::strcast_callback)),
..Default::default()
}, },
); );
@ -115,6 +122,7 @@ pub fn static_stdlib(syms: &mut SymTable) -> Result<(), String> {
conditional_branches: true, conditional_branches: true,
docs: control::IF_DOCSTRING.to_string(), docs: control::IF_DOCSTRING.to_string(),
value: ValueType::Internal(Rc::new(control::if_callback)), value: ValueType::Internal(Rc::new(control::if_callback)),
..Default::default()
}, },
); );
@ -126,6 +134,7 @@ pub fn static_stdlib(syms: &mut SymTable) -> Result<(), String> {
conditional_branches: true, conditional_branches: true,
docs: control::LET_DOCSTRING.to_string(), docs: control::LET_DOCSTRING.to_string(),
value: ValueType::Internal(Rc::new(control::let_callback)), value: ValueType::Internal(Rc::new(control::let_callback)),
..Default::default()
}, },
); );
@ -137,6 +146,7 @@ pub fn static_stdlib(syms: &mut SymTable) -> Result<(), String> {
conditional_branches: true, conditional_branches: true,
docs: control::WHILE_DOCSTRING.to_string(), docs: control::WHILE_DOCSTRING.to_string(),
value: ValueType::Internal(Rc::new(control::while_callback)), value: ValueType::Internal(Rc::new(control::while_callback)),
..Default::default()
}, },
); );
@ -148,6 +158,7 @@ pub fn static_stdlib(syms: &mut SymTable) -> Result<(), String> {
conditional_branches: true, conditional_branches: true,
docs: control::CIRCUIT_DOCSTRING.to_string(), docs: control::CIRCUIT_DOCSTRING.to_string(),
value: ValueType::Internal(Rc::new(control::circuit_callback)), value: ValueType::Internal(Rc::new(control::circuit_callback)),
..Default::default()
}, },
); );
@ -159,6 +170,7 @@ pub fn static_stdlib(syms: &mut SymTable) -> Result<(), String> {
conditional_branches: false, conditional_branches: false,
docs: boolean::AND_DOCSTRING.to_string(), docs: boolean::AND_DOCSTRING.to_string(),
value: ValueType::Internal(Rc::new(boolean::and_callback)), value: ValueType::Internal(Rc::new(boolean::and_callback)),
..Default::default()
}, },
); );
@ -170,6 +182,7 @@ pub fn static_stdlib(syms: &mut SymTable) -> Result<(), String> {
conditional_branches: false, conditional_branches: false,
docs: boolean::BOOLCAST_DOCSTRING.to_string(), docs: boolean::BOOLCAST_DOCSTRING.to_string(),
value: ValueType::Internal(Rc::new(boolean::boolcast_callback)), value: ValueType::Internal(Rc::new(boolean::boolcast_callback)),
..Default::default()
}, },
); );
@ -181,6 +194,7 @@ pub fn static_stdlib(syms: &mut SymTable) -> Result<(), String> {
conditional_branches: false, conditional_branches: false,
docs: boolean::OR_DOCSTRING.to_string(), docs: boolean::OR_DOCSTRING.to_string(),
value: ValueType::Internal(Rc::new(boolean::or_callback)), value: ValueType::Internal(Rc::new(boolean::or_callback)),
..Default::default()
}, },
); );
@ -192,6 +206,7 @@ pub fn static_stdlib(syms: &mut SymTable) -> Result<(), String> {
conditional_branches: false, conditional_branches: false,
docs: boolean::NOT_DOCSTRING.to_string(), docs: boolean::NOT_DOCSTRING.to_string(),
value: ValueType::Internal(Rc::new(boolean::not_callback)), value: ValueType::Internal(Rc::new(boolean::not_callback)),
..Default::default()
}, },
); );
@ -203,6 +218,7 @@ pub fn static_stdlib(syms: &mut SymTable) -> Result<(), String> {
conditional_branches: false, conditional_branches: false,
docs: boolean::ISEQ_DOCSTRING.to_string(), docs: boolean::ISEQ_DOCSTRING.to_string(),
value: ValueType::Internal(Rc::new(boolean::iseq_callback)), value: ValueType::Internal(Rc::new(boolean::iseq_callback)),
..Default::default()
}, },
); );
@ -214,6 +230,7 @@ pub fn static_stdlib(syms: &mut SymTable) -> Result<(), String> {
conditional_branches: true, conditional_branches: true,
docs: boolean::TOGGLE_DOCSTRING.to_string(), docs: boolean::TOGGLE_DOCSTRING.to_string(),
value: ValueType::Internal(Rc::new(boolean::toggle_callback)), value: ValueType::Internal(Rc::new(boolean::toggle_callback)),
..Default::default()
}, },
); );
@ -225,6 +242,7 @@ pub fn static_stdlib(syms: &mut SymTable) -> Result<(), String> {
conditional_branches: true, conditional_branches: true,
docs: decl::HELP_DOCSTRING.to_string(), docs: decl::HELP_DOCSTRING.to_string(),
value: ValueType::Internal(Rc::new(decl::help_callback)), value: ValueType::Internal(Rc::new(decl::help_callback)),
..Default::default()
}, },
); );
@ -236,6 +254,7 @@ pub fn static_stdlib(syms: &mut SymTable) -> Result<(), String> {
conditional_branches: true, conditional_branches: true,
docs: decl::ISSET_DOCSTRING.to_string(), docs: decl::ISSET_DOCSTRING.to_string(),
value: ValueType::Internal(Rc::new(decl::isset_callback)), value: ValueType::Internal(Rc::new(decl::isset_callback)),
..Default::default()
}, },
); );
@ -247,6 +266,7 @@ pub fn static_stdlib(syms: &mut SymTable) -> Result<(), String> {
conditional_branches: false, conditional_branches: false,
docs: decl::ENV_DOCSTRING.to_string(), docs: decl::ENV_DOCSTRING.to_string(),
value: ValueType::Internal(Rc::new(decl::env_callback)), value: ValueType::Internal(Rc::new(decl::env_callback)),
..Default::default()
}, },
); );
@ -258,6 +278,7 @@ pub fn static_stdlib(syms: &mut SymTable) -> Result<(), String> {
conditional_branches: false, conditional_branches: false,
docs: math::ADD_DOCSTRING.to_string(), docs: math::ADD_DOCSTRING.to_string(),
value: ValueType::Internal(Rc::new(math::add_callback)), value: ValueType::Internal(Rc::new(math::add_callback)),
..Default::default()
}, },
); );
@ -269,6 +290,7 @@ pub fn static_stdlib(syms: &mut SymTable) -> Result<(), String> {
conditional_branches: false, conditional_branches: false,
docs: math::SUB_DOCSTRING.to_string(), docs: math::SUB_DOCSTRING.to_string(),
value: ValueType::Internal(Rc::new(math::sub_callback)), value: ValueType::Internal(Rc::new(math::sub_callback)),
..Default::default()
}, },
); );
@ -280,6 +302,7 @@ pub fn static_stdlib(syms: &mut SymTable) -> Result<(), String> {
conditional_branches: false, conditional_branches: false,
docs: math::DIV_DOCSTRING.to_string(), docs: math::DIV_DOCSTRING.to_string(),
value: ValueType::Internal(Rc::new(math::div_callback)), value: ValueType::Internal(Rc::new(math::div_callback)),
..Default::default()
}, },
); );
@ -291,6 +314,7 @@ pub fn static_stdlib(syms: &mut SymTable) -> Result<(), String> {
conditional_branches: false, conditional_branches: false,
docs: math::MUL_DOCSTRING.to_string(), docs: math::MUL_DOCSTRING.to_string(),
value: ValueType::Internal(Rc::new(math::mul_callback)), value: ValueType::Internal(Rc::new(math::mul_callback)),
..Default::default()
}, },
); );
@ -302,6 +326,7 @@ pub fn static_stdlib(syms: &mut SymTable) -> Result<(), String> {
conditional_branches: false, conditional_branches: false,
docs: math::INTCAST_DOCSTRING.to_string(), docs: math::INTCAST_DOCSTRING.to_string(),
value: ValueType::Internal(Rc::new(math::intcast_callback)), value: ValueType::Internal(Rc::new(math::intcast_callback)),
..Default::default()
}, },
); );
@ -313,6 +338,7 @@ pub fn static_stdlib(syms: &mut SymTable) -> Result<(), String> {
conditional_branches: false, conditional_branches: false,
docs: math::FLOATCAST_DOCSTRING.to_string(), docs: math::FLOATCAST_DOCSTRING.to_string(),
value: ValueType::Internal(Rc::new(math::floatcast_callback)), value: ValueType::Internal(Rc::new(math::floatcast_callback)),
..Default::default()
}, },
); );
@ -324,6 +350,7 @@ pub fn static_stdlib(syms: &mut SymTable) -> Result<(), String> {
conditional_branches: false, conditional_branches: false,
docs: append::LEN_DOCSTRING.to_string(), docs: append::LEN_DOCSTRING.to_string(),
value: ValueType::Internal(Rc::new(append::len_callback)), value: ValueType::Internal(Rc::new(append::len_callback)),
..Default::default()
}, },
); );
@ -335,6 +362,7 @@ pub fn static_stdlib(syms: &mut SymTable) -> Result<(), String> {
conditional_branches: false, conditional_branches: false,
docs: append::CAR_DOCSTRING.to_string(), docs: append::CAR_DOCSTRING.to_string(),
value: ValueType::Internal(Rc::new(append::car_callback)), value: ValueType::Internal(Rc::new(append::car_callback)),
..Default::default()
}, },
); );
@ -346,6 +374,7 @@ pub fn static_stdlib(syms: &mut SymTable) -> Result<(), String> {
conditional_branches: false, conditional_branches: false,
docs: append::CDR_DOCSTRING.to_string(), docs: append::CDR_DOCSTRING.to_string(),
value: ValueType::Internal(Rc::new(append::cdr_callback)), value: ValueType::Internal(Rc::new(append::cdr_callback)),
..Default::default()
}, },
); );
@ -357,6 +386,7 @@ pub fn static_stdlib(syms: &mut SymTable) -> Result<(), String> {
conditional_branches: false, conditional_branches: false,
docs: append::POP_DOCSTRING.to_string(), docs: append::POP_DOCSTRING.to_string(),
value: ValueType::Internal(Rc::new(append::pop_callback)), value: ValueType::Internal(Rc::new(append::pop_callback)),
..Default::default()
}, },
); );
@ -368,6 +398,7 @@ pub fn static_stdlib(syms: &mut SymTable) -> Result<(), String> {
conditional_branches: false, conditional_branches: false,
docs: append::DEQUEUE_DOCSTRING.to_string(), docs: append::DEQUEUE_DOCSTRING.to_string(),
value: ValueType::Internal(Rc::new(append::dequeue_callback)), value: ValueType::Internal(Rc::new(append::dequeue_callback)),
..Default::default()
}, },
); );
@ -379,6 +410,7 @@ pub fn static_stdlib(syms: &mut SymTable) -> Result<(), String> {
conditional_branches: false, conditional_branches: false,
docs: append::REVERSE_DOCSTRING.to_string(), docs: append::REVERSE_DOCSTRING.to_string(),
value: ValueType::Internal(Rc::new(append::reverse_callback)), value: ValueType::Internal(Rc::new(append::reverse_callback)),
..Default::default()
}, },
); );
@ -390,6 +422,7 @@ pub fn static_stdlib(syms: &mut SymTable) -> Result<(), String> {
conditional_branches: false, conditional_branches: false,
docs: math::EXP_DOCSTRING.to_string(), docs: math::EXP_DOCSTRING.to_string(),
value: ValueType::Internal(Rc::new(math::exp_callback)), value: ValueType::Internal(Rc::new(math::exp_callback)),
..Default::default()
}, },
); );
@ -401,6 +434,7 @@ pub fn static_stdlib(syms: &mut SymTable) -> Result<(), String> {
conditional_branches: false, conditional_branches: false,
docs: math::MOD_DOCSTRING.to_string(), docs: math::MOD_DOCSTRING.to_string(),
value: ValueType::Internal(Rc::new(math::mod_callback)), value: ValueType::Internal(Rc::new(math::mod_callback)),
..Default::default()
}, },
); );
@ -412,6 +446,7 @@ pub fn static_stdlib(syms: &mut SymTable) -> Result<(), String> {
conditional_branches: false, conditional_branches: false,
docs: math::ISGT_DOCSTRING.to_string(), docs: math::ISGT_DOCSTRING.to_string(),
value: ValueType::Internal(Rc::new(math::isgt_callback)), value: ValueType::Internal(Rc::new(math::isgt_callback)),
..Default::default()
}, },
); );
@ -423,6 +458,7 @@ pub fn static_stdlib(syms: &mut SymTable) -> Result<(), String> {
conditional_branches: false, conditional_branches: false,
docs: math::ISLT_DOCSTRING.to_string(), docs: math::ISLT_DOCSTRING.to_string(),
value: ValueType::Internal(Rc::new(math::islt_callback)), value: ValueType::Internal(Rc::new(math::islt_callback)),
..Default::default()
}, },
); );
@ -434,6 +470,7 @@ pub fn static_stdlib(syms: &mut SymTable) -> Result<(), String> {
conditional_branches: false, conditional_branches: false,
docs: math::ISGTE_DOCSTRING.to_string(), docs: math::ISGTE_DOCSTRING.to_string(),
value: ValueType::Internal(Rc::new(math::isgte_callback)), value: ValueType::Internal(Rc::new(math::isgte_callback)),
..Default::default()
}, },
); );
@ -445,6 +482,7 @@ pub fn static_stdlib(syms: &mut SymTable) -> Result<(), String> {
conditional_branches: false, conditional_branches: false,
docs: math::ISLTE_DOCSTRING.to_string(), docs: math::ISLTE_DOCSTRING.to_string(),
value: ValueType::Internal(Rc::new(math::islte_callback)), value: ValueType::Internal(Rc::new(math::islte_callback)),
..Default::default()
}, },
); );
@ -456,6 +494,7 @@ pub fn static_stdlib(syms: &mut SymTable) -> Result<(), String> {
conditional_branches: true, conditional_branches: true,
docs: math::INC_DOCSTRING.to_string(), docs: math::INC_DOCSTRING.to_string(),
value: ValueType::Internal(Rc::new(math::inc_callback)), value: ValueType::Internal(Rc::new(math::inc_callback)),
..Default::default()
}, },
); );
@ -467,6 +506,7 @@ pub fn static_stdlib(syms: &mut SymTable) -> Result<(), String> {
conditional_branches: true, conditional_branches: true,
docs: math::DEC_DOCSTRING.to_string(), docs: math::DEC_DOCSTRING.to_string(),
value: ValueType::Internal(Rc::new(math::dec_callback)), value: ValueType::Internal(Rc::new(math::dec_callback)),
..Default::default()
}, },
); );
@ -478,6 +518,7 @@ pub fn static_stdlib(syms: &mut SymTable) -> Result<(), String> {
conditional_branches: true, conditional_branches: true,
docs: decl::QUOTE_DOCSTRING.to_string(), docs: decl::QUOTE_DOCSTRING.to_string(),
value: ValueType::Internal(Rc::new(decl::quote_callback)), value: ValueType::Internal(Rc::new(decl::quote_callback)),
..Default::default()
}, },
); );
@ -489,6 +530,7 @@ pub fn static_stdlib(syms: &mut SymTable) -> Result<(), String> {
conditional_branches: true, conditional_branches: true,
docs: decl::QUOTE_DOCSTRING.to_string(), docs: decl::QUOTE_DOCSTRING.to_string(),
value: ValueType::Internal(Rc::new(decl::quote_callback)), value: ValueType::Internal(Rc::new(decl::quote_callback)),
..Default::default()
}, },
); );
@ -500,6 +542,7 @@ pub fn static_stdlib(syms: &mut SymTable) -> Result<(), String> {
conditional_branches: true, conditional_branches: true,
docs: decl::EVAL_DOCSTRING.to_string(), docs: decl::EVAL_DOCSTRING.to_string(),
value: ValueType::Internal(Rc::new(decl::eval_callback)), value: ValueType::Internal(Rc::new(decl::eval_callback)),
..Default::default()
}, },
); );
@ -511,6 +554,7 @@ pub fn static_stdlib(syms: &mut SymTable) -> Result<(), String> {
conditional_branches: true, conditional_branches: true,
docs: decl::LAMBDA_DOCSTRING.to_string(), docs: decl::LAMBDA_DOCSTRING.to_string(),
value: ValueType::Internal(Rc::new(decl::lambda_callback)), value: ValueType::Internal(Rc::new(decl::lambda_callback)),
..Default::default()
} }
); );
@ -522,6 +566,7 @@ pub fn static_stdlib(syms: &mut SymTable) -> Result<(), String> {
conditional_branches: false, conditional_branches: false,
docs: decl::GETDOC_DOCSTRING.to_string(), docs: decl::GETDOC_DOCSTRING.to_string(),
value: ValueType::Internal(Rc::new(decl::getdoc_callback)), value: ValueType::Internal(Rc::new(decl::getdoc_callback)),
..Default::default()
} }
); );
@ -533,6 +578,7 @@ pub fn static_stdlib(syms: &mut SymTable) -> Result<(), String> {
conditional_branches: false, conditional_branches: false,
docs: decl::SETDOC_DOCSTRING.to_string(), docs: decl::SETDOC_DOCSTRING.to_string(),
value: ValueType::Internal(Rc::new(decl::setdoc_callback)), value: ValueType::Internal(Rc::new(decl::setdoc_callback)),
..Default::default()
} }
); );
@ -562,6 +608,7 @@ pub fn dynamic_stdlib(syms: &mut SymTable) -> Result<(), String> {
decl::store_callback(ast, syms, env_cfg_user_form) decl::store_callback(ast, syms, env_cfg_user_form)
}, },
)), )),
..Default::default()
}, },
); );

View file

@ -202,22 +202,10 @@ pub fn let_callback(ast: &Seg, syms: &mut SymTable) -> Result<Ctr, String> {
return Err("evaluation failure".to_string()); return Err("evaluation failure".to_string());
} }
// we need to get any var declared from within the let eval forms for i in locals {
// those need to exist in the outside context localsyms.remove(&i);
// TODO: make this more optimal
// How can we skip iterations?
// implement a counter for number of calls to def
// store it inside the SymTable and Symbol
// only re-insert into global scope what is most recent
for i in localsyms.iter() {
if !locals.contains(i.0) {
syms.insert(
i.0.clone(),
i.1.clone(),
);
}
} }
syms.update(&mut localsyms);
Ok((*result).clone()) Ok((*result).clone())
} }

View file

@ -22,7 +22,7 @@ use std::fmt;
use std::rc::Rc; use std::rc::Rc;
#[derive(Clone)] #[derive(Clone)]
pub struct SymTable(HashMap<String, Symbol>); pub struct SymTable(HashMap<String, Symbol>, usize);
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct UserFn { pub struct UserFn {
@ -68,11 +68,14 @@ pub struct Symbol {
// eval() will not eval the args // eval() will not eval the args
pub conditional_branches: bool, pub conditional_branches: bool,
pub docs: String, pub docs: String,
// see SymTable::Insert
// (only pub begrudgingly
pub __generation: usize,
} }
impl SymTable { impl SymTable {
pub fn new() -> SymTable { pub fn new() -> SymTable {
SymTable(HashMap::<String, Symbol>::new()) SymTable(HashMap::<String, Symbol>::new(), 0)
} }
pub fn get(&self, arg: &String) -> Option<&Symbol> { pub fn get(&self, arg: &String) -> Option<&Symbol> {
@ -83,7 +86,9 @@ impl SymTable {
self.0.contains_key(arg) 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) self.0.insert(k, v)
} }
@ -95,16 +100,40 @@ impl SymTable {
self.0.iter() 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( pub fn call_symbol(
&mut self, &mut self,
name: &String, name: &String,
args: &Seg, args: &Seg,
call_func: bool, call_func: bool,
) -> Result<Box<Ctr>, String> { ) -> Result<Box<Ctr>, String> {
let symbol = match self.remove(name) { let mut symbol = match self.remove(name) {
Some(s) => s, Some(s) => s,
None => return Err(format!("undefined symbol: {}", name)), 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()); self.insert(name.to_string(), symbol.clone());
let cond_args: &Seg; let cond_args: &Seg;
@ -338,6 +367,7 @@ impl Symbol {
args: Args::None, args: Args::None,
docs: format!("local argument to {}", f.arg_syms[n].clone()), docs: format!("local argument to {}", f.arg_syms[n].clone()),
conditional_branches: false, conditional_branches: false,
..Default::default()
}, },
) { ) {
holding_table.insert(f.arg_syms[n].clone(), old); holding_table.insert(f.arg_syms[n].clone(), old);
@ -412,6 +442,26 @@ impl Symbol {
docs: doc.clone(), docs: doc.clone(),
conditional_branches: false, conditional_branches: false,
args, value, 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"), docs: String::from("user defined lambda"),
args: Args::Lazy(lam.arg_syms.len() as u128), args: Args::Lazy(lam.arg_syms.len() as u128),
value: ValueType::FuncForm(lam.clone()), value: ValueType::FuncForm(lam.clone()),
..Default::default()
}; };
let args: &Seg; let args: &Seg;

View file

@ -38,6 +38,7 @@ mod eval_tests {
Box::from(Ctr::None), Box::from(Ctr::None),
)), )),
}), }),
..Default::default()
}; };
syms.insert(String::from("echo"), test_external_func); syms.insert(String::from("echo"), test_external_func);
@ -64,6 +65,7 @@ mod eval_tests {
Box::from(Ctr::None), Box::from(Ctr::None),
)), )),
}), }),
..Default::default()
}; };
syms.insert(String::from("echo"), test_external_func); syms.insert(String::from("echo"), test_external_func);

View file

@ -22,6 +22,7 @@ mod func_tests {
Ok(Ctr::Bool(is_bool)) Ok(Ctr::Bool(is_bool))
}, },
)), )),
..Default::default()
}; };
let args = Seg::from(Box::new(Ctr::Bool(true)), Box::new(Ctr::None)); let args = Seg::from(Box::new(Ctr::Bool(true)), Box::new(Ctr::None));
syms.insert(String::from("test_func_in"), test_internal_func); syms.insert(String::from("test_func_in"), test_internal_func);
@ -46,6 +47,7 @@ mod func_tests {
arg_syms: vec!["input".to_string()], arg_syms: vec!["input".to_string()],
ast: finner, ast: finner,
}), }),
..Default::default()
}; };
let args = Seg::from( let args = Seg::from(
@ -75,6 +77,7 @@ mod func_tests {
arg_syms: vec!["input".to_string()], arg_syms: vec!["input".to_string()],
ast: finner, ast: finner,
}), }),
..Default::default()
}; };
let args = Seg::from( let args = Seg::from(
@ -114,6 +117,7 @@ mod func_tests {
} }
}, },
)), )),
..Default::default()
}; };
let finner = lex(&"((test_inner true))".to_string()).unwrap(); let finner = lex(&"((test_inner true))".to_string()).unwrap();
@ -126,6 +130,7 @@ mod func_tests {
arg_syms: vec!["input".to_string()], arg_syms: vec!["input".to_string()],
ast: finner, ast: finner,
}), }),
..Default::default()
}; };
let args = Seg::from(Box::new(Ctr::Bool(true)), Box::new(Ctr::None)); let args = Seg::from(Box::new(Ctr::Bool(true)), Box::new(Ctr::None));
@ -157,6 +162,7 @@ mod func_tests {
Ok(Ctr::Bool(is_bool)) Ok(Ctr::Bool(is_bool))
}, },
)), )),
..Default::default()
}; };
let args = Seg::from(Box::new(Ctr::Integer(1)), Box::new(Ctr::None)); let args = Seg::from(Box::new(Ctr::Integer(1)), Box::new(Ctr::None));
@ -182,6 +188,7 @@ mod func_tests {
arg_syms: vec!["input".to_string()], arg_syms: vec!["input".to_string()],
ast: finner, ast: finner,
}), }),
..Default::default()
}; };
let args = Seg::from( let args = Seg::from(
@ -211,6 +218,7 @@ mod func_tests {
arg_syms: vec!["input".to_string()], arg_syms: vec!["input".to_string()],
ast: finner, ast: finner,
}), }),
..Default::default()
}; };
let args = Seg::new(); let args = Seg::new();
@ -241,6 +249,7 @@ mod func_tests {
Ok(Ctr::Bool(is_bool)) Ok(Ctr::Bool(is_bool))
}, },
)), )),
..Default::default()
}; };
let args = Seg::from( let args = Seg::from(
Box::new(Ctr::Symbol("undefined-symbol".to_string())), Box::new(Ctr::Symbol("undefined-symbol".to_string())),