fix evaluation behavior mismatch between functions and lambdas

Signed-off-by: Ava Hahn <ava@sunnypup.io>
This commit is contained in:
Ava Apples Affine 2023-06-08 12:48:34 -07:00
parent e0b837cb21
commit 398726568a
4 changed files with 41 additions and 13 deletions

View file

@ -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

View file

@ -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)

View file

@ -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<bool> {
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)

View file

@ -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(),
);
}
}