expand func call tests
Signed-off-by: Ava Hahn <ava@aidanis.online>
This commit is contained in:
parent
d640c815a8
commit
82854a58f8
2 changed files with 118 additions and 21 deletions
15
src/sym.rs
15
src/sym.rs
|
|
@ -149,6 +149,7 @@ impl Args {
|
|||
|
||||
Args::Strict(ref arg_types) => {
|
||||
let mut idx: usize = 0;
|
||||
let mut mismatch = false;
|
||||
let passes = args.circuit(&mut |c: &Ctr| -> bool {
|
||||
if idx >= arg_types.len() {
|
||||
return false;
|
||||
|
|
@ -160,6 +161,7 @@ impl Args {
|
|||
idx += 1;
|
||||
return true;
|
||||
}
|
||||
mismatch = true;
|
||||
false
|
||||
});
|
||||
|
||||
|
|
@ -171,16 +173,15 @@ impl Args {
|
|||
}
|
||||
|
||||
if !passes {
|
||||
if idx < (arg_types.len() - 1) {
|
||||
return Err(format!(
|
||||
"argument {} is of wrong type (expected {})",
|
||||
idx + 1,
|
||||
arg_types[idx]
|
||||
));
|
||||
if mismatch {
|
||||
return Err(format!("arg {} expected to be {}", idx+1, arg_types[idx]));
|
||||
}
|
||||
if idx == (arg_types.len() - 1) {
|
||||
if idx > (arg_types.len() - 1) {
|
||||
return Err("too many arguments".to_string());
|
||||
}
|
||||
if idx < (arg_types.len() - 1) {
|
||||
return Err("too few arguments".to_string());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -177,35 +177,131 @@ mod func_tests {
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
// TODO: These tests need completion!
|
||||
#[test]
|
||||
fn eval_lazy_func_call() {
|
||||
fn arg_type_mismatch() {
|
||||
let mut syms = SymTable::new();
|
||||
let test_internal_func: Symbol = Symbol {
|
||||
name: String::from("test_func_in"),
|
||||
conditional_branches: false,
|
||||
args: Args::Strict(vec![Type::Bool]),
|
||||
value: ValueType::Internal(Box::new(
|
||||
|a: &Seg, _: &mut SymTable| -> Ctr {
|
||||
let inner = a;
|
||||
let mut is_bool = false;
|
||||
if let Ctr::Bool(_) = *inner.car {
|
||||
is_bool = true;
|
||||
}
|
||||
Ctr::Bool(is_bool)
|
||||
},
|
||||
)),
|
||||
};
|
||||
let args = Seg::from(
|
||||
Box::new(Ctr::Integer(1)),
|
||||
Box::new(Ctr::None)
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sym_loose_func_call() {
|
||||
syms.insert(String::from("test_func_in"), test_internal_func);
|
||||
|
||||
if let Err(s) = syms.call_symbol(&"test_func_in".to_string(), &args, true) {
|
||||
assert_eq!(s, "failure to call test_func_in: arg 1 expected to be bool");
|
||||
} else {
|
||||
print!("call to function succeeded (shouldnt have)");
|
||||
assert!(false);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn too_many_args() {
|
||||
let mut syms = SymTable::new();
|
||||
match lex(&"((input))".to_string()) {
|
||||
Err(e) => panic!("{}", e),
|
||||
Ok(finner) => {
|
||||
let test_external_func: Symbol = Symbol {
|
||||
name: String::from("echo"),
|
||||
conditional_branches: false,
|
||||
args: Args::Lazy(1),
|
||||
value: ValueType::FuncForm(UserFn{
|
||||
arg_syms: vec!["input".to_string()],
|
||||
ast: finner,
|
||||
}),
|
||||
};
|
||||
|
||||
let args = Seg::from(
|
||||
Box::new(Ctr::String("test".to_string())),
|
||||
Box::new(Ctr::Seg(Seg::from_mono(Box::new(Ctr::Integer(1)))))
|
||||
);
|
||||
|
||||
syms.insert(String::from("test_func_in"), test_external_func);
|
||||
|
||||
if let Err(s) = syms.call_symbol(&"test_func_in".to_string(), &args, true) {
|
||||
assert_eq!(s, "failure to call echo: expected 1 args. Got 2.");
|
||||
} else {
|
||||
print!("call to function succeeded (shouldnt have)");
|
||||
assert!(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn not_enough_args() {
|
||||
fn too_few_args() {
|
||||
let mut syms = SymTable::new();
|
||||
match lex(&"((input))".to_string()) {
|
||||
Err(e) => panic!("{}", e),
|
||||
Ok(finner) => {
|
||||
let test_external_func: Symbol = Symbol {
|
||||
name: String::from("echo"),
|
||||
conditional_branches: false,
|
||||
args: Args::Lazy(1),
|
||||
value: ValueType::FuncForm(UserFn{
|
||||
arg_syms: vec!["input".to_string()],
|
||||
ast: finner,
|
||||
}),
|
||||
};
|
||||
|
||||
let args = Seg::new();
|
||||
syms.insert(String::from("test_func_in"), test_external_func);
|
||||
|
||||
if let Err(s) = syms.call_symbol(&"test_func_in".to_string(), &args, true) {
|
||||
assert_eq!(s, "failure to call echo: expected 1 args. Got 2.");
|
||||
} else {
|
||||
print!("call to function succeeded (shouldnt have)");
|
||||
assert!(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn bad_eval_arg() {
|
||||
fn arg_cant_eval() {
|
||||
let mut syms = SymTable::new();
|
||||
let test_internal_func: Symbol = Symbol {
|
||||
name: String::from("test_func_in"),
|
||||
conditional_branches: false,
|
||||
args: Args::Strict(vec![Type::Bool]),
|
||||
value: ValueType::Internal(Box::new(
|
||||
|a: &Seg, _: &mut SymTable| -> Ctr {
|
||||
let inner = a;
|
||||
let mut is_bool = false;
|
||||
if let Ctr::Bool(_) = *inner.car {
|
||||
is_bool = true;
|
||||
}
|
||||
Ctr::Bool(is_bool)
|
||||
},
|
||||
)),
|
||||
};
|
||||
let args = Seg::from(
|
||||
Box::new(Ctr::Symbol("undefined-symbol".to_string())),
|
||||
Box::new(Ctr::None)
|
||||
);
|
||||
|
||||
syms.insert(String::from("test_func_in"), test_internal_func);
|
||||
|
||||
if let Err(s) = syms.call_symbol(&"test_func_in".to_string(), &args, true) {
|
||||
assert_eq!(s, "failure to call echo: expected 1 args. Got 2.");
|
||||
} else {
|
||||
print!("call to function succeeded (shouldnt have)");
|
||||
assert!(false);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn bad_eval_fn_body() {
|
||||
|
||||
}*/
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue