Coerce the result of a function call to the function's return type (#6309)

Signed-off-by: Nick Cameron <nrc@ncameron.org>
This commit is contained in:
Nick Cameron
2025-04-22 11:00:53 +12:00
committed by GitHub
parent 30ee547ce4
commit e4e18dfd4b
207 changed files with 2796 additions and 1503 deletions

View File

@ -22,18 +22,8 @@ layout: manual
* [`string`](kcl/types/string) * [`string`](kcl/types/string)
* [`tag`](kcl/types/tag) * [`tag`](kcl/types/tag)
* **std** * **std**
* [`Axis2d`](kcl/types/Axis2d)
* [`Axis3d`](kcl/types/Axis3d)
* [`END`](kcl/consts/std-END) * [`END`](kcl/consts/std-END)
* [`Edge`](kcl/types/Edge)
* [`Face`](kcl/types/Face)
* [`Helix`](kcl/types/Helix)
* [`Plane`](kcl/types/Plane)
* [`Point2d`](kcl/types/Point2d)
* [`Point3d`](kcl/types/Point3d)
* [`START`](kcl/consts/std-START) * [`START`](kcl/consts/std-START)
* [`Sketch`](kcl/types/Sketch)
* [`Solid`](kcl/types/Solid)
* [`X`](kcl/consts/std-X) * [`X`](kcl/consts/std-X)
* [`XY`](kcl/consts/std-XY) * [`XY`](kcl/consts/std-XY)
* [`XZ`](kcl/consts/std-XZ) * [`XZ`](kcl/consts/std-XZ)
@ -152,3 +142,14 @@ layout: manual
* [`turns::QUARTER_TURN`](kcl/consts/std-turns-QUARTER_TURN) * [`turns::QUARTER_TURN`](kcl/consts/std-turns-QUARTER_TURN)
* [`turns::THREE_QUARTER_TURN`](kcl/consts/std-turns-THREE_QUARTER_TURN) * [`turns::THREE_QUARTER_TURN`](kcl/consts/std-turns-THREE_QUARTER_TURN)
* [`turns::ZERO`](kcl/consts/std-turns-ZERO) * [`turns::ZERO`](kcl/consts/std-turns-ZERO)
* **std::types**
* [`Axis2d`](kcl/types/Axis2d)
* [`Axis3d`](kcl/types/Axis3d)
* [`Edge`](kcl/types/Edge)
* [`Face`](kcl/types/Face)
* [`Helix`](kcl/types/Helix)
* [`Plane`](kcl/types/Plane)
* [`Point2d`](kcl/types/Point2d)
* [`Point3d`](kcl/types/Point3d)
* [`Sketch`](kcl/types/Sketch)
* [`Solid`](kcl/types/Solid)

View File

@ -1,5 +1,5 @@
--- ---
title: "std::Axis2d" title: "std::types::Axis2d"
excerpt: "An infinite line in 2d space." excerpt: "An infinite line in 2d space."
layout: manual layout: manual
--- ---

View File

@ -1,5 +1,5 @@
--- ---
title: "std::Axis3d" title: "std::types::Axis3d"
excerpt: "An infinite line in 3d space." excerpt: "An infinite line in 3d space."
layout: manual layout: manual
--- ---

View File

@ -1,5 +1,5 @@
--- ---
title: "std::Edge" title: "std::types::Edge"
excerpt: "The edge of a solid." excerpt: "The edge of a solid."
layout: manual layout: manual
--- ---

View File

@ -1,5 +1,5 @@
--- ---
title: "std::Face" title: "std::types::Face"
excerpt: "A face." excerpt: "A face."
layout: manual layout: manual
--- ---

View File

@ -1,5 +1,5 @@
--- ---
title: "std::Helix" title: "std::types::Helix"
excerpt: "A helix." excerpt: "A helix."
layout: manual layout: manual
--- ---

View File

@ -1,5 +1,5 @@
--- ---
title: "std::Plane" title: "std::types::Plane"
excerpt: "A plane." excerpt: "A plane."
layout: manual layout: manual
--- ---

View File

@ -1,5 +1,5 @@
--- ---
title: "std::Point2d" title: "std::types::Point2d"
excerpt: "A point in two dimensional space." excerpt: "A point in two dimensional space."
layout: manual layout: manual
--- ---

View File

@ -1,5 +1,5 @@
--- ---
title: "std::Point3d" title: "std::types::Point3d"
excerpt: "A point in three dimensional space." excerpt: "A point in three dimensional space."
layout: manual layout: manual
--- ---

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -12,7 +12,7 @@ The syntax for declaring a tag is `$myTag` you would use it in the following
way: way:
```js ```js
startSketchOn('XZ') startSketchOn(XZ)
|> startProfileAt(origin, %) |> startProfileAt(origin, %)
|> angledLine(angle = 0, length = 191.26, tag = $rectangleSegmentA001) |> angledLine(angle = 0, length = 191.26, tag = $rectangleSegmentA001)
|> angledLine( |> angledLine(
@ -46,7 +46,7 @@ However if the code was written like this:
```js ```js
fn rect(origin) { fn rect(origin) {
return startSketchOn('XZ') return startSketchOn(XZ)
|> startProfileAt(origin, %) |> startProfileAt(origin, %)
|> angledLine(angle = 0, length = 191.26, tag = $rectangleSegmentA001) |> angledLine(angle = 0, length = 191.26, tag = $rectangleSegmentA001)
|> angledLine( |> angledLine(
@ -75,7 +75,7 @@ For example the following code works.
```js ```js
fn rect(origin) { fn rect(origin) {
return startSketchOn('XZ') return startSketchOn(XZ)
|> startProfileAt(origin, %) |> startProfileAt(origin, %)
|> angledLine(angle = 0, length = 191.26, tag = $rectangleSegmentA001) |> angledLine(angle = 0, length = 191.26, tag = $rectangleSegmentA001)
|> angledLine( |> angledLine(

View File

@ -170,20 +170,23 @@ impl ExecutorContext {
self.exec_module_for_items(module_id, exec_state, source_range).await?; self.exec_module_for_items(module_id, exec_state, source_range).await?;
for import_item in items { for import_item in items {
// Extract the item from the module. // Extract the item from the module.
let item = exec_state let mem = &exec_state.stack().memory;
.stack() let mut value = mem
.memory
.get_from(&import_item.name.name, env_ref, import_item.into(), 0) .get_from(&import_item.name.name, env_ref, import_item.into(), 0)
.map_err(|_err| { .cloned();
KclError::UndefinedValue(KclErrorDetails { let ty_name = format!("{}{}", memory::TYPE_PREFIX, import_item.name.name);
let mut ty = mem.get_from(&ty_name, env_ref, import_item.into(), 0).cloned();
if value.is_err() && ty.is_err() {
return Err(KclError::UndefinedValue(KclErrorDetails {
message: format!("{} is not defined in module", import_item.name.name), message: format!("{} is not defined in module", import_item.name.name),
source_ranges: vec![SourceRange::from(&import_item.name)], source_ranges: vec![SourceRange::from(&import_item.name)],
}) }));
})? }
.clone();
// Check that the item is allowed to be imported. // Check that the item is allowed to be imported (in at least one namespace).
if !module_exports.contains(&import_item.name.name) { if value.is_ok() && !module_exports.contains(&import_item.name.name) {
return Err(KclError::Semantic(KclErrorDetails { value = Err(KclError::Semantic(KclErrorDetails {
message: format!( message: format!(
"Cannot import \"{}\" from module because it is not exported. Add \"export\" before the definition to export it.", "Cannot import \"{}\" from module because it is not exported. Add \"export\" before the definition to export it.",
import_item.name.name import_item.name.name
@ -192,10 +195,22 @@ impl ExecutorContext {
})); }));
} }
if ty.is_ok() && !module_exports.contains(&ty_name) {
ty = Err(KclError::Semantic(KclErrorDetails {
message: String::new(),
source_ranges: vec![],
}));
}
if value.is_err() && ty.is_err() {
return value.map(Option::Some);
}
// Add the item to the current module. // Add the item to the current module.
if let Ok(value) = value {
exec_state.mut_stack().add( exec_state.mut_stack().add(
import_item.identifier().to_owned(), import_item.identifier().to_owned(),
item, value,
SourceRange::from(&import_item.name), SourceRange::from(&import_item.name),
)?; )?;
@ -206,6 +221,21 @@ impl ExecutorContext {
.push(import_item.identifier().to_owned()); .push(import_item.identifier().to_owned());
} }
} }
if let Ok(ty) = ty {
let ty_name = format!("{}{}", memory::TYPE_PREFIX, import_item.identifier());
// Add the item to the current module.
exec_state.mut_stack().add(
ty_name.clone(),
ty,
SourceRange::from(&import_item.name),
)?;
if let ItemVisibility::Export = import_stmt.visibility {
exec_state.mod_local.module_exports.push(ty_name);
}
}
}
} }
ImportSelector::Glob(_) => { ImportSelector::Glob(_) => {
let (env_ref, module_exports) = let (env_ref, module_exports) =
@ -298,19 +328,20 @@ impl ExecutorContext {
value: TypeDef::RustRepr(t, props), value: TypeDef::RustRepr(t, props),
meta: vec![metadata], meta: vec![metadata],
}; };
let name_in_mem = format!("{}{}", memory::TYPE_PREFIX, ty.name.name);
exec_state exec_state
.mut_stack() .mut_stack()
.add( .add(name_in_mem.clone(), value, metadata.source_range)
format!("{}{}", memory::TYPE_PREFIX, ty.name.name),
value,
metadata.source_range,
)
.map_err(|_| { .map_err(|_| {
KclError::Semantic(KclErrorDetails { KclError::Semantic(KclErrorDetails {
message: format!("Redefinition of type {}.", ty.name.name), message: format!("Redefinition of type {}.", ty.name.name),
source_ranges: vec![metadata.source_range], source_ranges: vec![metadata.source_range],
}) })
})?; })?;
if let ItemVisibility::Export = ty.visibility {
exec_state.mod_local.module_exports.push(name_in_mem);
}
} }
// 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 => {}
@ -327,19 +358,20 @@ impl ExecutorContext {
), ),
meta: vec![metadata], meta: vec![metadata],
}; };
let name_in_mem = format!("{}{}", memory::TYPE_PREFIX, ty.name.name);
exec_state exec_state
.mut_stack() .mut_stack()
.add( .add(name_in_mem.clone(), value, metadata.source_range)
format!("{}{}", memory::TYPE_PREFIX, ty.name.name),
value,
metadata.source_range,
)
.map_err(|_| { .map_err(|_| {
KclError::Semantic(KclErrorDetails { KclError::Semantic(KclErrorDetails {
message: format!("Redefinition of type {}.", ty.name.name), message: format!("Redefinition of type {}.", ty.name.name),
source_ranges: vec![metadata.source_range], source_ranges: vec![metadata.source_range],
}) })
})?; })?;
if let ItemVisibility::Export = ty.visibility {
exec_state.mod_local.module_exports.push(name_in_mem);
}
} }
None => { None => {
return Err(KclError::Semantic(KclErrorDetails { return Err(KclError::Semantic(KclErrorDetails {
@ -485,7 +517,7 @@ impl ExecutorContext {
message: "Cannot import items from foreign modules".to_owned(), message: "Cannot import items from foreign modules".to_owned(),
source_ranges: vec![geom.source_range], source_ranges: vec![geom.source_range],
})), })),
ModuleRepr::Dummy => unreachable!(), ModuleRepr::Dummy => unreachable!("Looking up {}, but it is still being interpreted", path),
}; };
exec_state.global.module_infos[&module_id].restore_repr(repr); exec_state.global.module_infos[&module_id].restore_repr(repr);
@ -559,10 +591,10 @@ impl ExecutorContext {
// It was an import cycle. Keep the original message. // It was an import cycle. Keep the original message.
err.override_source_ranges(vec![source_range]) err.override_source_ranges(vec![source_range])
} else { } else {
// TODO would be great to have line/column for the underlying error here
KclError::Semantic(KclErrorDetails { KclError::Semantic(KclErrorDetails {
message: format!( message: format!(
"Error loading imported file. Open it to view more details. {}: {}", "Error loading imported file ({path}). Open it to view more details.\n {}",
path,
err.message() err.message()
), ),
source_ranges: vec![source_range], source_ranges: vec![source_range],
@ -2139,6 +2171,34 @@ fn assign_args_to_params_kw(
Ok(()) Ok(())
} }
fn coerce_result_type(
result: Result<Option<KclValue>, KclError>,
function_expression: NodeRef<'_, FunctionExpression>,
exec_state: &mut ExecState,
) -> Result<Option<KclValue>, KclError> {
if let Ok(Some(val)) = result {
if let Some(ret_ty) = &function_expression.return_type {
let ty = RuntimeType::from_parsed(ret_ty.inner.clone(), exec_state, ret_ty.as_source_range())
.map_err(|e| KclError::Semantic(e.into()))?;
let val = val.coerce(&ty, exec_state).map_err(|_| {
KclError::Semantic(KclErrorDetails {
message: format!(
"This function requires its result to be of type `{}`, but found {}",
ty.human_friendly_type(),
val.human_friendly_type(),
),
source_ranges: ret_ty.as_source_ranges(),
})
})?;
Ok(Some(val))
} else {
Ok(Some(val))
}
} else {
result
}
}
async fn call_user_defined_function( async fn call_user_defined_function(
args: Vec<Arg>, args: Vec<Arg>,
memory: EnvironmentRef, memory: EnvironmentRef,
@ -2159,13 +2219,16 @@ async fn call_user_defined_function(
let result = ctx let result = ctx
.exec_block(&function_expression.body, exec_state, BodyType::Block) .exec_block(&function_expression.body, exec_state, BodyType::Block)
.await; .await;
let result = result.map(|_| { let mut result = result.map(|_| {
exec_state exec_state
.stack() .stack()
.get(memory::RETURN_NAME, function_expression.as_source_range()) .get(memory::RETURN_NAME, function_expression.as_source_range())
.ok() .ok()
.cloned() .cloned()
}); });
result = coerce_result_type(result, function_expression, exec_state);
// Restore the previous memory. // Restore the previous memory.
exec_state.mut_stack().pop_env(); exec_state.mut_stack().pop_env();
@ -2193,13 +2256,16 @@ async fn call_user_defined_function_kw(
let result = ctx let result = ctx
.exec_block(&function_expression.body, exec_state, BodyType::Block) .exec_block(&function_expression.body, exec_state, BodyType::Block)
.await; .await;
let result = result.map(|_| { let mut result = result.map(|_| {
exec_state exec_state
.stack() .stack()
.get(memory::RETURN_NAME, function_expression.as_source_range()) .get(memory::RETURN_NAME, function_expression.as_source_range())
.ok() .ok()
.cloned() .cloned()
}); });
result = coerce_result_type(result, function_expression, exec_state);
// Restore the previous memory. // Restore the previous memory.
exec_state.mut_stack().pop_env(); exec_state.mut_stack().pop_env();
@ -2695,6 +2761,27 @@ foo(x = { direction = [0, 0], origin = [0, 0]})
} }
foo(x = { direction = [0, 0], origin = [0, 0]}) foo(x = { direction = [0, 0], origin = [0, 0]})
"#;
parse_execute(program).await.unwrap_err();
}
#[tokio::test(flavor = "multi_thread")]
async fn coerce_return() {
let program = r#"fn foo(): number(mm) {
return 42
}
a = foo()
"#;
parse_execute(program).await.unwrap();
let program = r#"fn foo(): number(mm) {
return { bar: 42 }
}
a = foo()
"#; "#;
parse_execute(program).await.unwrap_err(); parse_execute(program).await.unwrap_err();

View File

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

View File

@ -450,7 +450,6 @@ impl Program {
for item in &self.body { for item in &self.body {
let r = item.comment_range(); let r = item.comment_range();
eprintln!("item {r:?}");
if pos >= r.0 && pos < r.1 { if pos >= r.0 && pos < r.1 {
return true; return true;
} }

View File

@ -217,14 +217,14 @@ pub(crate) fn std_fn(path: &str, fn_name: &str) -> (crate::std::StdFn, StdFnProp
pub(crate) fn std_ty(path: &str, fn_name: &str) -> (PrimitiveType, StdFnProps) { pub(crate) fn std_ty(path: &str, fn_name: &str) -> (PrimitiveType, StdFnProps) {
match (path, fn_name) { match (path, fn_name) {
("prelude", "Sketch") => (PrimitiveType::Sketch, StdFnProps::default("std::Sketch")), ("types", "Sketch") => (PrimitiveType::Sketch, StdFnProps::default("std::types::Sketch")),
("prelude", "Solid") => (PrimitiveType::Solid, StdFnProps::default("std::Solid")), ("types", "Solid") => (PrimitiveType::Solid, StdFnProps::default("std::types::Solid")),
("prelude", "Plane") => (PrimitiveType::Plane, StdFnProps::default("std::Plane")), ("types", "Plane") => (PrimitiveType::Plane, StdFnProps::default("std::types::Plane")),
("prelude", "Face") => (PrimitiveType::Face, StdFnProps::default("std::Face")), ("types", "Face") => (PrimitiveType::Face, StdFnProps::default("std::types::Face")),
("prelude", "Helix") => (PrimitiveType::Helix, StdFnProps::default("std::Helix")), ("types", "Helix") => (PrimitiveType::Helix, StdFnProps::default("std::types::Helix")),
("prelude", "Edge") => (PrimitiveType::Edge, StdFnProps::default("std::Edge")), ("types", "Edge") => (PrimitiveType::Edge, StdFnProps::default("std::types::Edge")),
("prelude", "Axis2d") => (PrimitiveType::Axis2d, StdFnProps::default("std::Axis2d")), ("types", "Axis2d") => (PrimitiveType::Axis2d, StdFnProps::default("std::types::Axis2d")),
("prelude", "Axis3d") => (PrimitiveType::Axis3d, StdFnProps::default("std::Axis3d")), ("types", "Axis3d") => (PrimitiveType::Axis3d, StdFnProps::default("std::types::Axis3d")),
_ => unreachable!(), _ => unreachable!(),
} }
} }

View File

@ -1,6 +1,8 @@
@no_std @no_std
@settings(defaultLengthUnit = mm) @settings(defaultLengthUnit = mm)
import Point2d from "std::types"
/// The value of `pi`, Archimedes constant (π). /// The value of `pi`, Archimedes constant (π).
/// ///
/// ``` /// ```

View File

@ -3,253 +3,11 @@
// Note that everything in the prelude is treated as exported. // Note that everything in the prelude is treated as exported.
export import * from "std::types"
export import * from "std::math" export import * from "std::math"
export import * from "std::sketch" export import * from "std::sketch"
export import "std::turns" export import "std::turns"
/// A number
///
/// May be signed or unsigned, an integer or decimal value.
///
/// You may see a number type with units, e.g., `number(mm)`. These are currently experimental.
@(impl = primitive)
export type number(unit)
/// A boolean value.
///
/// `true` or `false`
@(impl = primitive)
export type bool
/// A sequence of characters
///
/// Strings may be delimited using either single or double quotes.
///
/// ```kcl,norun
/// "hello,"
/// 'world!'
/// ```
@(impl = primitive)
export type string
/// Tags are used to give a name (tag) to a specific path.
///
/// ### Tag Declaration
///
/// The syntax for declaring a tag is `$myTag` you would use it in the following
/// way:
///
/// ```norun,inline
/// startSketchOn('XZ')
/// |> startProfileAt(origin, %)
/// |> angledLine(angle = 0, length = 191.26, tag = $rectangleSegmentA001)
/// |> angledLine(
/// angle = segAng(rectangleSegmentA001) - 90,
/// length = 196.99,
/// tag = $rectangleSegmentB001,
/// )
/// |> angledLine(
/// angle = segAng(rectangleSegmentA001),
/// length = -segLen(rectangleSegmentA001),
/// tag = $rectangleSegmentC001,
/// )
/// |> line(endAbsolute = [profileStartX(%), profileStartY(%)])
/// |> close()
/// ```
///
/// ### Tag Identifier
///
/// As per the example above you can use the tag identifier to get a reference to the
/// tagged object. The syntax for this is `myTag`.
///
/// In the example above we use the tag identifier to get the angle of the segment
/// `segAng(rectangleSegmentA001, %)`.
///
/// ### Tag Scope
///
/// Tags are scoped globally if in the root context meaning in this example you can
/// use the tag `rectangleSegmentA001` in any function or expression in the file.
///
/// However if the code was written like this:
///
/// ```norun,inline
/// fn rect(origin) {
/// return startSketchOn('XZ')
/// |> startProfileAt(origin, %)
/// |> angledLine(angle = 0, length = 191.26, tag = $rectangleSegmentA001)
/// |> angledLine(
/// angle = segAng(rectangleSegmentA001) - 90,
/// length = 196.99,
/// tag = $rectangleSegmentB001)
/// |> angledLine(
/// angle = segAng(rectangleSegmentA001),
/// length = -segLen(rectangleSegmentA001),
/// tag = $rectangleSegmentC001
/// )
/// |> line(endAbsolute = [profileStartX(%), profileStartY(%)])
/// |> close()
/// }
///
/// rect([0, 0])
/// rect([20, 0])
/// ```
///
/// Those tags would only be available in the `rect` function and not globally.
///
/// However you likely want to use those tags somewhere outside the `rect` function.
///
/// Tags are accessible through the sketch group they are declared in.
/// For example the following code works.
///
/// ```norun,inline
/// fn rect(origin) {
/// return startSketchOn('XZ')
/// |> startProfileAt(origin, %)
/// |> angledLine(angle = 0, length = 191.26, tag = $rectangleSegmentA001)
/// |> angledLine(
/// angle = segAng(rectangleSegmentA001) - 90,
/// length = 196.99
/// , %, $rectangleSegmentB001)
/// |> angledLine(
/// angle = segAng(rectangleSegmentA001),
/// length = -segLen(rectangleSegmentA001)
/// , %, $rectangleSegmentC001)
/// |> line(endAbsolute = [profileStartX(%), profileStartY(%)])
/// |> close()
/// }
///
/// rect([0, 0])
/// myRect = rect([20, 0])
///
/// myRect
/// |> extrude(length = 10)
/// |> fillet(radius = 0.5, tags = [myRect.tags.rectangleSegmentA001])
/// ```
///
/// See how we use the tag `rectangleSegmentA001` in the `fillet` function outside
/// the `rect` function. This is because the `rect` function is returning the
/// sketch group that contains the tags.
@(impl = primitive)
export type tag
/// A plane.
@(impl = std_rust)
export type Plane
/// A sketch is a collection of paths.
///
/// When you define a sketch to a variable like:
///
/// ```kcl,inline
/// mySketch = startSketchOn('XY')
/// |> startProfileAt([-12, 12], %)
/// |> line(end = [24, 0])
/// |> line(end = [0, -24])
/// |> line(end = [-24, 0])
/// |> close()
/// ```
///
/// The `mySketch` variable will be an executed `Sketch` object. Executed being past
/// 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.
///
/// If you would like to encapsulate the commands to create the sketch any time you call it,
/// you can use a function.
///
/// ```kcl,inline
/// fn createSketch() {
/// return startSketchOn('XY')
/// |> startProfileAt([-12, 12], %)
/// |> line(end = [24, 0])
/// |> line(end = [0, -24])
/// |> line(end = [-24, 0])
/// |> close()
/// }
/// ```
///
/// Now, every time you call `createSketch()`, the commands will be
/// executed and a new sketch will be created.
///
/// When you assign the result of `createSketch()` to a variable (`mySketch = createSketch()`), you are assigning
/// the executed sketch to that variable. Meaning that the sketch `mySketch` will not be executed
/// again.
///
/// You can still execute _new_ commands on the sketch like `extrude`, `revolve`, `loft`, etc. and
/// the sketch will be updated.
@(impl = std_rust)
export type Sketch
/// A solid is a collection of extrude surfaces.
///
/// When you define a solid to a variable like:
///
/// ```kcl,inline
/// myPart = startSketchOn('XY')
/// |> startProfileAt([-12, 12], %)
/// |> line(end = [24, 0])
/// |> line(end = [0, -24])
/// |> line(end = [-24, 0])
/// |> close()
/// |> extrude(length = 6)
/// ```
///
/// The `myPart` variable will be an executed `Solid` object. Executed being past
/// 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.
///
/// If you would like to encapsulate the commands to create the solid any time you call it,
/// you can use a function.
///
/// ```kcl,inline
/// fn createPart() {
/// return startSketchOn('XY')
/// |> startProfileAt([-12, 12], %)
/// |> line(end = [24, 0])
/// |> line(end = [0, -24])
/// |> line(end = [-24, 0])
/// |> close()
/// |> extrude(length = 6)
/// }
/// ```
///
/// Now, every time you call `createPart()`, the commands will be
/// executed and a new solid will be created.
///
/// When you assign the result of `createPart()` to a variable (`myPart = createPart()`), you are assigning
/// the executed solid to that variable. Meaning that the solid `myPart` will not be executed
/// again.
///
/// You can still execute _new_ commands on the solid like `shell`, `fillet`, `chamfer`, etc.
/// and the solid will be updated.
@(impl = std_rust)
export type Solid
/// A face.
@(impl = std_rust)
export type Face
/// A helix.
@(impl = std_rust)
export type Helix
/// The edge of a solid.
@(impl = std_rust)
export type Edge
/// 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(Length); 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(Length); 3]
export XY = { export XY = {
origin = { x = 0, y = 0, z = 0 }, origin = { x = 0, y = 0, z = 0 },
xAxis = { x = 1, y = 0, z = 0 }, xAxis = { x = 1, y = 0, z = 0 },
@ -271,14 +29,6 @@ export YZ = {
zAxis = { x = 1, y = 0, z = 0 }, zAxis = { x = 1, y = 0, z = 0 },
}: Plane }: Plane
/// An infinite line in 2d space.
@(impl = std_rust)
export type Axis2d
/// An infinite line in 3d space.
@(impl = std_rust)
export type Axis3d
export X = { export X = {
origin = [0, 0, 0], origin = [0, 0, 0],
direction = [1, 0, 0], direction = [1, 0, 0],

253
rust/kcl-lib/std/types.kcl Normal file
View File

@ -0,0 +1,253 @@
@no_std
@settings(defaultLengthUnit = mm)
/// A number
///
/// May be signed or unsigned, an integer or decimal value.
///
/// You may see a number type with units, e.g., `number(mm)`. These are currently experimental.
@(impl = primitive)
export type number(unit)
/// A boolean value.
///
/// `true` or `false`
@(impl = primitive)
export type bool
/// A sequence of characters
///
/// Strings may be delimited using either single or double quotes.
///
/// ```kcl,norun
/// "hello,"
/// 'world!'
/// ```
@(impl = primitive)
export type string
/// Tags are used to give a name (tag) to a specific path.
///
/// ### Tag Declaration
///
/// The syntax for declaring a tag is `$myTag` you would use it in the following
/// way:
///
/// ```norun,inline
/// startSketchOn(XZ)
/// |> startProfileAt(origin, %)
/// |> angledLine(angle = 0, length = 191.26, tag = $rectangleSegmentA001)
/// |> angledLine(
/// angle = segAng(rectangleSegmentA001) - 90,
/// length = 196.99,
/// tag = $rectangleSegmentB001,
/// )
/// |> angledLine(
/// angle = segAng(rectangleSegmentA001),
/// length = -segLen(rectangleSegmentA001),
/// tag = $rectangleSegmentC001,
/// )
/// |> line(endAbsolute = [profileStartX(%), profileStartY(%)])
/// |> close()
/// ```
///
/// ### Tag Identifier
///
/// As per the example above you can use the tag identifier to get a reference to the
/// tagged object. The syntax for this is `myTag`.
///
/// In the example above we use the tag identifier to get the angle of the segment
/// `segAng(rectangleSegmentA001, %)`.
///
/// ### Tag Scope
///
/// Tags are scoped globally if in the root context meaning in this example you can
/// use the tag `rectangleSegmentA001` in any function or expression in the file.
///
/// However if the code was written like this:
///
/// ```norun,inline
/// fn rect(origin) {
/// return startSketchOn(XZ)
/// |> startProfileAt(origin, %)
/// |> angledLine(angle = 0, length = 191.26, tag = $rectangleSegmentA001)
/// |> angledLine(
/// angle = segAng(rectangleSegmentA001) - 90,
/// length = 196.99,
/// tag = $rectangleSegmentB001)
/// |> angledLine(
/// angle = segAng(rectangleSegmentA001),
/// length = -segLen(rectangleSegmentA001),
/// tag = $rectangleSegmentC001
/// )
/// |> line(endAbsolute = [profileStartX(%), profileStartY(%)])
/// |> close()
/// }
///
/// rect([0, 0])
/// rect([20, 0])
/// ```
///
/// Those tags would only be available in the `rect` function and not globally.
///
/// However you likely want to use those tags somewhere outside the `rect` function.
///
/// Tags are accessible through the sketch group they are declared in.
/// For example the following code works.
///
/// ```norun,inline
/// fn rect(origin) {
/// return startSketchOn(XZ)
/// |> startProfileAt(origin, %)
/// |> angledLine(angle = 0, length = 191.26, tag = $rectangleSegmentA001)
/// |> angledLine(
/// angle = segAng(rectangleSegmentA001) - 90,
/// length = 196.99
/// , %, $rectangleSegmentB001)
/// |> angledLine(
/// angle = segAng(rectangleSegmentA001),
/// length = -segLen(rectangleSegmentA001)
/// , %, $rectangleSegmentC001)
/// |> line(endAbsolute = [profileStartX(%), profileStartY(%)])
/// |> close()
/// }
///
/// rect([0, 0])
/// myRect = rect([20, 0])
///
/// myRect
/// |> extrude(length = 10)
/// |> fillet(radius = 0.5, tags = [myRect.tags.rectangleSegmentA001])
/// ```
///
/// See how we use the tag `rectangleSegmentA001` in the `fillet` function outside
/// the `rect` function. This is because the `rect` function is returning the
/// sketch group that contains the tags.
@(impl = primitive)
export type tag
/// A plane.
@(impl = std_rust)
export type Plane
/// A sketch is a collection of paths.
///
/// When you define a sketch to a variable like:
///
/// ```kcl,inline
/// mySketch = startSketchOn(XY)
/// |> startProfileAt([-12, 12], %)
/// |> line(end = [24, 0])
/// |> line(end = [0, -24])
/// |> line(end = [-24, 0])
/// |> close()
/// ```
///
/// The `mySketch` variable will be an executed `Sketch` object. Executed being past
/// 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.
///
/// If you would like to encapsulate the commands to create the sketch any time you call it,
/// you can use a function.
///
/// ```kcl,inline
/// fn createSketch() {
/// return startSketchOn(XY)
/// |> startProfileAt([-12, 12], %)
/// |> line(end = [24, 0])
/// |> line(end = [0, -24])
/// |> line(end = [-24, 0])
/// |> close()
/// }
/// ```
///
/// Now, every time you call `createSketch()`, the commands will be
/// executed and a new sketch will be created.
///
/// When you assign the result of `createSketch()` to a variable (`mySketch = createSketch()`), you are assigning
/// the executed sketch to that variable. Meaning that the sketch `mySketch` will not be executed
/// again.
///
/// You can still execute _new_ commands on the sketch like `extrude`, `revolve`, `loft`, etc. and
/// the sketch will be updated.
@(impl = std_rust)
export type Sketch
/// A solid is a collection of extrude surfaces.
///
/// When you define a solid to a variable like:
///
/// ```kcl,inline
/// myPart = startSketchOn('XY')
/// |> startProfileAt([-12, 12], %)
/// |> line(end = [24, 0])
/// |> line(end = [0, -24])
/// |> line(end = [-24, 0])
/// |> close()
/// |> extrude(length = 6)
/// ```
///
/// The `myPart` variable will be an executed `Solid` object. Executed being past
/// 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.
///
/// If you would like to encapsulate the commands to create the solid any time you call it,
/// you can use a function.
///
/// ```kcl,inline
/// fn createPart() {
/// return startSketchOn('XY')
/// |> startProfileAt([-12, 12], %)
/// |> line(end = [24, 0])
/// |> line(end = [0, -24])
/// |> line(end = [-24, 0])
/// |> close()
/// |> extrude(length = 6)
/// }
/// ```
///
/// Now, every time you call `createPart()`, the commands will be
/// executed and a new solid will be created.
///
/// When you assign the result of `createPart()` to a variable (`myPart = createPart()`), you are assigning
/// the executed solid to that variable. Meaning that the solid `myPart` will not be executed
/// again.
///
/// You can still execute _new_ commands on the solid like `shell`, `fillet`, `chamfer`, etc.
/// and the solid will be updated.
@(impl = std_rust)
export type Solid
/// A face.
@(impl = std_rust)
export type Face
/// A helix.
@(impl = std_rust)
export type Helix
/// The edge of a solid.
@(impl = std_rust)
export type Edge
/// 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(Length); 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(Length); 3]
/// An infinite line in 2d space.
@(impl = std_rust)
export type Axis2d
/// An infinite line in 3d space.
@(impl = std_rust)
export type Axis3d

View File

@ -45,6 +45,14 @@ description: Artifact commands add_lots.kcl
"unit": "mm" "unit": "mm"
} }
}, },
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{ {
"cmdId": "[uuid]", "cmdId": "[uuid]",
"range": [], "range": [],

View File

@ -377,6 +377,14 @@ description: Artifact commands angled_line.kcl
"unit": "mm" "unit": "mm"
} }
}, },
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{ {
"cmdId": "[uuid]", "cmdId": "[uuid]",
"range": [], "range": [],

View File

@ -45,6 +45,14 @@ description: Artifact commands argument_error.kcl
"unit": "mm" "unit": "mm"
} }
}, },
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{ {
"cmdId": "[uuid]", "cmdId": "[uuid]",
"range": [], "range": [],

View File

@ -45,6 +45,14 @@ description: Artifact commands array_elem_pop.kcl
"unit": "mm" "unit": "mm"
} }
}, },
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{ {
"cmdId": "[uuid]", "cmdId": "[uuid]",
"range": [], "range": [],

View File

@ -45,6 +45,14 @@ description: Artifact commands array_elem_pop_empty_fail.kcl
"unit": "mm" "unit": "mm"
} }
}, },
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{ {
"cmdId": "[uuid]", "cmdId": "[uuid]",
"range": [], "range": [],

View File

@ -45,6 +45,14 @@ description: Artifact commands array_elem_pop_fail.kcl
"unit": "mm" "unit": "mm"
} }
}, },
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{ {
"cmdId": "[uuid]", "cmdId": "[uuid]",
"range": [], "range": [],

View File

@ -45,6 +45,14 @@ description: Artifact commands array_elem_push.kcl
"unit": "mm" "unit": "mm"
} }
}, },
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{ {
"cmdId": "[uuid]", "cmdId": "[uuid]",
"range": [], "range": [],

View File

@ -45,6 +45,14 @@ description: Artifact commands array_elem_push_fail.kcl
"unit": "mm" "unit": "mm"
} }
}, },
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{ {
"cmdId": "[uuid]", "cmdId": "[uuid]",
"range": [], "range": [],

View File

@ -45,6 +45,14 @@ description: Artifact commands array_index_oob.kcl
"unit": "mm" "unit": "mm"
} }
}, },
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{ {
"cmdId": "[uuid]", "cmdId": "[uuid]",
"range": [], "range": [],

View File

@ -45,6 +45,14 @@ description: Artifact commands array_range_expr.kcl
"unit": "mm" "unit": "mm"
} }
}, },
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{ {
"cmdId": "[uuid]", "cmdId": "[uuid]",
"range": [], "range": [],

View File

@ -45,6 +45,14 @@ description: Artifact commands array_range_negative_expr.kcl
"unit": "mm" "unit": "mm"
} }
}, },
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{ {
"cmdId": "[uuid]", "cmdId": "[uuid]",
"range": [], "range": [],

View File

@ -537,6 +537,14 @@ description: Artifact commands artifact_graph_example_code1.kcl
"unit": "mm" "unit": "mm"
} }
}, },
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{ {
"cmdId": "[uuid]", "cmdId": "[uuid]",
"range": [], "range": [],

View File

@ -308,6 +308,14 @@ description: Artifact commands artifact_graph_example_code_no_3d.kcl
"unit": "mm" "unit": "mm"
} }
}, },
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{ {
"cmdId": "[uuid]", "cmdId": "[uuid]",
"range": [], "range": [],

View File

@ -231,6 +231,14 @@ description: Artifact commands artifact_graph_example_code_offset_planes.kcl
"unit": "mm" "unit": "mm"
} }
}, },
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{ {
"cmdId": "[uuid]", "cmdId": "[uuid]",
"range": [], "range": [],

View File

@ -898,6 +898,14 @@ description: Artifact commands artifact_graph_sketch_on_face_etc.kcl
"unit": "mm" "unit": "mm"
} }
}, },
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{ {
"cmdId": "[uuid]", "cmdId": "[uuid]",
"range": [], "range": [],

View File

@ -61,6 +61,14 @@ description: Artifact commands assembly_mixed_units_cubes.kcl
"unit": "mm" "unit": "mm"
} }
}, },
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{ {
"cmdId": "[uuid]", "cmdId": "[uuid]",
"range": [], "range": [],

View File

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

View File

@ -8,7 +8,7 @@ description: Operations executed assembly_mixed_units_cubes.kcl
"group": { "group": {
"type": "ModuleInstance", "type": "ModuleInstance",
"name": "cubeIn", "name": "cubeIn",
"moduleId": 5 "moduleId": 6
}, },
"sourceRange": [] "sourceRange": []
}, },
@ -67,7 +67,7 @@ description: Operations executed assembly_mixed_units_cubes.kcl
"group": { "group": {
"type": "ModuleInstance", "type": "ModuleInstance",
"name": "cubeMm", "name": "cubeMm",
"moduleId": 6 "moduleId": 7
}, },
"sourceRange": [] "sourceRange": []
}, },

View File

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

View File

@ -61,6 +61,14 @@ description: Artifact commands assembly_non_default_units.kcl
"unit": "mm" "unit": "mm"
} }
}, },
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{ {
"cmdId": "[uuid]", "cmdId": "[uuid]",
"range": [], "range": [],

View File

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

View File

@ -8,7 +8,7 @@ description: Operations executed assembly_non_default_units.kcl
"group": { "group": {
"type": "ModuleInstance", "type": "ModuleInstance",
"name": "other1", "name": "other1",
"moduleId": 5 "moduleId": 6
}, },
"sourceRange": [] "sourceRange": []
}, },
@ -35,7 +35,7 @@ description: Operations executed assembly_non_default_units.kcl
"group": { "group": {
"type": "ModuleInstance", "type": "ModuleInstance",
"name": "other2", "name": "other2",
"moduleId": 6 "moduleId": 7
}, },
"sourceRange": [] "sourceRange": []
}, },

View File

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

View File

@ -45,6 +45,14 @@ description: Artifact commands bad_units_in_annotation.kcl
"unit": "mm" "unit": "mm"
} }
}, },
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{ {
"cmdId": "[uuid]", "cmdId": "[uuid]",
"range": [], "range": [],

View File

@ -337,6 +337,14 @@ description: Artifact commands basic_fillet_cube_close_opposite.kcl
"unit": "mm" "unit": "mm"
} }
}, },
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{ {
"cmdId": "[uuid]", "cmdId": "[uuid]",
"range": [], "range": [],

View File

@ -337,6 +337,14 @@ description: Artifact commands basic_fillet_cube_end.kcl
"unit": "mm" "unit": "mm"
} }
}, },
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{ {
"cmdId": "[uuid]", "cmdId": "[uuid]",
"range": [], "range": [],

View File

@ -325,6 +325,14 @@ description: Artifact commands basic_fillet_cube_next_adjacent.kcl
"unit": "mm" "unit": "mm"
} }
}, },
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{ {
"cmdId": "[uuid]", "cmdId": "[uuid]",
"range": [], "range": [],

View File

@ -325,6 +325,14 @@ description: Artifact commands basic_fillet_cube_previous_adjacent.kcl
"unit": "mm" "unit": "mm"
} }
}, },
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{ {
"cmdId": "[uuid]", "cmdId": "[uuid]",
"range": [], "range": [],

View File

@ -327,6 +327,14 @@ description: Artifact commands basic_fillet_cube_start.kcl
"unit": "mm" "unit": "mm"
} }
}, },
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{ {
"cmdId": "[uuid]", "cmdId": "[uuid]",
"range": [], "range": [],

View File

@ -266,6 +266,14 @@ description: Artifact commands big_number_angle_to_match_length_x.kcl
"unit": "mm" "unit": "mm"
} }
}, },
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{ {
"cmdId": "[uuid]", "cmdId": "[uuid]",
"range": [], "range": [],

View File

@ -266,6 +266,14 @@ description: Artifact commands big_number_angle_to_match_length_y.kcl
"unit": "mm" "unit": "mm"
} }
}, },
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{ {
"cmdId": "[uuid]", "cmdId": "[uuid]",
"range": [], "range": [],

View File

@ -45,6 +45,14 @@ description: Artifact commands boolean_logical_and.kcl
"unit": "mm" "unit": "mm"
} }
}, },
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{ {
"cmdId": "[uuid]", "cmdId": "[uuid]",
"range": [], "range": [],

View File

@ -45,6 +45,14 @@ description: Artifact commands boolean_logical_multiple.kcl
"unit": "mm" "unit": "mm"
} }
}, },
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{ {
"cmdId": "[uuid]", "cmdId": "[uuid]",
"range": [], "range": [],

View File

@ -45,6 +45,14 @@ description: Artifact commands boolean_logical_or.kcl
"unit": "mm" "unit": "mm"
} }
}, },
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{ {
"cmdId": "[uuid]", "cmdId": "[uuid]",
"range": [], "range": [],

View File

@ -217,6 +217,14 @@ description: Artifact commands circle_three_point.kcl
"unit": "mm" "unit": "mm"
} }
}, },
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{ {
"cmdId": "[uuid]", "cmdId": "[uuid]",
"range": [], "range": [],

View File

@ -635,6 +635,14 @@ description: Artifact commands circular_pattern3d_a_pattern.kcl
"unit": "mm" "unit": "mm"
} }
}, },
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{ {
"cmdId": "[uuid]", "cmdId": "[uuid]",
"range": [], "range": [],

View File

@ -45,6 +45,14 @@ description: Artifact commands comparisons.kcl
"unit": "mm" "unit": "mm"
} }
}, },
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{ {
"cmdId": "[uuid]", "cmdId": "[uuid]",
"range": [], "range": [],

View File

@ -45,6 +45,14 @@ description: Artifact commands comparisons_multiple.kcl
"unit": "mm" "unit": "mm"
} }
}, },
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{ {
"cmdId": "[uuid]", "cmdId": "[uuid]",
"range": [], "range": [],

View File

@ -45,6 +45,14 @@ description: Artifact commands computed_var.kcl
"unit": "mm" "unit": "mm"
} }
}, },
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{ {
"cmdId": "[uuid]", "cmdId": "[uuid]",
"range": [], "range": [],

View File

@ -1672,6 +1672,14 @@ description: Artifact commands crazy_multi_profile.kcl
"unit": "mm" "unit": "mm"
} }
}, },
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{ {
"cmdId": "[uuid]", "cmdId": "[uuid]",
"range": [], "range": [],

View File

@ -320,6 +320,14 @@ description: Artifact commands cube.kcl
"unit": "mm" "unit": "mm"
} }
}, },
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{ {
"cmdId": "[uuid]", "cmdId": "[uuid]",
"range": [], "range": [],

View File

@ -240,6 +240,14 @@ description: Artifact commands cube_with_error.kcl
"unit": "mm" "unit": "mm"
} }
}, },
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{ {
"cmdId": "[uuid]", "cmdId": "[uuid]",
"range": [], "range": [],

View File

@ -45,6 +45,14 @@ description: Artifact commands double_map_fn.kcl
"unit": "mm" "unit": "mm"
} }
}, },
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{ {
"cmdId": "[uuid]", "cmdId": "[uuid]",
"range": [], "range": [],

View File

@ -1847,6 +1847,14 @@ description: Artifact commands fillet-and-shell.kcl
"unit": "mm" "unit": "mm"
} }
}, },
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{ {
"cmdId": "[uuid]", "cmdId": "[uuid]",
"range": [], "range": [],

View File

@ -339,6 +339,14 @@ description: Artifact commands flush_batch_on_end.kcl
"unit": "mm" "unit": "mm"
} }
}, },
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{ {
"cmdId": "[uuid]", "cmdId": "[uuid]",
"range": [], "range": [],

View File

@ -303,6 +303,14 @@ description: Artifact commands function_sketch.kcl
"unit": "mm" "unit": "mm"
} }
}, },
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{ {
"cmdId": "[uuid]", "cmdId": "[uuid]",
"range": [], "range": [],

View File

@ -303,6 +303,14 @@ description: Artifact commands function_sketch_with_position.kcl
"unit": "mm" "unit": "mm"
} }
}, },
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{ {
"cmdId": "[uuid]", "cmdId": "[uuid]",
"range": [], "range": [],

View File

@ -232,6 +232,14 @@ description: Artifact commands helix_ccw.kcl
"unit": "mm" "unit": "mm"
} }
}, },
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{ {
"cmdId": "[uuid]", "cmdId": "[uuid]",
"range": [], "range": [],

View File

@ -146,6 +146,14 @@ description: Artifact commands helix_simple.kcl
"unit": "mm" "unit": "mm"
} }
}, },
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{ {
"cmdId": "[uuid]", "cmdId": "[uuid]",
"range": [], "range": [],

View File

@ -1450,6 +1450,14 @@ description: Artifact commands i_shape.kcl
"unit": "mm" "unit": "mm"
} }
}, },
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{ {
"cmdId": "[uuid]", "cmdId": "[uuid]",
"range": [], "range": [],

View File

@ -45,6 +45,14 @@ description: Artifact commands if_else.kcl
"unit": "mm" "unit": "mm"
} }
}, },
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{ {
"cmdId": "[uuid]", "cmdId": "[uuid]",
"range": [], "range": [],

View File

@ -5575218,6 +5575218,14 @@ description: Artifact commands import_async.kcl
"unit": "mm" "unit": "mm"
} }
}, },
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{ {
"cmdId": "[uuid]", "cmdId": "[uuid]",
"range": [], "range": [],

View File

@ -8,7 +8,7 @@ description: Operations executed import_async.kcl
"group": { "group": {
"type": "ModuleInstance", "type": "ModuleInstance",
"name": "screw", "name": "screw",
"moduleId": 5 "moduleId": 6
}, },
"sourceRange": [] "sourceRange": []
}, },

View File

@ -3625,7 +3625,7 @@ description: Variables in memory after executing import_async.kcl
}, },
"screw": { "screw": {
"type": "Module", "type": "Module",
"value": 5 "value": 6
}, },
"start": { "start": {
"type": "Sketch", "type": "Sketch",

View File

@ -45,6 +45,14 @@ description: Artifact commands import_constant.kcl
"unit": "mm" "unit": "mm"
} }
}, },
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{ {
"cmdId": "[uuid]", "cmdId": "[uuid]",
"range": [], "range": [],

View File

@ -45,6 +45,14 @@ description: Artifact commands import_cycle1.kcl
"unit": "mm" "unit": "mm"
} }
}, },
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{ {
"cmdId": "[uuid]", "cmdId": "[uuid]",
"range": [], "range": [],

View File

@ -45,6 +45,14 @@ description: Artifact commands import_export.kcl
"unit": "mm" "unit": "mm"
} }
}, },
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{ {
"cmdId": "[uuid]", "cmdId": "[uuid]",
"range": [], "range": [],

View File

@ -45,6 +45,14 @@ description: Artifact commands import_file_not_exist_error.kcl
"unit": "mm" "unit": "mm"
} }
}, },
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{ {
"cmdId": "[uuid]", "cmdId": "[uuid]",
"range": [], "range": [],

View File

@ -45,6 +45,14 @@ description: Artifact commands import_file_parse_error.kcl
"unit": "mm" "unit": "mm"
} }
}, },
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{ {
"cmdId": "[uuid]", "cmdId": "[uuid]",
"range": [], "range": [],

View File

@ -3038,6 +3038,14 @@ description: Artifact commands import_foreign.kcl
"unit": "mm" "unit": "mm"
} }
}, },
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{ {
"cmdId": "[uuid]", "cmdId": "[uuid]",
"range": [], "range": [],

View File

@ -8,7 +8,7 @@ description: Operations executed import_foreign.kcl
"group": { "group": {
"type": "ModuleInstance", "type": "ModuleInstance",
"name": "cube", "name": "cube",
"moduleId": 5 "moduleId": 6
}, },
"sourceRange": [] "sourceRange": []
}, },

View File

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

View File

@ -69,6 +69,14 @@ description: Artifact commands import_function_not_sketch.kcl
"unit": "mm" "unit": "mm"
} }
}, },
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{ {
"cmdId": "[uuid]", "cmdId": "[uuid]",
"range": [], "range": [],

View File

@ -1,19 +1,19 @@
```mermaid ```mermaid
flowchart LR flowchart LR
subgraph path2 [Path] subgraph path2 [Path]
2["Path<br>[75, 101, 5]"] 2["Path<br>[75, 101, 6]"]
3["Segment<br>[107, 125, 5]"] 3["Segment<br>[107, 125, 6]"]
4["Segment<br>[131, 150, 5]"] 4["Segment<br>[131, 150, 6]"]
5["Segment<br>[156, 175, 5]"] 5["Segment<br>[156, 175, 6]"]
6["Segment<br>[181, 200, 5]"] 6["Segment<br>[181, 200, 6]"]
7["Segment<br>[206, 231, 5]"] 7["Segment<br>[206, 231, 6]"]
8["Segment<br>[237, 258, 5]"] 8["Segment<br>[237, 258, 6]"]
9["Segment<br>[264, 283, 5]"] 9["Segment<br>[264, 283, 6]"]
10["Segment<br>[289, 296, 5]"] 10["Segment<br>[289, 296, 6]"]
11[Solid2d] 11[Solid2d]
end end
1["Plane<br>[52, 69, 5]"] 1["Plane<br>[52, 69, 6]"]
12["Sweep Revolve<br>[302, 319, 5]"] 12["Sweep Revolve<br>[302, 319, 6]"]
13[Wall] 13[Wall]
14[Wall] 14[Wall]
15[Wall] 15[Wall]

View File

@ -45,6 +45,14 @@ description: Artifact commands import_glob.kcl
"unit": "mm" "unit": "mm"
} }
}, },
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{ {
"cmdId": "[uuid]", "cmdId": "[uuid]",
"range": [], "range": [],

View File

@ -53,6 +53,14 @@ description: Artifact commands import_side_effect.kcl
"unit": "mm" "unit": "mm"
} }
}, },
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{ {
"cmdId": "[uuid]", "cmdId": "[uuid]",
"range": [], "range": [],

View File

@ -1,11 +1,11 @@
```mermaid ```mermaid
flowchart LR flowchart LR
subgraph path2 [Path] subgraph path2 [Path]
2["Path<br>[102, 138, 5]"] 2["Path<br>[102, 138, 6]"]
3["Segment<br>[102, 138, 5]"] 3["Segment<br>[102, 138, 6]"]
4[Solid2d] 4[Solid2d]
end end
1["Plane<br>[77, 96, 5]"] 1["Plane<br>[77, 96, 6]"]
1 --- 2 1 --- 2
2 --- 3 2 --- 3
2 --- 4 2 --- 4

View File

@ -5571179,6 +5571179,14 @@ description: Artifact commands import_transform.kcl
"unit": "mm" "unit": "mm"
} }
}, },
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{ {
"cmdId": "[uuid]", "cmdId": "[uuid]",
"range": [], "range": [],

View File

@ -8,7 +8,7 @@ description: Operations executed import_transform.kcl
"group": { "group": {
"type": "ModuleInstance", "type": "ModuleInstance",
"name": "screw", "name": "screw",
"moduleId": 5 "moduleId": 6
}, },
"sourceRange": [] "sourceRange": []
}, },

View File

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

View File

@ -85,6 +85,14 @@ description: Artifact commands import_whole.kcl
"unit": "mm" "unit": "mm"
} }
}, },
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{ {
"cmdId": "[uuid]", "cmdId": "[uuid]",
"range": [], "range": [],

View File

@ -1,12 +1,12 @@
```mermaid ```mermaid
flowchart LR flowchart LR
subgraph path2 [Path] subgraph path2 [Path]
2["Path<br>[83, 119, 5]"] 2["Path<br>[83, 119, 6]"]
3["Segment<br>[83, 119, 5]"] 3["Segment<br>[83, 119, 6]"]
4[Solid2d] 4[Solid2d]
end end
1["Plane<br>[60, 77, 5]"] 1["Plane<br>[60, 77, 6]"]
5["Sweep Extrusion<br>[125, 145, 5]"] 5["Sweep Extrusion<br>[125, 145, 6]"]
6[Wall] 6[Wall]
7["Cap Start"] 7["Cap Start"]
8["Cap End"] 8["Cap End"]

View File

@ -8,7 +8,7 @@ description: Operations executed import_whole.kcl
"group": { "group": {
"type": "ModuleInstance", "type": "ModuleInstance",
"name": "foo", "name": "foo",
"moduleId": 5 "moduleId": 6
}, },
"sourceRange": [] "sourceRange": []
}, },

View File

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

View File

@ -45,6 +45,14 @@ description: Artifact commands index_of_array.kcl
"unit": "mm" "unit": "mm"
} }
}, },
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{ {
"cmdId": "[uuid]", "cmdId": "[uuid]",
"range": [], "range": [],

View File

@ -597,6 +597,14 @@ description: Artifact commands intersect_cubes.kcl
"unit": "mm" "unit": "mm"
} }
}, },
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{ {
"cmdId": "[uuid]", "cmdId": "[uuid]",
"range": [], "range": [],

View File

@ -45,6 +45,14 @@ description: Artifact commands invalid_index_fractional.kcl
"unit": "mm" "unit": "mm"
} }
}, },
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{ {
"cmdId": "[uuid]", "cmdId": "[uuid]",
"range": [], "range": [],

View File

@ -45,6 +45,14 @@ description: Artifact commands invalid_index_negative.kcl
"unit": "mm" "unit": "mm"
} }
}, },
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{ {
"cmdId": "[uuid]", "cmdId": "[uuid]",
"range": [], "range": [],

View File

@ -45,6 +45,14 @@ description: Artifact commands invalid_index_str.kcl
"unit": "mm" "unit": "mm"
} }
}, },
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{ {
"cmdId": "[uuid]", "cmdId": "[uuid]",
"range": [], "range": [],

View File

@ -45,6 +45,14 @@ description: Artifact commands invalid_member_object.kcl
"unit": "mm" "unit": "mm"
} }
}, },
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{ {
"cmdId": "[uuid]", "cmdId": "[uuid]",
"range": [], "range": [],

View File

@ -45,6 +45,14 @@ description: Artifact commands invalid_member_object_prop.kcl
"unit": "mm" "unit": "mm"
} }
}, },
{
"cmdId": "[uuid]",
"range": [],
"command": {
"type": "set_scene_units",
"unit": "mm"
}
},
{ {
"cmdId": "[uuid]", "cmdId": "[uuid]",
"range": [], "range": [],

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