Compare commits

...

10 Commits

Author SHA1 Message Date
32572c8ae7 Update grammar
Signed-off-by: Nick Cameron <nrc@ncameron.org>
2025-03-23 19:29:12 +13:00
e0e707ad85 Doc comments on parameters
Signed-off-by: Nick Cameron <nrc@ncameron.org>
2025-03-22 10:38:18 +13:00
0913d3ebdc Support calling KCL std KW fns, and move circle to KCL std
Signed-off-by: Nick Cameron <nrc@ncameron.org>
2025-03-21 22:26:23 +13:00
c545ad71c6 Rebasing and fixes
Signed-off-by: Nick Cameron <nrc@ncameron.org>
2025-03-20 20:23:27 +13:00
a70718687f Add Point2D/3D to std
Signed-off-by: Nick Cameron <nrc@ncameron.org>
2025-03-20 20:23:27 +13:00
85cd29424e Tests for type coercion and subtyping
Signed-off-by: Nick Cameron <nrc@ncameron.org>
2025-03-20 20:23:27 +13:00
df1ff68a6d code motion: factor our execution::types module
Signed-off-by: Nick Cameron <nrc@ncameron.org>
2025-03-20 20:23:26 +13:00
2678d1014e Treat Helix and Face as primitive types
Signed-off-by: Nick Cameron <nrc@ncameron.org>
2025-03-20 20:23:26 +13:00
cd59691663 type aliases
Signed-off-by: Nick Cameron <nrc@ncameron.org>
2025-03-20 20:23:24 +13:00
d7369d8a95 parse union and fancy array types
Signed-off-by: Nick Cameron <nrc@ncameron.org>
2025-03-20 20:21:35 +13:00
124 changed files with 13588 additions and 10759 deletions

File diff suppressed because one or more lines are too long

View File

@ -15,7 +15,7 @@ std::math::E: number = 2.71828182845904523536028747135266250_
### Examples ### Examples
```js ```js
exampleSketch = startSketchOn("XZ") exampleSketch = startSketchOn(XZ)
|> startProfileAt([0, 0], %) |> startProfileAt([0, 0], %)
|> angledLine({ |> angledLine({
angle = 30, angle = 30,

View File

@ -17,7 +17,7 @@ std::math::PI: number = 3.14159265358979323846264338327950288_
```js ```js
circumference = 70 circumference = 70
exampleSketch = startSketchOn("XZ") exampleSketch = startSketchOn(XZ)
|> circle(center = [0, 0], radius = circumference/ (2 * PI)) |> circle(center = [0, 0], radius = circumference/ (2 * PI))
example = extrude(exampleSketch, length = 5) example = extrude(exampleSketch, length = 5)

View File

@ -15,7 +15,7 @@ std::math::TAU: number = 6.28318530717958647692528676655900577_
### Examples ### Examples
```js ```js
exampleSketch = startSketchOn("XZ") exampleSketch = startSketchOn(XZ)
|> startProfileAt([0, 0], %) |> startProfileAt([0, 0], %)
|> angledLine({ |> angledLine({
angle = 50, angle = 50,

View File

@ -22,8 +22,12 @@ layout: manual
* [`string`](kcl/types/string) * [`string`](kcl/types/string)
* [`tag`](kcl/types/tag) * [`tag`](kcl/types/tag)
* **std** * **std**
* [`Face`](kcl/types/Face)
* [`HALF_TURN`](kcl/consts/std-HALF_TURN) * [`HALF_TURN`](kcl/consts/std-HALF_TURN)
* [`Helix`](kcl/types/Helix)
* [`Plane`](kcl/types/Plane) * [`Plane`](kcl/types/Plane)
* [`Point2d`](kcl/types/Point2d)
* [`Point3d`](kcl/types/Point3d)
* [`QUARTER_TURN`](kcl/consts/std-QUARTER_TURN) * [`QUARTER_TURN`](kcl/consts/std-QUARTER_TURN)
* [`Sketch`](kcl/types/Sketch) * [`Sketch`](kcl/types/Sketch)
* [`Solid`](kcl/types/Solid) * [`Solid`](kcl/types/Solid)
@ -57,7 +61,6 @@ layout: manual
* [`bezierCurve`](kcl/bezierCurve) * [`bezierCurve`](kcl/bezierCurve)
* [`ceil`](kcl/ceil) * [`ceil`](kcl/ceil)
* [`chamfer`](kcl/chamfer) * [`chamfer`](kcl/chamfer)
* [`circle`](kcl/circle)
* [`circleThreePoint`](kcl/circleThreePoint) * [`circleThreePoint`](kcl/circleThreePoint)
* [`close`](kcl/close) * [`close`](kcl/close)
* [`cm`](kcl/cm) * [`cm`](kcl/cm)
@ -142,3 +145,5 @@ layout: manual
* [`cos`](kcl/std-math-cos) * [`cos`](kcl/std-math-cos)
* [`sin`](kcl/std-math-sin) * [`sin`](kcl/std-math-sin)
* [`tan`](kcl/std-math-tan) * [`tan`](kcl/std-math-tan)
* **std::sketch**
* [`circle`](kcl/std-sketch-circle)

View File

@ -9,7 +9,7 @@ Compute the cosine of a number (in radians).
```js ```js
cos(num: number(rad)): number(_) cos(@num: number(rad)): number(_)
``` ```
@ -27,7 +27,7 @@ cos(num: number(rad)): number(_)
### Examples ### Examples
```js ```js
exampleSketch = startSketchOn("XZ") exampleSketch = startSketchOn(XZ)
|> startProfileAt([0, 0], %) |> startProfileAt([0, 0], %)
|> angledLine({ |> angledLine({
angle = 30, angle = 30,

View File

@ -9,7 +9,7 @@ Compute the sine of a number (in radians).
```js ```js
sin(num: number(rad)): number(_) sin(@num: number(rad)): number(_)
``` ```
@ -27,7 +27,7 @@ sin(num: number(rad)): number(_)
### Examples ### Examples
```js ```js
exampleSketch = startSketchOn("XZ") exampleSketch = startSketchOn(XZ)
|> startProfileAt([0, 0], %) |> startProfileAt([0, 0], %)
|> angledLine({ |> angledLine({
angle = 50, angle = 50,

View File

@ -9,7 +9,7 @@ Compute the tangent of a number (in radians).
```js ```js
tan(num: number(rad)): number(_) tan(@num: number(rad)): number(_)
``` ```
@ -27,7 +27,7 @@ tan(num: number(rad)): number(_)
### Examples ### Examples
```js ```js
exampleSketch = startSketchOn("XZ") exampleSketch = startSketchOn(XZ)
|> startProfileAt([0, 0], %) |> startProfileAt([0, 0], %)
|> angledLine({ |> angledLine({
angle = 50, angle = 50,

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@ -1,28 +1,12 @@
--- ---
title: "Face" title: "std::Face"
excerpt: "A face." excerpt: "A face."
layout: manual layout: manual
--- ---
A face. A face.
**Type:** `object`
## Properties
| Property | Type | Description | Required |
|----------|------|-------------|----------|
| `id` |[`string`](/docs/kcl/types/string)| The id of the face. | No |
| `artifactId` |[`ArtifactId`](/docs/kcl/types/ArtifactId)| The artifact ID. | No |
| `value` |[`string`](/docs/kcl/types/string)| The tag of the face. | No |
| `xAxis` |[`Point3d`](/docs/kcl/types/Point3d)| What should the face's X axis be? | No |
| `yAxis` |[`Point3d`](/docs/kcl/types/Point3d)| What should the face's Y axis be? | No |
| `zAxis` |[`Point3d`](/docs/kcl/types/Point3d)| The z-axis (normal). | No |
| `solid` |[`Solid`](/docs/kcl/types/Solid)| The solid the face is on. | No |
| `units` |[`UnitLen`](/docs/kcl/types/UnitLen)| A unit of length. | No |

View File

@ -1,26 +1,12 @@
--- ---
title: "Helix" title: "std::Helix"
excerpt: "A helix." excerpt: "A helix."
layout: manual layout: manual
--- ---
A helix. A helix.
**Type:** `object`
## Properties
| Property | Type | Description | Required |
|----------|------|-------------|----------|
| `value` |[`string`](/docs/kcl/types/string)| The id of the helix. | No |
| `artifactId` |[`ArtifactId`](/docs/kcl/types/ArtifactId)| The artifact ID. | No |
| `revolutions` |[`number`](/docs/kcl/types/number)| Number of revolutions. | No |
| `angleStart` |[`number`](/docs/kcl/types/number)| Start angle (in degrees). | No |
| `ccw` |`boolean`| Is the helix rotation counter clockwise? | No |
| `units` |[`UnitLen`](/docs/kcl/types/UnitLen)| A unit of length. | No |

View File

@ -188,7 +188,7 @@ Any KCL value.
| Property | Type | Description | Required | | Property | Type | Description | Required |
|----------|------|-------------|----------| |----------|------|-------------|----------|
| `type` |enum: [`Face`](/docs/kcl/types/Face)| | No | | `type` |enum: [`Face`](/docs/kcl/types/Face)| | No |
| `value` |[`Face`](/docs/kcl/types/Face)| A face. | No | | `value` |[`Face`](/docs/kcl/types/Face)| | No |
---- ----
@ -236,7 +236,7 @@ Any KCL value.
| Property | Type | Description | Required | | Property | Type | Description | Required |
|----------|------|-------------|----------| |----------|------|-------------|----------|
| `type` |enum: [`Helix`](/docs/kcl/types/Helix)| | No | | `type` |enum: [`Helix`](/docs/kcl/types/Helix)| | No |
| `value` |[`Helix`](/docs/kcl/types/Helix)| A helix. | No | | `value` |[`Helix`](/docs/kcl/types/Helix)| | No |
---- ----

17
docs/kcl/types/Point2d.md Normal file
View File

@ -0,0 +1,17 @@
---
title: "std::Point2d"
excerpt: "A point in two dimensional space."
layout: manual
---
A point in two dimensional space.
```kcl
type Point2d = [number; 2]
```
[`Point2d`](/docs/kcl/types/Point2d) is an alias for a two-element array of [number](/docs/kcl/types/number)s. To write a value
with type [`Point2d`](/docs/kcl/types/Point2d), use an array, e.g., `[0, 0]` or `[5.0, 3.14]`.

View File

@ -1,22 +1,17 @@
--- ---
title: "Point3d" title: "std::Point3d"
excerpt: "" excerpt: "A point in three dimensional space."
layout: manual layout: manual
--- ---
A point in three dimensional space.
**Type:** `object` ```kcl
type Point3d = [number; 3]
```
[`Point3d`](/docs/kcl/types/Point3d) is an alias for a three-element array of [number](/docs/kcl/types/number)s. To write a value
with type [`Point3d`](/docs/kcl/types/Point3d), use an array, e.g., `[0, 0, 0]` or `[5.0, 3.14, 6.8]`.
## Properties
| Property | Type | Description | Required |
|----------|------|-------------|----------|
| `x` |[`number`](/docs/kcl/types/number)| | No |
| `y` |[`number`](/docs/kcl/types/number)| | No |
| `z` |[`number`](/docs/kcl/types/number)| | No |

View File

@ -17,7 +17,7 @@ mySketch = startSketchOn('XY')
|> close() |> close()
``` ```
The `mySketch` variable will be an executed `Sketch` object. Executed being past The `mySketch` variable will be an executed [`Sketch`](/docs/kcl/types/Sketch) object. Executed being past
tense, because the engine has already executed the commands to create the sketch. tense, because the engine has already executed the commands to create the sketch.
The previous sketch commands will never be executed again, in this case. The previous sketch commands will never be executed again, in this case.

View File

@ -18,7 +18,7 @@ myPart = startSketchOn('XY')
|> extrude(length = 6) |> extrude(length = 6)
``` ```
The `myPart` variable will be an executed `Solid` object. Executed being past The `myPart` variable will be an executed [`Solid`](/docs/kcl/types/Solid) object. Executed being past
tense, because the engine has already executed the commands to create the solid. tense, because the engine has already executed the commands to create the solid.
The previous solid commands will never be executed again, in this case. The previous solid commands will never be executed again, in this case.

View File

@ -22,7 +22,6 @@ A path to sweep along.
---- ----
A helix.
[`Helix`](/docs/kcl/types/Helix) [`Helix`](/docs/kcl/types/Helix)

View File

@ -20,7 +20,7 @@ statement[@isGroup=Statement] {
ImportStatement { kw<"import"> ImportItems ImportFrom String } | ImportStatement { kw<"import"> ImportItems ImportFrom String } |
FunctionDeclaration { kw<"export">? kw<"fn"> VariableDefinition Equals? ParamList Arrow? Body } | FunctionDeclaration { kw<"export">? kw<"fn"> VariableDefinition Equals? ParamList Arrow? Body } |
VariableDeclaration { kw<"export">? (kw<"var"> | kw<"let"> | kw<"const">)? VariableDefinition Equals expression } | VariableDeclaration { kw<"export">? (kw<"var"> | kw<"let"> | kw<"const">)? VariableDefinition Equals expression } |
TypeDeclaration { kw<"export">? kw<"type"> identifier } | TypeDeclaration { kw<"export">? kw<"type"> identifier ("=" type)? } |
ReturnStatement { kw<"return"> expression } | ReturnStatement { kw<"return"> expression } |
ExpressionStatement { expression } | ExpressionStatement { expression } |
Annotation { AnnotationName AnnotationList? } Annotation { AnnotationName AnnotationList? }
@ -75,11 +75,8 @@ LabeledArgument { ArgumentLabel Equals expression }
ArgumentList { "(" commaSep<LabeledArgument | expression> ")" } ArgumentList { "(" commaSep<LabeledArgument | expression> ")" }
type[@isGroup=Type] { type[@isGroup=Type] {
@specialize[@name=PrimitiveType]< PrimitiveType { identifier } |
identifier, ArrayType { "[" type !member (";" Number "+"?)? "]" } |
"bool" | "number" | "string" | "tag" | "Sketch" | "SketchSurface" | "Solid" | "Plane"
> |
ArrayType { type !member "[" "]" } |
ObjectType { "{" commaSep<ObjectProperty { PropertyName ":" type }> "}" } ObjectType { "{" commaSep<ObjectProperty { PropertyName ":" type }> "}" }
} }
@ -137,7 +134,7 @@ commaSep1NoTrailingComma<term> { term ("," term)* }
"(" ")" "(" ")"
"{" "}" "{" "}"
"[" "]" "[" "]"
"," "?" ":" "." ".." "," "?" ":" "." ".." ";"
} }
@external propSource kclHighlight from "./highlight" @external propSource kclHighlight from "./highlight"

View File

@ -822,7 +822,7 @@ async fn kcl_test_stdlib_kcl_error_circle() {
// Create a function that defines the body width and length of the mounting plate. Tag the corners so they can be passed through the fillet function. // Create a function that defines the body width and length of the mounting plate. Tag the corners so they can be passed through the fillet function.
fn rectShape = (pos, w, l) => { fn rectShape = (pos, w, l) => {
rr = startSketchOn('XY') rr = startSketchOn(XY)
|> startProfileAt([pos[0] - (w / 2), pos[1] - (l / 2)], %) |> startProfileAt([pos[0] - (w / 2), pos[1] - (l / 2)], %)
|> line(endAbsolute = [pos[0] + w / 2, pos[1] - (l / 2)], tag = $edge1) |> line(endAbsolute = [pos[0] + w / 2, pos[1] - (l / 2)], tag = $edge1)
|> line(endAbsolute = [pos[0] + w / 2, pos[1] + l / 2], tag = $edge2) |> line(endAbsolute = [pos[0] + w / 2, pos[1] + l / 2], tag = $edge2)
@ -837,10 +837,10 @@ holeIndex = 6
// Create the mounting plate extrusion, holes, and fillets // Create the mounting plate extrusion, holes, and fillets
part = rectShape([0, 0], 20, 20) part = rectShape([0, 0], 20, 20)
|> hole(circle('XY', [-holeIndex, holeIndex], holeRadius), %) |> hole(circle('XY', center = [-holeIndex, holeIndex], radius = holeRadius), %)
|> hole(circle('XY', [holeIndex, holeIndex], holeRadius), %) |> hole(circle('XY', center = [holeIndex, holeIndex], radius = holeRadius), %)
|> hole(circle('XY', [-holeIndex, -holeIndex], holeRadius), %) |> hole(circle('XY', center = [-holeIndex, -holeIndex], radius = holeRadius), %)
|> hole(circle('XY', [holeIndex, -holeIndex], holeRadius), %) |> hole(circle('XY', center = [holeIndex, -holeIndex], radius = holeRadius), %)
|> extrude(length = 2) |> extrude(length = 2)
|> fillet( |> fillet(
radius = 4, radius = 4,
@ -860,7 +860,7 @@ part = rectShape([0, 0], 20, 20)
}; };
assert_eq!( assert_eq!(
err.error.message(), err.error.message(),
"This function expected the input argument to be of type SketchOrSurface but it's actually of type string (text)" "The input argument of std::sketch::circle requires a value with type `Sketch | Plane | Face`, but found string (text)"
); );
} }

View File

@ -23,7 +23,9 @@ use crate::{
const TYPES_DIR: &str = "../../docs/kcl/types"; const TYPES_DIR: &str = "../../docs/kcl/types";
const LANG_TOPICS: [&str; 5] = ["Types", "Modules", "Settings", "Known Issues", "Constants"]; const LANG_TOPICS: [&str; 5] = ["Types", "Modules", "Settings", "Known Issues", "Constants"];
// These types are declared in std. // These types are declared in std.
const DECLARED_TYPES: [&str; 7] = ["number", "string", "tag", "bool", "Sketch", "Solid", "Plane"]; const DECLARED_TYPES: [&str; 11] = [
"number", "string", "tag", "bool", "Sketch", "Solid", "Plane", "Helix", "Face", "Point2d", "Point3d",
];
fn init_handlebars() -> Result<handlebars::Handlebars<'static>> { fn init_handlebars() -> Result<handlebars::Handlebars<'static>> {
let mut hbs = handlebars::Handlebars::new(); let mut hbs = handlebars::Handlebars::new();
@ -457,6 +459,7 @@ fn generate_type_from_kcl(ty: &TyData, file_name: String, example_name: String)
let data = json!({ let data = json!({
"name": ty.qual_name(), "name": ty.qual_name(),
"definition": ty.alias.as_ref().map(|t| format!("type {} = {t}", ty.name)),
"summary": ty.summary, "summary": ty.summary,
"description": ty.description, "description": ty.description,
"deprecated": ty.properties.deprecated, "deprecated": ty.properties.deprecated,
@ -464,6 +467,10 @@ fn generate_type_from_kcl(ty: &TyData, file_name: String, example_name: String)
}); });
let output = hbs.render("kclType", &data)?; let output = hbs.render("kclType", &data)?;
let output = cleanup_type_links(
&output,
ty.referenced_types.iter().filter(|t| !DECLARED_TYPES.contains(&&***t)),
);
expectorate::assert_contents(format!("../../docs/kcl/{}.md", file_name), &output); expectorate::assert_contents(format!("../../docs/kcl/{}.md", file_name), &output);
Ok(()) Ok(())
@ -511,6 +518,13 @@ fn generate_function_from_kcl(function: &FnData, file_name: String) -> Result<()
}); });
let output = hbs.render("function", &data)?; let output = hbs.render("function", &data)?;
let output = cleanup_type_links(
&output,
function
.referenced_types
.iter()
.filter(|t| !DECLARED_TYPES.contains(&&***t)),
);
expectorate::assert_contents(format!("../../docs/kcl/{}.md", file_name), &output); expectorate::assert_contents(format!("../../docs/kcl/{}.md", file_name), &output);
Ok(()) Ok(())
@ -674,6 +688,12 @@ fn cleanup_type_links<'a>(output: &str, types: impl Iterator<Item = &'a String>)
} }
} }
// TODO handle union types generically rather than special casing them.
cleaned_output = cleaned_output.replace(
"`Sketch | Plane | Face`",
"[`Sketch`](/docs/kcl/types/Sketch) `|` [`Plane`](/docs/kcl/types/Face) `|` [`Plane`](/docs/kcl/types/Face)",
);
cleanup_static_links(&cleaned_output) cleanup_static_links(&cleaned_output)
} }

View File

@ -1,5 +1,6 @@
use std::str::FromStr; use std::{collections::HashSet, str::FromStr};
use regex::Regex;
use tower_lsp::lsp_types::{ use tower_lsp::lsp_types::{
CompletionItem, CompletionItemKind, CompletionItemLabelDetails, Documentation, InsertTextFormat, MarkupContent, CompletionItem, CompletionItemKind, CompletionItemLabelDetails, Documentation, InsertTextFormat, MarkupContent,
MarkupKind, ParameterInformation, ParameterLabel, SignatureHelp, SignatureInformation, MarkupKind, ParameterInformation, ParameterLabel, SignatureHelp, SignatureInformation,
@ -8,7 +9,7 @@ use tower_lsp::lsp_types::{
use crate::{ use crate::{
execution::annotations, execution::annotations,
parsing::{ parsing::{
ast::types::{Annotation, Node, NonCodeNode, VariableKind}, ast::types::{Annotation, Node, PrimitiveType, Type, VariableKind},
token::NumericSuffix, token::NumericSuffix,
}, },
ModuleId, ModuleId,
@ -58,7 +59,6 @@ impl CollectionVisitor {
format!("std::{}::", self.name) format!("std::{}::", self.name)
}; };
let mut dd = match var.kind { let mut dd = match var.kind {
// TODO metadata for args
VariableKind::Fn => DocData::Fn(FnData::from_ast(var, qual_name)), VariableKind::Fn => DocData::Fn(FnData::from_ast(var, qual_name)),
VariableKind::Const => DocData::Const(ConstData::from_ast(var, qual_name)), VariableKind::Const => DocData::Const(ConstData::from_ast(var, qual_name)),
}; };
@ -282,7 +282,7 @@ impl ConstData {
documentation: self.short_docs().map(|s| { documentation: self.short_docs().map(|s| {
Documentation::MarkupContent(MarkupContent { Documentation::MarkupContent(MarkupContent {
kind: MarkupKind::Markdown, kind: MarkupKind::Markdown,
value: s, value: remove_md_links(&s),
}) })
}), }),
deprecated: Some(self.properties.deprecated), deprecated: Some(self.properties.deprecated),
@ -321,6 +321,8 @@ pub struct FnData {
/// Code examples. /// Code examples.
/// These are tested and we know they compile and execute. /// These are tested and we know they compile and execute.
pub examples: Vec<(String, ExampleProperties)>, pub examples: Vec<(String, ExampleProperties)>,
#[allow(dead_code)]
pub referenced_types: Vec<String>,
} }
impl FnData { impl FnData {
@ -331,11 +333,22 @@ impl FnData {
}; };
let name = var.declaration.id.name.clone(); let name = var.declaration.id.name.clone();
qual_name.push_str(&name); qual_name.push_str(&name);
let mut referenced_types = HashSet::new();
if let Some(t) = &expr.return_type {
collect_type_names(&mut referenced_types, t);
}
for p in &expr.params {
if let Some(t) = &p.type_ {
collect_type_names(&mut referenced_types, t);
}
}
FnData { FnData {
name, name,
qual_name, qual_name,
args: expr.params.iter().map(ArgData::from_ast).collect(), args: expr.params.iter().map(ArgData::from_ast).collect(),
return_type: expr.return_type.as_ref().map(|t| t.recast(&Default::default(), 0)), return_type: expr.return_type.as_ref().map(|t| t.to_string()),
properties: Properties { properties: Properties {
exported: !var.visibility.is_default(), exported: !var.visibility.is_default(),
deprecated: false, deprecated: false,
@ -345,6 +358,7 @@ impl FnData {
summary: None, summary: None,
description: None, description: None,
examples: Vec::new(), examples: Vec::new(),
referenced_types: referenced_types.into_iter().collect(),
} }
} }
@ -393,7 +407,7 @@ impl FnData {
documentation: self.short_docs().map(|s| { documentation: self.short_docs().map(|s| {
Documentation::MarkupContent(MarkupContent { Documentation::MarkupContent(MarkupContent {
kind: MarkupKind::Markdown, kind: MarkupKind::Markdown,
value: s, value: remove_md_links(&s),
}) })
}), }),
deprecated: Some(self.properties.deprecated), deprecated: Some(self.properties.deprecated),
@ -413,7 +427,7 @@ impl FnData {
} }
#[allow(clippy::literal_string_with_formatting_args)] #[allow(clippy::literal_string_with_formatting_args)]
fn to_autocomplete_snippet(&self) -> String { pub(super) fn to_autocomplete_snippet(&self) -> String {
if self.name == "loft" { if self.name == "loft" {
return "loft([${0:sketch000}, ${1:sketch001}])${}".to_owned(); return "loft([${0:sketch000}, ${1:sketch001}])${}".to_owned();
} else if self.name == "hole" { } else if self.name == "hole" {
@ -479,12 +493,12 @@ pub struct ArgData {
/// If the argument is required. /// If the argument is required.
pub kind: ArgKind, pub kind: ArgKind,
/// Additional information that could be used instead of the type's description. /// Additional information that could be used instead of the type's description.
/// This is helpful if the type is really basic, like "u32" -- that won't tell the user much about /// This is helpful if the type is really basic, like "number" -- that won't tell the user much about
/// how this argument is meant to be used. /// how this argument is meant to be used.
pub docs: Option<String>, pub docs: Option<String>,
} }
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy, PartialEq)]
pub enum ArgKind { pub enum ArgKind {
Special, Special,
// Parameter is whether the arg is optional. // Parameter is whether the arg is optional.
@ -494,38 +508,47 @@ pub enum ArgKind {
impl ArgData { impl ArgData {
fn from_ast(arg: &crate::parsing::ast::types::Parameter) -> Self { fn from_ast(arg: &crate::parsing::ast::types::Parameter) -> Self {
ArgData { let mut result = ArgData {
name: arg.identifier.name.clone(), name: arg.identifier.name.clone(),
ty: arg.type_.as_ref().map(|t| t.recast(&Default::default(), 0)), ty: arg.type_.as_ref().map(|t| t.to_string()),
// Doc comments are not yet supported on parameters.
docs: None, docs: None,
kind: if arg.labeled { kind: if arg.labeled {
ArgKind::Labelled(arg.optional()) ArgKind::Labelled(arg.optional())
} else { } else {
ArgKind::Special ArgKind::Special
}, },
} };
}
fn _with_meta(&mut self, _meta: &[Node<NonCodeNode>]) { result.with_comments(&arg.identifier.pre_comments);
// TODO use comments for docs (we can't currently get the comments for an argument) result
} }
pub fn get_autocomplete_snippet(&self, index: usize) -> Option<(usize, String)> { pub fn get_autocomplete_snippet(&self, index: usize) -> Option<(usize, String)> {
match &self.ty { let label = if self.kind == ArgKind::Special {
Some(s) String::new()
if [ } else {
"Sketch", format!("{} = ", self.name)
"SketchSet", };
"Solid", match self.ty.as_deref() {
"SolidSet", Some(s) if ["Sketch", "Solid", "Plane | Face", "Sketch | Plane | Face"].contains(&s) => {
"SketchSurface", Some((index, format!("{label}${{{}:{}}}", index, "%")))
"SketchOrSurface",
]
.contains(&&**s) =>
{
Some((index, format!("${{{}:{}}}", index, "%")))
} }
Some("number") if self.kind.required() => Some((index, format!(r#"{label}${{{}:3.14}}"#, index))),
Some("Point2d") if self.kind.required() => Some((
index + 1,
format!(r#"{label}[${{{}:3.14}}, ${{{}:3.14}}]"#, index, index + 1),
)),
Some("Point3d") if self.kind.required() => Some((
index + 2,
format!(
r#"{label}[${{{}:3.14}}, ${{{}:3.14}}, ${{{}:3.14}}]"#,
index,
index + 1,
index + 2
),
)),
Some("string") if self.kind.required() => Some((index, format!(r#"{label}${{{}:"string"}}"#, index))),
Some("bool") if self.kind.required() => Some((index, format!(r#"{label}${{{}:false}}"#, index))),
_ => None, _ => None,
} }
} }
@ -560,6 +583,7 @@ pub struct TyData {
/// The fully qualified name. /// The fully qualified name.
pub qual_name: String, pub qual_name: String,
pub properties: Properties, pub properties: Properties,
pub alias: Option<String>,
/// The summary of the function. /// The summary of the function.
pub summary: Option<String>, pub summary: Option<String>,
@ -568,12 +592,19 @@ pub struct TyData {
/// Code examples. /// Code examples.
/// These are tested and we know they compile and execute. /// These are tested and we know they compile and execute.
pub examples: Vec<(String, ExampleProperties)>, pub examples: Vec<(String, ExampleProperties)>,
#[allow(dead_code)]
pub referenced_types: Vec<String>,
} }
impl TyData { impl TyData {
fn from_ast(ty: &crate::parsing::ast::types::TypeDeclaration, mut qual_name: String) -> Self { fn from_ast(ty: &crate::parsing::ast::types::TypeDeclaration, mut qual_name: String) -> Self {
let name = ty.name.name.clone(); let name = ty.name.name.clone();
qual_name.push_str(&name); qual_name.push_str(&name);
let mut referenced_types = HashSet::new();
if let Some(t) = &ty.alias {
collect_type_names(&mut referenced_types, t);
}
TyData { TyData {
name, name,
qual_name, qual_name,
@ -583,9 +614,11 @@ impl TyData {
doc_hidden: false, doc_hidden: false,
impl_kind: annotations::Impl::Kcl, impl_kind: annotations::Impl::Kcl,
}, },
alias: ty.alias.as_ref().map(|t| t.to_string()),
summary: None, summary: None,
description: None, description: None,
examples: Vec::new(), examples: Vec::new(),
referenced_types: referenced_types.into_iter().collect(),
} }
} }
@ -609,13 +642,16 @@ impl TyData {
fn to_completion_item(&self) -> CompletionItem { fn to_completion_item(&self) -> CompletionItem {
CompletionItem { CompletionItem {
label: self.name.clone(), label: self.name.clone(),
label_details: None, label_details: self.alias.as_ref().map(|t| CompletionItemLabelDetails {
detail: Some(format!("type {} = {t}", self.name)),
description: None,
}),
kind: Some(CompletionItemKind::FUNCTION), kind: Some(CompletionItemKind::FUNCTION),
detail: Some(self.qual_name().to_owned()), detail: Some(self.qual_name().to_owned()),
documentation: self.short_docs().map(|s| { documentation: self.short_docs().map(|s| {
Documentation::MarkupContent(MarkupContent { Documentation::MarkupContent(MarkupContent {
kind: MarkupKind::Markdown, kind: MarkupKind::Markdown,
value: s, value: remove_md_links(&s),
}) })
}), }),
deprecated: Some(self.properties.deprecated), deprecated: Some(self.properties.deprecated),
@ -635,6 +671,11 @@ impl TyData {
} }
} }
fn remove_md_links(s: &str) -> String {
let re = Regex::new(r"\[([^\]]*)\]\([^\)]*\)").unwrap();
re.replace_all(s, "$1").to_string()
}
trait ApplyMeta { trait ApplyMeta {
fn apply_docs( fn apply_docs(
&mut self, &mut self,
@ -841,6 +882,66 @@ impl ApplyMeta for TyData {
} }
} }
impl ApplyMeta for ArgData {
fn apply_docs(
&mut self,
summary: Option<String>,
description: Option<String>,
_examples: Vec<(String, ExampleProperties)>,
) {
let Some(mut docs) = summary else {
return;
};
if let Some(desc) = description {
docs.push_str("\n\n");
docs.push_str(&desc);
}
self.docs = Some(docs);
}
fn deprecated(&mut self, _deprecated: bool) {
unreachable!();
}
fn doc_hidden(&mut self, _doc_hidden: bool) {
unreachable!();
}
fn impl_kind(&mut self, _impl_kind: annotations::Impl) {
unreachable!();
}
}
fn collect_type_names(acc: &mut HashSet<String>, ty: &Type) {
match ty {
Type::Primitive(primitive_type) => {
acc.insert(collect_type_names_from_primitive(primitive_type));
}
Type::Array { ty, .. } => {
acc.insert(collect_type_names_from_primitive(ty));
}
Type::Union { tys } => tys.iter().for_each(|t| {
acc.insert(collect_type_names_from_primitive(t));
}),
Type::Object { properties } => properties.iter().for_each(|p| {
if let Some(t) = &p.type_ {
collect_type_names(acc, t)
}
}),
}
}
fn collect_type_names_from_primitive(ty: &PrimitiveType) -> String {
match ty {
PrimitiveType::String => "string".to_owned(),
PrimitiveType::Number(_) => "number".to_owned(),
PrimitiveType::Boolean => "bool".to_owned(),
PrimitiveType::Tag => "tag".to_owned(),
PrimitiveType::Named(id) => id.name.clone(),
}
}
#[cfg(test)] #[cfg(test)]
mod test { mod test {
use super::*; use super::*;
@ -863,6 +964,24 @@ mod test {
panic!("didn't find PI"); panic!("didn't find PI");
} }
#[test]
fn test_remove_md_links() {
assert_eq!(
remove_md_links("sdf dsf sd fj sdk fasdfs. asad[sdfs] dfsdf(dsfs, dsf)"),
"sdf dsf sd fj sdk fasdfs. asad[sdfs] dfsdf(dsfs, dsf)".to_owned()
);
assert_eq!(remove_md_links("[]()"), "".to_owned());
assert_eq!(remove_md_links("[foo](bar)"), "foo".to_owned());
assert_eq!(
remove_md_links("asdasda dsa[foo](http://www.bar/baz/qux.md). asdasdasdas asdas"),
"asdasda dsafoo. asdasdasdas asdas".to_owned()
);
assert_eq!(
remove_md_links("a [foo](bar) b [2](bar) c [_](bar)"),
"a foo b 2 c _".to_owned()
);
}
#[tokio::test(flavor = "multi_thread", worker_threads = 5)] #[tokio::test(flavor = "multi_thread", worker_threads = 5)]
async fn test_examples() -> miette::Result<()> { async fn test_examples() -> miette::Result<()> {
let std = walk_prelude(); let std = walk_prelude();

View File

@ -18,7 +18,7 @@ use tower_lsp::lsp_types::{
}; };
use crate::{ use crate::{
execution::{kcl_value::NumericType, Sketch}, execution::{types::NumericType, Sketch},
std::Primitive, std::Primitive,
}; };
@ -926,6 +926,8 @@ fn get_autocomplete_string_from_schema(schema: &schemars::schema::Schema) -> Res
mod tests { mod tests {
use pretty_assertions::assert_eq; use pretty_assertions::assert_eq;
use crate::docs::kcl_doc::{self, DocData};
use super::StdLibFn; use super::StdLibFn;
#[test] #[test]
@ -1006,8 +1008,11 @@ mod tests {
#[test] #[test]
#[allow(clippy::literal_string_with_formatting_args)] #[allow(clippy::literal_string_with_formatting_args)]
fn get_autocomplete_snippet_circle() { fn get_autocomplete_snippet_circle() {
let circle_fn: Box<dyn StdLibFn> = Box::new(crate::std::shapes::Circle); let data = kcl_doc::walk_prelude();
let snippet = circle_fn.to_autocomplete_snippet().unwrap(); let DocData::Fn(circle_fn) = data.into_iter().find(|d| d.name() == "circle").unwrap() else {
panic!();
};
let snippet = circle_fn.to_autocomplete_snippet();
assert_eq!( assert_eq!(
snippet, snippet,
r#"circle(${0:%}, center = [${1:3.14}, ${2:3.14}], radius = ${3:3.14})${}"# r#"circle(${0:%}, center = [${1:3.14}, ${2:3.14}], radius = ${3:3.14})${}"#

View File

@ -10,6 +10,12 @@ layout: manual
{{/if}} {{/if}}
{{{summary}}} {{{summary}}}
{{#if definition}}
```kcl
{{{definition}}}
```
{{/if}}
{{{description}}} {{{description}}}

View File

@ -6,7 +6,7 @@ use kittycad_modeling_cmds::coord::{System, KITTYCAD, OPENGL, VULKAN};
use crate::{ use crate::{
errors::KclErrorDetails, errors::KclErrorDetails,
execution::kcl_value::{UnitAngle, UnitLen}, execution::types::{UnitAngle, UnitLen},
parsing::ast::types::{Annotation, Expr, Node, ObjectProperty}, parsing::ast::types::{Annotation, Expr, Node, ObjectProperty},
KclError, SourceRange, KclError, SourceRange,
}; };

View File

@ -2,7 +2,7 @@ use indexmap::IndexMap;
use schemars::JsonSchema; use schemars::JsonSchema;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use super::{kcl_value::NumericType, ArtifactId, KclValue}; use super::{types::NumericType, ArtifactId, KclValue};
use crate::{docs::StdLibFn, std::get_stdlib_fn, SourceRange}; use crate::{docs::StdLibFn, std::get_stdlib_fn, SourceRange};
/// A CAD modeling operation for display in the feature tree, AKA operations /// A CAD modeling operation for display in the feature tree, AKA operations

View File

@ -8,9 +8,10 @@ use crate::{
execution::{ execution::{
annotations, annotations,
cad_op::{OpArg, OpKclValue, Operation}, cad_op::{OpArg, OpKclValue, Operation},
kcl_value::{FunctionSource, NumericType, RuntimeType}, kcl_value::FunctionSource,
memory, memory,
state::ModuleState, state::ModuleState,
types::{NumericType, RuntimeType},
BodyType, EnvironmentRef, ExecState, ExecutorContext, KclValue, Metadata, PlaneType, TagEngineInfo, BodyType, EnvironmentRef, ExecState, ExecutorContext, KclValue, Metadata, PlaneType, TagEngineInfo,
TagIdentifier, TagIdentifier,
}, },
@ -29,6 +30,8 @@ use crate::{
CompilationError, CompilationError,
}; };
use super::kcl_value::TypeDef;
enum StatementKind<'a> { enum StatementKind<'a> {
Declaration { name: &'a str }, Declaration { name: &'a str },
Expression, Expression,
@ -304,8 +307,9 @@ impl ExecutorContext {
})); }));
} }
}; };
let (t, props) = crate::std::std_ty(std_path, &ty.name.name);
let value = KclValue::Type { let value = KclValue::Type {
value: Some(crate::std::std_ty(std_path, &ty.name.name)), value: TypeDef::RustRepr(t, props),
meta: vec![metadata], meta: vec![metadata],
}; };
exec_state exec_state
@ -324,12 +328,40 @@ impl ExecutorContext {
} }
// Do nothing for primitive types, they get special treatment and their declarations are just for documentation. // Do nothing for primitive types, they get special treatment and their declarations are just for documentation.
annotations::Impl::Primitive => {} annotations::Impl::Primitive => {}
annotations::Impl::Kcl => { annotations::Impl::Kcl => match &ty.alias {
Some(alias) => {
let value = KclValue::Type {
value: TypeDef::Alias(
RuntimeType::from_parsed(
alias.inner.clone(),
exec_state,
metadata.source_range,
)
.map_err(|e| KclError::Semantic(e.into()))?,
),
meta: vec![metadata],
};
exec_state
.mut_stack()
.add(
format!("{}{}", memory::TYPE_PREFIX, ty.name.name),
value,
metadata.source_range,
)
.map_err(|_| {
KclError::Semantic(KclErrorDetails {
message: format!("Redefinition of type {}.", ty.name.name),
source_ranges: vec![metadata.source_range],
})
})?;
}
None => {
return Err(KclError::Semantic(KclErrorDetails { return Err(KclError::Semantic(KclErrorDetails {
message: "User-defined types are not yet supported.".to_owned(), message: "User-defined types are not yet supported.".to_owned(),
source_ranges: vec![metadata.source_range], source_ranges: vec![metadata.source_range],
})); }))
} }
},
} }
last_expr = None; last_expr = None;
@ -578,7 +610,11 @@ impl ExecutorContext {
if let Some(std_path) = &exec_state.mod_local.settings.std_path { if let Some(std_path) = &exec_state.mod_local.settings.std_path {
let (func, props) = crate::std::std_fn(std_path, statement_kind.expect_name()); let (func, props) = crate::std::std_fn(std_path, statement_kind.expect_name());
KclValue::Function { KclValue::Function {
value: FunctionSource::Std { func, props }, value: FunctionSource::Std {
func,
props,
ast: function_expression.clone(),
},
meta: vec![metadata.to_owned()], meta: vec![metadata.to_owned()],
} }
} else { } else {
@ -646,30 +682,28 @@ impl ExecutorContext {
let result = self let result = self
.execute_expr(&expr.expr, exec_state, metadata, &[], statement_kind) .execute_expr(&expr.expr, exec_state, metadata, &[], statement_kind)
.await?; .await?;
coerce(&result, &expr.ty, exec_state).ok_or_else(|| { coerce(&result, &expr.ty, exec_state, expr.into())?
KclError::Semantic(KclErrorDetails {
message: format!(
"could not coerce {} value to type {}",
result.human_friendly_type(),
expr.ty
),
source_ranges: vec![expr.into()],
})
})?
} }
}; };
Ok(item) Ok(item)
} }
} }
fn coerce(value: &KclValue, ty: &Node<Type>, exec_state: &mut ExecState) -> Option<KclValue> { fn coerce(
value: &KclValue,
ty: &Node<Type>,
exec_state: &mut ExecState,
source_range: SourceRange,
) -> Result<KclValue, KclError> {
let ty = RuntimeType::from_parsed(ty.inner.clone(), exec_state, value.into()) let ty = RuntimeType::from_parsed(ty.inner.clone(), exec_state, value.into())
.map_err(|e| { .map_err(|e| KclError::Semantic(e.into()))?;
exec_state.err(e);
})
.ok()??;
value.coerce(&ty, exec_state) value.coerce(&ty, exec_state).ok_or_else(|| {
KclError::Semantic(KclErrorDetails {
message: format!("could not coerce {} value to type {}", value.human_friendly_type(), ty),
source_ranges: vec![source_range],
})
})
} }
impl BinaryPart { impl BinaryPart {
@ -1088,10 +1122,35 @@ impl Node<CallExpressionKw> {
None None
}; };
let formals = func.args(false);
#[allow(clippy::iter_over_hash_type)]
for (label, arg) in &args.kw_args.labeled {
match formals.iter().find(|p| &p.name == label) {
Some(p) => {
if !p.label_required {
exec_state.err(CompilationError::err(
arg.source_range,
format!(
"The function `{fn_name}` expects an unlabeled first parameter (`{label}`), but it is labelled in the call"
),
));
}
}
None => {
exec_state.err(CompilationError::err(
arg.source_range,
format!("`{label}` is not an argument of `{fn_name}`"),
));
}
}
}
// Attempt to call the function. // Attempt to call the function.
let mut return_value = { let mut return_value = {
// Don't early-return in this block. // Don't early-return in this block.
exec_state.mut_stack().push_new_env_for_rust_call();
let result = func.std_lib_fn()(exec_state, args).await; let result = func.std_lib_fn()(exec_state, args).await;
exec_state.mut_stack().pop_env();
if let Some(mut op) = op { if let Some(mut op) = op {
op.set_std_lib_call_is_error(result.is_err()); op.set_std_lib_call_is_error(result.is_err());
@ -1110,10 +1169,9 @@ impl Node<CallExpressionKw> {
Ok(return_value) Ok(return_value)
} }
FunctionKind::UserDefined => { FunctionKind::UserDefined => {
let source_range = SourceRange::from(self);
// Clone the function so that we can use a mutable reference to // Clone the function so that we can use a mutable reference to
// exec_state. // exec_state.
let func = exec_state.stack().get(fn_name, source_range)?.clone(); let func = exec_state.stack().get(fn_name, callsite)?.clone();
// Track call operation. // Track call operation.
let op_labeled_args = args let op_labeled_args = args
@ -1134,17 +1192,21 @@ impl Node<CallExpressionKw> {
source_range: callsite, source_range: callsite,
}); });
let return_value = func let Some(fn_src) = func.as_fn() else {
.call_fn_kw(args, exec_state, ctx.clone(), callsite) return Err(KclError::Semantic(KclErrorDetails {
.await message: "cannot call this because it isn't a function".to_string(),
.map_err(|e| { source_ranges: vec![callsite],
}));
};
let return_value = fn_src.call_kw(exec_state, ctx, args, callsite).await.map_err(|e| {
// Add the call expression to the source ranges. // Add the call expression to the source ranges.
// TODO currently ignored by the frontend // TODO currently ignored by the frontend
e.add_source_ranges(vec![source_range]) e.add_source_ranges(vec![callsite])
})?; })?;
let result = return_value.ok_or_else(move || { let result = return_value.ok_or_else(move || {
let mut source_ranges: Vec<SourceRange> = vec![source_range]; let mut source_ranges: Vec<SourceRange> = vec![callsite];
// We want to send the source range of the original function. // We want to send the source range of the original function.
if let KclValue::Function { meta, .. } = func { if let KclValue::Function { meta, .. } = func {
source_ranges = meta.iter().map(|m| m.source_range).collect(); source_ranges = meta.iter().map(|m| m.source_range).collect();
@ -1261,10 +1323,13 @@ impl Node<CallExpression> {
source_range: callsite, source_range: callsite,
}); });
let return_value = func let Some(fn_src) = func.as_fn() else {
.call_fn(fn_args, exec_state, ctx.clone(), source_range) return Err(KclError::Semantic(KclErrorDetails {
.await message: "cannot call this because it isn't a function".to_string(),
.map_err(|e| { source_ranges: vec![source_range],
}));
};
let return_value = fn_src.call(exec_state, ctx, fn_args, source_range).await.map_err(|e| {
// Add the call expression to the source ranges. // Add the call expression to the source ranges.
// TODO currently ignored by the frontend // TODO currently ignored by the frontend
e.add_source_ranges(vec![source_range]) e.add_source_ranges(vec![source_range])
@ -1754,6 +1819,28 @@ fn assign_args_to_params_kw(
mut args: crate::std::args::KwArgs, mut args: crate::std::args::KwArgs,
exec_state: &mut ExecState, exec_state: &mut ExecState,
) -> Result<(), KclError> { ) -> Result<(), KclError> {
#[allow(clippy::iter_over_hash_type)]
for (label, arg) in &args.labeled {
match function_expression.params.iter().find(|p| &p.identifier.name == label) {
Some(p) => {
if !p.labeled {
exec_state.err(CompilationError::err(
arg.source_range,
format!(
"This function expects an unlabeled first parameter (`{label}`), but it is labelled in the call"
),
));
}
}
None => {
exec_state.err(CompilationError::err(
arg.source_range,
format!("`{label}` is not an argument of this function"),
));
}
}
}
// Add the arguments to the memory. A new call frame should have already // Add the arguments to the memory. A new call frame should have already
// been created. // been created.
let source_ranges = vec![function_expression.into()]; let source_ranges = vec![function_expression.into()];
@ -1802,10 +1889,11 @@ fn assign_args_to_params_kw(
)?; )?;
} }
} }
Ok(()) Ok(())
} }
pub(crate) async fn call_user_defined_function( async fn call_user_defined_function(
args: Vec<Arg>, args: Vec<Arg>,
memory: EnvironmentRef, memory: EnvironmentRef,
function_expression: NodeRef<'_, FunctionExpression>, function_expression: NodeRef<'_, FunctionExpression>,
@ -1838,7 +1926,7 @@ pub(crate) async fn call_user_defined_function(
result result
} }
pub(crate) async fn call_user_defined_function_kw( async fn call_user_defined_function_kw(
args: crate::std::args::KwArgs, args: crate::std::args::KwArgs,
memory: EnvironmentRef, memory: EnvironmentRef,
function_expression: NodeRef<'_, FunctionExpression>, function_expression: NodeRef<'_, FunctionExpression>,
@ -1876,35 +1964,139 @@ impl FunctionSource {
&self, &self,
exec_state: &mut ExecState, exec_state: &mut ExecState,
ctx: &ExecutorContext, ctx: &ExecutorContext,
args: Vec<Arg>, mut args: Vec<Arg>,
source_range: SourceRange, callsite: SourceRange,
) -> Result<Option<KclValue>, KclError> { ) -> Result<Option<KclValue>, KclError> {
match self { match self {
FunctionSource::Std { func, props } => { FunctionSource::Std { props, .. } => {
if args.len() <= 1 {
let args = crate::std::Args::new_kw(
KwArgs {
unlabeled: args.pop(),
labeled: HashMap::new(),
},
callsite,
ctx.clone(),
exec_state.mod_local.pipe_value.clone().map(|v| Arg::new(v, callsite)),
);
self.call_kw(exec_state, ctx, args, callsite).await
} else {
Err(KclError::Semantic(KclErrorDetails {
message: format!("{} requires its arguments to be labelled", props.name),
source_ranges: vec![callsite],
}))
}
}
FunctionSource::User { ast, memory, .. } => {
call_user_defined_function(args, *memory, ast, exec_state, ctx).await
}
FunctionSource::None => unreachable!(),
}
}
pub async fn call_kw(
&self,
exec_state: &mut ExecState,
ctx: &ExecutorContext,
mut args: crate::std::Args,
callsite: SourceRange,
) -> Result<Option<KclValue>, KclError> {
match self {
FunctionSource::Std { func, ast, props } => {
if props.deprecated { if props.deprecated {
exec_state.warn(CompilationError::err( exec_state.warn(CompilationError::err(
source_range, callsite,
format!( format!(
"`{}` is deprecated, see the docs for a recommended replacement", "`{}` is deprecated, see the docs for a recommended replacement",
props.name props.name
), ),
)); ));
} }
let args = crate::std::Args::new(
args,
source_range,
ctx.clone(),
exec_state
.mod_local
.pipe_value
.clone()
.map(|v| Arg::new(v, source_range)),
);
func(exec_state, args).await.map(Some) #[allow(clippy::iter_over_hash_type)]
for (label, arg) in &mut args.kw_args.labeled {
match ast.params.iter().find(|p| &p.identifier.name == label) {
Some(p) => {
if !p.labeled {
exec_state.err(CompilationError::err(
arg.source_range,
format!(
"The function `{}` expects an unlabeled first parameter (`{label}`), but it is labelled in the call",
props.name
),
));
}
if let Some(ty) = &p.type_ {
arg.value = arg
.value
.coerce(
&RuntimeType::from_parsed(ty.inner.clone(), exec_state, arg.source_range)
.unwrap(),
exec_state,
)
.ok_or_else(|| {
KclError::Semantic(KclErrorDetails {
message: format!(
"{label} requires a value with type `{}`, but found {}",
ty.inner,
arg.value.human_friendly_type()
),
source_ranges: vec![callsite],
})
})?;
}
}
None => {
exec_state.err(CompilationError::err(
arg.source_range,
format!("`{label}` is not an argument of `{}`", props.name),
));
}
}
}
if let Some(arg) = &mut args.kw_args.unlabeled {
if let Some(p) = ast.params.iter().find(|p| !p.labeled) {
if let Some(ty) = &p.type_ {
arg.value = arg
.value
.coerce(
&RuntimeType::from_parsed(ty.inner.clone(), exec_state, arg.source_range).unwrap(),
exec_state,
)
.ok_or_else(|| {
KclError::Semantic(KclErrorDetails {
message: format!(
"The input argument of {} requires a value with type `{}`, but found {}",
props.name,
ty.inner,
arg.value.human_friendly_type()
),
source_ranges: vec![callsite],
})
})?;
}
}
}
// Attempt to call the function.
exec_state.mut_stack().push_new_env_for_rust_call();
let mut result = {
// Don't early-return in this block.
let result = func(exec_state, args).await;
exec_state.mut_stack().pop_env();
// TODO support recording op into the feature tree
result
}?;
update_memory_for_tags_of_geometry(&mut result, exec_state)?;
Ok(Some(result))
} }
FunctionSource::User { ast, memory, .. } => { FunctionSource::User { ast, memory, .. } => {
call_user_defined_function(args, *memory, ast, exec_state, ctx).await call_user_defined_function_kw(args.kw_args, *memory, ast, exec_state, ctx).await
} }
FunctionSource::None => unreachable!(), FunctionSource::None => unreachable!(),
} }

View File

@ -104,7 +104,7 @@ impl From<SolidOrSketchOrImportedGeometry> for crate::execution::KclValue {
.into_iter() .into_iter()
.map(|s| crate::execution::KclValue::Solid { value: Box::new(s) }) .map(|s| crate::execution::KclValue::Solid { value: Box::new(s) })
.collect(), .collect(),
ty: crate::execution::PrimitiveType::Solid, ty: crate::execution::types::RuntimeType::solid(),
} }
} }
} }
@ -119,7 +119,7 @@ impl From<SolidOrSketchOrImportedGeometry> for crate::execution::KclValue {
.into_iter() .into_iter()
.map(|s| crate::execution::KclValue::Sketch { value: Box::new(s) }) .map(|s| crate::execution::KclValue::Sketch { value: Box::new(s) })
.collect(), .collect(),
ty: crate::execution::PrimitiveType::Sketch, ty: crate::execution::types::RuntimeType::sketch(),
} }
} }
} }

View File

@ -17,7 +17,7 @@ use uuid::Uuid;
use crate::{ use crate::{
errors::{KclError, KclErrorDetails}, errors::{KclError, KclErrorDetails},
execution::{annotations, kcl_value::UnitLen, ExecState, ExecutorContext, ImportedGeometry}, execution::{annotations, types::UnitLen, ExecState, ExecutorContext, ImportedGeometry},
fs::FileSystem, fs::FileSystem,
parsing::ast::types::{Annotation, Node}, parsing::ast::types::{Annotation, Node},
source_range::SourceRange, source_range::SourceRange,

View File

@ -1,30 +1,21 @@
use std::{collections::HashMap, fmt}; use std::collections::HashMap;
use anyhow::Result; use anyhow::Result;
use schemars::JsonSchema; use schemars::JsonSchema;
use serde::{Deserialize, Serialize}; use serde::Serialize;
use super::{ use super::{memory::EnvironmentRef, MetaSettings};
memory::{self, EnvironmentRef},
MetaSettings, Point3d,
};
use crate::{ use crate::{
errors::KclErrorDetails, errors::KclErrorDetails,
execution::{ execution::{
ExecState, ExecutorContext, Face, Helix, ImportedGeometry, Metadata, Plane, Sketch, Solid, TagIdentifier, types::{NumericType, PrimitiveType, RuntimeType},
Face, Helix, ImportedGeometry, Metadata, Plane, Sketch, Solid, TagIdentifier,
}, },
parsing::{ parsing::ast::types::{
ast::types::{ DefaultParamVal, FunctionExpression, KclNone, Literal, LiteralValue, Node, TagDeclarator, TagNode,
DefaultParamVal, FunctionExpression, KclNone, Literal, LiteralValue, Node,
PrimitiveType as AstPrimitiveType, TagDeclarator, TagNode, Type,
}, },
token::NumericSuffix, std::StdFnProps,
}, KclError, ModuleId, SourceRange,
std::{
args::{Arg, FromKclValue},
StdFnProps,
},
CompilationError, KclError, ModuleId, SourceRange,
}; };
pub type KclObjectFields = HashMap<String, KclValue>; pub type KclObjectFields = HashMap<String, KclValue>;
@ -65,7 +56,7 @@ pub enum KclValue {
value: Vec<KclValue>, value: Vec<KclValue>,
// The type of values, not the array type. // The type of values, not the array type.
#[serde(skip)] #[serde(skip)]
ty: PrimitiveType, ty: RuntimeType,
}, },
Object { Object {
value: KclObjectFields, value: KclObjectFields,
@ -105,7 +96,7 @@ pub enum KclValue {
#[ts(skip)] #[ts(skip)]
Type { Type {
#[serde(skip)] #[serde(skip)]
value: Option<(PrimitiveType, StdFnProps)>, value: TypeDef,
#[serde(skip)] #[serde(skip)]
meta: Vec<Metadata>, meta: Vec<Metadata>,
}, },
@ -122,6 +113,7 @@ pub enum FunctionSource {
None, None,
Std { Std {
func: crate::std::StdFn, func: crate::std::StdFn,
ast: crate::parsing::ast::types::BoxNode<FunctionExpression>,
props: StdFnProps, props: StdFnProps,
}, },
User { User {
@ -142,6 +134,12 @@ impl JsonSchema for FunctionSource {
} }
} }
#[derive(Debug, Clone, PartialEq)]
pub enum TypeDef {
RustRepr(PrimitiveType, StdFnProps),
Alias(RuntimeType),
}
impl From<Vec<Sketch>> for KclValue { impl From<Vec<Sketch>> for KclValue {
fn from(mut eg: Vec<Sketch>) -> Self { fn from(mut eg: Vec<Sketch>) -> Self {
if eg.len() == 1 { if eg.len() == 1 {
@ -154,7 +152,7 @@ impl From<Vec<Sketch>> for KclValue {
.into_iter() .into_iter()
.map(|s| KclValue::Sketch { value: Box::new(s) }) .map(|s| KclValue::Sketch { value: Box::new(s) })
.collect(), .collect(),
ty: crate::execution::PrimitiveType::Sketch, ty: RuntimeType::Primitive(PrimitiveType::Sketch),
} }
} }
} }
@ -169,7 +167,7 @@ impl From<Vec<Solid>> for KclValue {
} else { } else {
KclValue::HomArray { KclValue::HomArray {
value: eg.into_iter().map(|s| KclValue::Solid { value: Box::new(s) }).collect(), value: eg.into_iter().map(|s| KclValue::Solid { value: Box::new(s) }).collect(),
ty: crate::execution::PrimitiveType::Solid, ty: RuntimeType::Primitive(PrimitiveType::Solid),
} }
} }
} }
@ -553,347 +551,13 @@ impl KclValue {
Ok(*b) Ok(*b)
} }
/// True if `self` has a type which is a subtype of `ty` without coercion. pub fn as_fn(&self) -> Option<&FunctionSource> {
pub fn has_type(&self, ty: &RuntimeType) -> bool {
let Some(self_ty) = self.principal_type() else {
return false;
};
self_ty.subtype(ty)
}
/// Coerce `self` to a new value which has `ty` as it's closest supertype.
///
/// If the result is Some, then:
/// - result.principal_type().unwrap().subtype(ty)
///
/// If self.principal_type() == ty then result == self
pub fn coerce(&self, ty: &RuntimeType, exec_state: &mut ExecState) -> Option<KclValue> {
match ty {
RuntimeType::Primitive(ty) => self.coerce_to_primitive_type(ty, exec_state),
RuntimeType::Array(ty, len) => self.coerce_to_array_type(ty, *len, exec_state),
RuntimeType::Tuple(tys) => self.coerce_to_tuple_type(tys, exec_state),
RuntimeType::Union(tys) => self.coerce_to_union_type(tys, exec_state),
RuntimeType::Object(tys) => self.coerce_to_object_type(tys, exec_state),
}
}
fn coerce_to_primitive_type(&self, ty: &PrimitiveType, exec_state: &mut ExecState) -> Option<KclValue> {
let value = match self {
KclValue::MixedArray { value, .. } | KclValue::HomArray { value, .. } if value.len() == 1 => &value[0],
_ => self,
};
match ty {
// TODO numeric type coercions
PrimitiveType::Number(_ty) => match value {
KclValue::Number { .. } => Some(value.clone()),
_ => None,
},
PrimitiveType::String => match value {
KclValue::String { .. } => Some(value.clone()),
_ => None,
},
PrimitiveType::Boolean => match value {
KclValue::Bool { .. } => Some(value.clone()),
_ => None,
},
PrimitiveType::Sketch => match value {
KclValue::Sketch { .. } => Some(value.clone()),
_ => None,
},
PrimitiveType::Solid => match value {
KclValue::Solid { .. } => Some(value.clone()),
_ => None,
},
PrimitiveType::Plane => match value {
KclValue::Plane { .. } => Some(value.clone()),
KclValue::Object { value, meta } => {
let origin = value.get("origin").and_then(Point3d::from_kcl_val)?;
let x_axis = value.get("xAxis").and_then(Point3d::from_kcl_val)?;
let y_axis = value.get("yAxis").and_then(Point3d::from_kcl_val)?;
let z_axis = value.get("zAxis").and_then(Point3d::from_kcl_val)?;
let id = exec_state.mod_local.id_generator.next_uuid();
let plane = Plane {
id,
artifact_id: id.into(),
origin,
x_axis,
y_axis,
z_axis,
value: super::PlaneType::Uninit,
// TODO use length unit from origin
units: exec_state.length_unit(),
meta: meta.clone(),
};
Some(KclValue::Plane { value: Box::new(plane) })
}
_ => None,
},
PrimitiveType::ImportedGeometry => match value {
KclValue::ImportedGeometry { .. } => Some(value.clone()),
_ => None,
},
}
}
fn coerce_to_array_type(&self, ty: &PrimitiveType, len: ArrayLen, exec_state: &mut ExecState) -> Option<KclValue> {
match self { match self {
KclValue::HomArray { value, ty: aty } => { KclValue::Function { value, .. } => Some(value),
// TODO could check types of values individually
if aty != ty {
return None;
}
let value = match len {
ArrayLen::None => value.clone(),
ArrayLen::NonEmpty => {
if value.is_empty() {
return None;
}
value.clone()
}
ArrayLen::Known(n) => {
if n != value.len() {
return None;
}
value[..n].to_vec()
}
};
Some(KclValue::HomArray { value, ty: ty.clone() })
}
KclValue::MixedArray { value, .. } => {
let value = match len {
ArrayLen::None => value.clone(),
ArrayLen::NonEmpty => {
if value.is_empty() {
return None;
}
value.clone()
}
ArrayLen::Known(n) => {
if n != value.len() {
return None;
}
value[..n].to_vec()
}
};
let rt = RuntimeType::Primitive(ty.clone());
let value = value
.iter()
.map(|v| v.coerce(&rt, exec_state))
.collect::<Option<Vec<_>>>()?;
Some(KclValue::HomArray { value, ty: ty.clone() })
}
KclValue::KclNone { .. } if len.satisfied(0) => Some(KclValue::HomArray {
value: Vec::new(),
ty: ty.clone(),
}),
value if len.satisfied(1) => {
if value.has_type(&RuntimeType::Primitive(ty.clone())) {
Some(KclValue::HomArray {
value: vec![value.clone()],
ty: ty.clone(),
})
} else {
None
}
}
_ => None, _ => None,
} }
} }
fn coerce_to_tuple_type(&self, tys: &[PrimitiveType], exec_state: &mut ExecState) -> Option<KclValue> {
match self {
KclValue::MixedArray { value, .. } | KclValue::HomArray { value, .. } => {
if value.len() < tys.len() {
return None;
}
let mut result = Vec::new();
for (i, t) in tys.iter().enumerate() {
result.push(value[i].coerce_to_primitive_type(t, exec_state)?);
}
Some(KclValue::MixedArray {
value: result,
meta: Vec::new(),
})
}
KclValue::KclNone { meta, .. } if tys.is_empty() => Some(KclValue::MixedArray {
value: Vec::new(),
meta: meta.clone(),
}),
value if tys.len() == 1 => {
if value.has_type(&RuntimeType::Primitive(tys[0].clone())) {
Some(KclValue::MixedArray {
value: vec![value.clone()],
meta: Vec::new(),
})
} else {
None
}
}
_ => None,
}
}
fn coerce_to_union_type(&self, tys: &[RuntimeType], exec_state: &mut ExecState) -> Option<KclValue> {
for t in tys {
if let Some(v) = self.coerce(t, exec_state) {
return Some(v);
}
}
None
}
fn coerce_to_object_type(&self, tys: &[(String, RuntimeType)], _exec_state: &mut ExecState) -> Option<KclValue> {
match self {
KclValue::Object { value, .. } => {
for (s, t) in tys {
// TODO coerce fields
if !value.get(s)?.has_type(t) {
return None;
}
}
// TODO remove non-required fields
Some(self.clone())
}
_ => None,
}
}
pub fn principal_type(&self) -> Option<RuntimeType> {
match self {
KclValue::Bool { .. } => Some(RuntimeType::Primitive(PrimitiveType::Boolean)),
KclValue::Number { ty, .. } => Some(RuntimeType::Primitive(PrimitiveType::Number(ty.clone()))),
KclValue::String { .. } => Some(RuntimeType::Primitive(PrimitiveType::String)),
KclValue::Object { value, .. } => {
let properties = value
.iter()
.map(|(k, v)| v.principal_type().map(|t| (k.clone(), t)))
.collect::<Option<Vec<_>>>()?;
Some(RuntimeType::Object(properties))
}
KclValue::Plane { .. } => Some(RuntimeType::Primitive(PrimitiveType::Plane)),
KclValue::Sketch { .. } => Some(RuntimeType::Primitive(PrimitiveType::Sketch)),
KclValue::Solid { .. } => Some(RuntimeType::Primitive(PrimitiveType::Solid)),
KclValue::ImportedGeometry(..) => Some(RuntimeType::Primitive(PrimitiveType::ImportedGeometry)),
KclValue::MixedArray { value, .. } => Some(RuntimeType::Tuple(
value
.iter()
.map(|v| v.principal_type().and_then(RuntimeType::primitive))
.collect::<Option<Vec<_>>>()?,
)),
KclValue::HomArray { ty, value, .. } => Some(RuntimeType::Array(ty.clone(), ArrayLen::Known(value.len()))),
KclValue::Face { .. } => None,
KclValue::Helix { .. }
| KclValue::Function { .. }
| KclValue::Module { .. }
| KclValue::TagIdentifier(_)
| KclValue::TagDeclarator(_)
| KclValue::KclNone { .. }
| KclValue::Type { .. }
| KclValue::Uuid { .. } => None,
}
}
/// If this memory item is a function, call it with the given arguments, return its val as Ok.
/// If it's not a function, return Err.
pub async fn call_fn(
&self,
args: Vec<Arg>,
exec_state: &mut ExecState,
ctx: ExecutorContext,
source_range: SourceRange,
) -> Result<Option<KclValue>, KclError> {
match self {
KclValue::Function {
value: FunctionSource::Std { func, props },
..
} => {
if props.deprecated {
exec_state.warn(CompilationError::err(
source_range,
format!(
"`{}` is deprecated, see the docs for a recommended replacement",
props.name
),
));
}
exec_state.mut_stack().push_new_env_for_rust_call();
let args = crate::std::Args::new(
args,
source_range,
ctx.clone(),
exec_state
.mod_local
.pipe_value
.clone()
.map(|v| Arg::new(v, source_range)),
);
let result = func(exec_state, args).await.map(Some);
exec_state.mut_stack().pop_env();
result
}
KclValue::Function {
value: FunctionSource::User { ast, memory, .. },
..
} => crate::execution::exec_ast::call_user_defined_function(args, *memory, ast, exec_state, &ctx).await,
_ => Err(KclError::Semantic(KclErrorDetails {
message: "cannot call this because it isn't a function".to_string(),
source_ranges: vec![source_range],
})),
}
}
/// If this is a function, call it by applying keyword arguments.
/// If it's not a function, returns an error.
pub async fn call_fn_kw(
&self,
args: crate::std::Args,
exec_state: &mut ExecState,
ctx: ExecutorContext,
callsite: SourceRange,
) -> Result<Option<KclValue>, KclError> {
match self {
KclValue::Function {
value: FunctionSource::Std { func: _, props },
..
} => {
if props.deprecated {
exec_state.warn(CompilationError::err(
callsite,
format!(
"`{}` is deprecated, see the docs for a recommended replacement",
props.name
),
));
}
todo!("Implement KCL stdlib fns with keyword args");
}
KclValue::Function {
value: FunctionSource::User { ast, memory, .. },
..
} => {
crate::execution::exec_ast::call_user_defined_function_kw(args.kw_args, *memory, ast, exec_state, &ctx)
.await
}
_ => Err(KclError::Semantic(KclErrorDetails {
message: "cannot call this because it isn't a function".to_string(),
source_ranges: vec![callsite],
})),
}
}
pub fn value_str(&self) -> Option<String> { pub fn value_str(&self) -> Option<String> {
match self { match self {
KclValue::Bool { value, .. } => Some(format!("{value}")), KclValue::Bool { value, .. } => Some(format!("{value}")),
@ -919,447 +583,3 @@ impl KclValue {
} }
} }
} }
#[derive(Debug, Clone, PartialEq)]
pub enum RuntimeType {
Primitive(PrimitiveType),
Array(PrimitiveType, ArrayLen),
Union(Vec<RuntimeType>),
Tuple(Vec<PrimitiveType>),
Object(Vec<(String, RuntimeType)>),
}
impl RuntimeType {
pub fn from_parsed(
value: Type,
exec_state: &mut ExecState,
source_range: SourceRange,
) -> Result<Option<Self>, CompilationError> {
Ok(match value {
Type::Primitive(pt) => {
PrimitiveType::from_parsed(pt, exec_state, source_range)?.map(RuntimeType::Primitive)
}
Type::Array(pt) => {
PrimitiveType::from_parsed(pt, exec_state, source_range)?.map(|t| RuntimeType::Array(t, ArrayLen::None))
}
Type::Object { properties } => properties
.into_iter()
.map(|p| {
let pt = match p.type_ {
Some(t) => t,
None => return Ok(None),
};
Ok(RuntimeType::from_parsed(pt.inner, exec_state, source_range)?
.map(|ty| (p.identifier.inner.name, ty)))
})
.collect::<Result<Option<Vec<_>>, CompilationError>>()?
.map(RuntimeType::Object),
})
}
pub fn human_friendly_type(&self) -> String {
match self {
RuntimeType::Primitive(ty) => ty.to_string(),
RuntimeType::Array(ty, ArrayLen::None) => format!("an array of {}", ty.display_multiple()),
RuntimeType::Array(ty, ArrayLen::NonEmpty) => format!("one or more {}", ty.display_multiple()),
RuntimeType::Array(ty, ArrayLen::Known(n)) => format!("an array of {n} {}", ty.display_multiple()),
RuntimeType::Union(tys) => tys
.iter()
.map(Self::human_friendly_type)
.collect::<Vec<_>>()
.join(" or "),
RuntimeType::Tuple(tys) => format!(
"an array with values of types ({})",
tys.iter().map(PrimitiveType::to_string).collect::<Vec<_>>().join(", ")
),
RuntimeType::Object(_) => format!("an object with fields {}", self),
}
}
// Subtype with no coercion, including refining numeric types.
fn subtype(&self, sup: &RuntimeType) -> bool {
use RuntimeType::*;
match (self, sup) {
(Primitive(t1), Primitive(t2)) => t1 == t2,
// TODO arrays could be covariant
(Array(t1, l1), Array(t2, l2)) => t1 == t2 && l1.subtype(*l2),
(Tuple(t1), Tuple(t2)) => t1 == t2,
(Tuple(t1), Array(t2, l2)) => (l2.satisfied(t1.len())) && t1.iter().all(|t| t == t2),
(Union(ts1), Union(ts2)) => ts1.iter().all(|t| ts2.contains(t)),
(t1, Union(ts2)) => ts2.contains(t1),
// TODO record subtyping - subtype can be larger, fields can be covariant.
(Object(t1), Object(t2)) => t1 == t2,
_ => false,
}
}
fn primitive(self) -> Option<PrimitiveType> {
match self {
RuntimeType::Primitive(t) => Some(t),
_ => None,
}
}
}
impl fmt::Display for RuntimeType {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
RuntimeType::Primitive(t) => t.fmt(f),
RuntimeType::Array(t, l) => match l {
ArrayLen::None => write!(f, "[{t}]"),
ArrayLen::NonEmpty => write!(f, "[{t}; 1+]"),
ArrayLen::Known(n) => write!(f, "[{t}; {n}]"),
},
RuntimeType::Tuple(ts) => write!(
f,
"[{}]",
ts.iter().map(|t| t.to_string()).collect::<Vec<_>>().join(", ")
),
RuntimeType::Union(ts) => write!(
f,
"{}",
ts.iter().map(|t| t.to_string()).collect::<Vec<_>>().join(" | ")
),
RuntimeType::Object(items) => write!(
f,
"{{ {} }}",
items
.iter()
.map(|(n, t)| format!("{n}: {t}"))
.collect::<Vec<_>>()
.join(", ")
),
}
}
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum ArrayLen {
None,
NonEmpty,
Known(usize),
}
impl ArrayLen {
pub fn subtype(self, other: ArrayLen) -> bool {
match (self, other) {
(_, ArrayLen::None) => true,
(ArrayLen::NonEmpty, ArrayLen::NonEmpty) => true,
(ArrayLen::Known(size), ArrayLen::NonEmpty) if size > 0 => true,
(ArrayLen::Known(s1), ArrayLen::Known(s2)) if s1 == s2 => true,
_ => false,
}
}
/// True if the length constraint is satisfied by the supplied length.
fn satisfied(self, len: usize) -> bool {
match self {
ArrayLen::None => true,
ArrayLen::NonEmpty => len > 0,
ArrayLen::Known(s) => len == s,
}
}
}
#[derive(Debug, Clone, PartialEq)]
pub enum PrimitiveType {
Number(NumericType),
String,
Boolean,
Sketch,
Solid,
Plane,
ImportedGeometry,
}
impl PrimitiveType {
fn from_parsed(
value: AstPrimitiveType,
exec_state: &mut ExecState,
source_range: SourceRange,
) -> Result<Option<Self>, CompilationError> {
Ok(match value {
AstPrimitiveType::String => Some(PrimitiveType::String),
AstPrimitiveType::Boolean => Some(PrimitiveType::Boolean),
AstPrimitiveType::Number(suffix) => Some(PrimitiveType::Number(NumericType::from_parsed(
suffix,
&exec_state.mod_local.settings,
))),
AstPrimitiveType::Named(name) => {
let ty_val = exec_state
.stack()
.get(&format!("{}{}", memory::TYPE_PREFIX, name.name), source_range)
.map_err(|_| CompilationError::err(source_range, format!("Unknown type: {}", name.name)))?;
let (ty, _) = match ty_val {
KclValue::Type { value: Some(ty), .. } => ty,
_ => unreachable!(),
};
Some(ty.clone())
}
_ => None,
})
}
fn display_multiple(&self) -> String {
match self {
PrimitiveType::Number(NumericType::Known(unit)) => format!("numbers({unit})"),
PrimitiveType::Number(_) => "numbers".to_owned(),
PrimitiveType::String => "strings".to_owned(),
PrimitiveType::Boolean => "bools".to_owned(),
PrimitiveType::Sketch => "Sketches".to_owned(),
PrimitiveType::Solid => "Solids".to_owned(),
PrimitiveType::Plane => "Planes".to_owned(),
PrimitiveType::ImportedGeometry => "imported geometries".to_owned(),
}
}
}
impl fmt::Display for PrimitiveType {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
PrimitiveType::Number(NumericType::Known(unit)) => write!(f, "number({unit})"),
PrimitiveType::Number(_) => write!(f, "number"),
PrimitiveType::String => write!(f, "string"),
PrimitiveType::Boolean => write!(f, "bool"),
PrimitiveType::Sketch => write!(f, "Sketch"),
PrimitiveType::Solid => write!(f, "Solid"),
PrimitiveType::Plane => write!(f, "Plane"),
PrimitiveType::ImportedGeometry => write!(f, "imported geometry"),
}
}
}
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
#[ts(export)]
#[serde(tag = "type")]
pub enum NumericType {
// Specified by the user (directly or indirectly)
Known(UnitType),
// Unspecified, using defaults
Default { len: UnitLen, angle: UnitAngle },
// Exceeded the ability of the type system to track.
Unknown,
// Type info has been explicitly cast away.
Any,
}
impl NumericType {
pub fn count() -> Self {
NumericType::Known(UnitType::Count)
}
/// Combine two types when we expect them to be equal.
pub fn combine_eq(self, other: &NumericType) -> NumericType {
if &self == other {
self
} else {
NumericType::Unknown
}
}
/// Combine n types when we expect them to be equal.
///
/// Precondition: tys.len() > 0
pub fn combine_n_eq(tys: &[NumericType]) -> NumericType {
let ty0 = tys[0].clone();
for t in &tys[1..] {
if t != &ty0 {
return NumericType::Unknown;
}
}
ty0
}
/// Combine two types in addition-like operations.
pub fn combine_add(a: NumericType, b: NumericType) -> NumericType {
if a == b {
return a;
}
NumericType::Unknown
}
/// Combine two types in multiplication-like operations.
pub fn combine_mul(a: NumericType, b: NumericType) -> NumericType {
if a == NumericType::count() {
return b;
}
if b == NumericType::count() {
return a;
}
NumericType::Unknown
}
/// Combine two types in division-like operations.
pub fn combine_div(a: NumericType, b: NumericType) -> NumericType {
if b == NumericType::count() {
return a;
}
NumericType::Unknown
}
pub fn from_parsed(suffix: NumericSuffix, settings: &super::MetaSettings) -> Self {
match suffix {
NumericSuffix::None => NumericType::Default {
len: settings.default_length_units,
angle: settings.default_angle_units,
},
NumericSuffix::Count => NumericType::Known(UnitType::Count),
NumericSuffix::Mm => NumericType::Known(UnitType::Length(UnitLen::Mm)),
NumericSuffix::Cm => NumericType::Known(UnitType::Length(UnitLen::Cm)),
NumericSuffix::M => NumericType::Known(UnitType::Length(UnitLen::M)),
NumericSuffix::Inch => NumericType::Known(UnitType::Length(UnitLen::Inches)),
NumericSuffix::Ft => NumericType::Known(UnitType::Length(UnitLen::Feet)),
NumericSuffix::Yd => NumericType::Known(UnitType::Length(UnitLen::Yards)),
NumericSuffix::Deg => NumericType::Known(UnitType::Angle(UnitAngle::Degrees)),
NumericSuffix::Rad => NumericType::Known(UnitType::Angle(UnitAngle::Radians)),
}
}
}
impl From<UnitLen> for NumericType {
fn from(value: UnitLen) -> Self {
NumericType::Known(UnitType::Length(value))
}
}
impl From<UnitAngle> for NumericType {
fn from(value: UnitAngle) -> Self {
NumericType::Known(UnitType::Angle(value))
}
}
#[derive(Debug, Clone, Copy, Deserialize, Serialize, PartialEq, Eq, ts_rs::TS, JsonSchema)]
#[ts(export)]
#[serde(tag = "type")]
pub enum UnitType {
Count,
Length(UnitLen),
Angle(UnitAngle),
}
impl std::fmt::Display for UnitType {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
UnitType::Count => write!(f, "_"),
UnitType::Length(l) => l.fmt(f),
UnitType::Angle(a) => a.fmt(f),
}
}
}
// TODO called UnitLen so as not to clash with UnitLength in settings)
/// A unit of length.
#[derive(Debug, Default, Clone, Copy, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema, Eq)]
#[ts(export)]
#[serde(tag = "type")]
pub enum UnitLen {
#[default]
Mm,
Cm,
M,
Inches,
Feet,
Yards,
}
impl std::fmt::Display for UnitLen {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
UnitLen::Mm => write!(f, "mm"),
UnitLen::Cm => write!(f, "cm"),
UnitLen::M => write!(f, "m"),
UnitLen::Inches => write!(f, "in"),
UnitLen::Feet => write!(f, "ft"),
UnitLen::Yards => write!(f, "yd"),
}
}
}
impl TryFrom<NumericSuffix> for UnitLen {
type Error = ();
fn try_from(suffix: NumericSuffix) -> std::result::Result<Self, Self::Error> {
match suffix {
NumericSuffix::Mm => Ok(Self::Mm),
NumericSuffix::Cm => Ok(Self::Cm),
NumericSuffix::M => Ok(Self::M),
NumericSuffix::Inch => Ok(Self::Inches),
NumericSuffix::Ft => Ok(Self::Feet),
NumericSuffix::Yd => Ok(Self::Yards),
_ => Err(()),
}
}
}
impl From<crate::UnitLength> for UnitLen {
fn from(unit: crate::UnitLength) -> Self {
match unit {
crate::UnitLength::Cm => UnitLen::Cm,
crate::UnitLength::Ft => UnitLen::Feet,
crate::UnitLength::In => UnitLen::Inches,
crate::UnitLength::M => UnitLen::M,
crate::UnitLength::Mm => UnitLen::Mm,
crate::UnitLength::Yd => UnitLen::Yards,
}
}
}
impl From<UnitLen> for crate::UnitLength {
fn from(unit: UnitLen) -> Self {
match unit {
UnitLen::Cm => crate::UnitLength::Cm,
UnitLen::Feet => crate::UnitLength::Ft,
UnitLen::Inches => crate::UnitLength::In,
UnitLen::M => crate::UnitLength::M,
UnitLen::Mm => crate::UnitLength::Mm,
UnitLen::Yards => crate::UnitLength::Yd,
}
}
}
impl From<UnitLen> for kittycad_modeling_cmds::units::UnitLength {
fn from(unit: UnitLen) -> Self {
match unit {
UnitLen::Cm => kittycad_modeling_cmds::units::UnitLength::Centimeters,
UnitLen::Feet => kittycad_modeling_cmds::units::UnitLength::Feet,
UnitLen::Inches => kittycad_modeling_cmds::units::UnitLength::Inches,
UnitLen::M => kittycad_modeling_cmds::units::UnitLength::Meters,
UnitLen::Mm => kittycad_modeling_cmds::units::UnitLength::Millimeters,
UnitLen::Yards => kittycad_modeling_cmds::units::UnitLength::Yards,
}
}
}
/// A unit of angle.
#[derive(Debug, Default, Clone, Copy, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema, Eq)]
#[ts(export)]
#[serde(tag = "type")]
pub enum UnitAngle {
#[default]
Degrees,
Radians,
}
impl std::fmt::Display for UnitAngle {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
UnitAngle::Degrees => write!(f, "deg"),
UnitAngle::Radians => write!(f, "rad"),
}
}
}
impl TryFrom<NumericSuffix> for UnitAngle {
type Error = ();
fn try_from(suffix: NumericSuffix) -> std::result::Result<Self, Self::Error> {
match suffix {
NumericSuffix::Deg => Ok(Self::Degrees),
NumericSuffix::Rad => Ok(Self::Radians),
_ => Err(()),
}
}
}

View File

@ -1055,7 +1055,7 @@ mod env {
#[cfg(test)] #[cfg(test)]
mod test { mod test {
use super::*; use super::*;
use crate::execution::kcl_value::{FunctionSource, NumericType}; use crate::execution::{kcl_value::FunctionSource, types::NumericType};
fn sr() -> SourceRange { fn sr() -> SourceRange {
SourceRange::default() SourceRange::default()

View File

@ -15,7 +15,7 @@ pub(crate) use import::{
import_foreign, send_to_engine as send_import_to_engine, PreImportedGeometry, ZOO_COORD_SYSTEM, import_foreign, send_to_engine as send_import_to_engine, PreImportedGeometry, ZOO_COORD_SYSTEM,
}; };
use indexmap::IndexMap; use indexmap::IndexMap;
pub use kcl_value::{KclObjectFields, KclValue, PrimitiveType, UnitAngle, UnitLen}; pub use kcl_value::{KclObjectFields, KclValue};
use kcmc::{ use kcmc::{
each_cmd as mcmd, each_cmd as mcmd,
ok_response::{output::TakeSnapshot, OkModelingCmdResponse}, ok_response::{output::TakeSnapshot, OkModelingCmdResponse},
@ -34,6 +34,7 @@ use crate::{
execution::{ execution::{
artifact::build_artifact_graph, artifact::build_artifact_graph,
cache::{CacheInformation, CacheResult}, cache::{CacheInformation, CacheResult},
types::{UnitAngle, UnitLen},
}, },
fs::FileManager, fs::FileManager,
modules::{ModuleId, ModulePath}, modules::{ModuleId, ModulePath},
@ -55,6 +56,7 @@ mod import;
pub(crate) mod kcl_value; pub(crate) mod kcl_value;
mod memory; mod memory;
mod state; mod state;
pub(crate) mod types;
/// Outcome of executing a program. This is used in TS. /// Outcome of executing a program. This is used in TS.
#[derive(Debug, Clone, Serialize, ts_rs::TS)] #[derive(Debug, Clone, Serialize, ts_rs::TS)]
@ -1397,6 +1399,22 @@ const answer = returnX()"#;
assert!(errs.is_empty()); assert!(errs.is_empty());
} }
#[tokio::test(flavor = "multi_thread")]
async fn type_aliases() {
let text = r#"type MyTy = [number; 2]
fn foo(x: MyTy) {
return x[0]
}
foo([0, 1])
type Other = MyTy | Helix
"#;
let result = parse_execute(text).await.unwrap();
let errs = result.exec_state.errors();
assert!(errs.is_empty());
}
#[tokio::test(flavor = "multi_thread")] #[tokio::test(flavor = "multi_thread")]
async fn test_cannot_shebang_in_fn() { async fn test_cannot_shebang_in_fn() {
let ast = r#" let ast = r#"

View File

@ -12,10 +12,9 @@ use crate::{
execution::{ execution::{
annotations, annotations,
id_generator::IdGenerator, id_generator::IdGenerator,
kcl_value,
memory::{ProgramMemory, Stack}, memory::{ProgramMemory, Stack},
Artifact, ArtifactCommand, ArtifactGraph, ArtifactId, EnvironmentRef, ExecOutcome, ExecutorSettings, KclValue, types, Artifact, ArtifactCommand, ArtifactGraph, ArtifactId, EnvironmentRef, ExecOutcome, ExecutorSettings,
Operation, UnitAngle, UnitLen, KclValue, Operation, UnitAngle, UnitLen,
}, },
modules::{ModuleId, ModuleInfo, ModuleLoader, ModulePath, ModuleRepr, ModuleSource}, modules::{ModuleId, ModuleInfo, ModuleLoader, ModulePath, ModuleRepr, ModuleSource},
parsing::ast::types::Annotation, parsing::ast::types::Annotation,
@ -310,8 +309,8 @@ impl ModuleState {
#[ts(export)] #[ts(export)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct MetaSettings { pub struct MetaSettings {
pub default_length_units: kcl_value::UnitLen, pub default_length_units: types::UnitLen,
pub default_angle_units: kcl_value::UnitAngle, pub default_angle_units: types::UnitAngle,
pub std_path: Option<String>, pub std_path: Option<String>,
} }
@ -326,12 +325,12 @@ impl MetaSettings {
match &*p.inner.key.name { match &*p.inner.key.name {
annotations::SETTINGS_UNIT_LENGTH => { annotations::SETTINGS_UNIT_LENGTH => {
let value = annotations::expect_ident(&p.inner.value)?; let value = annotations::expect_ident(&p.inner.value)?;
let value = kcl_value::UnitLen::from_str(value, annotation.as_source_range())?; let value = types::UnitLen::from_str(value, annotation.as_source_range())?;
self.default_length_units = value; self.default_length_units = value;
} }
annotations::SETTINGS_UNIT_ANGLE => { annotations::SETTINGS_UNIT_ANGLE => {
let value = annotations::expect_ident(&p.inner.value)?; let value = annotations::expect_ident(&p.inner.value)?;
let value = kcl_value::UnitAngle::from_str(value, annotation.as_source_range())?; let value = types::UnitAngle::from_str(value, annotation.as_source_range())?;
self.default_angle_units = value; self.default_angle_units = value;
} }
name => { name => {

File diff suppressed because it is too large Load Diff

View File

@ -344,8 +344,8 @@ impl Node<Type> {
let range = self.as_source_range(); let range = self.as_source_range();
if range.contains(pos) { if range.contains(pos) {
match &self.inner { match &self.inner {
Type::Array(t) | Type::Primitive(t) => { Type::Array { ty, .. } | Type::Primitive(ty) => {
let mut name = t.to_string(); let mut name = ty.to_string();
if name.ends_with(')') { if name.ends_with(')') {
name.truncate(name.find('(').unwrap()); name.truncate(name.find('(').unwrap());
} }
@ -379,7 +379,7 @@ impl FunctionExpression {
if let Some(value) = self.body.get_expr_for_position(pos) { if let Some(value) = self.body.get_expr_for_position(pos) {
let mut vars = opts.vars.clone().unwrap_or_default(); let mut vars = opts.vars.clone().unwrap_or_default();
for arg in &self.params { for arg in &self.params {
let ty = arg.type_.as_ref().map(|ty| ty.recast(&FormatOptions::default(), 0)); let ty = arg.type_.as_ref().map(|ty| ty.to_string());
vars.insert(arg.identifier.inner.name.clone(), ty); vars.insert(arg.identifier.inner.name.clone(), ty);
} }
return value.get_hover_value_for_position( return value.get_hover_value_for_position(

View File

@ -1900,7 +1900,7 @@ async fn test_kcl_lsp_diagnostic_has_errors() {
assert_eq!(diagnostics.full_document_diagnostic_report.items.len(), 1); assert_eq!(diagnostics.full_document_diagnostic_report.items.len(), 1);
assert_eq!( assert_eq!(
diagnostics.full_document_diagnostic_report.items[0].message, diagnostics.full_document_diagnostic_report.items[0].message,
"lexical: found unknown token ';'" "Unexpected token: ;"
); );
} else { } else {
panic!("Expected full diagnostics"); panic!("Expected full diagnostics");

View File

@ -87,6 +87,7 @@ pub(crate) fn read_std(mod_name: &str) -> Option<&'static str> {
match mod_name { match mod_name {
"prelude" => Some(include_str!("../std/prelude.kcl")), "prelude" => Some(include_str!("../std/prelude.kcl")),
"math" => Some(include_str!("../std/math.kcl")), "math" => Some(include_str!("../std/math.kcl")),
"sketch" => Some(include_str!("../std/sketch.kcl")),
_ => None, _ => None,
} }
} }

View File

@ -194,9 +194,21 @@ impl Type {
hasher.update(b"FnArgType::Primitive"); hasher.update(b"FnArgType::Primitive");
hasher.update(prim.compute_digest()) hasher.update(prim.compute_digest())
} }
Type::Array(prim) => { Type::Array { ty, len } => {
hasher.update(b"FnArgType::Array"); hasher.update(b"FnArgType::Array");
hasher.update(prim.compute_digest()) hasher.update(ty.compute_digest());
match len {
crate::execution::types::ArrayLen::None => {}
crate::execution::types::ArrayLen::NonEmpty => hasher.update(usize::MAX.to_ne_bytes()),
crate::execution::types::ArrayLen::Known(n) => hasher.update(n.to_ne_bytes()),
}
}
Type::Union { tys } => {
hasher.update(b"FnArgType::Union");
hasher.update(tys.len().to_ne_bytes());
for t in tys.iter_mut() {
hasher.update(t.compute_digest());
}
} }
Type::Object { properties } => { Type::Object { properties } => {
hasher.update(b"FnArgType::Object"); hasher.update(b"FnArgType::Object");
@ -300,6 +312,9 @@ impl TypeDeclaration {
hasher.update(a.compute_digest()); hasher.update(a.compute_digest());
} }
} }
if let Some(alias) = &mut slf.alias {
hasher.update(alias.compute_digest());
}
}); });
} }

View File

@ -25,7 +25,7 @@ pub use crate::parsing::ast::types::{
use crate::{ use crate::{
docs::StdLibFn, docs::StdLibFn,
errors::KclError, errors::KclError,
execution::{annotations, KclValue, Metadata, TagIdentifier}, execution::{annotations, types::ArrayLen, KclValue, Metadata, TagIdentifier},
parsing::{ast::digest::Digest, token::NumericSuffix, PIPE_OPERATOR}, parsing::{ast::digest::Digest, token::NumericSuffix, PIPE_OPERATOR},
source_range::SourceRange, source_range::SourceRange,
ModuleId, ModuleId,
@ -150,7 +150,7 @@ impl<T> Node<T> {
self.start <= pos && pos <= self.end self.start <= pos && pos <= self.end
} }
pub fn map<U>(self, f: fn(T) -> U) -> Node<U> { pub fn map<U>(self, f: impl Fn(T) -> U) -> Node<U> {
Node { Node {
inner: f(self.inner), inner: f(self.inner),
start: self.start, start: self.start,
@ -1895,6 +1895,7 @@ pub struct TypeDeclaration {
pub args: Option<NodeList<Identifier>>, pub args: Option<NodeList<Identifier>>,
#[serde(default, skip_serializing_if = "ItemVisibility::is_default")] #[serde(default, skip_serializing_if = "ItemVisibility::is_default")]
pub visibility: ItemVisibility, pub visibility: ItemVisibility,
pub alias: Option<Node<Type>>,
#[serde(default, skip_serializing_if = "Option::is_none")] #[serde(default, skip_serializing_if = "Option::is_none")]
#[ts(optional)] #[ts(optional)]
@ -3024,7 +3025,14 @@ pub enum Type {
/// A primitive type. /// A primitive type.
Primitive(PrimitiveType), Primitive(PrimitiveType),
// An array of a primitive type. // An array of a primitive type.
Array(PrimitiveType), Array {
ty: PrimitiveType,
len: ArrayLen,
},
// Union/enum types
Union {
tys: NodeList<PrimitiveType>,
},
// An object type. // An object type.
Object { Object {
properties: Vec<Parameter>, properties: Vec<Parameter>,
@ -3035,7 +3043,22 @@ impl fmt::Display for Type {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self { match self {
Type::Primitive(primitive_type) => primitive_type.fmt(f), Type::Primitive(primitive_type) => primitive_type.fmt(f),
Type::Array(primitive_type) => write!(f, "[{primitive_type}]"), Type::Array { ty, len } => {
write!(f, "[{ty}")?;
match len {
ArrayLen::None => {}
ArrayLen::NonEmpty => write!(f, "; 1+")?,
ArrayLen::Known(n) => write!(f, "; {n}")?,
}
write!(f, "]")
}
Type::Union { tys } => {
write!(
f,
"{}",
tys.iter().map(|t| t.to_string()).collect::<Vec<_>>().join(" | ")
)
}
Type::Object { properties } => { Type::Object { properties } => {
write!(f, "{{")?; write!(f, "{{")?;
let mut first = true; let mut first = true;
@ -3624,11 +3647,17 @@ const cylinder = startSketchOn('-XZ')
assert_eq!(params.len(), 3); assert_eq!(params.len(), 3);
assert_eq!( assert_eq!(
params[0].type_.as_ref().unwrap().inner, params[0].type_.as_ref().unwrap().inner,
Type::Array(PrimitiveType::Number(NumericSuffix::None)) Type::Array {
ty: PrimitiveType::Number(NumericSuffix::None),
len: ArrayLen::None
}
); );
assert_eq!( assert_eq!(
params[1].type_.as_ref().unwrap().inner, params[1].type_.as_ref().unwrap().inner,
Type::Array(PrimitiveType::String) Type::Array {
ty: PrimitiveType::String,
len: ArrayLen::None
}
); );
assert_eq!( assert_eq!(
params[2].type_.as_ref().unwrap().inner, params[2].type_.as_ref().unwrap().inner,
@ -3656,7 +3685,10 @@ const cylinder = startSketchOn('-XZ')
assert_eq!(params.len(), 3); assert_eq!(params.len(), 3);
assert_eq!( assert_eq!(
params[0].type_.as_ref().unwrap().inner, params[0].type_.as_ref().unwrap().inner,
Type::Array(PrimitiveType::Number(NumericSuffix::None)) Type::Array {
ty: PrimitiveType::Number(NumericSuffix::None),
len: ArrayLen::None
}
); );
assert_eq!( assert_eq!(
params[1].type_.as_ref().unwrap().inner, params[1].type_.as_ref().unwrap().inner,
@ -3692,7 +3724,15 @@ const cylinder = startSketchOn('-XZ')
56, 56,
module_id, module_id,
), ),
type_: Some(Node::new(Type::Array(PrimitiveType::String), 59, 65, module_id)), type_: Some(Node::new(
Type::Array {
ty: PrimitiveType::String,
len: ArrayLen::None
},
59,
65,
module_id
)),
default_value: None, default_value: None,
labeled: true, labeled: true,
digest: None digest: None
@ -3773,7 +3813,15 @@ const cylinder = startSketchOn('-XZ')
34, 34,
module_id, module_id,
), ),
type_: Some(Node::new(Type::Array(PrimitiveType::String), 37, 43, module_id)), type_: Some(Node::new(
Type::Array {
ty: PrimitiveType::String,
len: ArrayLen::None
},
37,
43,
module_id
)),
default_value: None, default_value: None,
labeled: true, labeled: true,
digest: None digest: None
@ -3946,7 +3994,7 @@ startSketchOn('XY')"#;
assert_eq!( assert_eq!(
meta_settings.default_length_units, meta_settings.default_length_units,
crate::execution::kcl_value::UnitLen::Inches crate::execution::types::UnitLen::Inches
); );
} }
@ -3962,13 +4010,13 @@ startSketchOn('XY')"#;
assert_eq!( assert_eq!(
meta_settings.default_length_units, meta_settings.default_length_units,
crate::execution::kcl_value::UnitLen::Inches crate::execution::types::UnitLen::Inches
); );
// Edit the ast. // Edit the ast.
let new_program = program let new_program = program
.change_meta_settings(crate::execution::MetaSettings { .change_meta_settings(crate::execution::MetaSettings {
default_length_units: crate::execution::kcl_value::UnitLen::Mm, default_length_units: crate::execution::types::UnitLen::Mm,
..Default::default() ..Default::default()
}) })
.unwrap(); .unwrap();
@ -3977,10 +4025,7 @@ startSketchOn('XY')"#;
assert!(result.is_some()); assert!(result.is_some());
let meta_settings = result.unwrap(); let meta_settings = result.unwrap();
assert_eq!( assert_eq!(meta_settings.default_length_units, crate::execution::types::UnitLen::Mm);
meta_settings.default_length_units,
crate::execution::kcl_value::UnitLen::Mm
);
let formatted = new_program.recast(&Default::default(), 0); let formatted = new_program.recast(&Default::default(), 0);
@ -4003,7 +4048,7 @@ startSketchOn('XY')
// Edit the ast. // Edit the ast.
let new_program = program let new_program = program
.change_meta_settings(crate::execution::MetaSettings { .change_meta_settings(crate::execution::MetaSettings {
default_length_units: crate::execution::kcl_value::UnitLen::Mm, default_length_units: crate::execution::types::UnitLen::Mm,
..Default::default() ..Default::default()
}) })
.unwrap(); .unwrap();
@ -4012,10 +4057,7 @@ startSketchOn('XY')
assert!(result.is_some()); assert!(result.is_some());
let meta_settings = result.unwrap(); let meta_settings = result.unwrap();
assert_eq!( assert_eq!(meta_settings.default_length_units, crate::execution::types::UnitLen::Mm);
meta_settings.default_length_units,
crate::execution::kcl_value::UnitLen::Mm
);
let formatted = new_program.recast(&Default::default(), 0); let formatted = new_program.recast(&Default::default(), 0);

View File

@ -19,6 +19,7 @@ use super::{
use crate::{ use crate::{
docs::StdLibFn, docs::StdLibFn,
errors::{CompilationError, Severity, Tag}, errors::{CompilationError, Severity, Tag},
execution::types::ArrayLen,
parsing::{ parsing::{
ast::types::{ ast::types::{
Annotation, ArrayExpression, ArrayRangeExpression, BinaryExpression, BinaryOperator, BinaryPart, BodyItem, Annotation, ArrayExpression, ArrayRangeExpression, BinaryExpression, BinaryOperator, BinaryPart, BodyItem,
@ -2215,7 +2216,7 @@ fn ty_decl(i: &mut TokenSlice) -> PResult<BoxNode<TypeDeclaration>> {
let name = identifier(i)?; let name = identifier(i)?;
let mut end = name.end; let mut end = name.end;
let args = if peek(open_paren).parse_next(i).is_ok() { let args = if peek((opt(whitespace), open_paren)).parse_next(i).is_ok() {
ignore_whitespace(i); ignore_whitespace(i);
open_paren(i)?; open_paren(i)?;
ignore_whitespace(i); ignore_whitespace(i);
@ -2228,11 +2229,28 @@ fn ty_decl(i: &mut TokenSlice) -> PResult<BoxNode<TypeDeclaration>> {
None None
}; };
let alias = if peek((opt(whitespace), equals)).parse_next(i).is_ok() {
ignore_whitespace(i);
equals(i)?;
ignore_whitespace(i);
let ty = argument_type(i)?;
ParseContext::warn(CompilationError::err(
ty.as_source_range(),
"Type aliases are experimental, likely to change in the future, and likely to not work properly.",
));
Some(ty)
} else {
None
};
let module_id = name.module_id; let module_id = name.module_id;
let result = Node::boxed( let result = Node::boxed(
TypeDeclaration { TypeDeclaration {
name, name,
args, args,
alias,
visibility, visibility,
digest: None, digest: None,
}, },
@ -2336,21 +2354,7 @@ impl TryFrom<Token> for Node<TagDeclarator> {
format!("Cannot assign a tag to a reserved keyword: {}", token.value.as_str()), format!("Cannot assign a tag to a reserved keyword: {}", token.value.as_str()),
)), )),
TokenType::Bang _ => Err(CompilationError::fatal(
| TokenType::At
| TokenType::Hash
| TokenType::Colon
| TokenType::Period
| TokenType::Operator
| TokenType::DoublePeriod
| TokenType::QuestionMark
| TokenType::BlockComment
| TokenType::Function
| TokenType::String
| TokenType::Dollar
| TokenType::Keyword
| TokenType::Unknown
| TokenType::LineComment => Err(CompilationError::fatal(
token.as_source_range(), token.as_source_range(),
// this is `start with` because if most of these cases are in the middle, it ends // this is `start with` because if most of these cases are in the middle, it ends
// up hitting a different error path(e.g. including a bang) or being valid(e.g. including a comment) since it will get broken up into // up hitting a different error path(e.g. including a bang) or being valid(e.g. including a comment) since it will get broken up into
@ -2617,6 +2621,14 @@ fn colon(i: &mut TokenSlice) -> PResult<Token> {
TokenType::Colon.parse_from(i) TokenType::Colon.parse_from(i)
} }
fn semi_colon(i: &mut TokenSlice) -> PResult<Token> {
TokenType::SemiColon.parse_from(i)
}
fn plus(i: &mut TokenSlice) -> PResult<Token> {
one_of((TokenType::Operator, "+")).parse_next(i)
}
fn equals(i: &mut TokenSlice) -> PResult<Token> { fn equals(i: &mut TokenSlice) -> PResult<Token> {
one_of((TokenType::Operator, "=")) one_of((TokenType::Operator, "="))
.context(expected("the equals operator, =")) .context(expected("the equals operator, ="))
@ -2659,6 +2671,12 @@ fn comma_sep(i: &mut TokenSlice) -> PResult<()> {
Ok(()) Ok(())
} }
/// Parse a `|`, optionally followed by some whitespace.
fn pipe_sep(i: &mut TokenSlice) -> PResult<()> {
(opt(whitespace), one_of((TokenType::Operator, "|")), opt(whitespace)).parse_next(i)?;
Ok(())
}
/// Arguments are passed into a function. /// Arguments are passed into a function.
fn arguments(i: &mut TokenSlice) -> PResult<Vec<Expr>> { fn arguments(i: &mut TokenSlice) -> PResult<Vec<Expr>> {
separated(0.., expression, comma_sep) separated(0.., expression, comma_sep)
@ -2685,7 +2703,15 @@ fn argument_type(i: &mut TokenSlice) -> PResult<Node<Type>> {
let type_ = alt(( let type_ = alt((
// Object types // Object types
// TODO it is buggy to treat object fields like parameters since the parameters parser assumes a terminating `)`. // TODO it is buggy to treat object fields like parameters since the parameters parser assumes a terminating `)`.
(open_brace, parameters, close_brace).map(|(open, params, close)| { (open_brace, parameters, close_brace).try_map(|(open, params, close)| {
for p in &params {
if p.type_.is_none() {
return Err(CompilationError::fatal(
p.identifier.as_source_range(),
"Missing type for field in record type",
));
}
}
Ok(Node::new( Ok(Node::new(
Type::Object { properties: params }, Type::Object { properties: params },
open.start, open.start,
@ -2694,12 +2720,21 @@ fn argument_type(i: &mut TokenSlice) -> PResult<Node<Type>> {
)) ))
}), }),
// Array types // Array types
(open_bracket, primitive_type, close_bracket).map(|(_, t, _)| Ok(t.map(Type::Array))), array_type,
// Primitive types // Primitive or union types
primitive_type.map(|t| Ok(t.map(Type::Primitive))), separated(1.., primitive_type, pipe_sep).map(|mut tys: Vec<_>| {
if tys.len() == 1 {
tys.pop().unwrap().map(Type::Primitive)
} else {
let start = tys[0].start;
let module_id = tys[0].module_id;
let end = tys.last().unwrap().end;
Node::new(Type::Union { tys }, start, end, module_id)
}
}),
)) ))
.parse_next(i)? .parse_next(i)?;
.map_err(|e: CompilationError| ErrMode::Backtrack(ContextError::from(e)))?;
Ok(type_) Ok(type_)
} }
@ -2721,19 +2756,93 @@ fn primitive_type(i: &mut TokenSlice) -> PResult<Node<PrimitiveType>> {
Ok(result) Ok(result)
} }
fn array_type(i: &mut TokenSlice) -> PResult<Node<Type>> {
fn opt_whitespace(i: &mut TokenSlice) -> PResult<()> {
ignore_whitespace(i);
Ok(())
}
open_bracket(i)?;
let ty = primitive_type(i)?;
let len = opt((
semi_colon,
opt_whitespace,
any.try_map(|token: Token| match token.token_type {
TokenType::Number => {
let value = token.uint_value().ok_or_else(|| {
CompilationError::fatal(
token.as_source_range(),
format!("Expected unsigned integer literal, found: {}", token.value),
)
})?;
Ok(value as usize)
}
_ => Err(CompilationError::fatal(token.as_source_range(), "invalid array length")),
}),
opt(plus),
))
.parse_next(i)?;
close_bracket(i)?;
let len = if let Some((tok, _, n, plus)) = len {
if plus.is_some() {
if n != 1 {
return Err(ErrMode::Cut(ContextError::from(CompilationError::fatal(
tok.as_source_range(),
"Non-empty arrays are specified using `1+`, for a fixed-size array use just an integer",
))));
} else {
ArrayLen::NonEmpty
}
} else {
ArrayLen::Known(n)
}
} else {
ArrayLen::None
};
Ok(ty.map(|ty| Type::Array { ty, len }))
}
fn uom_for_type(i: &mut TokenSlice) -> PResult<NumericSuffix> { fn uom_for_type(i: &mut TokenSlice) -> PResult<NumericSuffix> {
any.try_map(|t: Token| t.value.parse()).parse_next(i) any.try_map(|t: Token| t.value.parse()).parse_next(i)
} }
fn comment(i: &mut TokenSlice) -> PResult<Node<String>> {
any.verify_map(|token: Token| {
let value = match token.token_type {
TokenType::LineComment => token.value,
TokenType::BlockComment => token.value,
_ => return None,
};
Some(Node::new(value, token.start, token.end, token.module_id))
})
.context(expected("Comment"))
.parse_next(i)
}
fn comments(i: &mut TokenSlice) -> PResult<Node<Vec<String>>> {
let comments: Vec<Node<String>> = repeat(1.., (comment, opt(whitespace)).map(|(c, _)| c)).parse_next(i)?;
let start = comments[0].start;
let module_id = comments[0].module_id;
let end = comments.last().unwrap().end;
let inner = comments.into_iter().map(|n| n.inner).collect();
Ok(Node::new(inner, start, end, module_id))
}
struct ParamDescription { struct ParamDescription {
labeled: bool, labeled: bool,
arg_name: Token, arg_name: Token,
type_: std::option::Option<Node<Type>>, type_: std::option::Option<Node<Type>>,
default_value: Option<DefaultParamVal>, default_value: Option<DefaultParamVal>,
comments: Option<Node<Vec<String>>>,
} }
fn parameter(i: &mut TokenSlice) -> PResult<ParamDescription> { fn parameter(i: &mut TokenSlice) -> PResult<ParamDescription> {
let (found_at_sign, arg_name, question_mark, _, type_, _ws, default_literal) = ( let (_, comments, found_at_sign, arg_name, question_mark, _, type_, _ws, default_literal) = (
opt(whitespace),
opt(comments),
opt(at_sign), opt(at_sign),
any.verify(|token: &Token| !matches!(token.token_type, TokenType::Brace) || token.value != ")"), any.verify(|token: &Token| !matches!(token.token_type, TokenType::Brace) || token.value != ")"),
opt(question_mark), opt(question_mark),
@ -2743,6 +2852,7 @@ fn parameter(i: &mut TokenSlice) -> PResult<ParamDescription> {
opt((equals, opt(whitespace), literal).map(|(_, _, literal)| literal)), opt((equals, opt(whitespace), literal).map(|(_, _, literal)| literal)),
) )
.parse_next(i)?; .parse_next(i)?;
Ok(ParamDescription { Ok(ParamDescription {
labeled: found_at_sign.is_none(), labeled: found_at_sign.is_none(),
arg_name, arg_name,
@ -2757,6 +2867,7 @@ fn parameter(i: &mut TokenSlice) -> PResult<ParamDescription> {
return Err(ErrMode::Backtrack(ContextError::from(e))); return Err(ErrMode::Backtrack(ContextError::from(e)));
} }
}, },
comments,
}) })
} }
@ -2766,6 +2877,7 @@ fn parameters(i: &mut TokenSlice) -> PResult<Vec<Parameter>> {
let candidates: Vec<_> = separated(0.., parameter, comma_sep) let candidates: Vec<_> = separated(0.., parameter, comma_sep)
.context(expected("function parameters")) .context(expected("function parameters"))
.parse_next(i)?; .parse_next(i)?;
opt(comma_sep).parse_next(i)?;
// Make sure all those tokens are valid parameters. // Make sure all those tokens are valid parameters.
let params: Vec<Parameter> = candidates let params: Vec<Parameter> = candidates
@ -2776,8 +2888,13 @@ fn parameters(i: &mut TokenSlice) -> PResult<Vec<Parameter>> {
arg_name, arg_name,
type_, type_,
default_value, default_value,
comments,
}| { }| {
let identifier = Node::<Identifier>::try_from(arg_name)?; let mut identifier = Node::<Identifier>::try_from(arg_name)?;
if let Some(comments) = comments {
identifier.comment_start = comments.start;
identifier.pre_comments = comments.inner;
}
Ok(Parameter { Ok(Parameter {
identifier, identifier,

View File

@ -52,7 +52,7 @@ expression: actual
"commentStart": 8, "commentStart": 8,
"end": 9, "end": 9,
"name": "x", "name": "x",
"start": 8, "start": 7,
"type": "Identifier" "type": "Identifier"
}, },
"labeled": false "labeled": false

View File

@ -367,6 +367,8 @@ pub enum TokenType {
QuestionMark, QuestionMark,
/// The @ symbol. /// The @ symbol.
At, At,
/// `;`
SemiColon,
} }
/// Most KCL tokens correspond to LSP semantic tokens (but not all). /// Most KCL tokens correspond to LSP semantic tokens (but not all).
@ -396,6 +398,7 @@ impl TryFrom<TokenType> for SemanticTokenType {
| TokenType::Hash | TokenType::Hash
| TokenType::Dollar | TokenType::Dollar
| TokenType::At | TokenType::At
| TokenType::SemiColon
| TokenType::Unknown => { | TokenType::Unknown => {
anyhow::bail!("unsupported token type: {:?}", token_type) anyhow::bail!("unsupported token type: {:?}", token_type)
} }
@ -488,6 +491,18 @@ impl Token {
value.parse().ok() value.parse().ok()
} }
pub fn uint_value(&self) -> Option<u32> {
if self.token_type != TokenType::Number {
return None;
}
let value = &self.value;
let value = value
.split_once(|c: char| c == '_' || c.is_ascii_alphabetic())
.map(|(s, _)| s)
.unwrap_or(value);
value.parse().ok()
}
pub fn numeric_suffix(&self) -> NumericSuffix { pub fn numeric_suffix(&self) -> NumericSuffix {
if self.token_type != TokenType::Number { if self.token_type != TokenType::Number {
return NumericSuffix::None; return NumericSuffix::None;

View File

@ -88,6 +88,7 @@ pub(super) fn token(i: &mut Input<'_>) -> PResult<Token> {
'@' => at, '@' => at,
'0'..='9' => number, '0'..='9' => number,
':' => colon, ':' => colon,
';' => semi_colon,
'.' => alt((number, double_period, period)), '.' => alt((number, double_period, period)),
'#' => hash, '#' => hash,
'$' => dollar, '$' => dollar,
@ -282,6 +283,16 @@ fn colon(i: &mut Input<'_>) -> PResult<Token> {
)) ))
} }
fn semi_colon(i: &mut Input<'_>) -> PResult<Token> {
let (value, range) = ';'.with_span().parse_next(i)?;
Ok(Token::from_range(
range,
i.state.module_id,
TokenType::SemiColon,
value.to_string(),
))
}
fn period(i: &mut Input<'_>) -> PResult<Token> { fn period(i: &mut Input<'_>) -> PResult<Token> {
let (value, range) = '.'.with_span().parse_next(i)?; let (value, range) = '.'.with_span().parse_next(i)?;
Ok(Token::from_range( Ok(Token::from_range(
@ -689,7 +700,7 @@ const things = "things"
#[test] #[test]
fn test_unrecognized_token() { fn test_unrecognized_token() {
let module_id = ModuleId::from_usize(1); let module_id = ModuleId::from_usize(1);
let actual = lex("12 ; 8", module_id).unwrap(); let actual = lex("12 ~ 8", module_id).unwrap();
use TokenType::*; use TokenType::*;
assert_tokens(&[(Number, 0, 2), (Unknown, 3, 4), (Number, 5, 6)], actual.as_slice()); assert_tokens(&[(Number, 0, 2), (Unknown, 3, 4), (Number, 5, 6)], actual.as_slice());

View File

@ -12,10 +12,7 @@ use validator::Validate;
use crate::{ use crate::{
errors::{KclError, KclErrorDetails}, errors::{KclError, KclErrorDetails},
execution::{ execution::{types::RuntimeType, ExecState, KclValue, Solid},
kcl_value::{ArrayLen, RuntimeType},
ExecState, KclValue, PrimitiveType, Solid,
},
std::Args, std::Args,
}; };
@ -42,11 +39,7 @@ struct AppearanceData {
/// Set the appearance of a solid. This only works on solids, not sketches or individual paths. /// Set the appearance of a solid. This only works on solids, not sketches or individual paths.
pub async fn appearance(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> { pub async fn appearance(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let solids = args.get_unlabeled_kw_arg_typed( let solids = args.get_unlabeled_kw_arg_typed("solids", &RuntimeType::solids(), exec_state)?;
"solids",
&RuntimeType::Array(PrimitiveType::Solid, ArrayLen::NonEmpty),
exec_state,
)?;
let color: String = args.get_kw_arg("color")?; let color: String = args.get_kw_arg("color")?;
let metalness: Option<f64> = args.get_kw_arg_opt("metalness")?; let metalness: Option<f64> = args.get_kw_arg_opt("metalness")?;

View File

@ -12,9 +12,10 @@ use serde::{Deserialize, Serialize};
use crate::{ use crate::{
errors::{KclError, KclErrorDetails}, errors::{KclError, KclErrorDetails},
execution::{ execution::{
kcl_value::{ArrayLen, FunctionSource, NumericType, RuntimeType}, kcl_value::FunctionSource,
ExecState, ExecutorContext, ExtrudeSurface, Helix, KclObjectFields, KclValue, Metadata, PrimitiveType, Sketch, types::{NumericType, PrimitiveType, RuntimeType},
SketchSurface, Solid, TagIdentifier, ExecState, ExecutorContext, ExtrudeSurface, Helix, KclObjectFields, KclValue, Metadata, Sketch, SketchSurface,
Solid, TagIdentifier,
}, },
parsing::ast::types::TagNode, parsing::ast::types::TagNode,
source_range::SourceRange, source_range::SourceRange,
@ -188,8 +189,10 @@ impl Args {
ty.human_friendly_type(), ty.human_friendly_type(),
); );
let suggestion = match (ty, actual_type_name) { let suggestion = match (ty, actual_type_name) {
(RuntimeType::Primitive(PrimitiveType::Solid), "Sketch") (RuntimeType::Primitive(PrimitiveType::Solid), "Sketch") => Some(
| (RuntimeType::Array(PrimitiveType::Solid, _), "Sketch") => Some( "You can convert a sketch (2D) into a Solid (3D) by calling a function like `extrude` or `revolve`",
),
(RuntimeType::Array(t, _), "Sketch") if **t == RuntimeType::Primitive(PrimitiveType::Solid) => Some(
"You can convert a sketch (2D) into a Solid (3D) by calling a function like `extrude` or `revolve`", "You can convert a sketch (2D) into a Solid (3D) by calling a function like `extrude` or `revolve`",
), ),
_ => None, _ => None,
@ -309,8 +312,10 @@ impl Args {
ty.human_friendly_type(), ty.human_friendly_type(),
); );
let suggestion = match (ty, actual_type_name) { let suggestion = match (ty, actual_type_name) {
(RuntimeType::Primitive(PrimitiveType::Solid), "Sketch") (RuntimeType::Primitive(PrimitiveType::Solid), "Sketch") => Some(
| (RuntimeType::Array(PrimitiveType::Solid, _), "Sketch") => Some( "You can convert a sketch (2D) into a Solid (3D) by calling a function like `extrude` or `revolve`",
),
(RuntimeType::Array(ty, _), "Sketch") if **ty == RuntimeType::Primitive(PrimitiveType::Solid) => Some(
"You can convert a sketch (2D) into a Solid (3D) by calling a function like `extrude` or `revolve`", "You can convert a sketch (2D) into a Solid (3D) by calling a function like `extrude` or `revolve`",
), ),
_ => None, _ => None,
@ -597,7 +602,7 @@ impl Args {
}; };
let sarg = arg0 let sarg = arg0
.value .value
.coerce(&RuntimeType::Array(PrimitiveType::Sketch, ArrayLen::None), exec_state) .coerce(&RuntimeType::sketches(), exec_state)
.ok_or(KclError::Type(KclErrorDetails { .ok_or(KclError::Type(KclErrorDetails {
message: format!( message: format!(
"Expected an array of sketches, found {}", "Expected an array of sketches, found {}",
@ -685,7 +690,7 @@ impl Args {
}; };
let sarg = arg1 let sarg = arg1
.value .value
.coerce(&RuntimeType::Array(PrimitiveType::Sketch, ArrayLen::None), exec_state) .coerce(&RuntimeType::sketches(), exec_state)
.ok_or(KclError::Type(KclErrorDetails { .ok_or(KclError::Type(KclErrorDetails {
message: format!( message: format!(
"Expected one or more sketches for second argument, found {}", "Expected one or more sketches for second argument, found {}",
@ -995,9 +1000,8 @@ where
impl<'a> FromKclValue<'a> for [f64; 2] { impl<'a> FromKclValue<'a> for [f64; 2] {
fn from_kcl_val(arg: &'a KclValue) -> Option<Self> { fn from_kcl_val(arg: &'a KclValue) -> Option<Self> {
let KclValue::MixedArray { value, meta: _ } = arg else { match arg {
return None; KclValue::MixedArray { value, meta: _ } | KclValue::HomArray { value, .. } => {
};
if value.len() != 2 { if value.len() != 2 {
return None; return None;
} }
@ -1006,13 +1010,15 @@ impl<'a> FromKclValue<'a> for [f64; 2] {
let array = [v0.as_f64()?, v1.as_f64()?]; let array = [v0.as_f64()?, v1.as_f64()?];
Some(array) Some(array)
} }
_ => None,
}
}
} }
impl<'a> FromKclValue<'a> for [usize; 3] { impl<'a> FromKclValue<'a> for [usize; 3] {
fn from_kcl_val(arg: &'a KclValue) -> Option<Self> { fn from_kcl_val(arg: &'a KclValue) -> Option<Self> {
let KclValue::MixedArray { value, meta: _ } = arg else { match arg {
return None; KclValue::MixedArray { value, meta: _ } | KclValue::HomArray { value, .. } => {
};
if value.len() != 3 { if value.len() != 3 {
return None; return None;
} }
@ -1022,13 +1028,15 @@ impl<'a> FromKclValue<'a> for [usize; 3] {
let array = [v0.as_usize()?, v1.as_usize()?, v2.as_usize()?]; let array = [v0.as_usize()?, v1.as_usize()?, v2.as_usize()?];
Some(array) Some(array)
} }
_ => None,
}
}
} }
impl<'a> FromKclValue<'a> for [f64; 3] { impl<'a> FromKclValue<'a> for [f64; 3] {
fn from_kcl_val(arg: &'a KclValue) -> Option<Self> { fn from_kcl_val(arg: &'a KclValue) -> Option<Self> {
let KclValue::MixedArray { value, meta: _ } = arg else { match arg {
return None; KclValue::MixedArray { value, meta: _ } | KclValue::HomArray { value, .. } => {
};
if value.len() != 3 { if value.len() != 3 {
return None; return None;
} }
@ -1038,6 +1046,9 @@ impl<'a> FromKclValue<'a> for [f64; 3] {
let array = [v0.as_f64()?, v1.as_f64()?, v2.as_f64()?]; let array = [v0.as_f64()?, v1.as_f64()?, v2.as_f64()?];
Some(array) Some(array)
} }
_ => None,
}
}
} }
impl<'a> FromKclValue<'a> for TagNode { impl<'a> FromKclValue<'a> for TagNode {

View File

@ -8,8 +8,8 @@ use kittycad_modeling_cmds as kcmc;
use crate::{ use crate::{
errors::{KclError, KclErrorDetails}, errors::{KclError, KclErrorDetails},
execution::{ execution::{
kcl_value::RuntimeType, ChamferSurface, EdgeCut, ExecState, ExtrudeSurface, GeoMeta, KclValue, PrimitiveType, types::{PrimitiveType, RuntimeType},
Solid, ChamferSurface, EdgeCut, ExecState, ExtrudeSurface, GeoMeta, KclValue, Solid,
}, },
parsing::ast::types::TagNode, parsing::ast::types::TagNode,
std::{fillet::EdgeReference, Args}, std::{fillet::EdgeReference, Args},

View File

@ -5,20 +5,14 @@ use kcl_derive_docs::stdlib;
use crate::{ use crate::{
errors::{KclError, KclErrorDetails}, errors::{KclError, KclErrorDetails},
execution::{ execution::{types::RuntimeType, ExecState, KclValue, Solid},
kcl_value::{ArrayLen, RuntimeType},
ExecState, KclValue, PrimitiveType, Solid,
},
std::Args, std::Args,
}; };
/// Union two or more solids into a single solid. /// Union two or more solids into a single solid.
pub async fn union(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> { pub async fn union(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let solids: Vec<Solid> = args.get_unlabeled_kw_arg_typed( let solids: Vec<Solid> =
"objects", args.get_unlabeled_kw_arg_typed("solids", &RuntimeType::Union(vec![RuntimeType::solids()]), exec_state)?;
&RuntimeType::Union(vec![RuntimeType::Array(PrimitiveType::Solid, ArrayLen::NonEmpty)]),
exec_state,
)?;
if solids.len() < 2 { if solids.len() < 2 {
return Err(KclError::UndefinedValue(KclErrorDetails { return Err(KclError::UndefinedValue(KclErrorDetails {
@ -74,11 +68,7 @@ async fn inner_union(solids: Vec<Solid>, exec_state: &mut ExecState, args: Args)
/// Intersect returns the shared volume between multiple solids, preserving only /// Intersect returns the shared volume between multiple solids, preserving only
/// overlapping regions. /// overlapping regions.
pub async fn intersect(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> { pub async fn intersect(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let solids: Vec<Solid> = args.get_unlabeled_kw_arg_typed( let solids: Vec<Solid> = args.get_unlabeled_kw_arg_typed("solids", &RuntimeType::solids(), exec_state)?;
"objects",
&RuntimeType::Union(vec![RuntimeType::Array(PrimitiveType::Solid, ArrayLen::NonEmpty)]),
exec_state,
)?;
if solids.len() < 2 { if solids.len() < 2 {
return Err(KclError::UndefinedValue(KclErrorDetails { return Err(KclError::UndefinedValue(KclErrorDetails {
@ -139,16 +129,8 @@ async fn inner_intersect(solids: Vec<Solid>, exec_state: &mut ExecState, args: A
/// Subtract removes tool solids from base solids, leaving the remaining material. /// Subtract removes tool solids from base solids, leaving the remaining material.
pub async fn subtract(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> { pub async fn subtract(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let solids: Vec<Solid> = args.get_unlabeled_kw_arg_typed( let solids: Vec<Solid> = args.get_unlabeled_kw_arg_typed("solids", &RuntimeType::solids(), exec_state)?;
"objects", let tools: Vec<Solid> = args.get_kw_arg_typed("tools", &RuntimeType::solids(), exec_state)?;
&RuntimeType::Union(vec![RuntimeType::Array(PrimitiveType::Solid, ArrayLen::NonEmpty)]),
exec_state,
)?;
let tools: Vec<Solid> = args.get_kw_arg_typed(
"tools",
&RuntimeType::Union(vec![RuntimeType::Array(PrimitiveType::Solid, ArrayLen::NonEmpty)]),
exec_state,
)?;
let solids = inner_subtract(solids, tools, exec_state, args).await?; let solids = inner_subtract(solids, tools, exec_state, args).await?;
Ok(solids.into()) Ok(solids.into())

View File

@ -19,8 +19,8 @@ use uuid::Uuid;
use crate::{ use crate::{
errors::{KclError, KclErrorDetails}, errors::{KclError, KclErrorDetails},
execution::{ execution::{
kcl_value::{ArrayLen, RuntimeType}, types::RuntimeType, ArtifactId, ExecState, ExtrudeSurface, GeoMeta, KclValue, Path, Sketch, SketchSurface,
ArtifactId, ExecState, ExtrudeSurface, GeoMeta, KclValue, Path, PrimitiveType, Sketch, SketchSurface, Solid, Solid,
}, },
parsing::ast::types::TagNode, parsing::ast::types::TagNode,
std::Args, std::Args,
@ -28,11 +28,7 @@ use crate::{
/// Extrudes by a given amount. /// Extrudes by a given amount.
pub async fn extrude(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> { pub async fn extrude(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let sketches = args.get_unlabeled_kw_arg_typed( let sketches = args.get_unlabeled_kw_arg_typed("sketches", &RuntimeType::sketches(), exec_state)?;
"sketches",
&RuntimeType::Array(PrimitiveType::Sketch, ArrayLen::NonEmpty),
exec_state,
)?;
let length = args.get_kw_arg("length")?; let length = args.get_kw_arg("length")?;
let tag_start = args.get_kw_arg_opt("tagStart")?; let tag_start = args.get_kw_arg_opt("tagStart")?;
let tag_end = args.get_kw_arg_opt("tagEnd")?; let tag_end = args.get_kw_arg_opt("tagEnd")?;

View File

@ -11,8 +11,8 @@ use serde::{Deserialize, Serialize};
use crate::{ use crate::{
errors::{KclError, KclErrorDetails}, errors::{KclError, KclErrorDetails},
execution::{ execution::{
kcl_value::RuntimeType, EdgeCut, ExecState, ExtrudeSurface, FilletSurface, GeoMeta, KclValue, PrimitiveType, types::{PrimitiveType, RuntimeType},
Solid, TagIdentifier, EdgeCut, ExecState, ExtrudeSurface, FilletSurface, GeoMeta, KclValue, Solid, TagIdentifier,
}, },
parsing::ast::types::TagNode, parsing::ast::types::TagNode,
settings::types::UnitLength, settings::types::UnitLength,

View File

@ -9,10 +9,7 @@ use kittycad_modeling_cmds as kcmc;
use crate::{ use crate::{
errors::{KclError, KclErrorDetails}, errors::{KclError, KclErrorDetails},
execution::{ execution::{types::RuntimeType, ExecState, KclValue, Sketch, Solid},
kcl_value::{ArrayLen, RuntimeType},
ExecState, KclValue, PrimitiveType, Sketch, Solid,
},
parsing::ast::types::TagNode, parsing::ast::types::TagNode,
std::{extrude::do_post_extrude, fillet::default_tolerance, Args}, std::{extrude::do_post_extrude, fillet::default_tolerance, Args},
}; };
@ -21,11 +18,7 @@ const DEFAULT_V_DEGREE: u32 = 2;
/// Create a 3D surface or solid by interpolating between two or more sketches. /// Create a 3D surface or solid by interpolating between two or more sketches.
pub async fn loft(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> { pub async fn loft(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let sketches = args.get_unlabeled_kw_arg_typed( let sketches = args.get_unlabeled_kw_arg_typed("sketches", &RuntimeType::sketches(), exec_state)?;
"sketches",
&RuntimeType::Array(PrimitiveType::Sketch, ArrayLen::NonEmpty),
exec_state,
)?;
let v_degree: NonZeroU32 = args let v_degree: NonZeroU32 = args
.get_kw_arg_opt("vDegree")? .get_kw_arg_opt("vDegree")?
.unwrap_or(NonZeroU32::new(DEFAULT_V_DEGREE).unwrap()); .unwrap_or(NonZeroU32::new(DEFAULT_V_DEGREE).unwrap());

View File

@ -47,19 +47,19 @@ fn inner_rem(num: f64, divisor: f64) -> f64 {
/// Compute the cosine of a number (in radians). /// Compute the cosine of a number (in radians).
pub async fn cos(_exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> { pub async fn cos(_exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let num = args.get_number()?; let num: f64 = args.get_unlabeled_kw_arg("input")?;
Ok(args.make_user_val_from_f64_with_type(TyF64::count(num.cos()))) Ok(args.make_user_val_from_f64_with_type(TyF64::count(num.cos())))
} }
/// Compute the sine of a number (in radians). /// Compute the sine of a number (in radians).
pub async fn sin(_exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> { pub async fn sin(_exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let num = args.get_number()?; let num: f64 = args.get_unlabeled_kw_arg("input")?;
Ok(args.make_user_val_from_f64_with_type(TyF64::count(num.sin()))) Ok(args.make_user_val_from_f64_with_type(TyF64::count(num.sin())))
} }
/// Compute the tangent of a number (in radians). /// Compute the tangent of a number (in radians).
pub async fn tan(_exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> { pub async fn tan(_exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let num = args.get_number()?; let num: f64 = args.get_unlabeled_kw_arg("input")?;
Ok(args.make_user_val_from_f64_with_type(TyF64::count(num.tan()))) Ok(args.make_user_val_from_f64_with_type(TyF64::count(num.tan())))
} }

View File

@ -42,7 +42,7 @@ use serde::{Deserialize, Serialize};
use crate::{ use crate::{
docs::StdLibFn, docs::StdLibFn,
errors::KclError, errors::KclError,
execution::{ExecState, KclValue}, execution::{types::PrimitiveType, ExecState, KclValue},
}; };
pub type StdFn = fn( pub type StdFn = fn(
@ -71,7 +71,6 @@ lazy_static! {
Box::new(crate::std::segment::TangentToEnd), Box::new(crate::std::segment::TangentToEnd),
Box::new(crate::std::segment::AngleToMatchLengthX), Box::new(crate::std::segment::AngleToMatchLengthX),
Box::new(crate::std::segment::AngleToMatchLengthY), Box::new(crate::std::segment::AngleToMatchLengthY),
Box::new(crate::std::shapes::Circle),
Box::new(crate::std::shapes::CircleThreePoint), Box::new(crate::std::shapes::CircleThreePoint),
Box::new(crate::std::shapes::Polygon), Box::new(crate::std::shapes::Polygon),
Box::new(crate::std::sketch::Line), Box::new(crate::std::sketch::Line),
@ -203,24 +202,21 @@ pub(crate) fn std_fn(path: &str, fn_name: &str) -> (crate::std::StdFn, StdFnProp
|e, a| Box::pin(crate::std::math::tan(e, a)), |e, a| Box::pin(crate::std::math::tan(e, a)),
StdFnProps::default("std::math::tan"), StdFnProps::default("std::math::tan"),
), ),
("sketch", "circle") => (
|e, a| Box::pin(crate::std::shapes::circle(e, a)),
StdFnProps::default("std::sketch::circle"),
),
_ => unreachable!(), _ => unreachable!(),
} }
} }
pub(crate) fn std_ty(path: &str, fn_name: &str) -> (crate::execution::PrimitiveType, StdFnProps) { pub(crate) fn std_ty(path: &str, fn_name: &str) -> (PrimitiveType, StdFnProps) {
match (path, fn_name) { match (path, fn_name) {
("prelude", "Sketch") => ( ("prelude", "Sketch") => (PrimitiveType::Sketch, StdFnProps::default("std::Sketch")),
crate::execution::PrimitiveType::Sketch, ("prelude", "Solid") => (PrimitiveType::Solid, StdFnProps::default("std::Solid")),
StdFnProps::default("std::Sketch"), ("prelude", "Plane") => (PrimitiveType::Plane, StdFnProps::default("std::Plane")),
), ("prelude", "Face") => (PrimitiveType::Face, StdFnProps::default("std::Face")),
("prelude", "Solid") => ( ("prelude", "Helix") => (PrimitiveType::Helix, StdFnProps::default("std::Helix")),
crate::execution::PrimitiveType::Solid,
StdFnProps::default("std::Solid"),
),
("prelude", "Plane") => (
crate::execution::PrimitiveType::Plane,
StdFnProps::default("std::Plane"),
),
_ => unreachable!(), _ => unreachable!(),
} }
} }

View File

@ -20,8 +20,9 @@ use super::args::Arg;
use crate::{ use crate::{
errors::{KclError, KclErrorDetails}, errors::{KclError, KclErrorDetails},
execution::{ execution::{
kcl_value::{ArrayLen, FunctionSource, NumericType, RuntimeType}, kcl_value::FunctionSource,
ExecState, Geometries, Geometry, KclObjectFields, KclValue, Point2d, Point3d, PrimitiveType, Sketch, Solid, types::{NumericType, RuntimeType},
ExecState, Geometries, Geometry, KclObjectFields, KclValue, Point2d, Point3d, Sketch, Solid,
}, },
std::Args, std::Args,
ExecutorContext, SourceRange, ExecutorContext, SourceRange,
@ -47,11 +48,7 @@ pub struct LinearPattern3dData {
/// Repeat some 3D solid, changing each repetition slightly. /// Repeat some 3D solid, changing each repetition slightly.
pub async fn pattern_transform(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> { pub async fn pattern_transform(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let solids = args.get_unlabeled_kw_arg_typed( let solids = args.get_unlabeled_kw_arg_typed("solids", &RuntimeType::solids(), exec_state)?;
"solids",
&RuntimeType::Array(PrimitiveType::Solid, ArrayLen::NonEmpty),
exec_state,
)?;
let instances: u32 = args.get_kw_arg("instances")?; let instances: u32 = args.get_kw_arg("instances")?;
let transform: &FunctionSource = args.get_kw_arg("transform")?; let transform: &FunctionSource = args.get_kw_arg("transform")?;
let use_original: Option<bool> = args.get_kw_arg_opt("useOriginal")?; let use_original: Option<bool> = args.get_kw_arg_opt("useOriginal")?;
@ -62,11 +59,7 @@ pub async fn pattern_transform(exec_state: &mut ExecState, args: Args) -> Result
/// Repeat some 2D sketch, changing each repetition slightly. /// Repeat some 2D sketch, changing each repetition slightly.
pub async fn pattern_transform_2d(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> { pub async fn pattern_transform_2d(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let sketches = args.get_unlabeled_kw_arg_typed( let sketches = args.get_unlabeled_kw_arg_typed("sketches", &RuntimeType::sketches(), exec_state)?;
"sketches",
&RuntimeType::Array(PrimitiveType::Sketch, ArrayLen::NonEmpty),
exec_state,
)?;
let instances: u32 = args.get_kw_arg("instances")?; let instances: u32 = args.get_kw_arg("instances")?;
let transform: &FunctionSource = args.get_kw_arg("transform")?; let transform: &FunctionSource = args.get_kw_arg("transform")?;
let use_original: Option<bool> = args.get_kw_arg_opt("useOriginal")?; let use_original: Option<bool> = args.get_kw_arg_opt("useOriginal")?;
@ -664,7 +657,7 @@ impl GeometryTrait for Solid {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
use crate::execution::kcl_value::NumericType; use crate::execution::types::NumericType;
#[test] #[test]
fn test_array_to_point3d() { fn test_array_to_point3d() {
@ -696,11 +689,7 @@ mod tests {
/// A linear pattern on a 2D sketch. /// A linear pattern on a 2D sketch.
pub async fn pattern_linear_2d(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> { pub async fn pattern_linear_2d(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let sketches = args.get_unlabeled_kw_arg_typed( let sketches = args.get_unlabeled_kw_arg_typed("sketches", &RuntimeType::sketches(), exec_state)?;
"sketches",
&RuntimeType::Array(PrimitiveType::Sketch, ArrayLen::NonEmpty),
exec_state,
)?;
let instances: u32 = args.get_kw_arg("instances")?; let instances: u32 = args.get_kw_arg("instances")?;
let distance: f64 = args.get_kw_arg("distance")?; let distance: f64 = args.get_kw_arg("distance")?;
let axis: [f64; 2] = args.get_kw_arg("axis")?; let axis: [f64; 2] = args.get_kw_arg("axis")?;
@ -779,11 +768,7 @@ async fn inner_pattern_linear_2d(
/// A linear pattern on a 3D model. /// A linear pattern on a 3D model.
pub async fn pattern_linear_3d(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> { pub async fn pattern_linear_3d(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let solids = args.get_unlabeled_kw_arg_typed( let solids = args.get_unlabeled_kw_arg_typed("solids", &RuntimeType::solids(), exec_state)?;
"solids",
&RuntimeType::Array(PrimitiveType::Solid, ArrayLen::NonEmpty),
exec_state,
)?;
let instances: u32 = args.get_kw_arg("instances")?; let instances: u32 = args.get_kw_arg("instances")?;
let distance: f64 = args.get_kw_arg("distance")?; let distance: f64 = args.get_kw_arg("distance")?;
let axis: [f64; 3] = args.get_kw_arg("axis")?; let axis: [f64; 3] = args.get_kw_arg("axis")?;
@ -1028,11 +1013,7 @@ impl CircularPattern {
/// A circular pattern on a 2D sketch. /// A circular pattern on a 2D sketch.
pub async fn pattern_circular_2d(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> { pub async fn pattern_circular_2d(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let sketches = args.get_unlabeled_kw_arg_typed( let sketches = args.get_unlabeled_kw_arg_typed("sketches", &RuntimeType::sketches(), exec_state)?;
"sketches",
&RuntimeType::Array(PrimitiveType::Sketch, ArrayLen::NonEmpty),
exec_state,
)?;
let instances: u32 = args.get_kw_arg("instances")?; let instances: u32 = args.get_kw_arg("instances")?;
let center: [f64; 2] = args.get_kw_arg("center")?; let center: [f64; 2] = args.get_kw_arg("center")?;
let arc_degrees: f64 = args.get_kw_arg("arcDegrees")?; let arc_degrees: f64 = args.get_kw_arg("arcDegrees")?;
@ -1136,11 +1117,7 @@ async fn inner_pattern_circular_2d(
/// A circular pattern on a 3D model. /// A circular pattern on a 3D model.
pub async fn pattern_circular_3d(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> { pub async fn pattern_circular_3d(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let solids = args.get_unlabeled_kw_arg_typed( let solids = args.get_unlabeled_kw_arg_typed("solids", &RuntimeType::solids(), exec_state)?;
"solids",
&RuntimeType::Array(PrimitiveType::Solid, ArrayLen::NonEmpty),
exec_state,
)?;
// The number of total instances. Must be greater than or equal to 1. // The number of total instances. Must be greater than or equal to 1.
// This includes the original entity. For example, if instances is 2, // This includes the original entity. For example, if instances is 2,
// there will be two copies -- the original, and one new copy. // there will be two copies -- the original, and one new copy.

View File

@ -7,21 +7,14 @@ use kittycad_modeling_cmds::{self as kcmc};
use crate::{ use crate::{
errors::{KclError, KclErrorDetails}, errors::{KclError, KclErrorDetails},
execution::{ execution::{types::RuntimeType, ExecState, KclValue, Sketch, Solid},
kcl_value::{ArrayLen, RuntimeType},
ExecState, KclValue, PrimitiveType, Sketch, Solid,
},
parsing::ast::types::TagNode, parsing::ast::types::TagNode,
std::{axis_or_reference::Axis2dOrEdgeReference, extrude::do_post_extrude, fillet::default_tolerance, Args}, std::{axis_or_reference::Axis2dOrEdgeReference, extrude::do_post_extrude, fillet::default_tolerance, Args},
}; };
/// Revolve a sketch or set of sketches around an axis. /// Revolve a sketch or set of sketches around an axis.
pub async fn revolve(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> { pub async fn revolve(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let sketches = args.get_unlabeled_kw_arg_typed( let sketches = args.get_unlabeled_kw_arg_typed("sketches", &RuntimeType::sketches(), exec_state)?;
"sketches",
&RuntimeType::Array(PrimitiveType::Sketch, ArrayLen::NonEmpty),
exec_state,
)?;
let axis: Axis2dOrEdgeReference = args.get_kw_arg("axis")?; let axis: Axis2dOrEdgeReference = args.get_kw_arg("axis")?;
let angle = args.get_kw_arg_opt("angle")?; let angle = args.get_kw_arg_opt("angle")?;
let tolerance = args.get_kw_arg_opt("tolerance")?; let tolerance = args.get_kw_arg_opt("tolerance")?;

View File

@ -6,7 +6,10 @@ use kittycad_modeling_cmds::shared::Angle;
use crate::{ use crate::{
errors::{KclError, KclErrorDetails}, errors::{KclError, KclErrorDetails},
execution::{kcl_value::RuntimeType, ExecState, KclValue, Point2d, PrimitiveType, Sketch, TagIdentifier}, execution::{
types::{PrimitiveType, RuntimeType},
ExecState, KclValue, Point2d, Sketch, TagIdentifier,
},
std::{utils::between, Args}, std::{utils::between, Args},
}; };

View File

@ -46,38 +46,17 @@ pub async fn circle(exec_state: &mut ExecState, args: Args) -> Result<KclValue,
}) })
} }
/// Construct a 2-dimensional circle, of the specified radius, centered at // #[stdlib {
/// the provided (x, y) origin point. // name = "circle",
/// // keywords = true,
/// ```no_run // unlabeled_first = true,
/// exampleSketch = startSketchOn("-XZ") // args = {
/// |> circle( center = [0, 0], radius = 10 ) // sketch_or_surface = {docs = "Plane or surface to sketch on."},
/// // center = {docs = "The center of the circle."},
/// example = extrude(exampleSketch, length = 5) // radius = {docs = "The radius of the circle."},
/// ``` // tag = { docs = "Create a new tag which refers to this circle"},
/// // }
/// ```no_run // }]
/// exampleSketch = startSketchOn("XZ")
/// |> startProfileAt([-15, 0], %)
/// |> line(end = [30, 0])
/// |> line(end = [0, 30])
/// |> line(end = [-30, 0])
/// |> close()
/// |> hole(circle( center = [0, 15], radius = 5), %)
///
/// example = extrude(exampleSketch, length = 5)
/// ```
#[stdlib {
name = "circle",
keywords = true,
unlabeled_first = true,
args = {
sketch_or_surface = {docs = "Plane or surface to sketch on."},
center = {docs = "The center of the circle."},
radius = {docs = "The radius of the circle."},
tag = { docs = "Create a new tag which refers to this circle"},
}
}]
async fn inner_circle( async fn inner_circle(
sketch_or_surface: SketchOrSurface, sketch_or_surface: SketchOrSurface,
center: [f64; 2], center: [f64; 2],
@ -174,7 +153,7 @@ pub async fn circle_three_point(exec_state: &mut ExecState, args: Args) -> Resul
#[stdlib { #[stdlib {
name = "circleThreePoint", name = "circleThreePoint",
keywords = true, keywords = true,
unlabeled_first = true, unlabeled_first = false,
args = { args = {
p1 = {docs = "1st point to derive the circle."}, p1 = {docs = "1st point to derive the circle."},
p2 = {docs = "2nd point to derive the circle."}, p2 = {docs = "2nd point to derive the circle."},

View File

@ -7,20 +7,13 @@ use kittycad_modeling_cmds as kcmc;
use crate::{ use crate::{
errors::{KclError, KclErrorDetails}, errors::{KclError, KclErrorDetails},
execution::{ execution::{types::RuntimeType, ExecState, KclValue, Solid},
kcl_value::{ArrayLen, RuntimeType},
ExecState, KclValue, PrimitiveType, Solid,
},
std::{sketch::FaceTag, Args}, std::{sketch::FaceTag, Args},
}; };
/// Create a shell. /// Create a shell.
pub async fn shell(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> { pub async fn shell(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let solids = args.get_unlabeled_kw_arg_typed( let solids = args.get_unlabeled_kw_arg_typed("solids", &RuntimeType::solids(), exec_state)?;
"solids",
&RuntimeType::Array(PrimitiveType::Solid, ArrayLen::NonEmpty),
exec_state,
)?;
let thickness = args.get_kw_arg("thickness")?; let thickness = args.get_kw_arg("thickness")?;
let faces = args.get_kw_arg("faces")?; let faces = args.get_kw_arg("faces")?;

View File

@ -14,9 +14,9 @@ use serde::{Deserialize, Serialize};
use crate::{ use crate::{
errors::{KclError, KclErrorDetails}, errors::{KclError, KclErrorDetails},
execution::{ execution::{
kcl_value::RuntimeType, Artifact, ArtifactId, BasePath, CodeRef, ExecState, Face, GeoMeta, KclValue, Path, types::{PrimitiveType, RuntimeType},
Plane, Point2d, Point3d, PrimitiveType, Sketch, SketchSurface, Solid, StartSketchOnFace, StartSketchOnPlane, Artifact, ArtifactId, BasePath, CodeRef, ExecState, Face, GeoMeta, KclValue, Path, Plane, Point2d, Point3d,
TagEngineInfo, TagIdentifier, Sketch, SketchSurface, Solid, StartSketchOnFace, StartSketchOnPlane, TagEngineInfo, TagIdentifier,
}, },
parsing::ast::types::TagNode, parsing::ast::types::TagNode,
std::{ std::{

View File

@ -9,10 +9,7 @@ use serde::{Deserialize, Serialize};
use crate::{ use crate::{
errors::KclError, errors::KclError,
execution::{ execution::{types::RuntimeType, ExecState, Helix, KclValue, Sketch, Solid},
kcl_value::{ArrayLen, RuntimeType},
ExecState, Helix, KclValue, PrimitiveType, Sketch, Solid,
},
parsing::ast::types::TagNode, parsing::ast::types::TagNode,
std::{extrude::do_post_extrude, fillet::default_tolerance, Args}, std::{extrude::do_post_extrude, fillet::default_tolerance, Args},
}; };
@ -28,11 +25,7 @@ pub enum SweepPath {
/// Extrude a sketch along a path. /// Extrude a sketch along a path.
pub async fn sweep(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> { pub async fn sweep(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let sketches = args.get_unlabeled_kw_arg_typed( let sketches = args.get_unlabeled_kw_arg_typed("sketches", &RuntimeType::sketches(), exec_state)?;
"sketches",
&RuntimeType::Array(PrimitiveType::Sketch, ArrayLen::NonEmpty),
exec_state,
)?;
let path: SweepPath = args.get_kw_arg("path")?; let path: SweepPath = args.get_kw_arg("path")?;
let sectional = args.get_kw_arg_opt("sectional")?; let sectional = args.get_kw_arg_opt("sectional")?;
let tolerance = args.get_kw_arg_opt("tolerance")?; let tolerance = args.get_kw_arg_opt("tolerance")?;

View File

@ -13,10 +13,7 @@ use kittycad_modeling_cmds as kcmc;
use crate::{ use crate::{
errors::{KclError, KclErrorDetails}, errors::{KclError, KclErrorDetails},
execution::{ execution::{types::RuntimeType, ExecState, KclValue, SolidOrSketchOrImportedGeometry},
kcl_value::{ArrayLen, RuntimeType},
ExecState, KclValue, PrimitiveType, SolidOrSketchOrImportedGeometry,
},
std::Args, std::Args,
}; };
@ -25,9 +22,9 @@ pub async fn scale(exec_state: &mut ExecState, args: Args) -> Result<KclValue, K
let objects = args.get_unlabeled_kw_arg_typed( let objects = args.get_unlabeled_kw_arg_typed(
"objects", "objects",
&RuntimeType::Union(vec![ &RuntimeType::Union(vec![
RuntimeType::Array(PrimitiveType::Sketch, ArrayLen::NonEmpty), RuntimeType::sketches(),
RuntimeType::Array(PrimitiveType::Solid, ArrayLen::NonEmpty), RuntimeType::solids(),
RuntimeType::Primitive(PrimitiveType::ImportedGeometry), RuntimeType::imported(),
]), ]),
exec_state, exec_state,
)?; )?;
@ -187,9 +184,9 @@ pub async fn translate(exec_state: &mut ExecState, args: Args) -> Result<KclValu
let objects = args.get_unlabeled_kw_arg_typed( let objects = args.get_unlabeled_kw_arg_typed(
"objects", "objects",
&RuntimeType::Union(vec![ &RuntimeType::Union(vec![
RuntimeType::Array(PrimitiveType::Sketch, ArrayLen::NonEmpty), RuntimeType::sketches(),
RuntimeType::Array(PrimitiveType::Solid, ArrayLen::NonEmpty), RuntimeType::solids(),
RuntimeType::Primitive(PrimitiveType::ImportedGeometry), RuntimeType::imported(),
]), ]),
exec_state, exec_state,
)?; )?;
@ -390,9 +387,9 @@ pub async fn rotate(exec_state: &mut ExecState, args: Args) -> Result<KclValue,
let objects = args.get_unlabeled_kw_arg_typed( let objects = args.get_unlabeled_kw_arg_typed(
"objects", "objects",
&RuntimeType::Union(vec![ &RuntimeType::Union(vec![
RuntimeType::Array(PrimitiveType::Sketch, ArrayLen::NonEmpty), RuntimeType::sketches(),
RuntimeType::Array(PrimitiveType::Solid, ArrayLen::NonEmpty), RuntimeType::solids(),
RuntimeType::Primitive(PrimitiveType::ImportedGeometry), RuntimeType::imported(),
]), ]),
exec_state, exec_state,
)?; )?;

View File

@ -5,7 +5,7 @@ use kcl_derive_docs::stdlib;
use crate::{ use crate::{
errors::KclError, errors::KclError,
execution::{ExecState, KclValue, UnitLen}, execution::{types::UnitLen, ExecState, KclValue},
std::Args, std::Args,
}; };

View File

@ -6,8 +6,7 @@ use crate::parsing::{
CallExpression, CallExpressionKw, CommentStyle, DefaultParamVal, Expr, FormatOptions, FunctionExpression, CallExpression, CallExpressionKw, CommentStyle, DefaultParamVal, Expr, FormatOptions, FunctionExpression,
IfExpression, ImportSelector, ImportStatement, ItemVisibility, LabeledArg, Literal, LiteralIdentifier, IfExpression, ImportSelector, ImportStatement, ItemVisibility, LabeledArg, Literal, LiteralIdentifier,
LiteralValue, MemberExpression, MemberObject, Node, NonCodeNode, NonCodeValue, ObjectExpression, Parameter, LiteralValue, MemberExpression, MemberObject, Node, NonCodeNode, NonCodeValue, ObjectExpression, Parameter,
PipeExpression, Program, TagDeclarator, Type, TypeDeclaration, UnaryExpression, VariableDeclaration, PipeExpression, Program, TagDeclarator, TypeDeclaration, UnaryExpression, VariableDeclaration, VariableKind,
VariableKind,
}, },
token::NumericSuffix, token::NumericSuffix,
PIPE_OPERATOR, PIPE_OPERATOR,
@ -308,7 +307,7 @@ impl Expr {
Expr::AscribedExpression(e) => { Expr::AscribedExpression(e) => {
let mut result = e.expr.recast(options, indentation_level, ctxt); let mut result = e.expr.recast(options, indentation_level, ctxt);
result += ": "; result += ": ";
result += &e.ty.recast(options, indentation_level); result += &e.ty.to_string();
result result
} }
Expr::None(_) => { Expr::None(_) => {
@ -457,6 +456,10 @@ impl TypeDeclaration {
} }
arg_str.push(')'); arg_str.push(')');
} }
if let Some(alias) = &self.alias {
arg_str.push_str(" = ");
arg_str.push_str(&alias.to_string());
}
format!("{}type {}{}", vis, self.name.name, arg_str) format!("{}type {}{}", vis, self.name.name, arg_str)
} }
} }
@ -812,7 +815,7 @@ impl FunctionExpression {
let tab0 = options.get_indentation(indentation_level); let tab0 = options.get_indentation(indentation_level);
let tab1 = options.get_indentation(indentation_level + 1); let tab1 = options.get_indentation(indentation_level + 1);
let return_type = match &self.return_type { let return_type = match &self.return_type {
Some(rt) => format!(": {}", rt.recast(&new_options, indentation_level)), Some(rt) => format!(": {rt}"),
None => String::new(), None => String::new(),
}; };
let body = self.body.recast(&new_options, indentation_level + 1); let body = self.body.recast(&new_options, indentation_level + 1);
@ -822,14 +825,14 @@ impl FunctionExpression {
} }
impl Parameter { impl Parameter {
pub fn recast(&self, options: &FormatOptions, indentation_level: usize) -> String { pub fn recast(&self, _options: &FormatOptions, _indentation_level: usize) -> String {
let at_sign = if self.labeled { "" } else { "@" }; let at_sign = if self.labeled { "" } else { "@" };
let identifier = &self.identifier.name; let identifier = &self.identifier.name;
let question_mark = if self.default_value.is_some() { "?" } else { "" }; let question_mark = if self.default_value.is_some() { "?" } else { "" };
let mut result = format!("{at_sign}{identifier}{question_mark}"); let mut result = format!("{at_sign}{identifier}{question_mark}");
if let Some(ty) = &self.type_ { if let Some(ty) = &self.type_ {
result += ": "; result += ": ";
result += &ty.recast(options, indentation_level); result += &ty.to_string();
} }
if let Some(DefaultParamVal::Literal(ref literal)) = self.default_value { if let Some(DefaultParamVal::Literal(ref literal)) = self.default_value {
let lit = literal.recast(); let lit = literal.recast();
@ -840,31 +843,6 @@ impl Parameter {
} }
} }
impl Type {
pub fn recast(&self, options: &FormatOptions, indentation_level: usize) -> String {
match self {
Type::Primitive(t) => t.to_string(),
Type::Array(t) => format!("[{t}]"),
Type::Object { properties } => {
let mut result = "{".to_owned();
for p in properties {
result += " ";
result += &p.recast(options, indentation_level);
result += ",";
}
if result.ends_with(',') {
result.pop();
result += " ";
}
result += "}";
result
}
}
}
}
/// Collect all the kcl files in a directory, recursively. /// Collect all the kcl files in a directory, recursively.
#[cfg(not(target_arch = "wasm32"))] #[cfg(not(target_arch = "wasm32"))]
#[async_recursion::async_recursion] #[async_recursion::async_recursion]
@ -1414,6 +1392,21 @@ thing(1)
assert_eq!(recasted, some_program_string); assert_eq!(recasted, some_program_string);
} }
#[test]
fn test_recast_typed_consts() {
let some_program_string = r#"a = 42: number
export b = 3.2: number(ft)
c = "dsfds": A | B | C
d = [1]: [number]
e = foo: [number; 3]
f = [1, 2, 3]: [number; 1+]
"#;
let program = crate::parsing::top_level_parse(some_program_string).unwrap();
let recasted = program.recast(&Default::default(), 0);
assert_eq!(recasted, some_program_string);
}
#[test] #[test]
fn test_recast_object_fn_in_array_weird_bracket() { fn test_recast_object_fn_in_array_weird_bracket() {
let some_program_string = r#"bing = { yo = 55 } let some_program_string = r#"bing = { yo = 55 }
@ -2438,6 +2431,7 @@ thickness = sqrt(distance * p * FOS * 6 / (sigmaAllow * width))"#;
// A comment // A comment
@(impl = primitive) @(impl = primitive)
export type bar(unit, baz) export type bar(unit, baz)
type baz = Foo | Bar
"#; "#;
let program = crate::parsing::top_level_parse(some_program_string).unwrap(); let program = crate::parsing::top_level_parse(some_program_string).unwrap();
let recasted = program.recast(&Default::default(), 0); let recasted = program.recast(&Default::default(), 0);

View File

@ -5,7 +5,7 @@
/// ``` /// ```
/// circumference = 70 /// circumference = 70
/// ///
/// exampleSketch = startSketchOn("XZ") /// exampleSketch = startSketchOn(XZ)
/// |> circle(center = [0, 0], radius = circumference/ (2 * PI)) /// |> circle(center = [0, 0], radius = circumference/ (2 * PI))
/// ///
/// example = extrude(exampleSketch, length = 5) /// example = extrude(exampleSketch, length = 5)
@ -15,7 +15,7 @@ export PI = 3.14159265358979323846264338327950288_
/// The value of Eulers number `e`. /// The value of Eulers number `e`.
/// ///
/// ``` /// ```
/// exampleSketch = startSketchOn("XZ") /// exampleSketch = startSketchOn(XZ)
/// |> startProfileAt([0, 0], %) /// |> startProfileAt([0, 0], %)
/// |> angledLine({ /// |> angledLine({
/// angle = 30, /// angle = 30,
@ -31,7 +31,7 @@ export E = 2.71828182845904523536028747135266250_
/// The value of `tau`, the full circle constant (τ). Equal to 2π. /// The value of `tau`, the full circle constant (τ). Equal to 2π.
/// ///
/// ``` /// ```
/// exampleSketch = startSketchOn("XZ") /// exampleSketch = startSketchOn(XZ)
/// |> startProfileAt([0, 0], %) /// |> startProfileAt([0, 0], %)
/// |> angledLine({ /// |> angledLine({
/// angle = 50, /// angle = 50,
@ -47,7 +47,7 @@ export TAU = 6.28318530717958647692528676655900577_
/// Compute the cosine of a number (in radians). /// Compute the cosine of a number (in radians).
/// ///
/// ``` /// ```
/// exampleSketch = startSketchOn("XZ") /// exampleSketch = startSketchOn(XZ)
/// |> startProfileAt([0, 0], %) /// |> startProfileAt([0, 0], %)
/// |> angledLine({ /// |> angledLine({
/// angle = 30, /// angle = 30,
@ -59,12 +59,12 @@ export TAU = 6.28318530717958647692528676655900577_
/// example = extrude(exampleSketch, length = 5) /// example = extrude(exampleSketch, length = 5)
/// ``` /// ```
@(impl = std_rust) @(impl = std_rust)
export fn cos(num: number(rad)): number(_) {} export fn cos(@num: number(rad)): number(_) {}
/// Compute the sine of a number (in radians). /// Compute the sine of a number (in radians).
/// ///
/// ``` /// ```
/// exampleSketch = startSketchOn("XZ") /// exampleSketch = startSketchOn(XZ)
/// |> startProfileAt([0, 0], %) /// |> startProfileAt([0, 0], %)
/// |> angledLine({ /// |> angledLine({
/// angle = 50, /// angle = 50,
@ -76,12 +76,12 @@ export fn cos(num: number(rad)): number(_) {}
/// example = extrude(exampleSketch, length = 5) /// example = extrude(exampleSketch, length = 5)
/// ``` /// ```
@(impl = std_rust) @(impl = std_rust)
export fn sin(num: number(rad)): number(_) {} export fn sin(@num: number(rad)): number(_) {}
/// Compute the tangent of a number (in radians). /// Compute the tangent of a number (in radians).
/// ///
/// ``` /// ```
/// exampleSketch = startSketchOn("XZ") /// exampleSketch = startSketchOn(XZ)
/// |> startProfileAt([0, 0], %) /// |> startProfileAt([0, 0], %)
/// |> angledLine({ /// |> angledLine({
/// angle = 50, /// angle = 50,
@ -93,4 +93,4 @@ export fn sin(num: number(rad)): number(_) {}
/// example = extrude(exampleSketch, length = 5) /// example = extrude(exampleSketch, length = 5)
/// ``` /// ```
@(impl = std_rust) @(impl = std_rust)
export fn tan(num: number(rad)): number(_) {} export fn tan(@num: number(rad)): number(_) {}

View File

@ -3,6 +3,7 @@
// Note that everything in the prelude is treated as exported. // Note that everything in the prelude is treated as exported.
export import * from "std::math" export import * from "std::math"
export import * from "std::sketch"
/// A number /// A number
/// ///
@ -223,6 +224,26 @@ export type Sketch
@(impl = std_rust) @(impl = std_rust)
export type Solid export type Solid
/// A face.
@(impl = std_rust)
export type Face
/// A helix.
@(impl = std_rust)
export type Helix
/// A point in two dimensional space.
///
/// `Point2d` is an alias for a two-element array of [number](/docs/kcl/types/number)s. To write a value
/// with type `Point2d`, use an array, e.g., `[0, 0]` or `[5.0, 3.14]`.
export type Point2d = [number; 2]
/// A point in three dimensional space.
///
/// `Point3d` is an alias for a three-element array of [number](/docs/kcl/types/number)s. To write a value
/// with type `Point3d`, use an array, e.g., `[0, 0, 0]` or `[5.0, 3.14, 6.8]`.
export type Point3d = [number; 3]
export ZERO = 0 export ZERO = 0
export QUARTER_TURN = 90deg export QUARTER_TURN = 90deg
export HALF_TURN = 180deg export HALF_TURN = 180deg

View File

@ -0,0 +1,34 @@
@no_std
/// Construct a 2-dimensional circle, of the specified radius, centered at
/// the provided (x, y) origin point.
///
/// ```
/// exampleSketch = startSketchOn(-XZ)
/// |> circle(center = [0, 0], radius = 10)
///
/// example = extrude(exampleSketch, length = 5)
/// ```
///
/// ```
/// exampleSketch = startSketchOn(XZ)
/// |> startProfileAt([-15, 0], %)
/// |> line(end = [30, 0])
/// |> line(end = [0, 30])
/// |> line(end = [-30, 0])
/// |> close()
/// |> hole(circle(center = [0, 15], radius = 5), %)
///
/// example = extrude(exampleSketch, length = 5)
/// ```
@(impl = std_rust)
export fn circle(
/// Sketch to extend, or plane or surface to sketch on.
@sketch_or_surface: Sketch | Plane | Face,
/// The center of the circle.
center: Point2d,
/// The radius of the circle.
radius: number,
/// Create a new tag which refers to this circle.
tag?: tag,
): Sketch {}

View File

@ -1,25 +1,25 @@
```mermaid ```mermaid
flowchart LR flowchart LR
subgraph path2 [Path] subgraph path2 [Path]
2["Path<br>[76, 113, 3]"] 2["Path<br>[76, 113, 4]"]
3["Segment<br>[119, 136, 3]"] 3["Segment<br>[119, 136, 4]"]
4["Segment<br>[142, 160, 3]"] 4["Segment<br>[142, 160, 4]"]
5["Segment<br>[166, 184, 3]"] 5["Segment<br>[166, 184, 4]"]
6["Segment<br>[190, 246, 3]"] 6["Segment<br>[190, 246, 4]"]
7["Segment<br>[252, 259, 3]"] 7["Segment<br>[252, 259, 4]"]
8[Solid2d] 8[Solid2d]
end end
subgraph path25 [Path] subgraph path25 [Path]
25["Path<br>[76, 111, 4]"] 25["Path<br>[76, 111, 5]"]
26["Segment<br>[117, 134, 4]"] 26["Segment<br>[117, 134, 5]"]
27["Segment<br>[140, 158, 4]"] 27["Segment<br>[140, 158, 5]"]
28["Segment<br>[164, 182, 4]"] 28["Segment<br>[164, 182, 5]"]
29["Segment<br>[188, 244, 4]"] 29["Segment<br>[188, 244, 5]"]
30["Segment<br>[250, 257, 4]"] 30["Segment<br>[250, 257, 5]"]
31[Solid2d] 31[Solid2d]
end end
1["Plane<br>[47, 66, 3]"] 1["Plane<br>[47, 66, 4]"]
9["Sweep Extrusion<br>[265, 287, 3]"] 9["Sweep Extrusion<br>[265, 287, 4]"]
10[Wall] 10[Wall]
11[Wall] 11[Wall]
12[Wall] 12[Wall]
@ -34,8 +34,8 @@ flowchart LR
21["SweepEdge Adjacent"] 21["SweepEdge Adjacent"]
22["SweepEdge Opposite"] 22["SweepEdge Opposite"]
23["SweepEdge Adjacent"] 23["SweepEdge Adjacent"]
24["Plane<br>[47, 66, 4]"] 24["Plane<br>[47, 66, 5]"]
32["Sweep Extrusion<br>[263, 285, 4]"] 32["Sweep Extrusion<br>[263, 285, 5]"]
33[Wall] 33[Wall]
34[Wall] 34[Wall]
35[Wall] 35[Wall]

View File

@ -5,10 +5,10 @@ description: Variables in memory after executing assembly_mixed_units_cubes.kcl
{ {
"cubeIn": { "cubeIn": {
"type": "Module", "type": "Module",
"value": 3 "value": 4
}, },
"cubeMm": { "cubeMm": {
"type": "Module", "type": "Module",
"value": 4 "value": 5
} }
} }

View File

@ -1,17 +1,17 @@
```mermaid ```mermaid
flowchart LR flowchart LR
subgraph path2 [Path] subgraph path2 [Path]
2["Path<br>[197, 232, 3]"] 2["Path<br>[197, 232, 4]"]
3["Segment<br>[197, 232, 3]"] 3["Segment<br>[197, 232, 4]"]
4[Solid2d] 4[Solid2d]
end end
subgraph path6 [Path] subgraph path6 [Path]
6["Path<br>[113, 148, 4]"] 6["Path<br>[113, 148, 5]"]
7["Segment<br>[113, 148, 4]"] 7["Segment<br>[113, 148, 5]"]
8[Solid2d] 8[Solid2d]
end end
1["Plane<br>[172, 191, 3]"] 1["Plane<br>[172, 191, 4]"]
5["Plane<br>[88, 107, 4]"] 5["Plane<br>[88, 107, 5]"]
1 --- 2 1 --- 2
2 --- 3 2 --- 3
2 --- 4 2 --- 4

View File

@ -18,6 +18,72 @@ description: Operations executed assembly_non_default_units.kcl
"type": "StdLibCall", "type": "StdLibCall",
"unlabeledArg": null "unlabeledArg": null
}, },
{
"type": "UserDefinedFunctionCall",
"name": "circle",
"functionSourceRange": [
0,
0,
0
],
"unlabeledArg": null,
"labeledArgs": {
"center": {
"value": {
"type": "Array",
"value": [
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
}
},
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
}
}
]
},
"sourceRange": []
},
"radius": {
"value": {
"type": "Number",
"value": 1.0,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
}
},
"sourceRange": []
}
},
"sourceRange": []
},
{
"type": "UserDefinedFunctionReturn"
},
{ {
"labeledArgs": { "labeledArgs": {
"data": { "data": {
@ -32,5 +98,71 @@ description: Operations executed assembly_non_default_units.kcl
"sourceRange": [], "sourceRange": [],
"type": "StdLibCall", "type": "StdLibCall",
"unlabeledArg": null "unlabeledArg": null
},
{
"type": "UserDefinedFunctionCall",
"name": "circle",
"functionSourceRange": [
0,
0,
0
],
"unlabeledArg": null,
"labeledArgs": {
"center": {
"value": {
"type": "Array",
"value": [
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
}
},
{
"type": "Number",
"value": 2.0,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
}
}
]
},
"sourceRange": []
},
"radius": {
"value": {
"type": "Number",
"value": 1.0,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
}
},
"sourceRange": []
}
},
"sourceRange": []
},
{
"type": "UserDefinedFunctionReturn"
} }
] ]

View File

@ -5,10 +5,10 @@ description: Variables in memory after executing assembly_non_default_units.kcl
{ {
"other1": { "other1": {
"type": "Module", "type": "Module",
"value": 3 "value": 4
}, },
"other2": { "other2": {
"type": "Module", "type": "Module",
"value": 4 "value": 5
} }
} }

View File

@ -75,6 +75,78 @@ description: Operations executed crazy_multi_profile.kcl
"type": "StdLibCall", "type": "StdLibCall",
"unlabeledArg": null "unlabeledArg": null
}, },
{
"type": "UserDefinedFunctionCall",
"name": "circle",
"functionSourceRange": [
0,
0,
0
],
"unlabeledArg": {
"value": {
"type": "Face",
"artifact_id": "[uuid]"
},
"sourceRange": []
},
"labeledArgs": {
"center": {
"value": {
"type": "Array",
"value": [
{
"type": "Number",
"value": 5.15,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
},
{
"type": "Number",
"value": 4.34,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
}
]
},
"sourceRange": []
},
"radius": {
"value": {
"type": "Number",
"value": 1.66,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
},
"sourceRange": []
}
},
"sourceRange": []
},
{
"type": "UserDefinedFunctionReturn"
},
{ {
"labeledArgs": { "labeledArgs": {
"angle": { "angle": {
@ -161,6 +233,78 @@ description: Operations executed crazy_multi_profile.kcl
"type": "StdLibCall", "type": "StdLibCall",
"unlabeledArg": null "unlabeledArg": null
}, },
{
"type": "UserDefinedFunctionCall",
"name": "circle",
"functionSourceRange": [
0,
0,
0
],
"unlabeledArg": {
"value": {
"type": "Plane",
"artifact_id": "[uuid]"
},
"sourceRange": []
},
"labeledArgs": {
"center": {
"value": {
"type": "Array",
"value": [
{
"type": "Number",
"value": 7.18,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
},
{
"type": "Number",
"value": -2.11,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
}
]
},
"sourceRange": []
},
"radius": {
"value": {
"type": "Number",
"value": 2.67,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
},
"sourceRange": []
}
},
"sourceRange": []
},
{
"type": "UserDefinedFunctionReturn"
},
{ {
"labeledArgs": { "labeledArgs": {
"length": { "length": {

View File

@ -149,37 +149,41 @@ description: Operations executed fillet-and-shell.kcl
"unlabeledArg": null "unlabeledArg": null
}, },
{ {
"type": "UserDefinedFunctionCall",
"name": "circle",
"functionSourceRange": [
0,
0,
0
],
"unlabeledArg": null,
"labeledArgs": { "labeledArgs": {
"holeSketch": { "center": {
"value": { "value": {
"type": "Sketch", "type": "Array",
"value": { "value": [
"artifactId": "[uuid]" {
"type": "Number",
"value": 7.5,
"ty": {
"type": "Unknown"
} }
}, },
"sourceRange": []
},
"sketch": {
"value": {
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
"sourceRange": []
}
},
"name": "hole",
"sourceRange": [],
"type": "StdLibCall",
"unlabeledArg": null
},
{ {
"labeledArgs": { "type": "Number",
"length": { "value": 7.5,
"ty": {
"type": "Unknown"
}
}
]
},
"sourceRange": []
},
"radius": {
"value": { "value": {
"type": "Number", "type": "Number",
"value": 4.0, "value": 2.5,
"ty": { "ty": {
"type": "Default", "type": "Default",
"len": { "len": {
@ -193,48 +197,64 @@ description: Operations executed fillet-and-shell.kcl
"sourceRange": [] "sourceRange": []
} }
}, },
"name": "extrude",
"sourceRange": [],
"type": "StdLibCall",
"unlabeledArg": {
"value": {
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
"sourceRange": [] "sourceRange": []
}
}, },
{ {
"type": "UserDefinedFunctionReturn" "type": "UserDefinedFunctionReturn"
}, },
{ {
"type": "UserDefinedFunctionCall", "type": "UserDefinedFunctionCall",
"name": "m25Screw", "name": "circle",
"functionSourceRange": [ "functionSourceRange": [
1310, 0,
1538, 0,
0 0
], ],
"unlabeledArg": null, "unlabeledArg": null,
"labeledArgs": {}, "labeledArgs": {
"sourceRange": [] "center": {
"value": {
"type": "Array",
"value": [
{
"type": "Number",
"value": 7.5,
"ty": {
"type": "Unknown"
}
}, },
{ {
"labeledArgs": { "type": "Number",
"data": { "value": 7.5,
"ty": {
"type": "Unknown"
}
}
]
},
"sourceRange": []
},
"radius": {
"value": { "value": {
"type": "String", "type": "Number",
"value": "XY" "value": 1.25,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
}, },
"sourceRange": [] "sourceRange": []
} }
}, },
"name": "startSketchOn", "sourceRange": []
"sourceRange": [], },
"type": "StdLibCall", {
"unlabeledArg": null "type": "UserDefinedFunctionReturn"
}, },
{ {
"labeledArgs": { "labeledArgs": {
@ -324,6 +344,114 @@ description: Operations executed fillet-and-shell.kcl
"type": "StdLibCall", "type": "StdLibCall",
"unlabeledArg": null "unlabeledArg": null
}, },
{
"type": "UserDefinedFunctionCall",
"name": "circle",
"functionSourceRange": [
0,
0,
0
],
"unlabeledArg": null,
"labeledArgs": {
"center": {
"value": {
"type": "Array",
"value": [
{
"type": "Number",
"value": 7.5,
"ty": {
"type": "Unknown"
}
},
{
"type": "Number",
"value": 65.5,
"ty": {
"type": "Unknown"
}
}
]
},
"sourceRange": []
},
"radius": {
"value": {
"type": "Number",
"value": 2.5,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
},
"sourceRange": []
}
},
"sourceRange": []
},
{
"type": "UserDefinedFunctionReturn"
},
{
"type": "UserDefinedFunctionCall",
"name": "circle",
"functionSourceRange": [
0,
0,
0
],
"unlabeledArg": null,
"labeledArgs": {
"center": {
"value": {
"type": "Array",
"value": [
{
"type": "Number",
"value": 7.5,
"ty": {
"type": "Unknown"
}
},
{
"type": "Number",
"value": 65.5,
"ty": {
"type": "Unknown"
}
}
]
},
"sourceRange": []
},
"radius": {
"value": {
"type": "Number",
"value": 1.25,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
},
"sourceRange": []
}
},
"sourceRange": []
},
{
"type": "UserDefinedFunctionReturn"
},
{ {
"labeledArgs": { "labeledArgs": {
"holeSketch": { "holeSketch": {
@ -412,6 +540,310 @@ description: Operations executed fillet-and-shell.kcl
"type": "StdLibCall", "type": "StdLibCall",
"unlabeledArg": null "unlabeledArg": null
}, },
{
"type": "UserDefinedFunctionCall",
"name": "circle",
"functionSourceRange": [
0,
0,
0
],
"unlabeledArg": null,
"labeledArgs": {
"center": {
"value": {
"type": "Array",
"value": [
{
"type": "Number",
"value": 30.5,
"ty": {
"type": "Unknown"
}
},
{
"type": "Number",
"value": 65.5,
"ty": {
"type": "Unknown"
}
}
]
},
"sourceRange": []
},
"radius": {
"value": {
"type": "Number",
"value": 2.5,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
},
"sourceRange": []
}
},
"sourceRange": []
},
{
"type": "UserDefinedFunctionReturn"
},
{
"type": "UserDefinedFunctionCall",
"name": "circle",
"functionSourceRange": [
0,
0,
0
],
"unlabeledArg": null,
"labeledArgs": {
"center": {
"value": {
"type": "Array",
"value": [
{
"type": "Number",
"value": 30.5,
"ty": {
"type": "Unknown"
}
},
{
"type": "Number",
"value": 65.5,
"ty": {
"type": "Unknown"
}
}
]
},
"sourceRange": []
},
"radius": {
"value": {
"type": "Number",
"value": 1.25,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
},
"sourceRange": []
}
},
"sourceRange": []
},
{
"type": "UserDefinedFunctionReturn"
},
{
"labeledArgs": {
"holeSketch": {
"value": {
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
"sourceRange": []
},
"sketch": {
"value": {
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
"sourceRange": []
}
},
"name": "hole",
"sourceRange": [],
"type": "StdLibCall",
"unlabeledArg": null
},
{
"labeledArgs": {
"length": {
"value": {
"type": "Number",
"value": 4.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
},
"sourceRange": []
}
},
"name": "extrude",
"sourceRange": [],
"type": "StdLibCall",
"unlabeledArg": {
"value": {
"type": "Sketch",
"value": {
"artifactId": "[uuid]"
}
},
"sourceRange": []
}
},
{
"type": "UserDefinedFunctionReturn"
},
{
"type": "UserDefinedFunctionCall",
"name": "m25Screw",
"functionSourceRange": [
1310,
1538,
0
],
"unlabeledArg": null,
"labeledArgs": {},
"sourceRange": []
},
{
"labeledArgs": {
"data": {
"value": {
"type": "String",
"value": "XY"
},
"sourceRange": []
}
},
"name": "startSketchOn",
"sourceRange": [],
"type": "StdLibCall",
"unlabeledArg": null
},
{
"type": "UserDefinedFunctionCall",
"name": "circle",
"functionSourceRange": [
0,
0,
0
],
"unlabeledArg": null,
"labeledArgs": {
"center": {
"value": {
"type": "Array",
"value": [
{
"type": "Number",
"value": 30.5,
"ty": {
"type": "Unknown"
}
},
{
"type": "Number",
"value": 7.5,
"ty": {
"type": "Unknown"
}
}
]
},
"sourceRange": []
},
"radius": {
"value": {
"type": "Number",
"value": 2.5,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
},
"sourceRange": []
}
},
"sourceRange": []
},
{
"type": "UserDefinedFunctionReturn"
},
{
"type": "UserDefinedFunctionCall",
"name": "circle",
"functionSourceRange": [
0,
0,
0
],
"unlabeledArg": null,
"labeledArgs": {
"center": {
"value": {
"type": "Array",
"value": [
{
"type": "Number",
"value": 30.5,
"ty": {
"type": "Unknown"
}
},
{
"type": "Number",
"value": 7.5,
"ty": {
"type": "Unknown"
}
}
]
},
"sourceRange": []
},
"radius": {
"value": {
"type": "Number",
"value": 1.25,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
},
"sourceRange": []
}
},
"sourceRange": []
},
{
"type": "UserDefinedFunctionReturn"
},
{ {
"labeledArgs": { "labeledArgs": {
"holeSketch": { "holeSketch": {

View File

@ -18,6 +18,152 @@ description: Operations executed flush_batch_on_end.kcl
"type": "StdLibCall", "type": "StdLibCall",
"unlabeledArg": null "unlabeledArg": null
}, },
{
"type": "UserDefinedFunctionCall",
"name": "circle",
"functionSourceRange": [
0,
0,
0
],
"unlabeledArg": {
"value": {
"type": "Plane",
"artifact_id": "[uuid]"
},
"sourceRange": []
},
"labeledArgs": {
"center": {
"value": {
"type": "Array",
"value": [
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
}
},
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
}
}
]
},
"sourceRange": []
},
"radius": {
"value": {
"type": "Number",
"value": 0.2734375,
"ty": {
"type": "Unknown"
}
},
"sourceRange": []
},
"tag": {
"value": {
"type": "TagDeclarator",
"name": "arc000"
},
"sourceRange": []
}
},
"sourceRange": []
},
{
"type": "UserDefinedFunctionReturn"
},
{
"type": "UserDefinedFunctionCall",
"name": "circle",
"functionSourceRange": [
0,
0,
0
],
"unlabeledArg": {
"value": {
"type": "Plane",
"artifact_id": "[uuid]"
},
"sourceRange": []
},
"labeledArgs": {
"center": {
"value": {
"type": "Array",
"value": [
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
}
},
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
}
}
]
},
"sourceRange": []
},
"radius": {
"value": {
"type": "Number",
"value": 0.182,
"ty": {
"type": "Unknown"
}
},
"sourceRange": []
},
"tag": {
"value": {
"type": "TagDeclarator",
"name": "arc001"
},
"sourceRange": []
}
},
"sourceRange": []
},
{
"type": "UserDefinedFunctionReturn"
},
{ {
"labeledArgs": { "labeledArgs": {
"holeSketch": { "holeSketch": {

View File

@ -18,6 +18,72 @@ description: Operations executed helix_ccw.kcl
"type": "StdLibCall", "type": "StdLibCall",
"unlabeledArg": null "unlabeledArg": null
}, },
{
"type": "UserDefinedFunctionCall",
"name": "circle",
"functionSourceRange": [
0,
0,
0
],
"unlabeledArg": null,
"labeledArgs": {
"center": {
"value": {
"type": "Array",
"value": [
{
"type": "Number",
"value": 5.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
},
{
"type": "Number",
"value": 5.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
}
]
},
"sourceRange": []
},
"radius": {
"value": {
"type": "Number",
"value": 10.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
},
"sourceRange": []
}
},
"sourceRange": []
},
{
"type": "UserDefinedFunctionReturn"
},
{ {
"labeledArgs": { "labeledArgs": {
"length": { "length": {

View File

@ -5,7 +5,7 @@ description: Variables in memory after executing import_foreign.kcl
{ {
"cube": { "cube": {
"type": "Module", "type": "Module",
"value": 3 "value": 4
}, },
"model": { "model": {
"type": "ImportedGeometry", "type": "ImportedGeometry",

View File

@ -17,5 +17,71 @@ description: Operations executed import_side_effect.kcl
"sourceRange": [], "sourceRange": [],
"type": "StdLibCall", "type": "StdLibCall",
"unlabeledArg": null "unlabeledArg": null
},
{
"type": "UserDefinedFunctionCall",
"name": "circle",
"functionSourceRange": [
0,
0,
0
],
"unlabeledArg": null,
"labeledArgs": {
"center": {
"value": {
"type": "Array",
"value": [
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
},
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
}
]
},
"sourceRange": []
},
"radius": {
"value": {
"type": "Number",
"value": 10.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
},
"sourceRange": []
}
},
"sourceRange": []
},
{
"type": "UserDefinedFunctionReturn"
} }
] ]

View File

@ -5,6 +5,6 @@ description: Variables in memory after executing import_transform.kcl
{ {
"screw": { "screw": {
"type": "Module", "type": "Module",
"value": 3 "value": 4
} }
} }

View File

@ -1,12 +1,12 @@
```mermaid ```mermaid
flowchart LR flowchart LR
subgraph path2 [Path] subgraph path2 [Path]
2["Path<br>[62, 98, 3]"] 2["Path<br>[62, 98, 4]"]
3["Segment<br>[62, 98, 3]"] 3["Segment<br>[62, 98, 4]"]
4[Solid2d] 4[Solid2d]
end end
1["Plane<br>[37, 56, 3]"] 1["Plane<br>[37, 56, 4]"]
5["Sweep Extrusion<br>[104, 124, 3]"] 5["Sweep Extrusion<br>[104, 124, 4]"]
6[Wall] 6[Wall]
7["Cap Start"] 7["Cap Start"]
8["Cap End"] 8["Cap End"]

View File

@ -18,6 +18,72 @@ description: Operations executed import_whole.kcl
"type": "StdLibCall", "type": "StdLibCall",
"unlabeledArg": null "unlabeledArg": null
}, },
{
"type": "UserDefinedFunctionCall",
"name": "circle",
"functionSourceRange": [
0,
0,
0
],
"unlabeledArg": null,
"labeledArgs": {
"center": {
"value": {
"type": "Array",
"value": [
{
"type": "Number",
"value": 5.0,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
}
},
{
"type": "Number",
"value": 5.0,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
}
}
]
},
"sourceRange": []
},
"radius": {
"value": {
"type": "Number",
"value": 10.0,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
}
},
"sourceRange": []
}
},
"sourceRange": []
},
{
"type": "UserDefinedFunctionReturn"
},
{ {
"labeledArgs": { "labeledArgs": {
"length": { "length": {

View File

@ -111,6 +111,6 @@ description: Variables in memory after executing import_whole.kcl
}, },
"foo": { "foo": {
"type": "Module", "type": "Module",
"value": 3 "value": 4
} }
} }

View File

@ -30,6 +30,54 @@ description: Operations executed 80-20-rail.kcl
"type": "StdLibCall", "type": "StdLibCall",
"unlabeledArg": null "unlabeledArg": null
}, },
{
"type": "UserDefinedFunctionCall",
"name": "circle",
"functionSourceRange": [
0,
0,
0
],
"unlabeledArg": null,
"labeledArgs": {
"center": {
"value": {
"type": "Array",
"value": [
{
"type": "Number",
"value": 0.75,
"ty": {
"type": "Unknown"
}
},
{
"type": "Number",
"value": 0.75,
"ty": {
"type": "Unknown"
}
}
]
},
"sourceRange": []
},
"radius": {
"value": {
"type": "Number",
"value": 0.15375,
"ty": {
"type": "Unknown"
}
},
"sourceRange": []
}
},
"sourceRange": []
},
{
"type": "UserDefinedFunctionReturn"
},
{ {
"labeledArgs": { "labeledArgs": {
"holeSketch": { "holeSketch": {

View File

@ -74,6 +74,54 @@ description: Operations executed a-parametric-bearing-pillow-block.kcl
"type": "StdLibCall", "type": "StdLibCall",
"unlabeledArg": null "unlabeledArg": null
}, },
{
"type": "UserDefinedFunctionCall",
"name": "circle",
"functionSourceRange": [
0,
0,
0
],
"unlabeledArg": null,
"labeledArgs": {
"center": {
"value": {
"type": "Array",
"value": [
{
"type": "Number",
"value": -1.25,
"ty": {
"type": "Unknown"
}
},
{
"type": "Number",
"value": -2.25,
"ty": {
"type": "Unknown"
}
}
]
},
"sourceRange": []
},
"radius": {
"value": {
"type": "Number",
"value": 0.35,
"ty": {
"type": "Unknown"
}
},
"sourceRange": []
}
},
"sourceRange": []
},
{
"type": "UserDefinedFunctionReturn"
},
{ {
"labeledArgs": { "labeledArgs": {
"length": { "length": {
@ -153,6 +201,54 @@ description: Operations executed a-parametric-bearing-pillow-block.kcl
"type": "StdLibCall", "type": "StdLibCall",
"unlabeledArg": null "unlabeledArg": null
}, },
{
"type": "UserDefinedFunctionCall",
"name": "circle",
"functionSourceRange": [
0,
0,
0
],
"unlabeledArg": null,
"labeledArgs": {
"center": {
"value": {
"type": "Array",
"value": [
{
"type": "Number",
"value": -1.25,
"ty": {
"type": "Unknown"
}
},
{
"type": "Number",
"value": -2.25,
"ty": {
"type": "Unknown"
}
}
]
},
"sourceRange": []
},
"radius": {
"value": {
"type": "Number",
"value": 0.1875,
"ty": {
"type": "Unknown"
}
},
"sourceRange": []
}
},
"sourceRange": []
},
{
"type": "UserDefinedFunctionReturn"
},
{ {
"labeledArgs": { "labeledArgs": {
"length": { "length": {
@ -232,6 +328,66 @@ description: Operations executed a-parametric-bearing-pillow-block.kcl
"type": "StdLibCall", "type": "StdLibCall",
"unlabeledArg": null "unlabeledArg": null
}, },
{
"type": "UserDefinedFunctionCall",
"name": "circle",
"functionSourceRange": [
0,
0,
0
],
"unlabeledArg": null,
"labeledArgs": {
"center": {
"value": {
"type": "Array",
"value": [
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
}
},
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
}
}
]
},
"sourceRange": []
},
"radius": {
"value": {
"type": "Number",
"value": 1.5,
"ty": {
"type": "Unknown"
}
},
"sourceRange": []
}
},
"sourceRange": []
},
{
"type": "UserDefinedFunctionReturn"
},
{ {
"labeledArgs": { "labeledArgs": {
"length": { "length": {

View File

@ -42,6 +42,126 @@ description: Operations executed ball-bearing.kcl
"type": "StdLibCall", "type": "StdLibCall",
"unlabeledArg": null "unlabeledArg": null
}, },
{
"type": "UserDefinedFunctionCall",
"name": "circle",
"functionSourceRange": [
0,
0,
0
],
"unlabeledArg": null,
"labeledArgs": {
"center": {
"value": {
"type": "Array",
"value": [
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
}
},
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
}
}
]
},
"sourceRange": []
},
"radius": {
"value": {
"type": "Number",
"value": 0.475,
"ty": {
"type": "Unknown"
}
},
"sourceRange": []
}
},
"sourceRange": []
},
{
"type": "UserDefinedFunctionReturn"
},
{
"type": "UserDefinedFunctionCall",
"name": "circle",
"functionSourceRange": [
0,
0,
0
],
"unlabeledArg": null,
"labeledArgs": {
"center": {
"value": {
"type": "Array",
"value": [
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
}
},
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
}
}
]
},
"sourceRange": []
},
"radius": {
"value": {
"type": "Number",
"value": 0.375,
"ty": {
"type": "Unknown"
}
},
"sourceRange": []
}
},
"sourceRange": []
},
{
"type": "UserDefinedFunctionReturn"
},
{ {
"labeledArgs": { "labeledArgs": {
"holeSketch": { "holeSketch": {
@ -504,6 +624,60 @@ description: Operations executed ball-bearing.kcl
"type": "StdLibCall", "type": "StdLibCall",
"unlabeledArg": null "unlabeledArg": null
}, },
{
"type": "UserDefinedFunctionCall",
"name": "circle",
"functionSourceRange": [
0,
0,
0
],
"unlabeledArg": null,
"labeledArgs": {
"center": {
"value": {
"type": "Array",
"value": [
{
"type": "Number",
"value": 0.6,
"ty": {
"type": "Unknown"
}
},
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
}
}
]
},
"sourceRange": []
},
"radius": {
"value": {
"type": "Number",
"value": 0.03125,
"ty": {
"type": "Unknown"
}
},
"sourceRange": []
}
},
"sourceRange": []
},
{
"type": "UserDefinedFunctionReturn"
},
{ {
"labeledArgs": { "labeledArgs": {
"angle": { "angle": {
@ -725,6 +899,126 @@ description: Operations executed ball-bearing.kcl
"type": "StdLibCall", "type": "StdLibCall",
"unlabeledArg": null "unlabeledArg": null
}, },
{
"type": "UserDefinedFunctionCall",
"name": "circle",
"functionSourceRange": [
0,
0,
0
],
"unlabeledArg": null,
"labeledArgs": {
"center": {
"value": {
"type": "Array",
"value": [
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
}
},
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
}
}
]
},
"sourceRange": []
},
"radius": {
"value": {
"type": "Number",
"value": 0.8125,
"ty": {
"type": "Unknown"
}
},
"sourceRange": []
}
},
"sourceRange": []
},
{
"type": "UserDefinedFunctionReturn"
},
{
"type": "UserDefinedFunctionCall",
"name": "circle",
"functionSourceRange": [
0,
0,
0
],
"unlabeledArg": null,
"labeledArgs": {
"center": {
"value": {
"type": "Array",
"value": [
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
}
},
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
}
}
]
},
"sourceRange": []
},
"radius": {
"value": {
"type": "Number",
"value": 0.725,
"ty": {
"type": "Unknown"
}
},
"sourceRange": []
}
},
"sourceRange": []
},
{
"type": "UserDefinedFunctionReturn"
},
{ {
"labeledArgs": { "labeledArgs": {
"holeSketch": { "holeSketch": {

View File

@ -1,239 +1,239 @@
```mermaid ```mermaid
flowchart LR flowchart LR
subgraph path2 [Path] subgraph path2 [Path]
2["Path<br>[361, 394, 3]"] 2["Path<br>[361, 394, 4]"]
3["Segment<br>[402, 428, 3]"] 3["Segment<br>[402, 428, 4]"]
4["Segment<br>[436, 489, 3]"] 4["Segment<br>[436, 489, 4]"]
5["Segment<br>[497, 550, 3]"] 5["Segment<br>[497, 550, 4]"]
6["Segment<br>[558, 612, 3]"] 6["Segment<br>[558, 612, 4]"]
7["Segment<br>[620, 645, 3]"] 7["Segment<br>[620, 645, 4]"]
8["Segment<br>[653, 673, 3]"] 8["Segment<br>[653, 673, 4]"]
9["Segment<br>[681, 705, 3]"] 9["Segment<br>[681, 705, 4]"]
10["Segment<br>[713, 766, 3]"] 10["Segment<br>[713, 766, 4]"]
11["Segment<br>[774, 799, 3]"] 11["Segment<br>[774, 799, 4]"]
12["Segment<br>[807, 827, 3]"] 12["Segment<br>[807, 827, 4]"]
13["Segment<br>[835, 859, 3]"] 13["Segment<br>[835, 859, 4]"]
14["Segment<br>[867, 919, 3]"] 14["Segment<br>[867, 919, 4]"]
15["Segment<br>[927, 979, 3]"] 15["Segment<br>[927, 979, 4]"]
16["Segment<br>[987, 1012, 3]"] 16["Segment<br>[987, 1012, 4]"]
17["Segment<br>[1020, 1044, 3]"] 17["Segment<br>[1020, 1044, 4]"]
18["Segment<br>[1052, 1105, 3]"] 18["Segment<br>[1052, 1105, 4]"]
19["Segment<br>[1113, 1138, 3]"] 19["Segment<br>[1113, 1138, 4]"]
20["Segment<br>[1146, 1173, 3]"] 20["Segment<br>[1146, 1173, 4]"]
21["Segment<br>[1181, 1233, 3]"] 21["Segment<br>[1181, 1233, 4]"]
22["Segment<br>[1241, 1276, 3]"] 22["Segment<br>[1241, 1276, 4]"]
23["Segment<br>[1284, 1291, 3]"] 23["Segment<br>[1284, 1291, 4]"]
24[Solid2d] 24[Solid2d]
end end
subgraph path89 [Path] subgraph path89 [Path]
89["Path<br>[361, 394, 3]"] 89["Path<br>[361, 394, 4]"]
90["Segment<br>[402, 428, 3]"] 90["Segment<br>[402, 428, 4]"]
91["Segment<br>[436, 489, 3]"] 91["Segment<br>[436, 489, 4]"]
92["Segment<br>[497, 550, 3]"] 92["Segment<br>[497, 550, 4]"]
93["Segment<br>[558, 612, 3]"] 93["Segment<br>[558, 612, 4]"]
94["Segment<br>[620, 645, 3]"] 94["Segment<br>[620, 645, 4]"]
95["Segment<br>[653, 673, 3]"] 95["Segment<br>[653, 673, 4]"]
96["Segment<br>[681, 705, 3]"] 96["Segment<br>[681, 705, 4]"]
97["Segment<br>[713, 766, 3]"] 97["Segment<br>[713, 766, 4]"]
98["Segment<br>[774, 799, 3]"] 98["Segment<br>[774, 799, 4]"]
99["Segment<br>[807, 827, 3]"] 99["Segment<br>[807, 827, 4]"]
100["Segment<br>[835, 859, 3]"] 100["Segment<br>[835, 859, 4]"]
101["Segment<br>[867, 919, 3]"] 101["Segment<br>[867, 919, 4]"]
102["Segment<br>[927, 979, 3]"] 102["Segment<br>[927, 979, 4]"]
103["Segment<br>[987, 1012, 3]"] 103["Segment<br>[987, 1012, 4]"]
104["Segment<br>[1020, 1044, 3]"] 104["Segment<br>[1020, 1044, 4]"]
105["Segment<br>[1052, 1105, 3]"] 105["Segment<br>[1052, 1105, 4]"]
106["Segment<br>[1113, 1138, 3]"] 106["Segment<br>[1113, 1138, 4]"]
107["Segment<br>[1146, 1173, 3]"] 107["Segment<br>[1146, 1173, 4]"]
108["Segment<br>[1181, 1233, 3]"] 108["Segment<br>[1181, 1233, 4]"]
109["Segment<br>[1241, 1276, 3]"] 109["Segment<br>[1241, 1276, 4]"]
110["Segment<br>[1284, 1291, 3]"] 110["Segment<br>[1284, 1291, 4]"]
111[Solid2d] 111[Solid2d]
end end
subgraph path176 [Path] subgraph path176 [Path]
176["Path<br>[361, 394, 3]"] 176["Path<br>[361, 394, 4]"]
177["Segment<br>[402, 428, 3]"] 177["Segment<br>[402, 428, 4]"]
178["Segment<br>[436, 489, 3]"] 178["Segment<br>[436, 489, 4]"]
179["Segment<br>[497, 550, 3]"] 179["Segment<br>[497, 550, 4]"]
180["Segment<br>[558, 612, 3]"] 180["Segment<br>[558, 612, 4]"]
181["Segment<br>[620, 645, 3]"] 181["Segment<br>[620, 645, 4]"]
182["Segment<br>[653, 673, 3]"] 182["Segment<br>[653, 673, 4]"]
183["Segment<br>[681, 705, 3]"] 183["Segment<br>[681, 705, 4]"]
184["Segment<br>[713, 766, 3]"] 184["Segment<br>[713, 766, 4]"]
185["Segment<br>[774, 799, 3]"] 185["Segment<br>[774, 799, 4]"]
186["Segment<br>[807, 827, 3]"] 186["Segment<br>[807, 827, 4]"]
187["Segment<br>[835, 859, 3]"] 187["Segment<br>[835, 859, 4]"]
188["Segment<br>[867, 919, 3]"] 188["Segment<br>[867, 919, 4]"]
189["Segment<br>[927, 979, 3]"] 189["Segment<br>[927, 979, 4]"]
190["Segment<br>[987, 1012, 3]"] 190["Segment<br>[987, 1012, 4]"]
191["Segment<br>[1020, 1044, 3]"] 191["Segment<br>[1020, 1044, 4]"]
192["Segment<br>[1052, 1105, 3]"] 192["Segment<br>[1052, 1105, 4]"]
193["Segment<br>[1113, 1138, 3]"] 193["Segment<br>[1113, 1138, 4]"]
194["Segment<br>[1146, 1173, 3]"] 194["Segment<br>[1146, 1173, 4]"]
195["Segment<br>[1181, 1233, 3]"] 195["Segment<br>[1181, 1233, 4]"]
196["Segment<br>[1241, 1276, 3]"] 196["Segment<br>[1241, 1276, 4]"]
197["Segment<br>[1284, 1291, 3]"] 197["Segment<br>[1284, 1291, 4]"]
198[Solid2d] 198[Solid2d]
end end
subgraph path262 [Path] subgraph path262 [Path]
262["Path<br>[361, 394, 3]"] 262["Path<br>[361, 394, 4]"]
263["Segment<br>[402, 428, 3]"] 263["Segment<br>[402, 428, 4]"]
264["Segment<br>[436, 489, 3]"] 264["Segment<br>[436, 489, 4]"]
265["Segment<br>[497, 550, 3]"] 265["Segment<br>[497, 550, 4]"]
266["Segment<br>[558, 612, 3]"] 266["Segment<br>[558, 612, 4]"]
267["Segment<br>[620, 645, 3]"] 267["Segment<br>[620, 645, 4]"]
268["Segment<br>[653, 673, 3]"] 268["Segment<br>[653, 673, 4]"]
269["Segment<br>[681, 705, 3]"] 269["Segment<br>[681, 705, 4]"]
270["Segment<br>[713, 766, 3]"] 270["Segment<br>[713, 766, 4]"]
271["Segment<br>[774, 799, 3]"] 271["Segment<br>[774, 799, 4]"]
272["Segment<br>[807, 827, 3]"] 272["Segment<br>[807, 827, 4]"]
273["Segment<br>[835, 859, 3]"] 273["Segment<br>[835, 859, 4]"]
274["Segment<br>[867, 919, 3]"] 274["Segment<br>[867, 919, 4]"]
275["Segment<br>[927, 979, 3]"] 275["Segment<br>[927, 979, 4]"]
276["Segment<br>[987, 1012, 3]"] 276["Segment<br>[987, 1012, 4]"]
277["Segment<br>[1020, 1044, 3]"] 277["Segment<br>[1020, 1044, 4]"]
278["Segment<br>[1052, 1105, 3]"] 278["Segment<br>[1052, 1105, 4]"]
279["Segment<br>[1113, 1138, 3]"] 279["Segment<br>[1113, 1138, 4]"]
280["Segment<br>[1146, 1173, 3]"] 280["Segment<br>[1146, 1173, 4]"]
281["Segment<br>[1181, 1233, 3]"] 281["Segment<br>[1181, 1233, 4]"]
282["Segment<br>[1241, 1276, 3]"] 282["Segment<br>[1241, 1276, 4]"]
283["Segment<br>[1284, 1291, 3]"] 283["Segment<br>[1284, 1291, 4]"]
284[Solid2d] 284[Solid2d]
end end
subgraph path349 [Path] subgraph path349 [Path]
349["Path<br>[361, 394, 3]"] 349["Path<br>[361, 394, 4]"]
350["Segment<br>[402, 428, 3]"] 350["Segment<br>[402, 428, 4]"]
351["Segment<br>[436, 489, 3]"] 351["Segment<br>[436, 489, 4]"]
352["Segment<br>[497, 550, 3]"] 352["Segment<br>[497, 550, 4]"]
353["Segment<br>[558, 612, 3]"] 353["Segment<br>[558, 612, 4]"]
354["Segment<br>[620, 645, 3]"] 354["Segment<br>[620, 645, 4]"]
355["Segment<br>[653, 673, 3]"] 355["Segment<br>[653, 673, 4]"]
356["Segment<br>[681, 705, 3]"] 356["Segment<br>[681, 705, 4]"]
357["Segment<br>[713, 766, 3]"] 357["Segment<br>[713, 766, 4]"]
358["Segment<br>[774, 799, 3]"] 358["Segment<br>[774, 799, 4]"]
359["Segment<br>[807, 827, 3]"] 359["Segment<br>[807, 827, 4]"]
360["Segment<br>[835, 859, 3]"] 360["Segment<br>[835, 859, 4]"]
361["Segment<br>[867, 919, 3]"] 361["Segment<br>[867, 919, 4]"]
362["Segment<br>[927, 979, 3]"] 362["Segment<br>[927, 979, 4]"]
363["Segment<br>[987, 1012, 3]"] 363["Segment<br>[987, 1012, 4]"]
364["Segment<br>[1020, 1044, 3]"] 364["Segment<br>[1020, 1044, 4]"]
365["Segment<br>[1052, 1105, 3]"] 365["Segment<br>[1052, 1105, 4]"]
366["Segment<br>[1113, 1138, 3]"] 366["Segment<br>[1113, 1138, 4]"]
367["Segment<br>[1146, 1173, 3]"] 367["Segment<br>[1146, 1173, 4]"]
368["Segment<br>[1181, 1233, 3]"] 368["Segment<br>[1181, 1233, 4]"]
369["Segment<br>[1241, 1276, 3]"] 369["Segment<br>[1241, 1276, 4]"]
370["Segment<br>[1284, 1291, 3]"] 370["Segment<br>[1284, 1291, 4]"]
371[Solid2d] 371[Solid2d]
end end
subgraph path435 [Path] subgraph path435 [Path]
435["Path<br>[361, 394, 3]"] 435["Path<br>[361, 394, 4]"]
436["Segment<br>[402, 428, 3]"] 436["Segment<br>[402, 428, 4]"]
437["Segment<br>[436, 489, 3]"] 437["Segment<br>[436, 489, 4]"]
438["Segment<br>[497, 550, 3]"] 438["Segment<br>[497, 550, 4]"]
439["Segment<br>[558, 612, 3]"] 439["Segment<br>[558, 612, 4]"]
440["Segment<br>[620, 645, 3]"] 440["Segment<br>[620, 645, 4]"]
441["Segment<br>[653, 673, 3]"] 441["Segment<br>[653, 673, 4]"]
442["Segment<br>[681, 705, 3]"] 442["Segment<br>[681, 705, 4]"]
443["Segment<br>[713, 766, 3]"] 443["Segment<br>[713, 766, 4]"]
444["Segment<br>[774, 799, 3]"] 444["Segment<br>[774, 799, 4]"]
445["Segment<br>[807, 827, 3]"] 445["Segment<br>[807, 827, 4]"]
446["Segment<br>[835, 859, 3]"] 446["Segment<br>[835, 859, 4]"]
447["Segment<br>[867, 919, 3]"] 447["Segment<br>[867, 919, 4]"]
448["Segment<br>[927, 979, 3]"] 448["Segment<br>[927, 979, 4]"]
449["Segment<br>[987, 1012, 3]"] 449["Segment<br>[987, 1012, 4]"]
450["Segment<br>[1020, 1044, 3]"] 450["Segment<br>[1020, 1044, 4]"]
451["Segment<br>[1052, 1105, 3]"] 451["Segment<br>[1052, 1105, 4]"]
452["Segment<br>[1113, 1138, 3]"] 452["Segment<br>[1113, 1138, 4]"]
453["Segment<br>[1146, 1173, 3]"] 453["Segment<br>[1146, 1173, 4]"]
454["Segment<br>[1181, 1233, 3]"] 454["Segment<br>[1181, 1233, 4]"]
455["Segment<br>[1241, 1276, 3]"] 455["Segment<br>[1241, 1276, 4]"]
456["Segment<br>[1284, 1291, 3]"] 456["Segment<br>[1284, 1291, 4]"]
457[Solid2d] 457[Solid2d]
end end
subgraph path522 [Path] subgraph path522 [Path]
522["Path<br>[1685, 1709, 3]"] 522["Path<br>[1685, 1709, 4]"]
end end
subgraph path523 [Path] subgraph path523 [Path]
523["Path<br>[1717, 1847, 3]"] 523["Path<br>[1717, 1847, 4]"]
524["Segment<br>[1717, 1847, 3]"] 524["Segment<br>[1717, 1847, 4]"]
525["Segment<br>[1717, 1847, 3]"] 525["Segment<br>[1717, 1847, 4]"]
526["Segment<br>[1717, 1847, 3]"] 526["Segment<br>[1717, 1847, 4]"]
527["Segment<br>[1717, 1847, 3]"] 527["Segment<br>[1717, 1847, 4]"]
528["Segment<br>[1717, 1847, 3]"] 528["Segment<br>[1717, 1847, 4]"]
529["Segment<br>[1717, 1847, 3]"] 529["Segment<br>[1717, 1847, 4]"]
530["Segment<br>[1717, 1847, 3]"] 530["Segment<br>[1717, 1847, 4]"]
531[Solid2d] 531[Solid2d]
end end
subgraph path553 [Path] subgraph path553 [Path]
553["Path<br>[1685, 1709, 3]"] 553["Path<br>[1685, 1709, 4]"]
end end
subgraph path554 [Path] subgraph path554 [Path]
554["Path<br>[1717, 1847, 3]"] 554["Path<br>[1717, 1847, 4]"]
555["Segment<br>[1717, 1847, 3]"] 555["Segment<br>[1717, 1847, 4]"]
556["Segment<br>[1717, 1847, 3]"] 556["Segment<br>[1717, 1847, 4]"]
557["Segment<br>[1717, 1847, 3]"] 557["Segment<br>[1717, 1847, 4]"]
558["Segment<br>[1717, 1847, 3]"] 558["Segment<br>[1717, 1847, 4]"]
559["Segment<br>[1717, 1847, 3]"] 559["Segment<br>[1717, 1847, 4]"]
560["Segment<br>[1717, 1847, 3]"] 560["Segment<br>[1717, 1847, 4]"]
561["Segment<br>[1717, 1847, 3]"] 561["Segment<br>[1717, 1847, 4]"]
562[Solid2d] 562[Solid2d]
end end
subgraph path585 [Path] subgraph path585 [Path]
585["Path<br>[2123, 2150, 3]"] 585["Path<br>[2123, 2150, 4]"]
586["Segment<br>[2158, 2180, 3]"] 586["Segment<br>[2158, 2180, 4]"]
587["Segment<br>[2188, 2210, 3]"] 587["Segment<br>[2188, 2210, 4]"]
588["Segment<br>[2218, 2240, 3]"] 588["Segment<br>[2218, 2240, 4]"]
589["Segment<br>[2248, 2271, 3]"] 589["Segment<br>[2248, 2271, 4]"]
590["Segment<br>[2279, 2302, 3]"] 590["Segment<br>[2279, 2302, 4]"]
591["Segment<br>[2310, 2345, 3]"] 591["Segment<br>[2310, 2345, 4]"]
592["Segment<br>[2353, 2360, 3]"] 592["Segment<br>[2353, 2360, 4]"]
593[Solid2d] 593[Solid2d]
end end
subgraph path618 [Path] subgraph path618 [Path]
618["Path<br>[2632, 2661, 3]"] 618["Path<br>[2632, 2661, 4]"]
619["Segment<br>[2669, 2692, 3]"] 619["Segment<br>[2669, 2692, 4]"]
620["Segment<br>[2700, 2725, 3]"] 620["Segment<br>[2700, 2725, 4]"]
621["Segment<br>[2733, 2757, 3]"] 621["Segment<br>[2733, 2757, 4]"]
622["Segment<br>[2765, 2789, 3]"] 622["Segment<br>[2765, 2789, 4]"]
623["Segment<br>[2797, 2819, 3]"] 623["Segment<br>[2797, 2819, 4]"]
624["Segment<br>[2827, 2862, 3]"] 624["Segment<br>[2827, 2862, 4]"]
625["Segment<br>[2870, 2877, 3]"] 625["Segment<br>[2870, 2877, 4]"]
626[Solid2d] 626[Solid2d]
end end
subgraph path650 [Path] subgraph path650 [Path]
650["Path<br>[3152, 3179, 3]"] 650["Path<br>[3152, 3179, 4]"]
651["Segment<br>[3187, 3206, 3]"] 651["Segment<br>[3187, 3206, 4]"]
652["Segment<br>[3214, 3304, 3]"] 652["Segment<br>[3214, 3304, 4]"]
end end
subgraph path654 [Path] subgraph path654 [Path]
654["Path<br>[3404, 3437, 3]"] 654["Path<br>[3404, 3437, 4]"]
655["Segment<br>[3445, 3464, 3]"] 655["Segment<br>[3445, 3464, 4]"]
656["Segment<br>[3472, 3494, 3]"] 656["Segment<br>[3472, 3494, 4]"]
657["Segment<br>[3502, 3525, 3]"] 657["Segment<br>[3502, 3525, 4]"]
658["Segment<br>[3533, 3553, 3]"] 658["Segment<br>[3533, 3553, 4]"]
659["Segment<br>[3561, 3585, 3]"] 659["Segment<br>[3561, 3585, 4]"]
660["Segment<br>[3593, 3616, 3]"] 660["Segment<br>[3593, 3616, 4]"]
661["Segment<br>[3624, 3631, 3]"] 661["Segment<br>[3624, 3631, 4]"]
662[Solid2d] 662[Solid2d]
end end
subgraph path688 [Path] subgraph path688 [Path]
688["Path<br>[3152, 3179, 3]"] 688["Path<br>[3152, 3179, 4]"]
689["Segment<br>[3187, 3206, 3]"] 689["Segment<br>[3187, 3206, 4]"]
690["Segment<br>[3214, 3304, 3]"] 690["Segment<br>[3214, 3304, 4]"]
end end
subgraph path692 [Path] subgraph path692 [Path]
692["Path<br>[3404, 3437, 3]"] 692["Path<br>[3404, 3437, 4]"]
693["Segment<br>[3445, 3464, 3]"] 693["Segment<br>[3445, 3464, 4]"]
694["Segment<br>[3472, 3494, 3]"] 694["Segment<br>[3472, 3494, 4]"]
695["Segment<br>[3502, 3525, 3]"] 695["Segment<br>[3502, 3525, 4]"]
696["Segment<br>[3533, 3553, 3]"] 696["Segment<br>[3533, 3553, 4]"]
697["Segment<br>[3561, 3585, 3]"] 697["Segment<br>[3561, 3585, 4]"]
698["Segment<br>[3593, 3616, 3]"] 698["Segment<br>[3593, 3616, 4]"]
699["Segment<br>[3624, 3631, 3]"] 699["Segment<br>[3624, 3631, 4]"]
700[Solid2d] 700[Solid2d]
end end
1["Plane<br>[333, 353, 3]"] 1["Plane<br>[333, 353, 4]"]
25["Sweep Extrusion<br>[1379, 1417, 3]"] 25["Sweep Extrusion<br>[1379, 1417, 4]"]
26[Wall] 26[Wall]
27[Wall] 27[Wall]
28[Wall] 28[Wall]
@ -296,8 +296,8 @@ flowchart LR
85["SweepEdge Adjacent"] 85["SweepEdge Adjacent"]
86["SweepEdge Opposite"] 86["SweepEdge Opposite"]
87["SweepEdge Adjacent"] 87["SweepEdge Adjacent"]
88["Plane<br>[333, 353, 3]"] 88["Plane<br>[333, 353, 4]"]
112["Sweep Extrusion<br>[1455, 1494, 3]"] 112["Sweep Extrusion<br>[1455, 1494, 4]"]
113[Wall] 113[Wall]
114[Wall] 114[Wall]
115[Wall] 115[Wall]
@ -361,7 +361,7 @@ flowchart LR
173["SweepEdge Opposite"] 173["SweepEdge Opposite"]
174["SweepEdge Adjacent"] 174["SweepEdge Adjacent"]
175["Plane<br>[825, 869, 0]"] 175["Plane<br>[825, 869, 0]"]
199["Sweep Extrusion<br>[1379, 1417, 3]"] 199["Sweep Extrusion<br>[1379, 1417, 4]"]
200[Wall] 200[Wall]
201[Wall] 201[Wall]
202[Wall] 202[Wall]
@ -424,7 +424,7 @@ flowchart LR
259["SweepEdge Adjacent"] 259["SweepEdge Adjacent"]
260["SweepEdge Opposite"] 260["SweepEdge Opposite"]
261["SweepEdge Adjacent"] 261["SweepEdge Adjacent"]
285["Sweep Extrusion<br>[1455, 1494, 3]"] 285["Sweep Extrusion<br>[1455, 1494, 4]"]
286[Wall] 286[Wall]
287[Wall] 287[Wall]
288[Wall] 288[Wall]
@ -488,7 +488,7 @@ flowchart LR
346["SweepEdge Opposite"] 346["SweepEdge Opposite"]
347["SweepEdge Adjacent"] 347["SweepEdge Adjacent"]
348["Plane<br>[879, 922, 0]"] 348["Plane<br>[879, 922, 0]"]
372["Sweep Extrusion<br>[1379, 1417, 3]"] 372["Sweep Extrusion<br>[1379, 1417, 4]"]
373[Wall] 373[Wall]
374[Wall] 374[Wall]
375[Wall] 375[Wall]
@ -551,7 +551,7 @@ flowchart LR
432["SweepEdge Adjacent"] 432["SweepEdge Adjacent"]
433["SweepEdge Opposite"] 433["SweepEdge Opposite"]
434["SweepEdge Adjacent"] 434["SweepEdge Adjacent"]
458["Sweep Extrusion<br>[1455, 1494, 3]"] 458["Sweep Extrusion<br>[1455, 1494, 4]"]
459[Wall] 459[Wall]
460[Wall] 460[Wall]
461[Wall] 461[Wall]
@ -615,7 +615,7 @@ flowchart LR
519["SweepEdge Opposite"] 519["SweepEdge Opposite"]
520["SweepEdge Adjacent"] 520["SweepEdge Adjacent"]
521["Plane<br>[981, 1025, 0]"] 521["Plane<br>[981, 1025, 0]"]
532["Sweep Extrusion<br>[1949, 1973, 3]"] 532["Sweep Extrusion<br>[1949, 1973, 4]"]
533[Wall] 533[Wall]
534[Wall] 534[Wall]
535[Wall] 535[Wall]
@ -636,7 +636,7 @@ flowchart LR
550["SweepEdge Adjacent"] 550["SweepEdge Adjacent"]
551["SweepEdge Opposite"] 551["SweepEdge Opposite"]
552["SweepEdge Adjacent"] 552["SweepEdge Adjacent"]
563["Sweep Extrusion<br>[2015, 2039, 3]"] 563["Sweep Extrusion<br>[2015, 2039, 4]"]
564[Wall] 564[Wall]
565[Wall] 565[Wall]
566[Wall] 566[Wall]
@ -658,7 +658,7 @@ flowchart LR
582["SweepEdge Opposite"] 582["SweepEdge Opposite"]
583["SweepEdge Adjacent"] 583["SweepEdge Adjacent"]
584["Plane<br>[1076, 1143, 0]"] 584["Plane<br>[1076, 1143, 0]"]
594["Sweep Extrusion<br>[2523, 2547, 3]"] 594["Sweep Extrusion<br>[2523, 2547, 4]"]
595[Wall] 595[Wall]
596[Wall] 596[Wall]
597[Wall] 597[Wall]
@ -679,10 +679,10 @@ flowchart LR
612["SweepEdge Adjacent"] 612["SweepEdge Adjacent"]
613["SweepEdge Opposite"] 613["SweepEdge Opposite"]
614["SweepEdge Adjacent"] 614["SweepEdge Adjacent"]
615["Sweep Extrusion<br>[2523, 2547, 3]"] 615["Sweep Extrusion<br>[2523, 2547, 4]"]
616["Sweep Extrusion<br>[2523, 2547, 3]"] 616["Sweep Extrusion<br>[2523, 2547, 4]"]
617["Plane<br>[1213, 1280, 0]"] 617["Plane<br>[1213, 1280, 0]"]
627["Sweep Extrusion<br>[3047, 3071, 3]"] 627["Sweep Extrusion<br>[3047, 3071, 4]"]
628[Wall] 628[Wall]
629[Wall] 629[Wall]
630[Wall] 630[Wall]
@ -703,10 +703,10 @@ flowchart LR
645["SweepEdge Adjacent"] 645["SweepEdge Adjacent"]
646["SweepEdge Opposite"] 646["SweepEdge Opposite"]
647["SweepEdge Adjacent"] 647["SweepEdge Adjacent"]
648["Sweep Extrusion<br>[3047, 3071, 3]"] 648["Sweep Extrusion<br>[3047, 3071, 4]"]
649["Plane<br>[3712, 3747, 3]"] 649["Plane<br>[3712, 3747, 4]"]
653["Plane<br>[3778, 3809, 3]"] 653["Plane<br>[3778, 3809, 4]"]
663["Sweep Sweep<br>[3821, 3848, 3]"] 663["Sweep Sweep<br>[3821, 3848, 4]"]
664[Wall] 664[Wall]
665[Wall] 665[Wall]
666[Wall] 666[Wall]
@ -730,9 +730,9 @@ flowchart LR
684["SweepEdge Adjacent"] 684["SweepEdge Adjacent"]
685["SweepEdge Opposite"] 685["SweepEdge Opposite"]
686["SweepEdge Adjacent"] 686["SweepEdge Adjacent"]
687["Plane<br>[3712, 3747, 3]"] 687["Plane<br>[3712, 3747, 4]"]
691["Plane<br>[3778, 3809, 3]"] 691["Plane<br>[3778, 3809, 4]"]
701["Sweep Sweep<br>[3821, 3848, 3]"] 701["Sweep Sweep<br>[3821, 3848, 4]"]
702[Wall] 702[Wall]
703[Wall] 703[Wall]
704[Wall] 704[Wall]
@ -756,18 +756,18 @@ flowchart LR
722["SweepEdge Adjacent"] 722["SweepEdge Adjacent"]
723["SweepEdge Opposite"] 723["SweepEdge Opposite"]
724["SweepEdge Adjacent"] 724["SweepEdge Adjacent"]
725["StartSketchOnPlane<br>[333, 353, 3]"] 725["StartSketchOnPlane<br>[333, 353, 4]"]
726["StartSketchOnPlane<br>[333, 353, 3]"] 726["StartSketchOnPlane<br>[333, 353, 4]"]
727["StartSketchOnPlane<br>[333, 353, 3]"] 727["StartSketchOnPlane<br>[333, 353, 4]"]
728["StartSketchOnPlane<br>[333, 353, 3]"] 728["StartSketchOnPlane<br>[333, 353, 4]"]
729["StartSketchOnPlane<br>[1657, 1677, 3]"] 729["StartSketchOnPlane<br>[1657, 1677, 4]"]
730["StartSketchOnPlane<br>[1657, 1677, 3]"] 730["StartSketchOnPlane<br>[1657, 1677, 4]"]
731["StartSketchOnPlane<br>[2095, 2115, 3]"] 731["StartSketchOnPlane<br>[2095, 2115, 4]"]
732["StartSketchOnPlane<br>[2604, 2624, 3]"] 732["StartSketchOnPlane<br>[2604, 2624, 4]"]
733["StartSketchOnPlane<br>[3124, 3144, 3]"] 733["StartSketchOnPlane<br>[3124, 3144, 4]"]
734["StartSketchOnPlane<br>[3376, 3396, 3]"] 734["StartSketchOnPlane<br>[3376, 3396, 4]"]
735["StartSketchOnPlane<br>[3124, 3144, 3]"] 735["StartSketchOnPlane<br>[3124, 3144, 4]"]
736["StartSketchOnPlane<br>[3376, 3396, 3]"] 736["StartSketchOnPlane<br>[3376, 3396, 4]"]
1 --- 2 1 --- 2
2 --- 3 2 --- 3
2 --- 4 2 --- 4

View File

@ -9,7 +9,7 @@ description: Operations executed bench.kcl
"functionSourceRange": [ "functionSourceRange": [
1331, 1331,
1606, 1606,
3 4
], ],
"unlabeledArg": null, "unlabeledArg": null,
"labeledArgs": {}, "labeledArgs": {},
@ -21,7 +21,7 @@ description: Operations executed bench.kcl
"functionSourceRange": [ "functionSourceRange": [
309, 309,
1312, 1312,
3 4
], ],
"unlabeledArg": null, "unlabeledArg": null,
"labeledArgs": {}, "labeledArgs": {},
@ -77,7 +77,7 @@ description: Operations executed bench.kcl
"functionSourceRange": [ "functionSourceRange": [
309, 309,
1312, 1312,
3 4
], ],
"unlabeledArg": null, "unlabeledArg": null,
"labeledArgs": {}, "labeledArgs": {},
@ -248,7 +248,7 @@ description: Operations executed bench.kcl
"functionSourceRange": [ "functionSourceRange": [
1331, 1331,
1606, 1606,
3 4
], ],
"unlabeledArg": null, "unlabeledArg": null,
"labeledArgs": {}, "labeledArgs": {},
@ -260,7 +260,7 @@ description: Operations executed bench.kcl
"functionSourceRange": [ "functionSourceRange": [
309, 309,
1312, 1312,
3 4
], ],
"unlabeledArg": null, "unlabeledArg": null,
"labeledArgs": {}, "labeledArgs": {},
@ -316,7 +316,7 @@ description: Operations executed bench.kcl
"functionSourceRange": [ "functionSourceRange": [
309, 309,
1312, 1312,
3 4
], ],
"unlabeledArg": null, "unlabeledArg": null,
"labeledArgs": {}, "labeledArgs": {},
@ -487,7 +487,7 @@ description: Operations executed bench.kcl
"functionSourceRange": [ "functionSourceRange": [
1331, 1331,
1606, 1606,
3 4
], ],
"unlabeledArg": null, "unlabeledArg": null,
"labeledArgs": {}, "labeledArgs": {},
@ -499,7 +499,7 @@ description: Operations executed bench.kcl
"functionSourceRange": [ "functionSourceRange": [
309, 309,
1312, 1312,
3 4
], ],
"unlabeledArg": null, "unlabeledArg": null,
"labeledArgs": {}, "labeledArgs": {},
@ -555,7 +555,7 @@ description: Operations executed bench.kcl
"functionSourceRange": [ "functionSourceRange": [
309, 309,
1312, 1312,
3 4
], ],
"unlabeledArg": null, "unlabeledArg": null,
"labeledArgs": {}, "labeledArgs": {},
@ -726,7 +726,7 @@ description: Operations executed bench.kcl
"functionSourceRange": [ "functionSourceRange": [
1889, 1889,
2052, 2052,
3 4
], ],
"unlabeledArg": null, "unlabeledArg": null,
"labeledArgs": {}, "labeledArgs": {},
@ -738,7 +738,7 @@ description: Operations executed bench.kcl
"functionSourceRange": [ "functionSourceRange": [
1626, 1626,
1868, 1868,
3 4
], ],
"unlabeledArg": null, "unlabeledArg": null,
"labeledArgs": {}, "labeledArgs": {},
@ -800,7 +800,7 @@ description: Operations executed bench.kcl
"functionSourceRange": [ "functionSourceRange": [
1626, 1626,
1868, 1868,
3 4
], ],
"unlabeledArg": null, "unlabeledArg": null,
"labeledArgs": {}, "labeledArgs": {},
@ -889,7 +889,7 @@ description: Operations executed bench.kcl
"functionSourceRange": [ "functionSourceRange": [
2474, 2474,
2560, 2560,
3 4
], ],
"unlabeledArg": null, "unlabeledArg": null,
"labeledArgs": {}, "labeledArgs": {},
@ -901,7 +901,7 @@ description: Operations executed bench.kcl
"functionSourceRange": [ "functionSourceRange": [
2071, 2071,
2453, 2453,
3 4
], ],
"unlabeledArg": null, "unlabeledArg": null,
"labeledArgs": {}, "labeledArgs": {},
@ -1007,7 +1007,7 @@ description: Operations executed bench.kcl
"functionSourceRange": [ "functionSourceRange": [
2993, 2993,
3084, 3084,
3 4
], ],
"unlabeledArg": null, "unlabeledArg": null,
"labeledArgs": {}, "labeledArgs": {},
@ -1019,7 +1019,7 @@ description: Operations executed bench.kcl
"functionSourceRange": [ "functionSourceRange": [
2580, 2580,
2972, 2972,
3 4
], ],
"unlabeledArg": null, "unlabeledArg": null,
"labeledArgs": {}, "labeledArgs": {},
@ -1095,7 +1095,7 @@ description: Operations executed bench.kcl
"functionSourceRange": [ "functionSourceRange": [
3671, 3671,
3861, 3861,
3 4
], ],
"unlabeledArg": null, "unlabeledArg": null,
"labeledArgs": {}, "labeledArgs": {},
@ -1131,7 +1131,7 @@ description: Operations executed bench.kcl
"functionSourceRange": [ "functionSourceRange": [
3100, 3100,
3325, 3325,
3 4
], ],
"unlabeledArg": null, "unlabeledArg": null,
"labeledArgs": {}, "labeledArgs": {},
@ -1191,7 +1191,7 @@ description: Operations executed bench.kcl
"functionSourceRange": [ "functionSourceRange": [
3344, 3344,
3652, 3652,
3 4
], ],
"unlabeledArg": null, "unlabeledArg": null,
"labeledArgs": {}, "labeledArgs": {},
@ -1249,7 +1249,7 @@ description: Operations executed bench.kcl
"functionSourceRange": [ "functionSourceRange": [
3671, 3671,
3861, 3861,
3 4
], ],
"unlabeledArg": null, "unlabeledArg": null,
"labeledArgs": {}, "labeledArgs": {},
@ -1285,7 +1285,7 @@ description: Operations executed bench.kcl
"functionSourceRange": [ "functionSourceRange": [
3100, 3100,
3325, 3325,
3 4
], ],
"unlabeledArg": null, "unlabeledArg": null,
"labeledArgs": {}, "labeledArgs": {},
@ -1345,7 +1345,7 @@ description: Operations executed bench.kcl
"functionSourceRange": [ "functionSourceRange": [
3344, 3344,
3652, 3652,
3 4
], ],
"unlabeledArg": null, "unlabeledArg": null,
"labeledArgs": {}, "labeledArgs": {},

View File

@ -255,6 +255,66 @@ description: Operations executed bracket.kcl
"type": "StdLibCall", "type": "StdLibCall",
"unlabeledArg": null "unlabeledArg": null
}, },
{
"type": "UserDefinedFunctionCall",
"name": "circle",
"functionSourceRange": [
0,
0,
0
],
"unlabeledArg": null,
"labeledArgs": {
"center": {
"value": {
"type": "Array",
"value": [
{
"type": "Number",
"value": -1.25,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
},
{
"type": "Number",
"value": 1.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
}
]
},
"sourceRange": []
},
"radius": {
"value": {
"type": "Number",
"value": 0.25,
"ty": {
"type": "Unknown"
}
},
"sourceRange": []
}
},
"sourceRange": []
},
{
"type": "UserDefinedFunctionReturn"
},
{ {
"labeledArgs": { "labeledArgs": {
"length": { "length": {
@ -329,6 +389,66 @@ description: Operations executed bracket.kcl
"type": "StdLibCall", "type": "StdLibCall",
"unlabeledArg": null "unlabeledArg": null
}, },
{
"type": "UserDefinedFunctionCall",
"name": "circle",
"functionSourceRange": [
0,
0,
0
],
"unlabeledArg": null,
"labeledArgs": {
"center": {
"value": {
"type": "Array",
"value": [
{
"type": "Number",
"value": 1.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
},
{
"type": "Number",
"value": -1.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
}
]
},
"sourceRange": []
},
"radius": {
"value": {
"type": "Number",
"value": 0.25,
"ty": {
"type": "Unknown"
}
},
"sourceRange": []
}
},
"sourceRange": []
},
{
"type": "UserDefinedFunctionReturn"
},
{ {
"labeledArgs": { "labeledArgs": {
"length": { "length": {

View File

@ -1,264 +1,264 @@
```mermaid ```mermaid
flowchart LR flowchart LR
subgraph path2 [Path] subgraph path2 [Path]
2["Path<br>[571, 643, 4]"] 2["Path<br>[571, 643, 5]"]
3["Segment<br>[571, 643, 4]"] 3["Segment<br>[571, 643, 5]"]
4[Solid2d] 4[Solid2d]
end end
subgraph path11 [Path] subgraph path11 [Path]
11["Path<br>[828, 905, 4]"] 11["Path<br>[828, 905, 5]"]
12["Segment<br>[828, 905, 4]"] 12["Segment<br>[828, 905, 5]"]
13[Solid2d] 13[Solid2d]
end end
subgraph path19 [Path] subgraph path19 [Path]
19["Path<br>[1030, 1104, 4]"] 19["Path<br>[1030, 1104, 5]"]
20["Segment<br>[1030, 1104, 4]"] 20["Segment<br>[1030, 1104, 5]"]
21[Solid2d] 21[Solid2d]
end end
subgraph path30 [Path] subgraph path30 [Path]
30["Path<br>[1486, 1526, 4]"] 30["Path<br>[1486, 1526, 5]"]
31["Segment<br>[1486, 1526, 4]"] 31["Segment<br>[1486, 1526, 5]"]
32[Solid2d] 32[Solid2d]
end end
subgraph path38 [Path] subgraph path38 [Path]
38["Path<br>[1630, 1702, 4]"] 38["Path<br>[1630, 1702, 5]"]
39["Segment<br>[1630, 1702, 4]"] 39["Segment<br>[1630, 1702, 5]"]
40[Solid2d] 40[Solid2d]
end end
subgraph path47 [Path] subgraph path47 [Path]
47["Path<br>[1835, 1909, 4]"] 47["Path<br>[1835, 1909, 5]"]
48["Segment<br>[1835, 1909, 4]"] 48["Segment<br>[1835, 1909, 5]"]
49[Solid2d] 49[Solid2d]
end end
subgraph path58 [Path] subgraph path58 [Path]
58["Path<br>[2151, 2244, 4]"] 58["Path<br>[2151, 2244, 5]"]
59["Segment<br>[2151, 2244, 4]"] 59["Segment<br>[2151, 2244, 5]"]
60[Solid2d] 60[Solid2d]
end end
subgraph path81 [Path] subgraph path81 [Path]
81["Path<br>[2500, 2531, 4]"] 81["Path<br>[2500, 2531, 5]"]
82["Segment<br>[2537, 2557, 4]"] 82["Segment<br>[2537, 2557, 5]"]
83["Segment<br>[2563, 2583, 4]"] 83["Segment<br>[2563, 2583, 5]"]
84["Segment<br>[2589, 2610, 4]"] 84["Segment<br>[2589, 2610, 5]"]
85["Segment<br>[2616, 2672, 4]"] 85["Segment<br>[2616, 2672, 5]"]
86["Segment<br>[2678, 2685, 4]"] 86["Segment<br>[2678, 2685, 5]"]
87[Solid2d] 87[Solid2d]
end end
subgraph path106 [Path] subgraph path106 [Path]
106["Path<br>[2986, 3018, 4]"] 106["Path<br>[2986, 3018, 5]"]
107["Segment<br>[3024, 3045, 4]"] 107["Segment<br>[3024, 3045, 5]"]
108["Segment<br>[3051, 3071, 4]"] 108["Segment<br>[3051, 3071, 5]"]
109["Segment<br>[3077, 3097, 4]"] 109["Segment<br>[3077, 3097, 5]"]
110["Segment<br>[3103, 3159, 4]"] 110["Segment<br>[3103, 3159, 5]"]
111["Segment<br>[3165, 3172, 4]"] 111["Segment<br>[3165, 3172, 5]"]
112[Solid2d] 112[Solid2d]
end end
subgraph path132 [Path] subgraph path132 [Path]
132["Path<br>[354, 431, 3]"] 132["Path<br>[354, 431, 4]"]
133["Segment<br>[354, 431, 3]"] 133["Segment<br>[354, 431, 4]"]
134[Solid2d] 134[Solid2d]
end end
subgraph path135 [Path] subgraph path135 [Path]
135["Path<br>[442, 519, 3]"] 135["Path<br>[442, 519, 4]"]
136["Segment<br>[442, 519, 3]"] 136["Segment<br>[442, 519, 4]"]
137[Solid2d] 137[Solid2d]
end end
subgraph path144 [Path] subgraph path144 [Path]
144["Path<br>[684, 761, 3]"] 144["Path<br>[684, 761, 4]"]
145["Segment<br>[684, 761, 3]"] 145["Segment<br>[684, 761, 4]"]
146[Solid2d] 146[Solid2d]
end end
subgraph path147 [Path] subgraph path147 [Path]
147["Path<br>[772, 849, 3]"] 147["Path<br>[772, 849, 4]"]
148["Segment<br>[772, 849, 3]"] 148["Segment<br>[772, 849, 4]"]
149[Solid2d] 149[Solid2d]
end end
subgraph path156 [Path] subgraph path156 [Path]
156["Path<br>[993, 1068, 3]"] 156["Path<br>[993, 1068, 4]"]
157["Segment<br>[993, 1068, 3]"] 157["Segment<br>[993, 1068, 4]"]
158[Solid2d] 158[Solid2d]
end end
subgraph path167 [Path] subgraph path167 [Path]
167["Path<br>[1345, 1426, 3]"] 167["Path<br>[1345, 1426, 4]"]
168["Segment<br>[1345, 1426, 3]"] 168["Segment<br>[1345, 1426, 4]"]
169[Solid2d] 169[Solid2d]
end end
subgraph path179 [Path] subgraph path179 [Path]
179["Path<br>[1785, 1831, 3]"] 179["Path<br>[1785, 1831, 4]"]
180["Segment<br>[1837, 1889, 3]"] 180["Segment<br>[1837, 1889, 4]"]
181["Segment<br>[1895, 2000, 3]"] 181["Segment<br>[1895, 2000, 4]"]
182["Segment<br>[2006, 2028, 3]"] 182["Segment<br>[2006, 2028, 4]"]
183["Segment<br>[2034, 2090, 3]"] 183["Segment<br>[2034, 2090, 4]"]
184["Segment<br>[2096, 2103, 3]"] 184["Segment<br>[2096, 2103, 4]"]
185[Solid2d] 185[Solid2d]
end end
subgraph path195 [Path] subgraph path195 [Path]
195["Path<br>[2239, 2285, 3]"] 195["Path<br>[2239, 2285, 4]"]
196["Segment<br>[2291, 2343, 3]"] 196["Segment<br>[2291, 2343, 4]"]
197["Segment<br>[2349, 2456, 3]"] 197["Segment<br>[2349, 2456, 4]"]
198["Segment<br>[2462, 2499, 3]"] 198["Segment<br>[2462, 2499, 4]"]
199["Segment<br>[2505, 2561, 3]"] 199["Segment<br>[2505, 2561, 4]"]
200["Segment<br>[2567, 2574, 3]"] 200["Segment<br>[2567, 2574, 4]"]
201[Solid2d] 201[Solid2d]
end end
subgraph path212 [Path] subgraph path212 [Path]
212["Path<br>[3085, 3132, 3]"] 212["Path<br>[3085, 3132, 4]"]
213["Segment<br>[3140, 3480, 3]"] 213["Segment<br>[3140, 3480, 4]"]
214["Segment<br>[3488, 3520, 3]"] 214["Segment<br>[3488, 3520, 4]"]
215["Segment<br>[3528, 3872, 3]"] 215["Segment<br>[3528, 3872, 4]"]
216["Segment<br>[3880, 3936, 3]"] 216["Segment<br>[3880, 3936, 4]"]
217["Segment<br>[3944, 3951, 3]"] 217["Segment<br>[3944, 3951, 4]"]
218[Solid2d] 218[Solid2d]
end end
subgraph path235 [Path] subgraph path235 [Path]
235["Path<br>[3085, 3132, 3]"] 235["Path<br>[3085, 3132, 4]"]
236["Segment<br>[3140, 3480, 3]"] 236["Segment<br>[3140, 3480, 4]"]
237["Segment<br>[3488, 3520, 3]"] 237["Segment<br>[3488, 3520, 4]"]
238["Segment<br>[3528, 3872, 3]"] 238["Segment<br>[3528, 3872, 4]"]
239["Segment<br>[3880, 3936, 3]"] 239["Segment<br>[3880, 3936, 4]"]
240["Segment<br>[3944, 3951, 3]"] 240["Segment<br>[3944, 3951, 4]"]
241[Solid2d] 241[Solid2d]
end end
subgraph path258 [Path] subgraph path258 [Path]
258["Path<br>[4480, 4575, 3]"] 258["Path<br>[4480, 4575, 4]"]
259["Segment<br>[4581, 4614, 3]"] 259["Segment<br>[4581, 4614, 4]"]
260["Segment<br>[4620, 4671, 3]"] 260["Segment<br>[4620, 4671, 4]"]
261["Segment<br>[4677, 4710, 3]"] 261["Segment<br>[4677, 4710, 4]"]
262["Segment<br>[4716, 4766, 3]"] 262["Segment<br>[4716, 4766, 4]"]
263["Segment<br>[4772, 4813, 3]"] 263["Segment<br>[4772, 4813, 4]"]
264["Segment<br>[4819, 4868, 3]"] 264["Segment<br>[4819, 4868, 4]"]
265["Segment<br>[4874, 4907, 3]"] 265["Segment<br>[4874, 4907, 4]"]
266["Segment<br>[4913, 4947, 3]"] 266["Segment<br>[4913, 4947, 4]"]
267["Segment<br>[4953, 4987, 3]"] 267["Segment<br>[4953, 4987, 4]"]
268["Segment<br>[4993, 5045, 3]"] 268["Segment<br>[4993, 5045, 4]"]
269["Segment<br>[5051, 5085, 3]"] 269["Segment<br>[5051, 5085, 4]"]
270["Segment<br>[5091, 5167, 3]"] 270["Segment<br>[5091, 5167, 4]"]
271["Segment<br>[5173, 5206, 3]"] 271["Segment<br>[5173, 5206, 4]"]
272["Segment<br>[5212, 5288, 3]"] 272["Segment<br>[5212, 5288, 4]"]
273["Segment<br>[5294, 5328, 3]"] 273["Segment<br>[5294, 5328, 4]"]
274["Segment<br>[5334, 5408, 3]"] 274["Segment<br>[5334, 5408, 4]"]
275["Segment<br>[5414, 5448, 3]"] 275["Segment<br>[5414, 5448, 4]"]
276["Segment<br>[5454, 5505, 3]"] 276["Segment<br>[5454, 5505, 4]"]
277["Segment<br>[5511, 5573, 3]"] 277["Segment<br>[5511, 5573, 4]"]
278["Segment<br>[5579, 5630, 3]"] 278["Segment<br>[5579, 5630, 4]"]
279["Segment<br>[5636, 5670, 3]"] 279["Segment<br>[5636, 5670, 4]"]
280["Segment<br>[5676, 5709, 3]"] 280["Segment<br>[5676, 5709, 4]"]
281["Segment<br>[5715, 5748, 3]"] 281["Segment<br>[5715, 5748, 4]"]
282["Segment<br>[5754, 5761, 3]"] 282["Segment<br>[5754, 5761, 4]"]
283[Solid2d] 283[Solid2d]
end end
subgraph path334 [Path] subgraph path334 [Path]
334["Path<br>[742, 782, 6]"] 334["Path<br>[742, 782, 7]"]
335["Segment<br>[790, 852, 6]"] 335["Segment<br>[790, 852, 7]"]
336["Segment<br>[860, 896, 6]"] 336["Segment<br>[860, 896, 7]"]
337["Segment<br>[904, 934, 6]"] 337["Segment<br>[904, 934, 7]"]
338["Segment<br>[942, 994, 6]"] 338["Segment<br>[942, 994, 7]"]
339["Segment<br>[1002, 1042, 6]"] 339["Segment<br>[1002, 1042, 7]"]
340["Segment<br>[1050, 1085, 6]"] 340["Segment<br>[1050, 1085, 7]"]
341["Segment<br>[1093, 1131, 6]"] 341["Segment<br>[1093, 1131, 7]"]
342["Segment<br>[1139, 1161, 6]"] 342["Segment<br>[1139, 1161, 7]"]
343["Segment<br>[1169, 1176, 6]"] 343["Segment<br>[1169, 1176, 7]"]
344[Solid2d] 344[Solid2d]
end end
subgraph path365 [Path] subgraph path365 [Path]
365["Path<br>[511, 592, 5]"] 365["Path<br>[511, 592, 6]"]
366["Segment<br>[598, 699, 5]"] 366["Segment<br>[598, 699, 6]"]
367["Segment<br>[705, 790, 5]"] 367["Segment<br>[705, 790, 6]"]
368["Segment<br>[796, 880, 5]"] 368["Segment<br>[796, 880, 6]"]
369["Segment<br>[886, 972, 5]"] 369["Segment<br>[886, 972, 6]"]
370["Segment<br>[978, 1063, 5]"] 370["Segment<br>[978, 1063, 6]"]
371["Segment<br>[1069, 1155, 5]"] 371["Segment<br>[1069, 1155, 6]"]
372["Segment<br>[1161, 1284, 5]"] 372["Segment<br>[1161, 1284, 6]"]
373["Segment<br>[1290, 1376, 5]"] 373["Segment<br>[1290, 1376, 6]"]
374["Segment<br>[1382, 1517, 5]"] 374["Segment<br>[1382, 1517, 6]"]
375["Segment<br>[1523, 1609, 5]"] 375["Segment<br>[1523, 1609, 6]"]
376["Segment<br>[1615, 1739, 5]"] 376["Segment<br>[1615, 1739, 6]"]
377["Segment<br>[1745, 1831, 5]"] 377["Segment<br>[1745, 1831, 6]"]
378["Segment<br>[1837, 1922, 5]"] 378["Segment<br>[1837, 1922, 6]"]
379["Segment<br>[1928, 2014, 5]"] 379["Segment<br>[1928, 2014, 6]"]
380["Segment<br>[2020, 2105, 5]"] 380["Segment<br>[2020, 2105, 6]"]
381["Segment<br>[2111, 2196, 5]"] 381["Segment<br>[2111, 2196, 6]"]
382["Segment<br>[2202, 2209, 5]"] 382["Segment<br>[2202, 2209, 6]"]
383[Solid2d] 383[Solid2d]
end end
subgraph path439 [Path] subgraph path439 [Path]
439["Path<br>[487, 544, 7]"] 439["Path<br>[487, 544, 8]"]
440["Segment<br>[550, 656, 7]"] 440["Segment<br>[550, 656, 8]"]
441["Segment<br>[662, 717, 7]"] 441["Segment<br>[662, 717, 8]"]
442["Segment<br>[723, 820, 7]"] 442["Segment<br>[723, 820, 8]"]
443["Segment<br>[826, 858, 7]"] 443["Segment<br>[826, 858, 8]"]
444["Segment<br>[864, 896, 7]"] 444["Segment<br>[864, 896, 8]"]
445["Segment<br>[902, 933, 7]"] 445["Segment<br>[902, 933, 8]"]
446["Segment<br>[939, 1054, 7]"] 446["Segment<br>[939, 1054, 8]"]
447["Segment<br>[1060, 1092, 7]"] 447["Segment<br>[1060, 1092, 8]"]
448["Segment<br>[1098, 1130, 7]"] 448["Segment<br>[1098, 1130, 8]"]
449["Segment<br>[1136, 1167, 7]"] 449["Segment<br>[1136, 1167, 8]"]
450["Segment<br>[1173, 1266, 7]"] 450["Segment<br>[1173, 1266, 8]"]
451["Segment<br>[1272, 1327, 7]"] 451["Segment<br>[1272, 1327, 8]"]
452["Segment<br>[1333, 1406, 7]"] 452["Segment<br>[1333, 1406, 8]"]
453["Segment<br>[1412, 1419, 7]"] 453["Segment<br>[1412, 1419, 8]"]
454[Solid2d] 454[Solid2d]
end end
1["Plane<br>[546, 565, 4]"] 1["Plane<br>[546, 565, 5]"]
5["Sweep Extrusion<br>[652, 708, 4]"] 5["Sweep Extrusion<br>[652, 708, 5]"]
6[Wall] 6[Wall]
7["Cap Start"] 7["Cap Start"]
8["Cap End"] 8["Cap End"]
9["SweepEdge Opposite"] 9["SweepEdge Opposite"]
10["SweepEdge Adjacent"] 10["SweepEdge Adjacent"]
14["Sweep Extrusion<br>[918, 980, 4]"] 14["Sweep Extrusion<br>[918, 980, 5]"]
15[Wall] 15[Wall]
16["Cap End"] 16["Cap End"]
17["SweepEdge Opposite"] 17["SweepEdge Opposite"]
18["SweepEdge Adjacent"] 18["SweepEdge Adjacent"]
22["Sweep Extrusion<br>[1250, 1329, 4]"] 22["Sweep Extrusion<br>[1250, 1329, 5]"]
23[Wall] 23[Wall]
24["SweepEdge Opposite"] 24["SweepEdge Opposite"]
25["SweepEdge Adjacent"] 25["SweepEdge Adjacent"]
26["Sweep Extrusion<br>[1250, 1329, 4]"] 26["Sweep Extrusion<br>[1250, 1329, 5]"]
27["Sweep Extrusion<br>[1250, 1329, 4]"] 27["Sweep Extrusion<br>[1250, 1329, 5]"]
28["Sweep Extrusion<br>[1250, 1329, 4]"] 28["Sweep Extrusion<br>[1250, 1329, 5]"]
29["Sweep Extrusion<br>[1250, 1329, 4]"] 29["Sweep Extrusion<br>[1250, 1329, 5]"]
33["Sweep Extrusion<br>[1532, 1565, 4]"] 33["Sweep Extrusion<br>[1532, 1565, 5]"]
34[Wall] 34[Wall]
35["Cap End"] 35["Cap End"]
36["SweepEdge Opposite"] 36["SweepEdge Opposite"]
37["SweepEdge Adjacent"] 37["SweepEdge Adjacent"]
41["Sweep Extrusion<br>[1717, 1782, 4]"] 41["Sweep Extrusion<br>[1717, 1782, 5]"]
42[Wall] 42[Wall]
43["Cap Start"] 43["Cap Start"]
44["Cap End"] 44["Cap End"]
45["SweepEdge Opposite"] 45["SweepEdge Opposite"]
46["SweepEdge Adjacent"] 46["SweepEdge Adjacent"]
50["Sweep Extrusion<br>[2055, 2099, 4]"] 50["Sweep Extrusion<br>[2055, 2099, 5]"]
51[Wall] 51[Wall]
52["SweepEdge Opposite"] 52["SweepEdge Opposite"]
53["SweepEdge Adjacent"] 53["SweepEdge Adjacent"]
54["Sweep Extrusion<br>[2055, 2099, 4]"] 54["Sweep Extrusion<br>[2055, 2099, 5]"]
55["Sweep Extrusion<br>[2055, 2099, 4]"] 55["Sweep Extrusion<br>[2055, 2099, 5]"]
56["Sweep Extrusion<br>[2055, 2099, 4]"] 56["Sweep Extrusion<br>[2055, 2099, 5]"]
57["Sweep Extrusion<br>[2055, 2099, 4]"] 57["Sweep Extrusion<br>[2055, 2099, 5]"]
61["Sweep Extrusion<br>[2398, 2442, 4]"] 61["Sweep Extrusion<br>[2398, 2442, 5]"]
62[Wall] 62[Wall]
63["Cap End"] 63["Cap End"]
64["SweepEdge Opposite"] 64["SweepEdge Opposite"]
65["SweepEdge Adjacent"] 65["SweepEdge Adjacent"]
66["Sweep Extrusion<br>[2398, 2442, 4]"] 66["Sweep Extrusion<br>[2398, 2442, 5]"]
67["Sweep Extrusion<br>[2398, 2442, 4]"] 67["Sweep Extrusion<br>[2398, 2442, 5]"]
68["Sweep Extrusion<br>[2398, 2442, 4]"] 68["Sweep Extrusion<br>[2398, 2442, 5]"]
69["Sweep Extrusion<br>[2398, 2442, 4]"] 69["Sweep Extrusion<br>[2398, 2442, 5]"]
70["Sweep Extrusion<br>[2398, 2442, 4]"] 70["Sweep Extrusion<br>[2398, 2442, 5]"]
71["Sweep Extrusion<br>[2398, 2442, 4]"] 71["Sweep Extrusion<br>[2398, 2442, 5]"]
72["Sweep Extrusion<br>[2398, 2442, 4]"] 72["Sweep Extrusion<br>[2398, 2442, 5]"]
73["Sweep Extrusion<br>[2398, 2442, 4]"] 73["Sweep Extrusion<br>[2398, 2442, 5]"]
74["Sweep Extrusion<br>[2398, 2442, 4]"] 74["Sweep Extrusion<br>[2398, 2442, 5]"]
75["Sweep Extrusion<br>[2398, 2442, 4]"] 75["Sweep Extrusion<br>[2398, 2442, 5]"]
76["Sweep Extrusion<br>[2398, 2442, 4]"] 76["Sweep Extrusion<br>[2398, 2442, 5]"]
77["Sweep Extrusion<br>[2398, 2442, 4]"] 77["Sweep Extrusion<br>[2398, 2442, 5]"]
78["Sweep Extrusion<br>[2398, 2442, 4]"] 78["Sweep Extrusion<br>[2398, 2442, 5]"]
79["Sweep Extrusion<br>[2398, 2442, 4]"] 79["Sweep Extrusion<br>[2398, 2442, 5]"]
80["Sweep Extrusion<br>[2398, 2442, 4]"] 80["Sweep Extrusion<br>[2398, 2442, 5]"]
88["Sweep Extrusion<br>[2850, 2918, 4]"] 88["Sweep Extrusion<br>[2850, 2918, 5]"]
89[Wall] 89[Wall]
90[Wall] 90[Wall]
91[Wall] 91[Wall]
@ -272,11 +272,11 @@ flowchart LR
99["SweepEdge Adjacent"] 99["SweepEdge Adjacent"]
100["SweepEdge Opposite"] 100["SweepEdge Opposite"]
101["SweepEdge Adjacent"] 101["SweepEdge Adjacent"]
102["Sweep Extrusion<br>[2850, 2918, 4]"] 102["Sweep Extrusion<br>[2850, 2918, 5]"]
103["Sweep Extrusion<br>[2850, 2918, 4]"] 103["Sweep Extrusion<br>[2850, 2918, 5]"]
104["Sweep Extrusion<br>[2850, 2918, 4]"] 104["Sweep Extrusion<br>[2850, 2918, 5]"]
105["Sweep Extrusion<br>[2850, 2918, 4]"] 105["Sweep Extrusion<br>[2850, 2918, 5]"]
113["Sweep Extrusion<br>[3323, 3397, 4]"] 113["Sweep Extrusion<br>[3323, 3397, 5]"]
114[Wall] 114[Wall]
115[Wall] 115[Wall]
116[Wall] 116[Wall]
@ -290,41 +290,41 @@ flowchart LR
124["SweepEdge Adjacent"] 124["SweepEdge Adjacent"]
125["SweepEdge Opposite"] 125["SweepEdge Opposite"]
126["SweepEdge Adjacent"] 126["SweepEdge Adjacent"]
127["Sweep Extrusion<br>[3323, 3397, 4]"] 127["Sweep Extrusion<br>[3323, 3397, 5]"]
128["Sweep Extrusion<br>[3323, 3397, 4]"] 128["Sweep Extrusion<br>[3323, 3397, 5]"]
129["Sweep Extrusion<br>[3323, 3397, 4]"] 129["Sweep Extrusion<br>[3323, 3397, 5]"]
130["Sweep Extrusion<br>[3323, 3397, 4]"] 130["Sweep Extrusion<br>[3323, 3397, 5]"]
131["Plane<br>[329, 348, 3]"] 131["Plane<br>[329, 348, 4]"]
138["Sweep Extrusion<br>[529, 562, 3]"] 138["Sweep Extrusion<br>[529, 562, 4]"]
139[Wall] 139[Wall]
140["Cap Start"] 140["Cap Start"]
141["Cap End"] 141["Cap End"]
142["SweepEdge Opposite"] 142["SweepEdge Opposite"]
143["SweepEdge Adjacent"] 143["SweepEdge Adjacent"]
150["Sweep Extrusion<br>[859, 892, 3]"] 150["Sweep Extrusion<br>[859, 892, 4]"]
151[Wall] 151[Wall]
152["Cap Start"] 152["Cap Start"]
153["Cap End"] 153["Cap End"]
154["SweepEdge Opposite"] 154["SweepEdge Opposite"]
155["SweepEdge Adjacent"] 155["SweepEdge Adjacent"]
159["Sweep Extrusion<br>[1214, 1248, 3]"] 159["Sweep Extrusion<br>[1214, 1248, 4]"]
160[Wall] 160[Wall]
161["SweepEdge Opposite"] 161["SweepEdge Opposite"]
162["SweepEdge Adjacent"] 162["SweepEdge Adjacent"]
163["Sweep Extrusion<br>[1214, 1248, 3]"] 163["Sweep Extrusion<br>[1214, 1248, 4]"]
164["Sweep Extrusion<br>[1214, 1248, 3]"] 164["Sweep Extrusion<br>[1214, 1248, 4]"]
165["Sweep Extrusion<br>[1214, 1248, 3]"] 165["Sweep Extrusion<br>[1214, 1248, 4]"]
166["Sweep Extrusion<br>[1214, 1248, 3]"] 166["Sweep Extrusion<br>[1214, 1248, 4]"]
170["Sweep Extrusion<br>[1572, 1606, 3]"] 170["Sweep Extrusion<br>[1572, 1606, 4]"]
171[Wall] 171[Wall]
172["SweepEdge Opposite"] 172["SweepEdge Opposite"]
173["SweepEdge Adjacent"] 173["SweepEdge Adjacent"]
174["Sweep Extrusion<br>[1572, 1606, 3]"] 174["Sweep Extrusion<br>[1572, 1606, 4]"]
175["Sweep Extrusion<br>[1572, 1606, 3]"] 175["Sweep Extrusion<br>[1572, 1606, 4]"]
176["Sweep Extrusion<br>[1572, 1606, 3]"] 176["Sweep Extrusion<br>[1572, 1606, 4]"]
177["Sweep Extrusion<br>[1572, 1606, 3]"] 177["Sweep Extrusion<br>[1572, 1606, 4]"]
178["Plane<br>[1760, 1779, 3]"] 178["Plane<br>[1760, 1779, 4]"]
186["Sweep Revolve<br>[2109, 2128, 3]"] 186["Sweep Revolve<br>[2109, 2128, 4]"]
187[Wall] 187[Wall]
188[Wall] 188[Wall]
189[Wall] 189[Wall]
@ -332,8 +332,8 @@ flowchart LR
191["SweepEdge Adjacent"] 191["SweepEdge Adjacent"]
192["SweepEdge Adjacent"] 192["SweepEdge Adjacent"]
193["SweepEdge Adjacent"] 193["SweepEdge Adjacent"]
194["Plane<br>[2214, 2233, 3]"] 194["Plane<br>[2214, 2233, 4]"]
202["Sweep Revolve<br>[2580, 2599, 3]"] 202["Sweep Revolve<br>[2580, 2599, 4]"]
203[Wall] 203[Wall]
204[Wall] 204[Wall]
205[Wall] 205[Wall]
@ -342,8 +342,8 @@ flowchart LR
208["SweepEdge Adjacent"] 208["SweepEdge Adjacent"]
209["SweepEdge Adjacent"] 209["SweepEdge Adjacent"]
210["SweepEdge Adjacent"] 210["SweepEdge Adjacent"]
211["Plane<br>[3054, 3077, 3]"] 211["Plane<br>[3054, 3077, 4]"]
219["Sweep Extrusion<br>[3999, 4045, 3]"] 219["Sweep Extrusion<br>[3999, 4045, 4]"]
220[Wall] 220[Wall]
221[Wall] 221[Wall]
222[Wall] 222[Wall]
@ -358,8 +358,8 @@ flowchart LR
231["SweepEdge Adjacent"] 231["SweepEdge Adjacent"]
232["SweepEdge Opposite"] 232["SweepEdge Opposite"]
233["SweepEdge Adjacent"] 233["SweepEdge Adjacent"]
234["Plane<br>[3054, 3077, 3]"] 234["Plane<br>[3054, 3077, 4]"]
242["Sweep Extrusion<br>[3999, 4045, 3]"] 242["Sweep Extrusion<br>[3999, 4045, 4]"]
243[Wall] 243[Wall]
244[Wall] 244[Wall]
245[Wall] 245[Wall]
@ -374,8 +374,8 @@ flowchart LR
254["SweepEdge Adjacent"] 254["SweepEdge Adjacent"]
255["SweepEdge Opposite"] 255["SweepEdge Opposite"]
256["SweepEdge Adjacent"] 256["SweepEdge Adjacent"]
257["Plane<br>[4455, 4474, 3]"] 257["Plane<br>[4455, 4474, 4]"]
284["Sweep Revolve<br>[5767, 5786, 3]"] 284["Sweep Revolve<br>[5767, 5786, 4]"]
285[Wall] 285[Wall]
286[Wall] 286[Wall]
287[Wall] 287[Wall]
@ -424,8 +424,8 @@ flowchart LR
330["SweepEdge Adjacent"] 330["SweepEdge Adjacent"]
331["SweepEdge Adjacent"] 331["SweepEdge Adjacent"]
332["SweepEdge Adjacent"] 332["SweepEdge Adjacent"]
333["Plane<br>[708, 734, 6]"] 333["Plane<br>[708, 734, 7]"]
345["Sweep Revolve<br>[1184, 1203, 6]"] 345["Sweep Revolve<br>[1184, 1203, 7]"]
346[Wall] 346[Wall]
347[Wall] 347[Wall]
348[Wall] 348[Wall]
@ -444,8 +444,8 @@ flowchart LR
361["SweepEdge Adjacent"] 361["SweepEdge Adjacent"]
362["SweepEdge Adjacent"] 362["SweepEdge Adjacent"]
363["SweepEdge Adjacent"] 363["SweepEdge Adjacent"]
364["Plane<br>[486, 505, 5]"] 364["Plane<br>[486, 505, 6]"]
384["Sweep Revolve<br>[2247, 2299, 5]"] 384["Sweep Revolve<br>[2247, 2299, 6]"]
385[Wall] 385[Wall]
386[Wall] 386[Wall]
387[Wall] 387[Wall]
@ -499,8 +499,8 @@ flowchart LR
435["SweepEdge Adjacent"] 435["SweepEdge Adjacent"]
436["SweepEdge Opposite"] 436["SweepEdge Opposite"]
437["SweepEdge Adjacent"] 437["SweepEdge Adjacent"]
438["Plane<br>[462, 481, 7]"] 438["Plane<br>[462, 481, 8]"]
455["Sweep Revolve<br>[1462, 1493, 7]"] 455["Sweep Revolve<br>[1462, 1493, 8]"]
456[Wall] 456[Wall]
457[Wall] 457[Wall]
458[Wall] 458[Wall]
@ -529,17 +529,17 @@ flowchart LR
481["SweepEdge Adjacent"] 481["SweepEdge Adjacent"]
482["SweepEdge Adjacent"] 482["SweepEdge Adjacent"]
483["SweepEdge Adjacent"] 483["SweepEdge Adjacent"]
484["StartSketchOnFace<br>[795, 822, 4]"] 484["StartSketchOnFace<br>[795, 822, 5]"]
485["StartSketchOnFace<br>[993, 1024, 4]"] 485["StartSketchOnFace<br>[993, 1024, 5]"]
486["StartSketchOnFace<br>[1451, 1480, 4]"] 486["StartSketchOnFace<br>[1451, 1480, 5]"]
487["StartSketchOnFace<br>[1590, 1624, 4]"] 487["StartSketchOnFace<br>[1590, 1624, 5]"]
488["StartSketchOnFace<br>[1796, 1829, 4]"] 488["StartSketchOnFace<br>[1796, 1829, 5]"]
489["StartSketchOnFace<br>[2116, 2145, 4]"] 489["StartSketchOnFace<br>[2116, 2145, 5]"]
490["StartSketchOnFace<br>[2465, 2494, 4]"] 490["StartSketchOnFace<br>[2465, 2494, 5]"]
491["StartSketchOnFace<br>[2947, 2980, 4]"] 491["StartSketchOnFace<br>[2947, 2980, 5]"]
492["StartSketchOnFace<br>[649, 678, 3]"] 492["StartSketchOnFace<br>[649, 678, 4]"]
493["StartSketchOnFace<br>[953, 987, 3]"] 493["StartSketchOnFace<br>[953, 987, 4]"]
494["StartSketchOnFace<br>[1310, 1339, 3]"] 494["StartSketchOnFace<br>[1310, 1339, 4]"]
1 --- 2 1 --- 2
2 --- 3 2 --- 3
2 ---- 5 2 ---- 5

View File

@ -18,6 +18,66 @@ description: Operations executed car-wheel-assembly.kcl
"type": "StdLibCall", "type": "StdLibCall",
"unlabeledArg": null "unlabeledArg": null
}, },
{
"type": "UserDefinedFunctionCall",
"name": "circle",
"functionSourceRange": [
0,
0,
0
],
"unlabeledArg": null,
"labeledArgs": {
"center": {
"value": {
"type": "Array",
"value": [
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
}
},
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
}
}
]
},
"sourceRange": []
},
"radius": {
"value": {
"type": "Number",
"value": 6.0,
"ty": {
"type": "Unknown"
}
},
"sourceRange": []
}
},
"sourceRange": []
},
{
"type": "UserDefinedFunctionReturn"
},
{ {
"labeledArgs": { "labeledArgs": {
"length": { "length": {
@ -74,6 +134,66 @@ description: Operations executed car-wheel-assembly.kcl
"type": "StdLibCall", "type": "StdLibCall",
"unlabeledArg": null "unlabeledArg": null
}, },
{
"type": "UserDefinedFunctionCall",
"name": "circle",
"functionSourceRange": [
0,
0,
0
],
"unlabeledArg": null,
"labeledArgs": {
"center": {
"value": {
"type": "Array",
"value": [
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
}
},
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
}
}
]
},
"sourceRange": []
},
"radius": {
"value": {
"type": "Number",
"value": 3.0,
"ty": {
"type": "Unknown"
}
},
"sourceRange": []
}
},
"sourceRange": []
},
{
"type": "UserDefinedFunctionReturn"
},
{ {
"labeledArgs": { "labeledArgs": {
"length": { "length": {
@ -130,6 +250,66 @@ description: Operations executed car-wheel-assembly.kcl
"type": "StdLibCall", "type": "StdLibCall",
"unlabeledArg": null "unlabeledArg": null
}, },
{
"type": "UserDefinedFunctionCall",
"name": "circle",
"functionSourceRange": [
0,
0,
0
],
"unlabeledArg": null,
"labeledArgs": {
"center": {
"value": {
"type": "Array",
"value": [
{
"type": "Number",
"value": -2.25,
"ty": {
"type": "Unknown"
}
},
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
}
}
]
},
"sourceRange": []
},
"radius": {
"value": {
"type": "Number",
"value": 0.315,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
}
},
"sourceRange": []
}
},
"sourceRange": []
},
{
"type": "UserDefinedFunctionReturn"
},
{ {
"labeledArgs": { "labeledArgs": {
"length": { "length": {
@ -215,6 +395,78 @@ description: Operations executed car-wheel-assembly.kcl
"type": "StdLibCall", "type": "StdLibCall",
"unlabeledArg": null "unlabeledArg": null
}, },
{
"type": "UserDefinedFunctionCall",
"name": "circle",
"functionSourceRange": [
0,
0,
0
],
"unlabeledArg": {
"value": {
"type": "Face",
"artifact_id": "[uuid]"
},
"sourceRange": []
},
"labeledArgs": {
"center": {
"value": {
"type": "Array",
"value": [
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
}
},
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
}
}
]
},
"sourceRange": []
},
"radius": {
"value": {
"type": "Number",
"value": 0.25,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
}
},
"sourceRange": []
}
},
"sourceRange": []
},
{
"type": "UserDefinedFunctionReturn"
},
{ {
"labeledArgs": { "labeledArgs": {
"length": { "length": {
@ -265,6 +517,66 @@ description: Operations executed car-wheel-assembly.kcl
"type": "StdLibCall", "type": "StdLibCall",
"unlabeledArg": null "unlabeledArg": null
}, },
{
"type": "UserDefinedFunctionCall",
"name": "circle",
"functionSourceRange": [
0,
0,
0
],
"unlabeledArg": null,
"labeledArgs": {
"center": {
"value": {
"type": "Array",
"value": [
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
}
},
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
}
}
]
},
"sourceRange": []
},
"radius": {
"value": {
"type": "Number",
"value": 6.0,
"ty": {
"type": "Unknown"
}
},
"sourceRange": []
}
},
"sourceRange": []
},
{
"type": "UserDefinedFunctionReturn"
},
{ {
"labeledArgs": { "labeledArgs": {
"length": { "length": {
@ -321,6 +633,66 @@ description: Operations executed car-wheel-assembly.kcl
"type": "StdLibCall", "type": "StdLibCall",
"unlabeledArg": null "unlabeledArg": null
}, },
{
"type": "UserDefinedFunctionCall",
"name": "circle",
"functionSourceRange": [
0,
0,
0
],
"unlabeledArg": null,
"labeledArgs": {
"center": {
"value": {
"type": "Array",
"value": [
{
"type": "Number",
"value": -2.25,
"ty": {
"type": "Unknown"
}
},
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
}
}
]
},
"sourceRange": []
},
"radius": {
"value": {
"type": "Number",
"value": 0.315,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
}
},
"sourceRange": []
}
},
"sourceRange": []
},
{
"type": "UserDefinedFunctionReturn"
},
{ {
"labeledArgs": { "labeledArgs": {
"length": { "length": {
@ -406,6 +778,66 @@ description: Operations executed car-wheel-assembly.kcl
"type": "StdLibCall", "type": "StdLibCall",
"unlabeledArg": null "unlabeledArg": null
}, },
{
"type": "UserDefinedFunctionCall",
"name": "circle",
"functionSourceRange": [
0,
0,
0
],
"unlabeledArg": null,
"labeledArgs": {
"center": {
"value": {
"type": "Array",
"value": [
{
"type": "Number",
"value": 5.5,
"ty": {
"type": "Unknown"
}
},
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
}
}
]
},
"sourceRange": []
},
"radius": {
"value": {
"type": "Number",
"value": 0.25,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
}
},
"sourceRange": []
}
},
"sourceRange": []
},
{
"type": "UserDefinedFunctionReturn"
},
{ {
"labeledArgs": { "labeledArgs": {
"length": { "length": {
@ -700,6 +1132,126 @@ description: Operations executed car-wheel-assembly.kcl
"type": "StdLibCall", "type": "StdLibCall",
"unlabeledArg": null "unlabeledArg": null
}, },
{
"type": "UserDefinedFunctionCall",
"name": "circle",
"functionSourceRange": [
0,
0,
0
],
"unlabeledArg": null,
"labeledArgs": {
"center": {
"value": {
"type": "Array",
"value": [
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
}
},
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
}
}
]
},
"sourceRange": []
},
"radius": {
"value": {
"type": "Number",
"value": 3.0,
"ty": {
"type": "Unknown"
}
},
"sourceRange": []
}
},
"sourceRange": []
},
{
"type": "UserDefinedFunctionReturn"
},
{
"type": "UserDefinedFunctionCall",
"name": "circle",
"functionSourceRange": [
0,
0,
0
],
"unlabeledArg": null,
"labeledArgs": {
"center": {
"value": {
"type": "Array",
"value": [
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
}
},
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
}
}
]
},
"sourceRange": []
},
"radius": {
"value": {
"type": "Number",
"value": 1.5,
"ty": {
"type": "Unknown"
}
},
"sourceRange": []
}
},
"sourceRange": []
},
{
"type": "UserDefinedFunctionReturn"
},
{ {
"labeledArgs": { "labeledArgs": {
"holeSketch": { "holeSketch": {
@ -776,6 +1328,126 @@ description: Operations executed car-wheel-assembly.kcl
"type": "StdLibCall", "type": "StdLibCall",
"unlabeledArg": null "unlabeledArg": null
}, },
{
"type": "UserDefinedFunctionCall",
"name": "circle",
"functionSourceRange": [
0,
0,
0
],
"unlabeledArg": null,
"labeledArgs": {
"center": {
"value": {
"type": "Array",
"value": [
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
}
},
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
}
}
]
},
"sourceRange": []
},
"radius": {
"value": {
"type": "Number",
"value": 3.0,
"ty": {
"type": "Unknown"
}
},
"sourceRange": []
}
},
"sourceRange": []
},
{
"type": "UserDefinedFunctionReturn"
},
{
"type": "UserDefinedFunctionCall",
"name": "circle",
"functionSourceRange": [
0,
0,
0
],
"unlabeledArg": null,
"labeledArgs": {
"center": {
"value": {
"type": "Array",
"value": [
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
}
},
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
}
}
]
},
"sourceRange": []
},
"radius": {
"value": {
"type": "Number",
"value": 1.5,
"ty": {
"type": "Unknown"
}
},
"sourceRange": []
}
},
"sourceRange": []
},
{
"type": "UserDefinedFunctionReturn"
},
{ {
"labeledArgs": { "labeledArgs": {
"holeSketch": { "holeSketch": {
@ -852,6 +1524,60 @@ description: Operations executed car-wheel-assembly.kcl
"type": "StdLibCall", "type": "StdLibCall",
"unlabeledArg": null "unlabeledArg": null
}, },
{
"type": "UserDefinedFunctionCall",
"name": "circle",
"functionSourceRange": [
0,
0,
0
],
"unlabeledArg": null,
"labeledArgs": {
"center": {
"value": {
"type": "Array",
"value": [
{
"type": "Number",
"value": 2.25,
"ty": {
"type": "Unknown"
}
},
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
}
}
]
},
"sourceRange": []
},
"radius": {
"value": {
"type": "Number",
"value": 0.6,
"ty": {
"type": "Unknown"
}
},
"sourceRange": []
}
},
"sourceRange": []
},
{
"type": "UserDefinedFunctionReturn"
},
{ {
"labeledArgs": { "labeledArgs": {
"length": { "length": {
@ -931,6 +1657,60 @@ description: Operations executed car-wheel-assembly.kcl
"type": "StdLibCall", "type": "StdLibCall",
"unlabeledArg": null "unlabeledArg": null
}, },
{
"type": "UserDefinedFunctionCall",
"name": "circle",
"functionSourceRange": [
0,
0,
0
],
"unlabeledArg": null,
"labeledArgs": {
"center": {
"value": {
"type": "Array",
"value": [
{
"type": "Number",
"value": 2.25,
"ty": {
"type": "Unknown"
}
},
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
}
}
]
},
"sourceRange": []
},
"radius": {
"value": {
"type": "Number",
"value": 0.31496062992125984,
"ty": {
"type": "Unknown"
}
},
"sourceRange": []
}
},
"sourceRange": []
},
{
"type": "UserDefinedFunctionReturn"
},
{ {
"labeledArgs": { "labeledArgs": {
"length": { "length": {
@ -1068,7 +1848,7 @@ description: Operations executed car-wheel-assembly.kcl
"functionSourceRange": [ "functionSourceRange": [
2752, 2752,
4324, 4324,
3 4
], ],
"unlabeledArg": null, "unlabeledArg": null,
"labeledArgs": {}, "labeledArgs": {},
@ -1455,7 +2235,7 @@ description: Operations executed car-wheel-assembly.kcl
"functionSourceRange": [ "functionSourceRange": [
2752, 2752,
4324, 4324,
3 4
], ],
"unlabeledArg": null, "unlabeledArg": null,
"labeledArgs": {}, "labeledArgs": {},
@ -1880,7 +2660,7 @@ description: Operations executed car-wheel-assembly.kcl
"functionSourceRange": [ "functionSourceRange": [
666, 666,
1293, 1293,
6 7
], ],
"unlabeledArg": null, "unlabeledArg": null,
"labeledArgs": {}, "labeledArgs": {},

View File

@ -5,7 +5,7 @@ description: Variables in memory after executing car-wheel-assembly.kcl
{ {
"brakeCaliper": { "brakeCaliper": {
"type": "Module", "type": "Module",
"value": 5 "value": 6
}, },
"c1": { "c1": {
"type": "TagIdentifier", "type": "TagIdentifier",
@ -14,15 +14,15 @@ description: Variables in memory after executing car-wheel-assembly.kcl
}, },
"carRotor": { "carRotor": {
"type": "Module", "type": "Module",
"value": 4 "value": 5
}, },
"carTire": { "carTire": {
"type": "Module", "type": "Module",
"value": 7 "value": 8
}, },
"carWheel": { "carWheel": {
"type": "Module", "type": "Module",
"value": 3 "value": 4
}, },
"lugCount": { "lugCount": {
"type": "Number", "type": "Number",
@ -39,6 +39,6 @@ description: Variables in memory after executing car-wheel-assembly.kcl
}, },
"lugNut": { "lugNut": {
"type": "Module", "type": "Module",
"value": 6 "value": 7
} }
} }

View File

@ -132,6 +132,66 @@ description: Operations executed cycloidal-gear.kcl
{ {
"type": "UserDefinedFunctionReturn" "type": "UserDefinedFunctionReturn"
}, },
{
"type": "UserDefinedFunctionCall",
"name": "circle",
"functionSourceRange": [
0,
0,
0
],
"unlabeledArg": null,
"labeledArgs": {
"center": {
"value": {
"type": "Array",
"value": [
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
}
},
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
}
}
]
},
"sourceRange": []
},
"radius": {
"value": {
"type": "Number",
"value": 0.1485,
"ty": {
"type": "Unknown"
}
},
"sourceRange": []
}
},
"sourceRange": []
},
{
"type": "UserDefinedFunctionReturn"
},
{ {
"labeledArgs": { "labeledArgs": {
"holeSketch": { "holeSketch": {
@ -272,6 +332,66 @@ description: Operations executed cycloidal-gear.kcl
{ {
"type": "UserDefinedFunctionReturn" "type": "UserDefinedFunctionReturn"
}, },
{
"type": "UserDefinedFunctionCall",
"name": "circle",
"functionSourceRange": [
0,
0,
0
],
"unlabeledArg": null,
"labeledArgs": {
"center": {
"value": {
"type": "Array",
"value": [
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
}
},
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
}
}
]
},
"sourceRange": []
},
"radius": {
"value": {
"type": "Number",
"value": 0.1485,
"ty": {
"type": "Unknown"
}
},
"sourceRange": []
}
},
"sourceRange": []
},
{
"type": "UserDefinedFunctionReturn"
},
{ {
"labeledArgs": { "labeledArgs": {
"holeSketch": { "holeSketch": {
@ -418,6 +538,66 @@ description: Operations executed cycloidal-gear.kcl
{ {
"type": "UserDefinedFunctionReturn" "type": "UserDefinedFunctionReturn"
}, },
{
"type": "UserDefinedFunctionCall",
"name": "circle",
"functionSourceRange": [
0,
0,
0
],
"unlabeledArg": null,
"labeledArgs": {
"center": {
"value": {
"type": "Array",
"value": [
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
}
},
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
}
}
]
},
"sourceRange": []
},
"radius": {
"value": {
"type": "Number",
"value": 0.1485,
"ty": {
"type": "Unknown"
}
},
"sourceRange": []
}
},
"sourceRange": []
},
{
"type": "UserDefinedFunctionReturn"
},
{ {
"labeledArgs": { "labeledArgs": {
"holeSketch": { "holeSketch": {

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -18,6 +18,60 @@ description: Operations executed flange.kcl
"type": "StdLibCall", "type": "StdLibCall",
"unlabeledArg": null "unlabeledArg": null
}, },
{
"type": "UserDefinedFunctionCall",
"name": "circle",
"functionSourceRange": [
0,
0,
0
],
"unlabeledArg": null,
"labeledArgs": {
"center": {
"value": {
"type": "Array",
"value": [
{
"type": "Number",
"value": 1.75,
"ty": {
"type": "Unknown"
}
},
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
}
}
]
},
"sourceRange": []
},
"radius": {
"value": {
"type": "Number",
"value": 0.3125,
"ty": {
"type": "Unknown"
}
},
"sourceRange": []
}
},
"sourceRange": []
},
{
"type": "UserDefinedFunctionReturn"
},
{ {
"labeledArgs": { "labeledArgs": {
"data": { "data": {
@ -33,6 +87,66 @@ description: Operations executed flange.kcl
"type": "StdLibCall", "type": "StdLibCall",
"unlabeledArg": null "unlabeledArg": null
}, },
{
"type": "UserDefinedFunctionCall",
"name": "circle",
"functionSourceRange": [
0,
0,
0
],
"unlabeledArg": null,
"labeledArgs": {
"center": {
"value": {
"type": "Array",
"value": [
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
}
},
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
}
}
]
},
"sourceRange": []
},
"radius": {
"value": {
"type": "Number",
"value": 2.3125,
"ty": {
"type": "Unknown"
}
},
"sourceRange": []
}
},
"sourceRange": []
},
{
"type": "UserDefinedFunctionReturn"
},
{ {
"labeledArgs": { "labeledArgs": {
"holeSketch": { "holeSketch": {
@ -138,6 +252,66 @@ description: Operations executed flange.kcl
"type": "StdLibCall", "type": "StdLibCall",
"unlabeledArg": null "unlabeledArg": null
}, },
{
"type": "UserDefinedFunctionCall",
"name": "circle",
"functionSourceRange": [
0,
0,
0
],
"unlabeledArg": null,
"labeledArgs": {
"center": {
"value": {
"type": "Array",
"value": [
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
}
},
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
}
}
]
},
"sourceRange": []
},
"radius": {
"value": {
"type": "Number",
"value": 1.1565,
"ty": {
"type": "Unknown"
}
},
"sourceRange": []
}
},
"sourceRange": []
},
{
"type": "UserDefinedFunctionReturn"
},
{ {
"labeledArgs": { "labeledArgs": {
"length": { "length": {
@ -194,6 +368,66 @@ description: Operations executed flange.kcl
"type": "StdLibCall", "type": "StdLibCall",
"unlabeledArg": null "unlabeledArg": null
}, },
{
"type": "UserDefinedFunctionCall",
"name": "circle",
"functionSourceRange": [
0,
0,
0
],
"unlabeledArg": null,
"labeledArgs": {
"center": {
"value": {
"type": "Array",
"value": [
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
}
},
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
}
}
]
},
"sourceRange": []
},
"radius": {
"value": {
"type": "Number",
"value": 1.25,
"ty": {
"type": "Unknown"
}
},
"sourceRange": []
}
},
"sourceRange": []
},
{
"type": "UserDefinedFunctionReturn"
},
{ {
"labeledArgs": { "labeledArgs": {
"length": { "length": {
@ -250,6 +484,66 @@ description: Operations executed flange.kcl
"type": "StdLibCall", "type": "StdLibCall",
"unlabeledArg": null "unlabeledArg": null
}, },
{
"type": "UserDefinedFunctionCall",
"name": "circle",
"functionSourceRange": [
0,
0,
0
],
"unlabeledArg": null,
"labeledArgs": {
"center": {
"value": {
"type": "Array",
"value": [
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
}
},
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
}
}
]
},
"sourceRange": []
},
"radius": {
"value": {
"type": "Number",
"value": 0.625,
"ty": {
"type": "Unknown"
}
},
"sourceRange": []
}
},
"sourceRange": []
},
{
"type": "UserDefinedFunctionReturn"
},
{ {
"labeledArgs": { "labeledArgs": {
"length": { "length": {

View File

@ -488,6 +488,54 @@ description: Operations executed focusrite-scarlett-mounting-bracket.kcl
"type": "StdLibCall", "type": "StdLibCall",
"unlabeledArg": null "unlabeledArg": null
}, },
{
"type": "UserDefinedFunctionCall",
"name": "circle",
"functionSourceRange": [
0,
0,
0
],
"unlabeledArg": null,
"labeledArgs": {
"center": {
"value": {
"type": "Array",
"value": [
{
"type": "Number",
"value": 82.0,
"ty": {
"type": "Unknown"
}
},
{
"type": "Number",
"value": 27.333333333333332,
"ty": {
"type": "Unknown"
}
}
]
},
"sourceRange": []
},
"radius": {
"value": {
"type": "Number",
"value": 2.5,
"ty": {
"type": "Unknown"
}
},
"sourceRange": []
}
},
"sourceRange": []
},
{
"type": "UserDefinedFunctionReturn"
},
{ {
"labeledArgs": { "labeledArgs": {
"holeSketch": { "holeSketch": {
@ -874,6 +922,54 @@ description: Operations executed focusrite-scarlett-mounting-bracket.kcl
"type": "StdLibCall", "type": "StdLibCall",
"unlabeledArg": null "unlabeledArg": null
}, },
{
"type": "UserDefinedFunctionCall",
"name": "circle",
"functionSourceRange": [
0,
0,
0
],
"unlabeledArg": null,
"labeledArgs": {
"center": {
"value": {
"type": "Array",
"value": [
{
"type": "Number",
"value": -82.0,
"ty": {
"type": "Unknown"
}
},
{
"type": "Number",
"value": 27.333333333333332,
"ty": {
"type": "Unknown"
}
}
]
},
"sourceRange": []
},
"radius": {
"value": {
"type": "Number",
"value": 2.5,
"ty": {
"type": "Unknown"
}
},
"sourceRange": []
}
},
"sourceRange": []
},
{
"type": "UserDefinedFunctionReturn"
},
{ {
"labeledArgs": { "labeledArgs": {
"holeSketch": { "holeSketch": {

View File

@ -480,6 +480,66 @@ description: Operations executed french-press.kcl
"type": "StdLibCall", "type": "StdLibCall",
"unlabeledArg": null "unlabeledArg": null
}, },
{
"type": "UserDefinedFunctionCall",
"name": "circle",
"functionSourceRange": [
0,
0,
0
],
"unlabeledArg": null,
"labeledArgs": {
"center": {
"value": {
"type": "Array",
"value": [
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
}
},
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
}
}
]
},
"sourceRange": []
},
"radius": {
"value": {
"type": "Number",
"value": 2.055,
"ty": {
"type": "Unknown"
}
},
"sourceRange": []
}
},
"sourceRange": []
},
{
"type": "UserDefinedFunctionReturn"
},
{ {
"labeledArgs": { "labeledArgs": {
"length": { "length": {
@ -706,6 +766,132 @@ description: Operations executed french-press.kcl
"type": "StdLibCall", "type": "StdLibCall",
"unlabeledArg": null "unlabeledArg": null
}, },
{
"type": "UserDefinedFunctionCall",
"name": "circle",
"functionSourceRange": [
0,
0,
0
],
"unlabeledArg": null,
"labeledArgs": {
"center": {
"value": {
"type": "Array",
"value": [
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
}
},
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
}
}
]
},
"sourceRange": []
},
"radius": {
"value": {
"type": "Number",
"value": 1.965,
"ty": {
"type": "Unknown"
}
},
"sourceRange": []
}
},
"sourceRange": []
},
{
"type": "UserDefinedFunctionReturn"
},
{
"type": "UserDefinedFunctionCall",
"name": "circle",
"functionSourceRange": [
0,
0,
0
],
"unlabeledArg": null,
"labeledArgs": {
"center": {
"value": {
"type": "Array",
"value": [
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
}
},
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
}
}
]
},
"sourceRange": []
},
"radius": {
"value": {
"type": "Number",
"value": 0.15,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
}
},
"sourceRange": []
}
},
"sourceRange": []
},
{
"type": "UserDefinedFunctionReturn"
},
{ {
"labeledArgs": { "labeledArgs": {
"holeSketch": { "holeSketch": {
@ -788,6 +974,72 @@ description: Operations executed french-press.kcl
"type": "StdLibCall", "type": "StdLibCall",
"unlabeledArg": null "unlabeledArg": null
}, },
{
"type": "UserDefinedFunctionCall",
"name": "circle",
"functionSourceRange": [
0,
0,
0
],
"unlabeledArg": null,
"labeledArgs": {
"center": {
"value": {
"type": "Array",
"value": [
{
"type": "Number",
"value": 1.4,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
}
},
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
}
}
]
},
"sourceRange": []
},
"radius": {
"value": {
"type": "Number",
"value": 0.3,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
}
},
"sourceRange": []
}
},
"sourceRange": []
},
{
"type": "UserDefinedFunctionReturn"
},
{ {
"labeledArgs": { "labeledArgs": {
"length": { "length": {
@ -891,6 +1143,72 @@ description: Operations executed french-press.kcl
"type": "StdLibCall", "type": "StdLibCall",
"unlabeledArg": null "unlabeledArg": null
}, },
{
"type": "UserDefinedFunctionCall",
"name": "circle",
"functionSourceRange": [
0,
0,
0
],
"unlabeledArg": null,
"labeledArgs": {
"center": {
"value": {
"type": "Array",
"value": [
{
"type": "Number",
"value": 0.6,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
}
},
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
}
}
]
},
"sourceRange": []
},
"radius": {
"value": {
"type": "Number",
"value": 0.2,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
}
},
"sourceRange": []
}
},
"sourceRange": []
},
{
"type": "UserDefinedFunctionReturn"
},
{ {
"labeledArgs": { "labeledArgs": {
"length": { "length": {
@ -961,6 +1279,66 @@ description: Operations executed french-press.kcl
"type": "StdLibCall", "type": "StdLibCall",
"unlabeledArg": null "unlabeledArg": null
}, },
{
"type": "UserDefinedFunctionCall",
"name": "circle",
"functionSourceRange": [
0,
0,
0
],
"unlabeledArg": null,
"labeledArgs": {
"center": {
"value": {
"type": "Array",
"value": [
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
}
},
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
}
}
]
},
"sourceRange": []
},
"radius": {
"value": {
"type": "Number",
"value": 2.205,
"ty": {
"type": "Unknown"
}
},
"sourceRange": []
}
},
"sourceRange": []
},
{
"type": "UserDefinedFunctionReturn"
},
{ {
"labeledArgs": { "labeledArgs": {
"length": { "length": {

View File

@ -4623,6 +4623,66 @@ description: Operations executed gear.kcl
"type": "StdLibCall", "type": "StdLibCall",
"unlabeledArg": null "unlabeledArg": null
}, },
{
"type": "UserDefinedFunctionCall",
"name": "circle",
"functionSourceRange": [
0,
0,
0
],
"unlabeledArg": null,
"labeledArgs": {
"center": {
"value": {
"type": "Array",
"value": [
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
}
},
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
}
}
]
},
"sourceRange": []
},
"radius": {
"value": {
"type": "Number",
"value": 4.933386259126019,
"ty": {
"type": "Unknown"
}
},
"sourceRange": []
}
},
"sourceRange": []
},
{
"type": "UserDefinedFunctionReturn"
},
{ {
"labeledArgs": { "labeledArgs": {
"length": { "length": {

View File

@ -1065,6 +1065,54 @@ description: Operations executed gridfinity-baseplate-magnets.kcl
"type": "StdLibCall", "type": "StdLibCall",
"unlabeledArg": null "unlabeledArg": null
}, },
{
"type": "UserDefinedFunctionCall",
"name": "circle",
"functionSourceRange": [
0,
0,
0
],
"unlabeledArg": null,
"labeledArgs": {
"center": {
"value": {
"type": "Array",
"value": [
{
"type": "Number",
"value": 8.0,
"ty": {
"type": "Unknown"
}
},
{
"type": "Number",
"value": 8.0,
"ty": {
"type": "Unknown"
}
}
]
},
"sourceRange": []
},
"radius": {
"value": {
"type": "Number",
"value": 3.25,
"ty": {
"type": "Unknown"
}
},
"sourceRange": []
}
},
"sourceRange": []
},
{
"type": "UserDefinedFunctionReturn"
},
{ {
"type": "UserDefinedFunctionCall", "type": "UserDefinedFunctionCall",
"name": "magnetBase", "name": "magnetBase",

View File

@ -657,6 +657,66 @@ description: Operations executed gridfinity-bins-stacking-lip.kcl
"type": "StdLibCall", "type": "StdLibCall",
"unlabeledArg": null "unlabeledArg": null
}, },
{
"type": "UserDefinedFunctionCall",
"name": "circle",
"functionSourceRange": [
0,
0,
0
],
"unlabeledArg": null,
"labeledArgs": {
"center": {
"value": {
"type": "Array",
"value": [
{
"type": "Number",
"value": -8.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
},
{
"type": "Number",
"value": 8.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
}
]
},
"sourceRange": []
},
"radius": {
"value": {
"type": "Number",
"value": 3.25,
"ty": {
"type": "Unknown"
}
},
"sourceRange": []
}
},
"sourceRange": []
},
{
"type": "UserDefinedFunctionReturn"
},
{ {
"labeledArgs": { "labeledArgs": {
"length": { "length": {

View File

@ -657,6 +657,66 @@ description: Operations executed gridfinity-bins.kcl
"type": "StdLibCall", "type": "StdLibCall",
"unlabeledArg": null "unlabeledArg": null
}, },
{
"type": "UserDefinedFunctionCall",
"name": "circle",
"functionSourceRange": [
0,
0,
0
],
"unlabeledArg": null,
"labeledArgs": {
"center": {
"value": {
"type": "Array",
"value": [
{
"type": "Number",
"value": -8.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
},
{
"type": "Number",
"value": 8.0,
"ty": {
"type": "Default",
"len": {
"type": "Mm"
},
"angle": {
"type": "Degrees"
}
}
}
]
},
"sourceRange": []
},
"radius": {
"value": {
"type": "Number",
"value": 3.25,
"ty": {
"type": "Unknown"
}
},
"sourceRange": []
}
},
"sourceRange": []
},
{
"type": "UserDefinedFunctionReturn"
},
{ {
"labeledArgs": { "labeledArgs": {
"length": { "length": {

View File

@ -30,6 +30,66 @@ description: Operations executed hex-nut.kcl
"type": "StdLibCall", "type": "StdLibCall",
"unlabeledArg": null "unlabeledArg": null
}, },
{
"type": "UserDefinedFunctionCall",
"name": "circle",
"functionSourceRange": [
0,
0,
0
],
"unlabeledArg": null,
"labeledArgs": {
"center": {
"value": {
"type": "Array",
"value": [
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
}
},
{
"type": "Number",
"value": 0.0,
"ty": {
"type": "Default",
"len": {
"type": "Inches"
},
"angle": {
"type": "Degrees"
}
}
}
]
},
"sourceRange": []
},
"radius": {
"value": {
"type": "Number",
"value": 0.15625,
"ty": {
"type": "Unknown"
}
},
"sourceRange": []
}
},
"sourceRange": []
},
{
"type": "UserDefinedFunctionReturn"
},
{ {
"labeledArgs": { "labeledArgs": {
"holeSketch": { "holeSketch": {

Some files were not shown because too many files have changed in this diff Show More