diff --git a/Readme.org b/Readme.org index a05a683..4751d2a 100644 --- a/Readme.org +++ b/Readme.org @@ -154,10 +154,8 @@ Note: this section only tracks the state of incomplete TODO items. Having everyt ** DONE Beta tasks (See tag: v0.3.0) ** TODO v1.0 tasks -- Post to relevant channels - Version flag - islist type query -- Scripts can use shell functions - Can pass args to relish scripts (via interpreter) - Can pass args to relish scripts (via command line) - File operations diff --git a/src/stl/posix.rs b/src/stl/posix.rs index bdb4e93..e2a8cdf 100644 --- a/src/stl/posix.rs +++ b/src/stl/posix.rs @@ -198,12 +198,10 @@ fn launch_command( // glibc says to do this in both parent and child if let Ok(child) = newchld { let pid = child.id(); - if let Err(e) = unistd::setpgid( + _ = unistd::setpgid( Pid::from_raw(pid as i32), Pid::from_raw(pid as i32), - ) { - eprintln!("parent couldnt setpgid on chld: {}", e); - } + ); // ignore result state.children.push(child); if !background { make_foreground(pid, state) diff --git a/src/sym.rs b/src/sym.rs index 591a772..0a499af 100644 --- a/src/sym.rs +++ b/src/sym.rs @@ -143,15 +143,29 @@ impl SymTable { if let ValueType::VarForm(ref val) = symbol.value { match **val { Ctr::Lambda(ref l) if call_func => { - call_lambda( + return call_lambda( l, &Box::new(Ctr::Seg(args.clone())), self ) }, - _ => Ok(val.clone()), + Ctr::Symbol(ref s) if self.is_function_type(s).is_some() + && self.is_function_type(s).unwrap() => { + symbol = match self.remove(s) { + Some(sym) => sym, + None => return Err( + Traceback::new().with_trace( + (name, format!("(references undefined symbol {})", s)) + .into())), + }; + symbol.__generation -= 1; + self.insert(symbol.name.clone(), symbol.clone()); + }, + _ => return Ok(val.clone()), } - } else if call_func { + } + + if call_func { symbol.call(args, self) } else { // its a function but call_func is off @@ -161,10 +175,10 @@ impl SymTable { pub fn is_function_type(&self, name: &String) -> Option { if let ValueType::VarForm(ref val) = self.get(name)?.value { - if let Ctr::Lambda(_) = **val { - Some(true) - } else { - Some(false) + match **val { + Ctr::Lambda(_) => Some(true), + Ctr::Symbol(ref n) => self.is_function_type(n), + _ => Some(false), } } else { Some(true) diff --git a/tests/test_eval.rs b/tests/test_eval.rs index 128fa1b..8ba3a90 100644 --- a/tests/test_eval.rs +++ b/tests/test_eval.rs @@ -1,6 +1,7 @@ mod eval_tests { use relish::ast::{eval, lex, SymTable}; use relish::ast::{Args, Ctr, Seg, Symbol, UserFn, ValueType}; + use relish::stdlib::{dynamic_stdlib, static_stdlib}; #[test] fn eval_simple() { @@ -92,4 +93,21 @@ mod eval_tests { } } } + + #[test] + fn func_lambda_equivalency() { + let comparator = "(def apply 'applicator' (fn x) (fn x))"; + let lh_doc = "(apply car (1 2 3))"; + let rh_doc = "(apply (lambda (x) (car x)) (1 2 3))"; + + let mut syms = SymTable::new(); + static_stdlib(&mut syms); + dynamic_stdlib(&mut syms, None); + + eval(&lex(&comparator.to_string()).unwrap(), &mut syms).unwrap(); + assert_eq!( + eval(&lex(&lh_doc.to_string()).unwrap(), &mut syms).unwrap(), + eval(&lex(&rh_doc.to_string()).unwrap(), &mut syms).unwrap(), + ); + } }