use std::sync::{Arc, Mutex};
use mumu::parser::interpreter::{Interpreter, DynamicFnInfo};
use mumu::parser::types::{Value, FunctionValue};
use crate::common::{is_placeholder, once_transform};
pub fn register_flow_of(interp: &mut Interpreter) {
let f = Arc::new(Mutex::new(flow_of_bridge));
let info = DynamicFnInfo::new(f, true);
interp.register_dynamic_function_ex("flow:of", info);
interp.set_variable(
"flow:of",
Value::Function(Box::new(FunctionValue::Named("flow:of".to_string())))
);
}
fn flow_of_bridge(_interp: &mut Interpreter, args: Vec<Value>) -> Result<Value, String> {
match args.len() {
0 => Ok(make_partial(None)),
1 => {
let a = &args[0];
if is_placeholder(a) {
Ok(make_partial(None))
} else {
Ok(Value::Function(once_transform(a.clone())))
}
}
n => Err(format!("flow:of => expected 0 or 1 argument, got {}", n)),
}
}
fn make_partial(val_opt: Option<Value>) -> Value {
use mumu::parser::types::FunctionValue::RustClosure;
Value::Function(Box::new(RustClosure(
"flow:of-partial".to_string(),
Arc::new(Mutex::new(move |_interp: &mut Interpreter, new_args: Vec<Value>| {
let mut v = val_opt.clone();
for a in new_args {
if v.is_none() {
if is_placeholder(&a) {
} else {
v = Some(a);
}
continue;
}
return Err("flow:of => partial => too many arguments".to_string());
}
if let Some(x) = v.clone() {
Ok(Value::Function(once_transform(x)))
} else {
Ok(make_partial(v))
}
})),
0,
)))
}