mirror of
https://github.com/storytold/gridcraft.git
synced 2026-10-28 12:46:48 -06:00
Return #VALUE! when a LAMBDA call has too few argument positions (#557)
This commit is contained in:
@@ -860,7 +860,12 @@ impl<'h> Evaluator<'h> {
|
||||
}
|
||||
|
||||
pub fn apply_lambda(&mut self, l: &Lambda, args: &[Expr]) -> Ev {
|
||||
if args.len() > l.params.len() {
|
||||
// Too many or too few argument positions is #VALUE!. An explicitly empty position, as in
|
||||
// `(1,)`, is `Expr::Missing` and still counts as a position (it binds as omitted). `f()`
|
||||
// parses to no arguments, which for a one-parameter lambda can also be read as one empty
|
||||
// position, so that call still binds the parameter as omitted.
|
||||
let positions_ok = args.len() == l.params.len() || (args.is_empty() && l.params.len() == 1);
|
||||
if !positions_ok {
|
||||
return err(CellError::Value);
|
||||
}
|
||||
let mut bound = Vec::with_capacity(l.params.len());
|
||||
|
||||
@@ -501,6 +501,38 @@ fn let_lambda() {
|
||||
assert_eq!(t.num("A4"), 14.0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn lambda_argument_count() {
|
||||
let mut t = T::new();
|
||||
t.wb.names.push(gridcraft_model::DefinedName {
|
||||
name: "AddPair".into(),
|
||||
scope: None,
|
||||
formula: "LAMBDA(a,b,a+b)".into(),
|
||||
comment: String::new(),
|
||||
hidden: false,
|
||||
});
|
||||
t.calc.rebuild(&t.wb);
|
||||
let omit = "LAMBDA(x,y,IF(ISOMITTED(y),\"Missing\",x+y))";
|
||||
t.set("A1", "=LAMBDA(a,b,a+b)(2)");
|
||||
t.set("A2", "=LAMBDA(a,b,a+b)(2,3,4)");
|
||||
t.set("A3", &format!("={omit}(1,)"));
|
||||
t.set("A4", &format!("={omit}(1)"));
|
||||
t.set("A5", &format!("={omit}(1,2)"));
|
||||
t.set("A6", "=LAMBDA(7)()");
|
||||
t.set("A7", "=AddPair(2)");
|
||||
t.set("A8", "=AddPair(2,3)");
|
||||
assert_eq!(t.get("A1"), Value::Error(CellError::Value));
|
||||
assert_eq!(t.get("A2"), Value::Error(CellError::Value));
|
||||
assert_eq!(t.get("A3"), Value::Text("Missing".into()));
|
||||
assert_eq!(t.get("A4"), Value::Error(CellError::Value));
|
||||
assert_eq!(t.num("A5"), 3.0);
|
||||
assert_eq!(t.num("A6"), 7.0);
|
||||
assert_eq!(t.get("A7"), Value::Error(CellError::Value));
|
||||
assert_eq!(t.num("A8"), 5.0);
|
||||
t.set("A9", "=LAMBDA(x,ISOMITTED(x))()");
|
||||
assert_eq!(t.get("A9"), Value::Bool(true));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn names_and_sheets() {
|
||||
let mut t = T::new();
|
||||
|
||||
Reference in New Issue
Block a user