Skip to content

Commit

Permalink
Update SketchGroup when calling lineTo (#1713)
Browse files Browse the repository at this point in the history
* Update SketchGroup when calling lineTo

* Verify the next free address after the partial cube unit test
  • Loading branch information
adamchalmers committed Mar 13, 2024
1 parent 5d7d15a commit 17b7c68
Show file tree
Hide file tree
Showing 8 changed files with 300 additions and 86 deletions.
14 changes: 7 additions & 7 deletions src/wasm-lib/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions src/wasm-lib/grackle/src/binding_scope.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ pub enum EpBinding {
},
/// Not associated with a KCEP address.
Function(KclFunction),
/// SketchGroups have their own storage.
SketchGroup { index: usize },
}

impl From<KclFunction> for EpBinding {
Expand All @@ -47,13 +49,15 @@ impl EpBinding {
.ok_or(CompileError::IndexOutOfBounds { i, len: elements.len() })
}
EpBinding::Map { .. } => Err(CompileError::CannotIndex),
EpBinding::SketchGroup { .. } => Err(CompileError::CannotIndex),
EpBinding::Single(_) => Err(CompileError::CannotIndex),
EpBinding::Function(_) => Err(CompileError::CannotIndex),
},
// Objects can be indexed by string properties.
LiteralValue::String(property) => match self {
EpBinding::Single(_) => Err(CompileError::NoProperties),
EpBinding::Function(_) => Err(CompileError::NoProperties),
EpBinding::SketchGroup { .. } => Err(CompileError::NoProperties),
EpBinding::Sequence { .. } => Err(CompileError::ArrayDoesNotHaveProperties),
EpBinding::Map {
properties,
Expand Down
26 changes: 23 additions & 3 deletions src/wasm-lib/grackle/src/error.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use kcl_lib::ast::types::RequiredParamAfterOptionalParam;
use kittycad_execution_plan::ExecutionError;
use kittycad_execution_plan::{ExecutionError, ExecutionFailed, Instruction};

use crate::String2;

Expand Down Expand Up @@ -58,6 +58,26 @@ pub enum CompileError {
pub enum Error {
#[error("{0}")]
Compile(#[from] CompileError),
#[error("{0}")]
Execution(#[from] ExecutionError),
#[error("Failed on instruction {instruction_index}:\n{error}\n\nInstruction contents were {instruction:#?}")]
Execution {
error: ExecutionError,
instruction: Instruction,
instruction_index: usize,
},
}

impl From<ExecutionFailed> for Error {
fn from(
ExecutionFailed {
error,
instruction,
instruction_index,
}: ExecutionFailed,
) -> Self {
Self::Execution {
error,
instruction,
instruction_index,
}
}
}
18 changes: 13 additions & 5 deletions src/wasm-lib/grackle/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,18 +33,22 @@ pub async fn execute(ast: Program, session: Option<Session>) -> Result<ep::Memor
}

/// Compiles KCL programs into Execution Plans.
#[derive(Debug)]
struct Planner {
/// Maps KCL identifiers to what they hold, and where in KCEP virtual memory they'll be written to.
binding_scope: BindingScope,
/// Next available KCEP virtual machine memory address.
/// Next available KCVM virtual machine memory address.
next_addr: Address,
/// Next available KCVM sketch group index.
next_sketch_group: usize,
}

impl Planner {
pub fn new() -> Self {
Self {
binding_scope: BindingScope::prelude(),
next_addr: Address::ZERO,
next_sketch_group: 0,
}
}

Expand Down Expand Up @@ -246,14 +250,18 @@ impl Planner {

// Emit instructions to call that function with the given arguments.
use native_functions::Callable;
let mut ctx = native_functions::Context {
next_address: &mut self.next_addr,
next_sketch_group: &mut self.next_sketch_group,
};
let EvalPlan {
instructions: eval_instrs,
binding,
} = match callee {
KclFunction::Id(f) => f.call(&mut self.next_addr, args)?,
KclFunction::StartSketchAt(f) => f.call(&mut self.next_addr, args)?,
KclFunction::LineTo(f) => f.call(&mut self.next_addr, args)?,
KclFunction::Add(f) => f.call(&mut self.next_addr, args)?,
KclFunction::Id(f) => f.call(&mut ctx, args)?,
KclFunction::StartSketchAt(f) => f.call(&mut ctx, args)?,
KclFunction::LineTo(f) => f.call(&mut ctx, args)?,
KclFunction::Add(f) => f.call(&mut ctx, args)?,
KclFunction::UserDefined(f) => {
let UserDefinedFunction {
params_optional,
Expand Down
22 changes: 18 additions & 4 deletions src/wasm-lib/grackle/src/native_functions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,25 @@ pub mod sketch;
pub struct Id;

pub trait Callable {
fn call(&self, next_addr: &mut Address, args: Vec<EpBinding>) -> Result<EvalPlan, CompileError>;
fn call(&self, ctx: &mut Context<'_>, args: Vec<EpBinding>) -> Result<EvalPlan, CompileError>;
}

#[derive(Debug)]
pub struct Context<'a> {
pub next_address: &'a mut Address,
pub next_sketch_group: &'a mut usize,
}

impl<'a> Context<'a> {
pub fn assign_sketch_group(&mut self) -> usize {
let out = *self.next_sketch_group;
*self.next_sketch_group += 1;
out
}
}

impl Callable for Id {
fn call(&self, _: &mut Address, args: Vec<EpBinding>) -> Result<EvalPlan, CompileError> {
fn call(&self, _: &mut Context<'_>, args: Vec<EpBinding>) -> Result<EvalPlan, CompileError> {
if args.len() > 1 {
return Err(CompileError::TooManyArgs {
fn_name: "id".into(),
Expand Down Expand Up @@ -48,7 +62,7 @@ impl Callable for Id {
pub struct Add;

impl Callable for Add {
fn call(&self, next_address: &mut Address, mut args: Vec<EpBinding>) -> Result<EvalPlan, CompileError> {
fn call(&self, ctx: &mut Context<'_>, mut args: Vec<EpBinding>) -> Result<EvalPlan, CompileError> {
let len = args.len();
if len > 2 {
return Err(CompileError::TooManyArgs {
Expand All @@ -69,7 +83,7 @@ impl Callable for Add {
let EpBinding::Single(arg0) = args.pop().ok_or(not_enough_args)? else {
return Err(CompileError::InvalidOperand(ERR));
};
let destination = next_address.offset_by(1);
let destination = ctx.next_address.offset_by(1);
Ok(EvalPlan {
instructions: vec![Instruction::BinaryArithmetic {
arithmetic: BinaryArithmetic {
Expand Down
51 changes: 49 additions & 2 deletions src/wasm-lib/grackle/src/native_functions/sketch/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,40 @@ pub fn stack_api_call<const N: usize>(
}))
}

pub fn sg_binding(
b: EpBinding,
fn_name: &'static str,
expected: &'static str,
arg_number: usize,
) -> Result<usize, CompileError> {
match b {
EpBinding::SketchGroup { index } => Ok(index),
EpBinding::Single(_) => Err(CompileError::ArgWrongType {
fn_name,
expected,
actual: "single".to_owned(),
arg_number,
}),
EpBinding::Sequence { .. } => Err(CompileError::ArgWrongType {
fn_name,
expected,
actual: "array".to_owned(),
arg_number,
}),
EpBinding::Map { .. } => Err(CompileError::ArgWrongType {
fn_name,
expected,
actual: "object".to_owned(),
arg_number,
}),
EpBinding::Function(_) => Err(CompileError::ArgWrongType {
fn_name,
expected,
actual: "function".to_owned(),
arg_number,
}),
}
}
pub fn single_binding(
b: EpBinding,
fn_name: &'static str,
Expand All @@ -43,6 +77,12 @@ pub fn single_binding(
) -> Result<Address, CompileError> {
match b {
EpBinding::Single(a) => Ok(a),
EpBinding::SketchGroup { .. } => Err(CompileError::ArgWrongType {
fn_name,
expected,
actual: "SketchGroup".to_owned(),
arg_number,
}),
EpBinding::Sequence { .. } => Err(CompileError::ArgWrongType {
fn_name,
expected,
Expand Down Expand Up @@ -78,6 +118,12 @@ pub fn sequence_binding(
actual: "single".to_owned(),
arg_number,
}),
EpBinding::SketchGroup { .. } => Err(CompileError::ArgWrongType {
fn_name,
expected,
actual: "SketchGroup".to_owned(),
arg_number,
}),
EpBinding::Map { .. } => Err(CompileError::ArgWrongType {
fn_name,
expected,
Expand All @@ -98,7 +144,7 @@ pub fn arg_point2d(
arg: EpBinding,
fn_name: &'static str,
instructions: &mut Vec<Instruction>,
next_addr: &mut Address,
ctx: &mut crate::native_functions::Context<'_>,
arg_number: usize,
) -> Result<Address, CompileError> {
let expected = "2D point (array with length 2)";
Expand All @@ -113,7 +159,7 @@ pub fn arg_point2d(
}
// KCL stores points as an array.
// KC API stores them as Rust objects laid flat out in memory.
let start = next_addr.offset_by(2);
let start = ctx.next_address.offset_by(2);
let start_x = start;
let start_y = start + 1;
let start_z = start + 2;
Expand All @@ -133,5 +179,6 @@ pub fn arg_point2d(
value: 0.0.into(),
},
]);
ctx.next_address.offset_by(1); // After we pushed 0.0 here, just above.
Ok(start)
}
Loading

0 comments on commit 17b7c68

Please sign in to comment.