Grackle: Allow objects to be params into arrays (#1322)

This commit is contained in:
Adam Chalmers
2024-01-25 11:05:41 +11:00
committed by GitHub
parent 18ffc43e89
commit 09760fc2e9
2 changed files with 82 additions and 59 deletions

View File

@ -232,7 +232,7 @@ impl Planner {
} = match KclValueGroup::from(argument) {
KclValueGroup::Single(value) => self.plan_to_compute_single(ctx, value)?,
KclValueGroup::ArrayExpression(expr) => self.plan_to_bind_array(ctx, *expr)?,
KclValueGroup::ObjectExpression(_) => todo!(),
KclValueGroup::ObjectExpression(expr) => self.plan_to_bind_object(ctx, *expr)?,
};
acc_instrs.extend(new_instructions);
acc_args.push(arg);
@ -430,7 +430,15 @@ impl Planner {
self.plan_to_compute_single(ctx, init_value)
}
KclValueGroup::ArrayExpression(expr) => self.plan_to_bind_array(ctx, *expr),
KclValueGroup::ObjectExpression(expr) => {
KclValueGroup::ObjectExpression(expr) => self.plan_to_bind_object(ctx, *expr),
}
}
fn plan_to_bind_object(
&mut self,
ctx: &mut Context,
expr: ast::types::ObjectExpression,
) -> Result<EvalPlan, CompileError> {
// Convert the object to a sequence of key-value pairs.
let mut kvs = expr.properties.into_iter().map(|prop| (prop.key, prop.value));
let (instructions, each_property_binding) = kvs.try_fold(
@ -451,8 +459,7 @@ impl Planner {
.elements
.into_iter()
.try_fold(Vec::with_capacity(n), |mut seq, child_element| {
let EvalPlan { instructions, binding } =
self.plan_to_bind_one(ctx, child_element)?;
let EvalPlan { instructions, binding } = self.plan_to_bind_one(ctx, child_element)?;
seq.push(binding);
acc_instrs.extend(instructions);
Ok(seq)
@ -470,8 +477,7 @@ impl Planner {
.properties
.into_iter()
.try_fold(HashMap::with_capacity(n), |mut map, property| {
let EvalPlan { instructions, binding } =
self.plan_to_bind_one(ctx, property.value)?;
let EvalPlan { instructions, binding } = self.plan_to_bind_one(ctx, property.value)?;
map.insert(property.key.name, binding);
acc_instrs.extend(instructions);
Ok(map)
@ -488,8 +494,6 @@ impl Planner {
binding: EpBinding::Map(each_property_binding),
})
}
}
}
fn plan_to_bind_array(
&mut self,

View File

@ -744,6 +744,25 @@ fn stdlib_api_calls() {
must_plan(program);
}
#[test]
fn objects_as_parameters() {
let program = "fn identity = (x) => { return x }
let obj = identity({x: 1})";
let (plan, scope) = must_plan(program);
let expected_plan = vec![
// Object contents
Instruction::SetPrimitive {
address: Address::ZERO,
value: 1i64.into(),
},
];
assert_eq!(plan, expected_plan);
assert_eq!(
scope.get("obj").unwrap(),
&EpBinding::Map(HashMap::from([("x".to_owned(), EpBinding::Single(Address::ZERO)),]))
)
}
#[test]
fn arrays_as_parameters() {
let program = "fn identity = (x) => { return x }