Grackle: unary operations (#1308)
Support compiling logical not and sign-flipping negation.
This commit is contained in:
10
src/wasm-lib/Cargo.lock
generated
10
src/wasm-lib/Cargo.lock
generated
@ -1943,7 +1943,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "kittycad-execution-plan"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/KittyCAD/modeling-api?branch=main#9200b9540fa5ae99b692db276c625223116f467f"
|
||||
source = "git+https://github.com/KittyCAD/modeling-api?branch=main#935256e4a7080ea130b09b578e16820dc96e78e4"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"insta",
|
||||
@ -1972,7 +1972,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "kittycad-execution-plan-macros"
|
||||
version = "0.1.2"
|
||||
source = "git+https://github.com/KittyCAD/modeling-api?branch=main#9200b9540fa5ae99b692db276c625223116f467f"
|
||||
source = "git+https://github.com/KittyCAD/modeling-api?branch=main#935256e4a7080ea130b09b578e16820dc96e78e4"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@ -1992,8 +1992,8 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "kittycad-modeling-cmds"
|
||||
version = "0.1.11"
|
||||
source = "git+https://github.com/KittyCAD/modeling-api?branch=main#9200b9540fa5ae99b692db276c625223116f467f"
|
||||
version = "0.1.12"
|
||||
source = "git+https://github.com/KittyCAD/modeling-api?branch=main#935256e4a7080ea130b09b578e16820dc96e78e4"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"chrono",
|
||||
@ -2020,7 +2020,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "kittycad-modeling-session"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/KittyCAD/modeling-api?branch=main#9200b9540fa5ae99b692db276c625223116f467f"
|
||||
source = "git+https://github.com/KittyCAD/modeling-api?branch=main#935256e4a7080ea130b09b578e16820dc96e78e4"
|
||||
dependencies = [
|
||||
"futures",
|
||||
"kittycad",
|
||||
|
||||
@ -133,6 +133,30 @@ impl Planner {
|
||||
binding: previously_bound_to.clone(),
|
||||
})
|
||||
}
|
||||
SingleValue::UnaryExpression(expr) => {
|
||||
let operand = self.plan_to_compute_single(SingleValue::from(expr.argument))?;
|
||||
let EpBinding::Single(binding) = operand.binding else {
|
||||
return Err(CompileError::InvalidOperand(
|
||||
"you tried to use a composite value (e.g. array or object) as the operand to some math",
|
||||
));
|
||||
};
|
||||
let destination = self.next_addr.offset_by(1);
|
||||
let mut plan = operand.instructions;
|
||||
plan.push(Instruction::UnaryArithmetic {
|
||||
arithmetic: ep::UnaryArithmetic {
|
||||
operation: match expr.operator {
|
||||
ast::types::UnaryOperator::Neg => ep::UnaryOperation::Neg,
|
||||
ast::types::UnaryOperator::Not => ep::UnaryOperation::Not,
|
||||
},
|
||||
operand: ep::Operand::Reference(binding),
|
||||
},
|
||||
destination,
|
||||
});
|
||||
Ok(EvalPlan {
|
||||
instructions: plan,
|
||||
binding: EpBinding::Single(destination),
|
||||
})
|
||||
}
|
||||
SingleValue::BinaryExpression(expr) => {
|
||||
let l = self.plan_to_compute_single(SingleValue::from(expr.left))?;
|
||||
let r = self.plan_to_compute_single(SingleValue::from(expr.right))?;
|
||||
@ -150,13 +174,13 @@ impl Planner {
|
||||
let mut plan = Vec::with_capacity(l.instructions.len() + r.instructions.len() + 1);
|
||||
plan.extend(l.instructions);
|
||||
plan.extend(r.instructions);
|
||||
plan.push(Instruction::Arithmetic {
|
||||
arithmetic: ep::Arithmetic {
|
||||
plan.push(Instruction::BinaryArithmetic {
|
||||
arithmetic: ep::BinaryArithmetic {
|
||||
operation: match expr.operator {
|
||||
ast::types::BinaryOperator::Add => ep::Operation::Add,
|
||||
ast::types::BinaryOperator::Sub => ep::Operation::Sub,
|
||||
ast::types::BinaryOperator::Mul => ep::Operation::Mul,
|
||||
ast::types::BinaryOperator::Div => ep::Operation::Div,
|
||||
ast::types::BinaryOperator::Add => ep::BinaryOperation::Add,
|
||||
ast::types::BinaryOperator::Sub => ep::BinaryOperation::Sub,
|
||||
ast::types::BinaryOperator::Mul => ep::BinaryOperation::Mul,
|
||||
ast::types::BinaryOperator::Div => ep::BinaryOperation::Div,
|
||||
ast::types::BinaryOperator::Mod => {
|
||||
todo!("execution plan instruction set doesn't support Mod yet")
|
||||
}
|
||||
@ -300,7 +324,6 @@ impl Planner {
|
||||
})
|
||||
}
|
||||
SingleValue::PipeExpression(_) => todo!(),
|
||||
SingleValue::UnaryExpression(_) => todo!(),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
//! But some other stdlib functions will be written in KCL.
|
||||
|
||||
use kcl_lib::std::sketch::PlaneData;
|
||||
use kittycad_execution_plan::{Address, Arithmetic, Instruction};
|
||||
use kittycad_execution_plan::{Address, BinaryArithmetic, Instruction};
|
||||
use kittycad_execution_plan_traits::Value;
|
||||
|
||||
use crate::{CompileError, EpBinding, EvalPlan};
|
||||
@ -98,9 +98,9 @@ impl Callable for Add {
|
||||
};
|
||||
let destination = next_address.offset_by(1);
|
||||
Ok(EvalPlan {
|
||||
instructions: vec![Instruction::Arithmetic {
|
||||
arithmetic: Arithmetic {
|
||||
operation: kittycad_execution_plan::Operation::Add,
|
||||
instructions: vec![Instruction::BinaryArithmetic {
|
||||
arithmetic: BinaryArithmetic {
|
||||
operation: kittycad_execution_plan::BinaryOperation::Add,
|
||||
operand0: kittycad_execution_plan::Operand::Reference(arg0),
|
||||
operand1: kittycad_execution_plan::Operand::Reference(arg1),
|
||||
},
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
use ep::UnaryArithmetic;
|
||||
use pretty_assertions::assert_eq;
|
||||
|
||||
use super::*;
|
||||
@ -157,9 +158,9 @@ fn use_native_function_add() {
|
||||
address: Address::ZERO.offset(1),
|
||||
value: 2i64.into()
|
||||
},
|
||||
Instruction::Arithmetic {
|
||||
arithmetic: ep::Arithmetic {
|
||||
operation: ep::Operation::Add,
|
||||
Instruction::BinaryArithmetic {
|
||||
arithmetic: ep::BinaryArithmetic {
|
||||
operation: ep::BinaryOperation::Add,
|
||||
operand0: ep::Operand::Reference(Address::ZERO),
|
||||
operand1: ep::Operand::Reference(Address::ZERO.offset(1))
|
||||
},
|
||||
@ -263,6 +264,27 @@ fn member_expressions_array() {
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn compile_flipped_sign() {
|
||||
let program = "let x = 3
|
||||
let y = -x";
|
||||
let (plan, _scope) = must_plan(program);
|
||||
let expected = vec![
|
||||
Instruction::SetPrimitive {
|
||||
address: Address::ZERO,
|
||||
value: 3i64.into(),
|
||||
},
|
||||
Instruction::UnaryArithmetic {
|
||||
arithmetic: UnaryArithmetic {
|
||||
operation: ep::UnaryOperation::Neg,
|
||||
operand: ep::Operand::Reference(Address::ZERO),
|
||||
},
|
||||
destination: Address::ZERO + 1,
|
||||
},
|
||||
];
|
||||
assert_eq!(plan, expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn add_literals() {
|
||||
let program = "let x = 1 + 2";
|
||||
@ -278,9 +300,9 @@ fn add_literals() {
|
||||
address: Address::ZERO.offset(1),
|
||||
value: 2i64.into()
|
||||
},
|
||||
Instruction::Arithmetic {
|
||||
arithmetic: ep::Arithmetic {
|
||||
operation: ep::Operation::Add,
|
||||
Instruction::BinaryArithmetic {
|
||||
arithmetic: ep::BinaryArithmetic {
|
||||
operation: ep::BinaryOperation::Add,
|
||||
operand0: ep::Operand::Reference(Address::ZERO),
|
||||
operand1: ep::Operand::Reference(Address::ZERO.offset(1)),
|
||||
},
|
||||
@ -310,9 +332,9 @@ fn add_vars() {
|
||||
address: addr1,
|
||||
value: 2i64.into(),
|
||||
},
|
||||
Instruction::Arithmetic {
|
||||
arithmetic: ep::Arithmetic {
|
||||
operation: ep::Operation::Add,
|
||||
Instruction::BinaryArithmetic {
|
||||
arithmetic: ep::BinaryArithmetic {
|
||||
operation: ep::BinaryOperation::Add,
|
||||
operand0: ep::Operand::Reference(addr0),
|
||||
operand1: ep::Operand::Reference(addr1),
|
||||
},
|
||||
@ -351,18 +373,18 @@ fn composite_binary_exprs() {
|
||||
value: 3i64.into(),
|
||||
},
|
||||
// Adds 1 + 2
|
||||
Instruction::Arithmetic {
|
||||
arithmetic: ep::Arithmetic {
|
||||
operation: ep::Operation::Add,
|
||||
Instruction::BinaryArithmetic {
|
||||
arithmetic: ep::BinaryArithmetic {
|
||||
operation: ep::BinaryOperation::Add,
|
||||
operand0: ep::Operand::Reference(addr0),
|
||||
operand1: ep::Operand::Reference(addr1),
|
||||
},
|
||||
destination: addr3,
|
||||
},
|
||||
// Adds `x` + 3, where `x` is (1 + 2)
|
||||
Instruction::Arithmetic {
|
||||
arithmetic: ep::Arithmetic {
|
||||
operation: ep::Operation::Add,
|
||||
Instruction::BinaryArithmetic {
|
||||
arithmetic: ep::BinaryArithmetic {
|
||||
operation: ep::BinaryOperation::Add,
|
||||
operand0: ep::Operand::Reference(addr3),
|
||||
operand1: ep::Operand::Reference(addr2),
|
||||
},
|
||||
@ -419,9 +441,9 @@ fn use_kcl_functions_with_optional_params() {
|
||||
address: Address::ZERO + 2,
|
||||
value: 3i64.into(),
|
||||
},
|
||||
Instruction::Arithmetic {
|
||||
arithmetic: ep::Arithmetic {
|
||||
operation: ep::Operation::Mul,
|
||||
Instruction::BinaryArithmetic {
|
||||
arithmetic: ep::BinaryArithmetic {
|
||||
operation: ep::BinaryOperation::Mul,
|
||||
operand0: ep::Operand::Reference(Address::ZERO),
|
||||
operand1: ep::Operand::Reference(Address::ZERO + 2)
|
||||
},
|
||||
@ -540,9 +562,9 @@ fn use_kcl_functions_with_params() {
|
||||
address: Address::ZERO + 1,
|
||||
value: 3i64.into(),
|
||||
},
|
||||
Instruction::Arithmetic {
|
||||
arithmetic: ep::Arithmetic {
|
||||
operation: ep::Operation::Mul,
|
||||
Instruction::BinaryArithmetic {
|
||||
arithmetic: ep::BinaryArithmetic {
|
||||
operation: ep::BinaryOperation::Mul,
|
||||
operand0: ep::Operand::Reference(Address::ZERO),
|
||||
operand1: ep::Operand::Reference(Address::ZERO.offset(1))
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user