feat: EvalState.call
(cherry picked from commit f3aa6e523c0c5214533d0005d8c3f85a0579b1de)
This commit is contained in:
parent
fbbc7cb490
commit
52778c37e9
1 changed files with 76 additions and 0 deletions
|
|
@ -192,6 +192,23 @@ impl EvalState {
|
|||
Ok(RealisedString { s, paths })
|
||||
}
|
||||
|
||||
/// Eagerly apply a function to an argument.
|
||||
pub fn call(&self, f: Value, a: Value) -> Result<Value> {
|
||||
let v = unsafe {
|
||||
let value = self.new_value_uninitialized();
|
||||
raw::value_call(
|
||||
self.context.ptr(),
|
||||
self.raw_ptr(),
|
||||
f.raw_ptr(),
|
||||
a.raw_ptr(),
|
||||
value.raw_ptr(),
|
||||
);
|
||||
value
|
||||
};
|
||||
self.context.check_err()?;
|
||||
Ok(v)
|
||||
}
|
||||
|
||||
fn new_value_uninitialized(&self) -> Value {
|
||||
let value = unsafe { raw::alloc_value(self.context.ptr(), self.raw_ptr()) };
|
||||
Value::new(value)
|
||||
|
|
@ -490,4 +507,63 @@ mod tests {
|
|||
})
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn eval_state_call() {
|
||||
gc_registering_current_thread(|| {
|
||||
let store = Store::open("auto").unwrap();
|
||||
let es = EvalState::new(store).unwrap();
|
||||
let f = es.eval_from_string("x: x + 1", "<test>").unwrap();
|
||||
let a = es.eval_from_string("2", "<test>").unwrap();
|
||||
let v = es.call(f, a).unwrap();
|
||||
es.force(&v).unwrap();
|
||||
let t = es.value_type(&v).unwrap();
|
||||
assert!(t == ValueType::Int);
|
||||
let i = es.require_int(&v).unwrap();
|
||||
assert!(i == 3);
|
||||
})
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn eval_state_call_fail_body() {
|
||||
gc_registering_current_thread(|| {
|
||||
let store = Store::open("auto").unwrap();
|
||||
let es = EvalState::new(store).unwrap();
|
||||
let f = es.eval_from_string("x: x + 1", "<test>").unwrap();
|
||||
let a = es.eval_from_string("true", "<test>").unwrap();
|
||||
let r = es.call(f, a);
|
||||
match r {
|
||||
Ok(_) => panic!("expected an error"),
|
||||
Err(e) => {
|
||||
if !e.to_string().contains("cannot coerce") {
|
||||
eprintln!("{}", e);
|
||||
assert!(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn eval_state_call_fail_args() {
|
||||
gc_registering_current_thread(|| {
|
||||
let store = Store::open("auto").unwrap();
|
||||
let es = EvalState::new(store).unwrap();
|
||||
let f = es.eval_from_string("{x}: x + 1", "<test>").unwrap();
|
||||
let a = es.eval_from_string("{}", "<test>").unwrap();
|
||||
let r = es.call(f, a);
|
||||
match r {
|
||||
Ok(_) => panic!("expected an error"),
|
||||
Err(e) => {
|
||||
if !e.to_string().contains("called without required argument") {
|
||||
eprintln!("{}", e);
|
||||
assert!(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue