Merge branch 'main' into pierremtb/issue1349

This commit is contained in:
Pierre Jacquier
2024-03-29 05:56:23 -04:00
25 changed files with 1063 additions and 417 deletions

View File

@ -1,6 +1,6 @@
{
"name": "untitled-app",
"version": "0.17.0",
"version": "0.17.1",
"private": true,
"dependencies": {
"@codemirror/autocomplete": "^6.15.0",
@ -26,7 +26,7 @@
"@ts-stack/markdown": "^1.5.0",
"@tweenjs/tween.js": "^23.1.1",
"@types/node": "^18.19.26",
"@types/react": "^18.2.67",
"@types/react": "^18.2.73",
"@types/react-dom": "^18.2.22",
"@uiw/react-codemirror": "^4.21.24",
"@xstate/inspect": "^0.8.0",

View File

@ -55,5 +55,5 @@
}
},
"productName": "zoo-modeling-app",
"version": "0.17.0"
"version": "0.17.1"
}

View File

@ -251,9 +251,9 @@ dependencies = [
[[package]]
name = "async-trait"
version = "0.1.78"
version = "0.1.79"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "461abc97219de0eaaf81fe3ef974a540158f3d079c2ab200f891f1a2ef201e85"
checksum = "a507401cad91ec6a857ed5513a2073c82a9b9048762b885bb98655b306964681"
dependencies = [
"proc-macro2",
"quote",
@ -513,9 +513,9 @@ dependencies = [
[[package]]
name = "chrono"
version = "0.4.35"
version = "0.4.37"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8eaf5903dcbc0a39312feb77df2ff4c76387d591b9fc7b04a238dcf8bb62639a"
checksum = "8a0d04d43504c61aa6c7531f1871dd0d418d91130162063b789da00fd7057a5e"
dependencies = [
"android-tzdata",
"iana-time-zone",
@ -565,9 +565,9 @@ dependencies = [
[[package]]
name = "clap"
version = "4.5.3"
version = "4.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "949626d00e063efc93b6dca932419ceb5432f99769911c0b995f7e884c778813"
checksum = "90bc066a67923782aa8515dbaea16946c5bcc5addbd668bb80af688e53e548a0"
dependencies = [
"clap_builder",
"clap_derive",
@ -589,9 +589,9 @@ dependencies = [
[[package]]
name = "clap_derive"
version = "4.5.3"
version = "4.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90239a040c80f5e14809ca132ddc4176ab33d5e17e49691793296e3fcb34d72f"
checksum = "528131438037fd55894f62d6e9f068b8f45ac57ffa77517819645d10aed04f64"
dependencies = [
"heck 0.5.0",
"proc-macro2",
@ -944,6 +944,23 @@ dependencies = [
"syn 2.0.55",
]
[[package]]
name = "derive-docs"
version = "0.1.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "138b94245509a9dd516008788b585c34847829cf37b40a758b4aa581cf94f147"
dependencies = [
"Inflector",
"convert_case",
"once_cell",
"proc-macro2",
"quote",
"regex",
"serde",
"serde_tokenstream",
"syn 2.0.55",
]
[[package]]
name = "diesel_derives"
version = "2.1.3"
@ -1730,16 +1747,15 @@ dependencies = [
[[package]]
name = "insta"
version = "1.36.1"
version = "1.37.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0a7c22c4d34ef4788c351e971c52bfdfe7ea2766f8c5466bc175dd46e52ac22e"
checksum = "1718b3f2b85bb5054baf8ce406e36401f27c3169205f4175504c4b1d98252d3f"
dependencies = [
"console",
"lazy_static",
"linked-hash-map",
"serde",
"similar",
"yaml-rust",
]
[[package]]
@ -1843,7 +1859,7 @@ dependencies = [
[[package]]
name = "kcl-lib"
version = "0.1.46"
version = "0.1.47"
dependencies = [
"anyhow",
"approx 0.5.1",
@ -1857,7 +1873,7 @@ dependencies = [
"criterion",
"dashmap",
"databake",
"derive-docs",
"derive-docs 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
"expectorate",
"futures",
"gltf-json",
@ -1944,8 +1960,9 @@ dependencies = [
[[package]]
name = "kittycad-execution-plan"
version = "0.1.1"
source = "git+https://github.com/KittyCAD/modeling-api?branch=main#a3b8df282c684b3f7003ec96f5cea85284e0f1f9"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e913f8e5f3ef7928cddca2e7b53c6582d7be6a8f900d18ce6c31c04083056270"
dependencies = [
"bytes",
"gltf-json",
@ -1967,7 +1984,8 @@ dependencies = [
[[package]]
name = "kittycad-execution-plan-macros"
version = "0.1.9"
source = "git+https://github.com/KittyCAD/modeling-api?branch=main#a3b8df282c684b3f7003ec96f5cea85284e0f1f9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0611fc9b9786175da21d895ffa0f65039e19c9111e94a41b7af999e3b95f045f"
dependencies = [
"proc-macro2",
"quote",
@ -1977,7 +1995,8 @@ dependencies = [
[[package]]
name = "kittycad-execution-plan-traits"
version = "0.1.15"
source = "git+https://github.com/KittyCAD/modeling-api?branch=main#a3b8df282c684b3f7003ec96f5cea85284e0f1f9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "123cb47e2780ea8ef3aa67b4db237a27b388d3d3b96db457e274aa4565723151"
dependencies = [
"serde",
"thiserror",
@ -1986,8 +2005,9 @@ dependencies = [
[[package]]
name = "kittycad-modeling-cmds"
version = "0.2.7"
source = "git+https://github.com/KittyCAD/modeling-api?branch=main#a3b8df282c684b3f7003ec96f5cea85284e0f1f9"
version = "0.2.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b41beb7d9b776df93fd449604de5c447e33c7bd3326fd590002dc18cf5f08166"
dependencies = [
"anyhow",
"chrono",
@ -2015,7 +2035,8 @@ dependencies = [
[[package]]
name = "kittycad-modeling-cmds-macros"
version = "0.1.5"
source = "git+https://github.com/KittyCAD/modeling-api?branch=main#a3b8df282c684b3f7003ec96f5cea85284e0f1f9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "385775cc9d5bf25579f3029824ca1a6e7ab1b7c338e972ec8e8fcefff801f353"
dependencies = [
"proc-macro2",
"quote",
@ -2024,8 +2045,9 @@ dependencies = [
[[package]]
name = "kittycad-modeling-session"
version = "0.1.1"
source = "git+https://github.com/KittyCAD/modeling-api?branch=main#a3b8df282c684b3f7003ec96f5cea85284e0f1f9"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6ee3a24232a086ec12ae4cfee443485c22e6c6959936d861006fa13bebef0904"
dependencies = [
"futures",
"kittycad",
@ -3507,9 +3529,9 @@ dependencies = [
[[package]]
name = "serde_json"
version = "1.0.114"
version = "1.0.115"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c5f09b1bd632ef549eaa9f60a1f8de742bdbc698e6cee2095fc84dde5f549ae0"
checksum = "12dc5c46daa8e9fdf4f5e71b6cf9a53f2487da0e86e55808e2d35539666497dd"
dependencies = [
"indexmap 2.2.5",
"itoa",

View File

@ -14,7 +14,7 @@ bson = { version = "2.9.0", features = ["uuid-1", "chrono"] }
gloo-utils = "0.2.0"
kcl-lib = { path = "kcl" }
kittycad = { workspace = true }
serde_json = "1.0.114"
serde_json = "1.0.115"
uuid = { version = "1.8.0", features = ["v4", "js", "serde"] }
wasm-bindgen = "0.2.91"
wasm-bindgen-futures = "0.4.42"
@ -60,11 +60,11 @@ members = [
[workspace.dependencies]
kittycad = { version = "0.2.63", default-features = false, features = ["js", "requests"] }
kittycad-execution-plan = { git = "https://github.com/KittyCAD/modeling-api", branch = "main" }
kittycad-execution-plan-macros = { git = "https://github.com/KittyCAD/modeling-api", branch = "main" }
kittycad-execution-plan-traits = { git = "https://github.com/KittyCAD/modeling-api", branch = "main" }
kittycad-modeling-cmds = { git = "https://github.com/KittyCAD/modeling-api", branch = "main" }
kittycad-modeling-session = { git = "https://github.com/KittyCAD/modeling-api", branch = "main" }
kittycad-execution-plan = "0.1.3"
kittycad-execution-plan-macros = "0.1.9"
kittycad-execution-plan-traits = "0.1.14"
kittycad-modeling-cmds = "0.2.10"
kittycad-modeling-session = "0.1.2"
[[test]]
name = "executor"

View File

@ -21,4 +21,4 @@ uuid = "1.8"
[dev-dependencies]
pretty_assertions = "1"
serde_json = "1.0.114"
serde_json = "1.0.115"

View File

@ -1,7 +1,7 @@
[package]
name = "kcl-lib"
description = "KittyCAD Language implementation and tools"
version = "0.1.46"
version = "0.1.47"
edition = "2021"
license = "MIT"
repository = "https://github.com/KittyCAD/modeling-app"
@ -13,13 +13,13 @@ keywords = ["kcl", "KittyCAD", "CAD"]
[dependencies]
anyhow = { version = "1.0.81", features = ["backtrace"] }
async-recursion = "1.1.0"
async-trait = "0.1.78"
chrono = "0.4.35"
clap = { version = "4.5.3", features = ["cargo", "derive", "env", "unicode"], optional = true }
async-trait = "0.1.79"
chrono = "0.4.37"
clap = { version = "4.5.4", features = ["cargo", "derive", "env", "unicode"], optional = true }
dashmap = "5.5.3"
databake = { version = "0.1.7", features = ["derive"] }
#derive-docs = { version = "0.1.12" }
derive-docs = { path = "../derive-docs" }
derive-docs = { version = "0.1.12" }
#derive-docs = { path = "../derive-docs" }
futures = { version = "0.3.30" }
gltf-json = "1.4.0"
kittycad = { workspace = true }
@ -32,7 +32,7 @@ reqwest = { version = "0.11.26", default-features = false, features = ["stream",
ropey = "1.6.1"
schemars = { version = "0.8.16", features = ["impl_json_schema", "url", "uuid1"] }
serde = { version = "1.0.197", features = ["derive"] }
serde_json = "1.0.114"
serde_json = "1.0.115"
sha2 = "0.10.8"
thiserror = "1.0.58"
ts-rs = { version = "7.1.1", features = ["uuid-impl"] }
@ -72,7 +72,7 @@ convert_case = "0.6.0"
criterion = "0.5.1"
expectorate = "1.1.0"
image = "0.24.9"
insta = { version = "1.36.1", features = ["json"] }
insta = { version = "1.37.0", features = ["json"] }
itertools = "0.12.1"
pretty_assertions = "1.4.0"
tokio = { version = "1.36.0", features = ["rt-multi-thread", "macros", "time"] }

View File

@ -715,15 +715,9 @@ impl BinaryPart {
pub async fn get_result(
&self,
memory: &mut ProgramMemory,
pipe_info: &mut PipeInfo,
pipe_info: &PipeInfo,
ctx: &ExecutorContext,
) -> Result<MemoryItem, KclError> {
// We DO NOT set this globally because if we did and this was called inside a pipe it would
// stop the execution of the pipe.
// THIS IS IMPORTANT.
let mut new_pipe_info = pipe_info.clone();
new_pipe_info.is_in_pipe = false;
match self {
BinaryPart::Literal(literal) => Ok(literal.into()),
BinaryPart::Identifier(identifier) => {
@ -731,14 +725,10 @@ impl BinaryPart {
Ok(value.clone())
}
BinaryPart::BinaryExpression(binary_expression) => {
binary_expression.get_result(memory, &mut new_pipe_info, ctx).await
}
BinaryPart::CallExpression(call_expression) => {
call_expression.execute(memory, &mut new_pipe_info, ctx).await
}
BinaryPart::UnaryExpression(unary_expression) => {
unary_expression.get_result(memory, &mut new_pipe_info, ctx).await
binary_expression.get_result(memory, pipe_info, ctx).await
}
BinaryPart::CallExpression(call_expression) => call_expression.execute(memory, pipe_info, ctx).await,
BinaryPart::UnaryExpression(unary_expression) => unary_expression.get_result(memory, pipe_info, ctx).await,
BinaryPart::MemberExpression(member_expression) => member_expression.get_result(memory),
}
}
@ -1019,7 +1009,7 @@ impl CallExpression {
pub async fn execute(
&self,
memory: &mut ProgramMemory,
pipe_info: &mut PipeInfo,
pipe_info: &PipeInfo,
ctx: &ExecutorContext,
) -> Result<MemoryItem, KclError> {
let fn_name = self.callee.name.clone();
@ -1037,14 +1027,7 @@ impl CallExpression {
Value::BinaryExpression(binary_expression) => {
binary_expression.get_result(memory, pipe_info, ctx).await?
}
Value::CallExpression(call_expression) => {
// We DO NOT set this globally because if we did and this was called inside a pipe it would
// stop the execution of the pipe.
// THIS IS IMPORTANT.
let mut new_pipe_info = pipe_info.clone();
new_pipe_info.is_in_pipe = false;
call_expression.execute(memory, &mut new_pipe_info, ctx).await?
}
Value::CallExpression(call_expression) => call_expression.execute(memory, pipe_info, ctx).await?,
Value::UnaryExpression(unary_expression) => unary_expression.get_result(memory, pipe_info, ctx).await?,
Value::ObjectExpression(object_expression) => object_expression.execute(memory, pipe_info, ctx).await?,
Value::ArrayExpression(array_expression) => array_expression.execute(memory, pipe_info, ctx).await?,
@ -1056,7 +1039,7 @@ impl CallExpression {
}
Value::PipeSubstitution(pipe_substitution) => pipe_info
.previous_results
.get(&pipe_info.index - 1)
.as_ref()
.ok_or_else(|| {
KclError::Semantic(KclErrorDetails {
message: format!("PipeSubstitution index out of bounds: {:?}", pipe_info),
@ -1081,13 +1064,7 @@ impl CallExpression {
// Attempt to call the function.
let args = crate::std::Args::new(fn_args, self.into(), ctx.clone());
let result = func.std_lib_fn()(args).await?;
if pipe_info.is_in_pipe {
pipe_info.index += 1;
pipe_info.previous_results.push(result);
execute_pipe_body(memory, &pipe_info.body.clone(), pipe_info, self.into(), ctx).await
} else {
Ok(result)
}
Ok(result)
}
FunctionKind::Std(func) => {
let function_expression = func.function();
@ -1152,14 +1129,7 @@ impl CallExpression {
})?;
let result = result.get_value()?;
if pipe_info.is_in_pipe {
pipe_info.index += 1;
pipe_info.previous_results.push(result);
execute_pipe_body(memory, &pipe_info.body.clone(), pipe_info, self.into(), ctx).await
} else {
Ok(result)
}
Ok(result)
}
FunctionKind::UserDefined => {
let func = memory.get(&fn_name, self.into())?;
@ -1175,14 +1145,7 @@ impl CallExpression {
let result = result.get_value()?;
if pipe_info.is_in_pipe {
pipe_info.index += 1;
pipe_info.previous_results.push(result);
execute_pipe_body(memory, &pipe_info.body.clone(), pipe_info, self.into(), ctx).await
} else {
Ok(result)
}
Ok(result)
}
}
}
@ -1731,7 +1694,7 @@ impl ArrayExpression {
pub async fn execute(
&self,
memory: &mut ProgramMemory,
pipe_info: &mut PipeInfo,
pipe_info: &PipeInfo,
ctx: &ExecutorContext,
) -> Result<MemoryItem, KclError> {
let mut results = Vec::with_capacity(self.elements.len());
@ -1747,14 +1710,7 @@ impl ArrayExpression {
Value::BinaryExpression(binary_expression) => {
binary_expression.get_result(memory, pipe_info, ctx).await?
}
Value::CallExpression(call_expression) => {
// We DO NOT set this globally because if we did and this was called inside a pipe it would
// stop the execution of the pipe.
// THIS IS IMPORTANT.
let mut new_pipe_info = pipe_info.clone();
new_pipe_info.is_in_pipe = false;
call_expression.execute(memory, &mut new_pipe_info, ctx).await?
}
Value::CallExpression(call_expression) => call_expression.execute(memory, pipe_info, ctx).await?,
Value::UnaryExpression(unary_expression) => unary_expression.get_result(memory, pipe_info, ctx).await?,
Value::ObjectExpression(object_expression) => object_expression.execute(memory, pipe_info, ctx).await?,
Value::ArrayExpression(array_expression) => array_expression.execute(memory, pipe_info, ctx).await?,
@ -1885,7 +1841,7 @@ impl ObjectExpression {
pub async fn execute(
&self,
memory: &mut ProgramMemory,
pipe_info: &mut PipeInfo,
pipe_info: &PipeInfo,
ctx: &ExecutorContext,
) -> Result<MemoryItem, KclError> {
let mut object = Map::new();
@ -1900,14 +1856,7 @@ impl ObjectExpression {
Value::BinaryExpression(binary_expression) => {
binary_expression.get_result(memory, pipe_info, ctx).await?
}
Value::CallExpression(call_expression) => {
// We DO NOT set this globally because if we did and this was called inside a pipe it would
// stop the execution of the pipe.
// THIS IS IMPORTANT.
let mut new_pipe_info = pipe_info.clone();
new_pipe_info.is_in_pipe = false;
call_expression.execute(memory, &mut new_pipe_info, ctx).await?
}
Value::CallExpression(call_expression) => call_expression.execute(memory, pipe_info, ctx).await?,
Value::UnaryExpression(unary_expression) => unary_expression.get_result(memory, pipe_info, ctx).await?,
Value::ObjectExpression(object_expression) => object_expression.execute(memory, pipe_info, ctx).await?,
Value::ArrayExpression(array_expression) => array_expression.execute(memory, pipe_info, ctx).await?,
@ -2338,25 +2287,11 @@ impl BinaryExpression {
pub async fn get_result(
&self,
memory: &mut ProgramMemory,
pipe_info: &mut PipeInfo,
pipe_info: &PipeInfo,
ctx: &ExecutorContext,
) -> Result<MemoryItem, KclError> {
// We DO NOT set this globally because if we did and this was called inside a pipe it would
// stop the execution of the pipe.
// THIS IS IMPORTANT.
let mut new_pipe_info = pipe_info.clone();
new_pipe_info.is_in_pipe = false;
let left_json_value = self
.left
.get_result(memory, &mut new_pipe_info, ctx)
.await?
.get_json_value()?;
let right_json_value = self
.right
.get_result(memory, &mut new_pipe_info, ctx)
.await?
.get_json_value()?;
let left_json_value = self.left.get_result(memory, pipe_info, ctx).await?.get_json_value()?;
let right_json_value = self.right.get_result(memory, pipe_info, ctx).await?.get_json_value()?;
// First check if we are doing string concatenation.
if self.operator == BinaryOperator::Add {
@ -2542,19 +2477,13 @@ impl UnaryExpression {
pub async fn get_result(
&self,
memory: &mut ProgramMemory,
pipe_info: &mut PipeInfo,
pipe_info: &PipeInfo,
ctx: &ExecutorContext,
) -> Result<MemoryItem, KclError> {
// We DO NOT set this globally because if we did and this was called inside a pipe it would
// stop the execution of the pipe.
// THIS IS IMPORTANT.
let mut new_pipe_info = pipe_info.clone();
new_pipe_info.is_in_pipe = false;
let num = parse_json_number_as_f64(
&self
.argument
.get_result(memory, &mut new_pipe_info, ctx)
.get_result(memory, pipe_info, ctx)
.await?
.get_json_value()?,
self.into(),
@ -2606,6 +2535,8 @@ pub enum UnaryOperator {
pub struct PipeExpression {
pub start: usize,
pub end: usize,
// TODO: Only the first body expression can be any Value.
// The rest will be CallExpression, and the AST type should reflect this.
pub body: Vec<Value>,
pub non_code_meta: NonCodeMeta,
}
@ -2696,12 +2627,9 @@ impl PipeExpression {
pub async fn get_result(
&self,
memory: &mut ProgramMemory,
pipe_info: &mut PipeInfo,
pipe_info: &PipeInfo,
ctx: &ExecutorContext,
) -> Result<MemoryItem, KclError> {
// Reset the previous results.
pipe_info.previous_results = vec![];
pipe_info.index = 0;
execute_pipe_body(memory, &self.body, pipe_info, self.into(), ctx).await
}
@ -2717,57 +2645,59 @@ impl PipeExpression {
async fn execute_pipe_body(
memory: &mut ProgramMemory,
body: &[Value],
pipe_info: &mut PipeInfo,
pipe_info: &PipeInfo,
source_range: SourceRange,
ctx: &ExecutorContext,
) -> Result<MemoryItem, KclError> {
if pipe_info.index == body.len() {
pipe_info.is_in_pipe = false;
return Ok(pipe_info
.previous_results
.last()
.ok_or_else(|| {
KclError::Semantic(KclErrorDetails {
message: "Pipe body results should have at least one expression".to_string(),
source_ranges: vec![source_range],
})
})?
.clone());
}
let expression = body.get(pipe_info.index).ok_or_else(|| {
let mut body_iter = body.iter();
let first = body_iter.next().ok_or_else(|| {
KclError::Semantic(KclErrorDetails {
message: format!("Invalid index for pipe: {}", pipe_info.index),
message: "Pipe expressions cannot be empty".to_owned(),
source_ranges: vec![source_range],
})
})?;
match expression {
Value::BinaryExpression(binary_expression) => {
let result = binary_expression.get_result(memory, pipe_info, ctx).await?;
pipe_info.previous_results.push(result);
pipe_info.index += 1;
execute_pipe_body(memory, body, pipe_info, source_range, ctx).await
}
Value::CallExpression(call_expression) => {
pipe_info.is_in_pipe = true;
pipe_info.body = body.to_vec();
call_expression.execute(memory, pipe_info, ctx).await
}
Value::Identifier(identifier) => {
let result = memory.get(&identifier.name, identifier.into())?;
pipe_info.previous_results.push(result.clone());
pipe_info.index += 1;
execute_pipe_body(memory, body, pipe_info, source_range, ctx).await
}
// Evaluate the first element in the pipeline.
// They use the `pipe_info` from some AST node above this, so that if pipe expression is nested in a larger pipe expression,
// they use the % from the parent. After all, this pipe expression hasn't been executed yet, so it doesn't have any % value
// of its own.
let output = match first {
Value::BinaryExpression(binary_expression) => binary_expression.get_result(memory, pipe_info, ctx).await?,
Value::CallExpression(call_expression) => call_expression.execute(memory, pipe_info, ctx).await?,
Value::Identifier(identifier) => memory.get(&identifier.name, identifier.into())?.clone(),
_ => {
// Return an error this should not happen.
Err(KclError::Semantic(KclErrorDetails {
message: format!("PipeExpression not implemented here: {:?}", expression),
source_ranges: vec![expression.into()],
}))
return Err(KclError::Semantic(KclErrorDetails {
message: format!("PipeExpression not implemented here: {:?}", first),
source_ranges: vec![first.into()],
}));
}
};
// Now that we've evaluated the first child expression in the pipeline, following child expressions
// should use the previous child expression for %.
// This means there's no more need for the previous `pipe_info` from the parent AST node above this one.
let mut new_pipe_info = PipeInfo::new();
new_pipe_info.previous_results = Some(output);
// Evaluate remaining elements.
for expression in body {
let output = match expression {
Value::BinaryExpression(binary_expression) => {
binary_expression.get_result(memory, &new_pipe_info, ctx).await?
}
Value::CallExpression(call_expression) => call_expression.execute(memory, &new_pipe_info, ctx).await?,
Value::Identifier(identifier) => memory.get(&identifier.name, identifier.into())?.clone(),
_ => {
// Return an error this should not happen.
return Err(KclError::Semantic(KclErrorDetails {
message: format!("PipeExpression not implemented here: {:?}", expression),
source_ranges: vec![expression.into()],
}));
}
};
new_pipe_info.previous_results = Some(output);
}
// Safe to unwrap here, because `newpipe_info` always has something pushed in when the `match first` executes.
let final_output = new_pipe_info.previous_results.unwrap();
Ok(final_output)
}
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq, JsonSchema, Bake, FromStr, Display)]

View File

@ -953,20 +953,12 @@ impl ExtrudeSurface {
#[ts(export)]
#[serde(rename_all = "camelCase")]
pub struct PipeInfo {
pub previous_results: Vec<MemoryItem>,
pub is_in_pipe: bool,
pub index: usize,
pub body: Vec<Value>,
pub previous_results: Option<MemoryItem>,
}
impl PipeInfo {
pub fn new() -> Self {
Self {
previous_results: Vec::new(),
is_in_pipe: false,
index: 0,
body: Vec::new(),
}
Self { previous_results: None }
}
}
@ -1022,14 +1014,14 @@ pub async fn execute(
)
.await?;
let mut pipe_info = PipeInfo::default();
let pipe_info = PipeInfo::default();
// Iterate over the body of the program.
for statement in &program.body {
match statement {
BodyItem::ExpressionStatement(expression_statement) => {
if let Value::PipeExpression(pipe_expr) = &expression_statement.expression {
pipe_expr.get_result(memory, &mut pipe_info, ctx).await?;
pipe_expr.get_result(memory, &pipe_info, ctx).await?;
} else if let Value::CallExpression(call_expr) = &expression_statement.expression {
let fn_name = call_expr.callee.name.to_string();
let mut args: Vec<MemoryItem> = Vec::new();
@ -1041,23 +1033,23 @@ pub async fn execute(
args.push(memory_item.clone());
}
Value::CallExpression(call_expr) => {
let result = call_expr.execute(memory, &mut pipe_info, ctx).await?;
let result = call_expr.execute(memory, &pipe_info, ctx).await?;
args.push(result);
}
Value::BinaryExpression(binary_expression) => {
let result = binary_expression.get_result(memory, &mut pipe_info, ctx).await?;
let result = binary_expression.get_result(memory, &pipe_info, ctx).await?;
args.push(result);
}
Value::UnaryExpression(unary_expression) => {
let result = unary_expression.get_result(memory, &mut pipe_info, ctx).await?;
let result = unary_expression.get_result(memory, &pipe_info, ctx).await?;
args.push(result);
}
Value::ObjectExpression(object_expression) => {
let result = object_expression.execute(memory, &mut pipe_info, ctx).await?;
let result = object_expression.execute(memory, &pipe_info, ctx).await?;
args.push(result);
}
Value::ArrayExpression(array_expression) => {
let result = array_expression.execute(memory, &mut pipe_info, ctx).await?;
let result = array_expression.execute(memory, &pipe_info, ctx).await?;
args.push(result);
}
// We do nothing for the rest.
@ -1108,7 +1100,7 @@ pub async fn execute(
memory.add(&var_name, value.clone(), source_range)?;
}
Value::BinaryExpression(binary_expression) => {
let result = binary_expression.get_result(memory, &mut pipe_info, ctx).await?;
let result = binary_expression.get_result(memory, &pipe_info, ctx).await?;
memory.add(&var_name, result, source_range)?;
}
Value::FunctionExpression(function_expression) => {
@ -1145,11 +1137,11 @@ pub async fn execute(
)?;
}
Value::CallExpression(call_expression) => {
let result = call_expression.execute(memory, &mut pipe_info, ctx).await?;
let result = call_expression.execute(memory, &pipe_info, ctx).await?;
memory.add(&var_name, result, source_range)?;
}
Value::PipeExpression(pipe_expression) => {
let result = pipe_expression.get_result(memory, &mut pipe_info, ctx).await?;
let result = pipe_expression.get_result(memory, &pipe_info, ctx).await?;
memory.add(&var_name, result, source_range)?;
}
Value::PipeSubstitution(pipe_substitution) => {
@ -1162,11 +1154,11 @@ pub async fn execute(
}));
}
Value::ArrayExpression(array_expression) => {
let result = array_expression.execute(memory, &mut pipe_info, ctx).await?;
let result = array_expression.execute(memory, &pipe_info, ctx).await?;
memory.add(&var_name, result, source_range)?;
}
Value::ObjectExpression(object_expression) => {
let result = object_expression.execute(memory, &mut pipe_info, ctx).await?;
let result = object_expression.execute(memory, &pipe_info, ctx).await?;
memory.add(&var_name, result, source_range)?;
}
Value::MemberExpression(member_expression) => {
@ -1174,7 +1166,7 @@ pub async fn execute(
memory.add(&var_name, result, source_range)?;
}
Value::UnaryExpression(unary_expression) => {
let result = unary_expression.get_result(memory, &mut pipe_info, ctx).await?;
let result = unary_expression.get_result(memory, &pipe_info, ctx).await?;
memory.add(&var_name, result, source_range)?;
}
}
@ -1182,11 +1174,11 @@ pub async fn execute(
}
BodyItem::ReturnStatement(return_statement) => match &return_statement.argument {
Value::BinaryExpression(bin_expr) => {
let result = bin_expr.get_result(memory, &mut pipe_info, ctx).await?;
let result = bin_expr.get_result(memory, &pipe_info, ctx).await?;
memory.return_ = Some(ProgramReturn::Value(result));
}
Value::UnaryExpression(unary_expr) => {
let result = unary_expr.get_result(memory, &mut pipe_info, ctx).await?;
let result = unary_expr.get_result(memory, &pipe_info, ctx).await?;
memory.return_ = Some(ProgramReturn::Value(result));
}
Value::Identifier(identifier) => {
@ -1197,15 +1189,15 @@ pub async fn execute(
memory.return_ = Some(ProgramReturn::Value(literal.into()));
}
Value::ArrayExpression(array_expr) => {
let result = array_expr.execute(memory, &mut pipe_info, ctx).await?;
let result = array_expr.execute(memory, &pipe_info, ctx).await?;
memory.return_ = Some(ProgramReturn::Value(result));
}
Value::ObjectExpression(obj_expr) => {
let result = obj_expr.execute(memory, &mut pipe_info, ctx).await?;
let result = obj_expr.execute(memory, &pipe_info, ctx).await?;
memory.return_ = Some(ProgramReturn::Value(result));
}
Value::CallExpression(call_expr) => {
let result = call_expr.execute(memory, &mut pipe_info, ctx).await?;
let result = call_expr.execute(memory, &pipe_info, ctx).await?;
memory.return_ = Some(ProgramReturn::Value(result));
}
Value::MemberExpression(member_expr) => {
@ -1213,7 +1205,7 @@ pub async fn execute(
memory.return_ = Some(ProgramReturn::Value(result));
}
Value::PipeExpression(pipe_expr) => {
let result = pipe_expr.get_result(memory, &mut pipe_info, ctx).await?;
let result = pipe_expr.get_result(memory, &pipe_info, ctx).await?;
memory.return_ = Some(ProgramReturn::Value(result));
}
Value::PipeSubstitution(_) => {}

File diff suppressed because it is too large Load Diff

View File

@ -142,6 +142,15 @@ const part002 = startSketchOn(part001, "start")
twenty_twenty::assert_image("tests/executor/outputs/sketch_on_face_start.png", &result, 0.999);
}
#[tokio::test(flavor = "multi_thread")]
async fn serial_test_mike_stress_lines() {
let code = include_str!("inputs/mike_stress_test.kcl");
let result = execute_and_snapshot(code, kittycad::types::UnitLength::Mm)
.await
.unwrap();
twenty_twenty::assert_image("tests/executor/outputs/mike_stress_test.png", &result, 0.999);
}
#[tokio::test(flavor = "multi_thread")]
async fn serial_test_sketch_on_face_end() {
let code = r#"fn cube = (pos, scale) => {
@ -493,7 +502,7 @@ async fn serial_test_execute_i_shape() {
}
#[tokio::test(flavor = "multi_thread")]
#[ignore] // ignore until more stack fixes
#[ignore] // No longer a stack overflow problem, instead it causes an engine internal error.
async fn serial_test_execute_pipes_on_pipes() {
let code = include_str!("inputs/pipes_on_pipes.kcl");
@ -514,7 +523,6 @@ async fn serial_test_execute_cylinder() {
}
#[tokio::test(flavor = "multi_thread")]
#[ignore = "currently stack overflows"]
async fn serial_test_execute_kittycad_svg() {
let code = include_str!("inputs/kittycad_svg.kcl");

Binary file not shown.

Before

Width:  |  Height:  |  Size: 125 KiB

After

Width:  |  Height:  |  Size: 125 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 90 KiB

After

Width:  |  Height:  |  Size: 107 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 122 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 95 KiB

After

Width:  |  Height:  |  Size: 95 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 100 KiB

After

Width:  |  Height:  |  Size: 100 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 114 KiB

After

Width:  |  Height:  |  Size: 114 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 114 KiB

After

Width:  |  Height:  |  Size: 114 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 111 KiB

After

Width:  |  Height:  |  Size: 111 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 109 KiB

After

Width:  |  Height:  |  Size: 110 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 111 KiB

After

Width:  |  Height:  |  Size: 112 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 112 KiB

After

Width:  |  Height:  |  Size: 112 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 95 KiB

After

Width:  |  Height:  |  Size: 95 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 95 KiB

After

Width:  |  Height:  |  Size: 95 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 95 KiB

After

Width:  |  Height:  |  Size: 95 KiB

View File

@ -2506,20 +2506,14 @@
dependencies:
"@types/react" "*"
"@types/react@*", "@types/react@^18.2.67":
version "18.2.67"
resolved "https://registry.yarnpkg.com/@types/react/-/react-18.2.67.tgz#96b7af0b5e79c756f4bdd981de2ca28472c858e5"
integrity sha512-vkIE2vTIMHQ/xL0rgmuoECBCkZFZeHr49HeWSc24AptMbNRo7pwSBvj73rlJJs9fGKj0koS+V7kQB1jHS0uCgw==
"@types/react@*", "@types/react@^18.2.73":
version "18.2.73"
resolved "https://registry.yarnpkg.com/@types/react/-/react-18.2.73.tgz#0579548ad122660d99e00499d22e33b81e73ed94"
integrity sha512-XcGdod0Jjv84HOC7N5ziY3x+qL0AfmubvKOZ9hJjJ2yd5EE+KYjWhdOjt387e9HPheHkdggF9atTifMRtyAaRA==
dependencies:
"@types/prop-types" "*"
"@types/scheduler" "*"
csstype "^3.0.2"
"@types/scheduler@*":
version "0.16.3"
resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.3.tgz#cef09e3ec9af1d63d2a6cc5b383a737e24e6dcf5"
integrity sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ==
"@types/semver@^7.3.12":
version "7.5.0"
resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.0.tgz#591c1ce3a702c45ee15f47a42ade72c2fd78978a"