///|
/// Call argument evaluation helpers.
///|
fn eval_call_args(
args : Array[Expr],
locals : Array[(String, Value)],
globals : Array[(String, Value)],
builtins : Array[(String, Value)],
io : MockIO,
) -> Result[(Array[Value], Array[(String, Value)]), RuntimeError] {
let positional : Array[Value] = []
let keywords : Array[(String, Value)] = []
for arg in args {
match arg {
Expr::Starred(value~) => {
let iter_value = match
eval_expr_with_env(value, locals, globals, builtins, io) {
Ok(v) => v
Err(err) => return Err(err)
}
let items = match iterable_values(iter_value) {
Ok(v) => v
Err(err) => return Err(err)
}
for item in items {
positional.push(item)
}
}
Expr::DoubleStarred(value~) => {
let mapping = match
eval_expr_with_env(value, locals, globals, builtins, io) {
Ok(v) => v
Err(err) => return Err(err)
}
match mapping {
Value::Dict(pairs) =>
for pair in pairs {
match pair.0 {
Value::Str(name) => keywords.push((name, pair.1))
_ =>
return Err(
make_runtime_error(
RuntimeErrorKind::Type,
"keywords must be strings".to_string(),
),
)
}
}
_ =>
return Err(
make_runtime_error(
RuntimeErrorKind::Type,
"keywords must be strings".to_string(),
),
)
}
}
Expr::Keyword(name~, value~) => {
let eval_value = match
eval_expr_with_env(value, locals, globals, builtins, io) {
Ok(v) => v
Err(err) => return Err(err)
}
keywords.push((name, eval_value))
}
_ => {
let eval_value = match
eval_expr_with_env(arg, locals, globals, builtins, io) {
Ok(v) => v
Err(err) => return Err(err)
}
positional.push(eval_value)
}
}
}
Ok((positional, keywords))
}