Merge branch 'main' into kurt-multi-profile-again

This commit is contained in:
Jonathan Tran
2025-02-12 18:34:02 -05:00
131 changed files with 160491 additions and 156513 deletions

File diff suppressed because one or more lines are too long

View File

@ -17,7 +17,7 @@ lastSegX(sketch: Sketch) -> number
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `sketch` | [`Sketch`](/docs/kcl/types/Sketch) | A sketch is a collection of paths. | Yes |
| `sketch` | [`Sketch`](/docs/kcl/types/Sketch) | The sketch whose line segment is being queried | Yes |
### Returns

View File

@ -17,7 +17,7 @@ lastSegY(sketch: Sketch) -> number
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `sketch` | [`Sketch`](/docs/kcl/types/Sketch) | A sketch is a collection of paths. | Yes |
| `sketch` | [`Sketch`](/docs/kcl/types/Sketch) | The sketch whose line segment is being queried | Yes |
### Returns

View File

@ -57,3 +57,55 @@ Imported symbols can be renamed for convenience or to avoid name collisions.
```
import increment as inc, decrement as dec from "util.kcl"
```
## Importing files from other CAD systems
`import` can also be used to import files from other CAD systems. The format of the statement is the
same as for KCL files. You can only import the whole file, not items from it. E.g.,
```
import "tests/inputs/cube.obj"
// Use `cube` just like a KCL object.
```
```
import "tests/inputs/cube-2.sldprt" as cube
// Use `cube` just like a KCL object.
```
You can make the file format explicit using a format attribute (useful if using a different
extension), e.g.,
```
@(format = obj)
import "tests/inputs/cube"
```
For formats lacking unit data (such as STL, OBJ, or PLY files), the default
unit of measurement is millimeters. Alternatively you may specify the unit
by using an attirbute. Likewise, you can also specify a coordinate system. E.g.,
```
@(unitLength = ft, coords = opengl)
import "tests/inputs/cube.obj"
```
When importing a GLTF file, the bin file will be imported as well.
Import paths are relative to the current project directory. Imports currently only work when
using the native Modeling App, not in the browser.
### Supported values
File formats: `fbx`, `gltf`/`glb`, `obj`+, `ply`+, `sldprt`, `step`/`stp`, `stl`+. (Those marked with a
'+' support customising the length unit and coordinate system).
Length units: `mm` (the default), `cm`, `m`, `inch`, `ft`, `yd`.
Coordinate systems:
- `zoo` (the default), forward: -Y, up: +Z, handedness: right
- `opengl`, forward: +Z, up: +Y, handedness: right
- `vulkan`, forward: +Z, up: -Y, handedness: left

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -17,7 +17,7 @@ segAng(tag: TagIdentifier) -> number
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `tag` | [`TagIdentifier`](/docs/kcl/types#tag-identifier) | | Yes |
| `tag` | [`TagIdentifier`](/docs/kcl/types#tag-identifier) | The line segment being queried by its tag | Yes |
### Returns

View File

@ -17,7 +17,7 @@ segEnd(tag: TagIdentifier) -> [number]
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `tag` | [`TagIdentifier`](/docs/kcl/types#tag-identifier) | | Yes |
| `tag` | [`TagIdentifier`](/docs/kcl/types#tag-identifier) | The line segment being queried by its tag | Yes |
### Returns

View File

@ -17,7 +17,7 @@ segEndX(tag: TagIdentifier) -> number
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `tag` | [`TagIdentifier`](/docs/kcl/types#tag-identifier) | | Yes |
| `tag` | [`TagIdentifier`](/docs/kcl/types#tag-identifier) | The line segment being queried by its tag | Yes |
### Returns

View File

@ -17,7 +17,7 @@ segEndY(tag: TagIdentifier) -> number
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `tag` | [`TagIdentifier`](/docs/kcl/types#tag-identifier) | | Yes |
| `tag` | [`TagIdentifier`](/docs/kcl/types#tag-identifier) | The line segment being queried by its tag | Yes |
### Returns

View File

@ -17,7 +17,7 @@ segLen(tag: TagIdentifier) -> number
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `tag` | [`TagIdentifier`](/docs/kcl/types#tag-identifier) | | Yes |
| `tag` | [`TagIdentifier`](/docs/kcl/types#tag-identifier) | The line segment being queried by its tag | Yes |
### Returns

View File

@ -17,7 +17,7 @@ segStart(tag: TagIdentifier) -> [number]
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `tag` | [`TagIdentifier`](/docs/kcl/types#tag-identifier) | | Yes |
| `tag` | [`TagIdentifier`](/docs/kcl/types#tag-identifier) | The line segment being queried by its tag | Yes |
### Returns

View File

@ -17,7 +17,7 @@ segStartX(tag: TagIdentifier) -> number
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `tag` | [`TagIdentifier`](/docs/kcl/types#tag-identifier) | | Yes |
| `tag` | [`TagIdentifier`](/docs/kcl/types#tag-identifier) | The line segment being queried by its tag | Yes |
### Returns

View File

@ -17,7 +17,7 @@ segStartY(tag: TagIdentifier) -> number
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `tag` | [`TagIdentifier`](/docs/kcl/types#tag-identifier) | | Yes |
| `tag` | [`TagIdentifier`](/docs/kcl/types#tag-identifier) | The line segment being queried by its tag | Yes |
### Returns

File diff suppressed because it is too large Load Diff

View File

@ -17,7 +17,7 @@ tangentToEnd(tag: TagIdentifier) -> number
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `tag` | [`TagIdentifier`](/docs/kcl/types#tag-identifier) | | Yes |
| `tag` | [`TagIdentifier`](/docs/kcl/types#tag-identifier) | The line segment being queried by its tag | Yes |
### Returns

View File

@ -26,7 +26,7 @@
"@fortawesome/react-fontawesome": "^0.2.0",
"@headlessui/react": "^1.7.19",
"@headlessui/tailwindcss": "^0.2.0",
"@kittycad/lib": "2.0.13",
"@kittycad/lib": "2.0.17",
"@lezer/highlight": "^1.2.1",
"@lezer/lr": "^1.4.1",
"@react-hook/resize-observer": "^2.0.1",
@ -85,7 +85,7 @@
"fmt": "prettier --write ./src *.ts *.json *.js ./e2e ./packages",
"fmt-check": "prettier --check ./src *.ts *.json *.js ./e2e ./packages",
"fetch:wasm": "./get-latest-wasm-bundle.sh",
"fetch:samples": "echo \"Fetching latest KCL samples...\" && curl -o public/kcl-samples-manifest-fallback.json https://raw.githubusercontent.com/KittyCAD/kcl-samples/achalmers/kw-pattern/manifest.json",
"fetch:samples": "echo \"Fetching latest KCL samples...\" && curl -o public/kcl-samples-manifest-fallback.json https://raw.githubusercontent.com/KittyCAD/kcl-samples/achalmers/kw-pattern-transform2/manifest.json",
"isomorphic-copy-wasm": "(copy src/wasm-lib/pkg/wasm_lib_bg.wasm public || cp src/wasm-lib/pkg/wasm_lib_bg.wasm public)",
"build:wasm-dev": "yarn wasm-prep && (cd src/wasm-lib && wasm-pack build --dev --target web --out-dir pkg && cargo test -p kcl-lib export_bindings) && yarn isomorphic-copy-wasm && yarn fmt",
"build:wasm": "yarn wasm-prep && cd src/wasm-lib && wasm-pack build --release --target web --out-dir pkg && cargo test -p kcl-lib export_bindings && cd ../.. && yarn isomorphic-copy-wasm && yarn fmt",

View File

@ -34,6 +34,13 @@
"title": "Car Wheel Assembly",
"description": "A car wheel assembly with a rotor, tire, and lug nuts."
},
{
"file": "main.kcl",
"pathFromProjectDirectoryToFirstFile": "cycloidal-gear/main.kcl",
"multipleFiles": false,
"title": "Cycloidal Gear",
"description": "A cycloidal gear is a gear with a continuous, curved tooth profile. They are used in watchmaking and high precision robotics actuation"
},
{
"file": "main.kcl",
"pathFromProjectDirectoryToFirstFile": "dodecahedron/main.kcl",
@ -48,6 +55,13 @@
"title": "Enclosure",
"description": "An enclosure body and sealing lid for storing items"
},
{
"file": "main.kcl",
"pathFromProjectDirectoryToFirstFile": "exhaust-manifold/main.kcl",
"multipleFiles": false,
"title": "Exhaust Manifold",
"description": "A welded exhaust header for an inline 4-cylinder engine"
},
{
"file": "main.kcl",
"pathFromProjectDirectoryToFirstFile": "flange-with-patterns/main.kcl",

View File

@ -1551,6 +1551,7 @@ export const ModelingMachineProvider = ({
selections: input.selection,
token,
artifactGraph: engineCommandManager.artifactGraph,
projectName: context.project.name,
})
}),
},

View File

@ -32,7 +32,7 @@ child_process.spawnSync('git', [
'clone',
'--single-branch',
'--branch',
'achalmers/kw-pattern',
'achalmers/kw-pattern-transform2',
URL_GIT_KCL_SAMPLES,
DIR_KCL_SAMPLES,
])

View File

@ -9,7 +9,6 @@ import {
modify_ast_for_sketch_wasm,
is_points_ccw,
get_tangential_arc_to_info,
program_memory_init,
make_default_planes,
coredump,
toml_stringify,
@ -43,9 +42,6 @@ import { DeepPartial } from 'lib/types'
import { ProjectConfiguration } from 'wasm-lib/kcl/bindings/ProjectConfiguration'
import { Sketch } from '../wasm-lib/kcl/bindings/Sketch'
import { ExecOutcome as RustExecOutcome } from 'wasm-lib/kcl/bindings/ExecOutcome'
import { ProgramMemory as RawProgramMemory } from '../wasm-lib/kcl/bindings/ProgramMemory'
import { EnvironmentRef } from '../wasm-lib/kcl/bindings/EnvironmentRef'
import { Environment } from '../wasm-lib/kcl/bindings/Environment'
import { Node } from 'wasm-lib/kcl/bindings/Node'
import { CompilationError } from 'wasm-lib/kcl/bindings/CompilationError'
import { SourceRange } from 'wasm-lib/kcl/bindings/SourceRange'

View File

@ -40,10 +40,12 @@ export async function submitPromptToEditToQueue({
code,
token,
artifactGraph,
projectName,
}: {
prompt: string
selections: Selections
code: string
projectName: string
token?: string
artifactGraph: ArtifactGraph
}): Promise<Models['TextToCadIteration_type'] | Error> {
@ -157,6 +159,8 @@ See later source ranges for more context. about the sweep`,
original_source_code: code,
prompt,
source_ranges: ranges,
project_name:
projectName !== '' && projectName !== 'browser' ? projectName : undefined,
}
const url = VITE_KC_API_BASE_URL + '/ml/text-to-cad/iteration'
const data: Models['TextToCadIteration_type'] | Error =
@ -203,11 +207,13 @@ export async function doPromptEdit({
code,
token,
artifactGraph,
projectName,
}: {
prompt: string
selections: Selections
code: string
token?: string
projectName: string
artifactGraph: ArtifactGraph
}): Promise<Models['TextToCadIteration_type'] | Error> {
const toastId = toast.loading('Submitting to Text-to-CAD API...')
@ -217,6 +223,7 @@ export async function doPromptEdit({
code,
token,
artifactGraph,
projectName,
})
if (err(submitResult)) return submitResult
@ -269,12 +276,14 @@ export async function promptToEditFlow({
code,
token,
artifactGraph,
projectName,
}: {
prompt: string
selections: Selections
code: string
token?: string
artifactGraph: ArtifactGraph
projectName: string
}) {
const result = await doPromptEdit({
prompt,
@ -282,6 +291,7 @@ export async function promptToEditFlow({
code,
token,
artifactGraph,
projectName,
})
if (err(result)) return Promise.reject(result)
const oldCode = codeManager.code

View File

@ -19,9 +19,14 @@ import { toSync } from './utils'
async function submitTextToCadPrompt(
prompt: string,
projectName: string,
token?: string
): Promise<Models['TextToCad_type'] | Error> {
const body: Models['TextToCadCreateBody_type'] = { prompt }
const body: Models['TextToCadCreateBody_type'] = {
prompt,
project_name:
projectName !== '' && projectName !== 'browser' ? projectName : undefined,
}
// Glb has a smaller footprint than gltf, should we want to render it.
const url = VITE_KC_API_BASE_URL + '/ai/text-to-cad/glb?kcl=true'
const data: Models['TextToCad_type'] | Error = await crossPlatformFetch(
@ -100,7 +105,11 @@ export async function submitAndAwaitTextToKcl({
)
}
const textToCadQueued = await submitTextToCadPrompt(trimmedPrompt, token)
const textToCadQueued = await submitTextToCadPrompt(
trimmedPrompt,
context.project.name,
token
)
.then((value) => {
if (value instanceof Error) {
return Promise.reject(value)

View File

@ -17,7 +17,6 @@ import {
modify_ast_for_sketch_wasm as ModifyAstForSketch,
is_points_ccw as IsPointsCcw,
get_tangential_arc_to_info as GetTangentialArcToInfo,
program_memory_init as ProgramMemoryInit,
make_default_planes as MakeDefaultPlanes,
coredump as CoreDump,
toml_stringify as TomlStringify,
@ -80,9 +79,6 @@ export const get_tangential_arc_to_info: typeof GetTangentialArcToInfo = (
) => {
return getModule().get_tangential_arc_to_info(...args)
}
export const program_memory_init: typeof ProgramMemoryInit = (...args) => {
return getModule().program_memory_init(...args)
}
export const make_default_planes: typeof MakeDefaultPlanes = (...args) => {
return getModule().make_default_planes(...args)
}

View File

@ -442,7 +442,7 @@ fn do_stdlib_inner(
#const_struct
fn #boxed_fn_name_ident(
exec_state: &mut crate::ExecState,
exec_state: &mut crate::execution::ExecState,
args: crate::std::Args,
) -> std::pin::Pin<
Box<dyn std::future::Future<Output = anyhow::Result<crate::execution::KclValue, crate::errors::KclError>> + Send + '_>,
@ -831,7 +831,7 @@ fn generate_code_block_test(fn_name: &str, code_block: &str, index: usize) -> pr
context_type: crate::execution::ContextType::Mock,
};
if let Err(e) = ctx.run(&program, &mut crate::ExecState::new(&ctx.settings)).await {
if let Err(e) = ctx.run(&program, &mut crate::execution::ExecState::new(&ctx.settings)).await {
return Err(miette::Report::new(crate::errors::Report {
error: e,
filename: format!("{}{}", #fn_name, #index),

View File

@ -15,7 +15,10 @@ mod test_examples_someFn {
context_type: crate::execution::ContextType::Mock,
};
if let Err(e) = ctx
.run(&program, &mut crate::ExecState::new(&ctx.settings))
.run(
&program,
&mut crate::execution::ExecState::new(&ctx.settings),
)
.await
{
return Err(miette::Report::new(crate::errors::Report {
@ -67,7 +70,7 @@ pub(crate) struct SomeFn {}
#[doc = "Std lib function: someFn\nDocs"]
pub(crate) const SomeFn: SomeFn = SomeFn {};
fn boxed_someFn(
exec_state: &mut crate::ExecState,
exec_state: &mut crate::execution::ExecState,
args: crate::std::Args,
) -> std::pin::Pin<
Box<

View File

@ -15,7 +15,10 @@ mod test_examples_someFn {
context_type: crate::execution::ContextType::Mock,
};
if let Err(e) = ctx
.run(&program, &mut crate::ExecState::new(&ctx.settings))
.run(
&program,
&mut crate::execution::ExecState::new(&ctx.settings),
)
.await
{
return Err(miette::Report::new(crate::errors::Report {
@ -67,7 +70,7 @@ pub(crate) struct SomeFn {}
#[doc = "Std lib function: someFn\nDocs"]
pub(crate) const SomeFn: SomeFn = SomeFn {};
fn boxed_someFn(
exec_state: &mut crate::ExecState,
exec_state: &mut crate::execution::ExecState,
args: crate::std::Args,
) -> std::pin::Pin<
Box<

View File

@ -16,7 +16,10 @@ mod test_examples_show {
context_type: crate::execution::ContextType::Mock,
};
if let Err(e) = ctx
.run(&program, &mut crate::ExecState::new(&ctx.settings))
.run(
&program,
&mut crate::execution::ExecState::new(&ctx.settings),
)
.await
{
return Err(miette::Report::new(crate::errors::Report {
@ -73,7 +76,10 @@ mod test_examples_show {
context_type: crate::execution::ContextType::Mock,
};
if let Err(e) = ctx
.run(&program, &mut crate::ExecState::new(&ctx.settings))
.run(
&program,
&mut crate::execution::ExecState::new(&ctx.settings),
)
.await
{
return Err(miette::Report::new(crate::errors::Report {
@ -125,7 +131,7 @@ pub(crate) struct Show {}
#[doc = "Std lib function: show\nThis is some function.\nIt does shit."]
pub(crate) const Show: Show = Show {};
fn boxed_show(
exec_state: &mut crate::ExecState,
exec_state: &mut crate::execution::ExecState,
args: crate::std::Args,
) -> std::pin::Pin<
Box<

View File

@ -16,7 +16,10 @@ mod test_examples_show {
context_type: crate::execution::ContextType::Mock,
};
if let Err(e) = ctx
.run(&program, &mut crate::ExecState::new(&ctx.settings))
.run(
&program,
&mut crate::execution::ExecState::new(&ctx.settings),
)
.await
{
return Err(miette::Report::new(crate::errors::Report {
@ -68,7 +71,7 @@ pub(crate) struct Show {}
#[doc = "Std lib function: show\nThis is some function.\nIt does shit."]
pub(crate) const Show: Show = Show {};
fn boxed_show(
exec_state: &mut crate::ExecState,
exec_state: &mut crate::execution::ExecState,
args: crate::std::Args,
) -> std::pin::Pin<
Box<

View File

@ -17,7 +17,10 @@ mod test_examples_my_func {
context_type: crate::execution::ContextType::Mock,
};
if let Err(e) = ctx
.run(&program, &mut crate::ExecState::new(&ctx.settings))
.run(
&program,
&mut crate::execution::ExecState::new(&ctx.settings),
)
.await
{
return Err(miette::Report::new(crate::errors::Report {
@ -74,7 +77,10 @@ mod test_examples_my_func {
context_type: crate::execution::ContextType::Mock,
};
if let Err(e) = ctx
.run(&program, &mut crate::ExecState::new(&ctx.settings))
.run(
&program,
&mut crate::execution::ExecState::new(&ctx.settings),
)
.await
{
return Err(miette::Report::new(crate::errors::Report {
@ -126,7 +132,7 @@ pub(crate) struct MyFunc {}
#[doc = "Std lib function: myFunc\nThis is some function.\nIt does shit."]
pub(crate) const MyFunc: MyFunc = MyFunc {};
fn boxed_my_func(
exec_state: &mut crate::ExecState,
exec_state: &mut crate::execution::ExecState,
args: crate::std::Args,
) -> std::pin::Pin<
Box<

View File

@ -17,7 +17,10 @@ mod test_examples_line_to {
context_type: crate::execution::ContextType::Mock,
};
if let Err(e) = ctx
.run(&program, &mut crate::ExecState::new(&ctx.settings))
.run(
&program,
&mut crate::execution::ExecState::new(&ctx.settings),
)
.await
{
return Err(miette::Report::new(crate::errors::Report {
@ -74,7 +77,10 @@ mod test_examples_line_to {
context_type: crate::execution::ContextType::Mock,
};
if let Err(e) = ctx
.run(&program, &mut crate::ExecState::new(&ctx.settings))
.run(
&program,
&mut crate::execution::ExecState::new(&ctx.settings),
)
.await
{
return Err(miette::Report::new(crate::errors::Report {
@ -126,7 +132,7 @@ pub(crate) struct LineTo {}
#[doc = "Std lib function: lineTo\nThis is some function.\nIt does shit."]
pub(crate) const LineTo: LineTo = LineTo {};
fn boxed_line_to(
exec_state: &mut crate::ExecState,
exec_state: &mut crate::execution::ExecState,
args: crate::std::Args,
) -> std::pin::Pin<
Box<

View File

@ -16,7 +16,10 @@ mod test_examples_min {
context_type: crate::execution::ContextType::Mock,
};
if let Err(e) = ctx
.run(&program, &mut crate::ExecState::new(&ctx.settings))
.run(
&program,
&mut crate::execution::ExecState::new(&ctx.settings),
)
.await
{
return Err(miette::Report::new(crate::errors::Report {
@ -73,7 +76,10 @@ mod test_examples_min {
context_type: crate::execution::ContextType::Mock,
};
if let Err(e) = ctx
.run(&program, &mut crate::ExecState::new(&ctx.settings))
.run(
&program,
&mut crate::execution::ExecState::new(&ctx.settings),
)
.await
{
return Err(miette::Report::new(crate::errors::Report {
@ -125,7 +131,7 @@ pub(crate) struct Min {}
#[doc = "Std lib function: min\nThis is some function.\nIt does shit."]
pub(crate) const Min: Min = Min {};
fn boxed_min(
exec_state: &mut crate::ExecState,
exec_state: &mut crate::execution::ExecState,
args: crate::std::Args,
) -> std::pin::Pin<
Box<

View File

@ -16,7 +16,10 @@ mod test_examples_show {
context_type: crate::execution::ContextType::Mock,
};
if let Err(e) = ctx
.run(&program, &mut crate::ExecState::new(&ctx.settings))
.run(
&program,
&mut crate::execution::ExecState::new(&ctx.settings),
)
.await
{
return Err(miette::Report::new(crate::errors::Report {
@ -68,7 +71,7 @@ pub(crate) struct Show {}
#[doc = "Std lib function: show\nThis is some function.\nIt does shit."]
pub(crate) const Show: Show = Show {};
fn boxed_show(
exec_state: &mut crate::ExecState,
exec_state: &mut crate::execution::ExecState,
args: crate::std::Args,
) -> std::pin::Pin<
Box<

View File

@ -16,7 +16,10 @@ mod test_examples_import {
context_type: crate::execution::ContextType::Mock,
};
if let Err(e) = ctx
.run(&program, &mut crate::ExecState::new(&ctx.settings))
.run(
&program,
&mut crate::execution::ExecState::new(&ctx.settings),
)
.await
{
return Err(miette::Report::new(crate::errors::Report {
@ -68,7 +71,7 @@ pub(crate) struct Import {}
#[doc = "Std lib function: import\nThis is some function.\nIt does shit."]
pub(crate) const Import: Import = Import {};
fn boxed_import(
exec_state: &mut crate::ExecState,
exec_state: &mut crate::execution::ExecState,
args: crate::std::Args,
) -> std::pin::Pin<
Box<

View File

@ -16,7 +16,10 @@ mod test_examples_import {
context_type: crate::execution::ContextType::Mock,
};
if let Err(e) = ctx
.run(&program, &mut crate::ExecState::new(&ctx.settings))
.run(
&program,
&mut crate::execution::ExecState::new(&ctx.settings),
)
.await
{
return Err(miette::Report::new(crate::errors::Report {
@ -68,7 +71,7 @@ pub(crate) struct Import {}
#[doc = "Std lib function: import\nThis is some function.\nIt does shit."]
pub(crate) const Import: Import = Import {};
fn boxed_import(
exec_state: &mut crate::ExecState,
exec_state: &mut crate::execution::ExecState,
args: crate::std::Args,
) -> std::pin::Pin<
Box<

View File

@ -16,7 +16,10 @@ mod test_examples_import {
context_type: crate::execution::ContextType::Mock,
};
if let Err(e) = ctx
.run(&program, &mut crate::ExecState::new(&ctx.settings))
.run(
&program,
&mut crate::execution::ExecState::new(&ctx.settings),
)
.await
{
return Err(miette::Report::new(crate::errors::Report {
@ -68,7 +71,7 @@ pub(crate) struct Import {}
#[doc = "Std lib function: import\nThis is some function.\nIt does shit."]
pub(crate) const Import: Import = Import {};
fn boxed_import(
exec_state: &mut crate::ExecState,
exec_state: &mut crate::execution::ExecState,
args: crate::std::Args,
) -> std::pin::Pin<
Box<

View File

@ -16,7 +16,10 @@ mod test_examples_show {
context_type: crate::execution::ContextType::Mock,
};
if let Err(e) = ctx
.run(&program, &mut crate::ExecState::new(&ctx.settings))
.run(
&program,
&mut crate::execution::ExecState::new(&ctx.settings),
)
.await
{
return Err(miette::Report::new(crate::errors::Report {
@ -68,7 +71,7 @@ pub(crate) struct Show {}
#[doc = "Std lib function: show\nThis is some function.\nIt does shit."]
pub(crate) const Show: Show = Show {};
fn boxed_show(
exec_state: &mut crate::ExecState,
exec_state: &mut crate::execution::ExecState,
args: crate::std::Args,
) -> std::pin::Pin<
Box<

View File

@ -15,7 +15,10 @@ mod test_examples_some_function {
context_type: crate::execution::ContextType::Mock,
};
if let Err(e) = ctx
.run(&program, &mut crate::ExecState::new(&ctx.settings))
.run(
&program,
&mut crate::execution::ExecState::new(&ctx.settings),
)
.await
{
return Err(miette::Report::new(crate::errors::Report {
@ -67,7 +70,7 @@ pub(crate) struct SomeFunction {}
#[doc = "Std lib function: someFunction\nDocs"]
pub(crate) const SomeFunction: SomeFunction = SomeFunction {};
fn boxed_some_function(
exec_state: &mut crate::ExecState,
exec_state: &mut crate::execution::ExecState,
args: crate::std::Args,
) -> std::pin::Pin<
Box<

View File

@ -31,12 +31,12 @@ impl From<KclErrorWithOutputs> for ExecError {
#[derive(Debug)]
pub struct ExecErrorWithState {
pub error: ExecError,
pub exec_state: Option<crate::ExecState>,
pub exec_state: Option<crate::execution::ExecState>,
}
impl ExecErrorWithState {
#[cfg_attr(target_arch = "wasm32", expect(dead_code))]
pub fn new(error: ExecError, exec_state: crate::ExecState) -> Self {
pub fn new(error: ExecError, exec_state: crate::execution::ExecState) -> Self {
Self {
error,
exec_state: Some(exec_state),

View File

@ -1,8 +1,10 @@
//! Data on available annotations.
use super::kcl_value::{UnitAngle, UnitLen};
use kittycad_modeling_cmds::coord::{System, KITTYCAD, OPENGL, VULKAN};
use crate::{
errors::KclErrorDetails,
execution::kcl_value::{UnitAngle, UnitLen},
parsing::ast::types::{Expr, Node, NonCodeValue, ObjectProperty},
KclError, SourceRange,
};
@ -11,6 +13,12 @@ pub(crate) const SETTINGS: &str = "settings";
pub(crate) const SETTINGS_UNIT_LENGTH: &str = "defaultLengthUnit";
pub(crate) const SETTINGS_UNIT_ANGLE: &str = "defaultAngleUnit";
pub(super) const NO_PRELUDE: &str = "no_prelude";
pub(super) const IMPORT_FORMAT: &str = "format";
pub(super) const IMPORT_FORMAT_VALUES: [&str; 9] = ["fbx", "gltf", "glb", "obj", "ply", "sldprt", "stp", "step", "stl"];
pub(super) const IMPORT_COORDS: &str = "coords";
pub(super) const IMPORT_COORDS_VALUES: [(&str, &System); 3] =
[("zoo", KITTYCAD), ("opengl", OPENGL), ("vulkan", VULKAN)];
pub(super) const IMPORT_LENGTH_UNIT: &str = "lengthUnit";
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub(super) enum AnnotationScope {
@ -36,6 +44,18 @@ pub(super) fn expect_properties<'a>(
}
}
pub(super) fn unnamed_properties<'a>(
annotations: impl Iterator<Item = &'a NonCodeValue>,
) -> Option<&'a [Node<ObjectProperty>]> {
for annotation in annotations {
if let NonCodeValue::Annotation { name: None, properties } = annotation {
return properties.as_deref();
}
}
None
}
pub(super) fn expect_ident(expr: &Expr) -> Result<&str, KclError> {
match expr {
Expr::Identifier(id) => Ok(&id.name),
@ -57,7 +77,7 @@ impl UnitLen {
"yd" => Ok(UnitLen::Yards),
value => Err(KclError::Semantic(KclErrorDetails {
message: format!(
"Unexpected settings value: `{value}`; expected one of `mm`, `cm`, `m`, `inch`, `ft`, `yd`"
"Unexpected value for length units: `{value}`; expected one of `mm`, `cm`, `m`, `inch`, `ft`, `yd`"
),
source_ranges: vec![source_range],
})),
@ -71,7 +91,7 @@ impl UnitAngle {
"deg" => Ok(UnitAngle::Degrees),
"rad" => Ok(UnitAngle::Radians),
value => Err(KclError::Semantic(KclErrorDetails {
message: format!("Unexpected settings value: `{value}`; expected one of `deg`, `rad`"),
message: format!("Unexpected value for angle units: `{value}`; expected one of `deg`, `rad`"),
source_ranges: vec![source_range],
})),
}

View File

@ -6,13 +6,11 @@ use itertools::{EitherOrBoth, Itertools};
use tokio::sync::RwLock;
use crate::{
execution::{ExecState, ExecutorSettings},
execution::{memory::ProgramMemory, ExecState, ExecutorSettings},
parsing::ast::types::{Node, NonCodeValue, Program},
walk::Node as WalkNode,
};
use super::ProgramMemory;
lazy_static::lazy_static! {
/// A static mutable lock for updating the last successful execution state for the cache.
static ref OLD_AST: Arc<RwLock<Option<OldAstState>>> = Default::default();

View File

@ -10,16 +10,17 @@ use crate::{
annotations,
cad_op::{OpArg, Operation},
memory,
memory::ProgramMemory,
state::ModuleState,
BodyType, EnvironmentRef, ExecState, ExecutorContext, KclValue, MemoryFunction, Metadata, ProgramMemory,
TagEngineInfo, TagIdentifier,
BodyType, EnvironmentRef, ExecState, ExecutorContext, KclValue, MemoryFunction, Metadata, TagEngineInfo,
TagIdentifier,
},
modules::{ModuleId, ModulePath, ModuleRepr},
parsing::ast::types::{
ArrayExpression, ArrayRangeExpression, BinaryExpression, BinaryOperator, BinaryPart, BodyItem, CallExpression,
CallExpressionKw, Expr, FunctionExpression, IfExpression, ImportPath, ImportSelector, ItemVisibility,
LiteralIdentifier, LiteralValue, MemberExpression, MemberObject, Node, NodeRef, NonCodeValue, ObjectExpression,
PipeExpression, Program, TagDeclarator, UnaryExpression, UnaryOperator,
LiteralIdentifier, LiteralValue, MemberExpression, MemberObject, Node, NodeRef, NonCodeNode, NonCodeValue,
ObjectExpression, PipeExpression, Program, TagDeclarator, UnaryExpression, UnaryOperator,
},
source_range::SourceRange,
std::{
@ -110,7 +111,10 @@ impl ExecutorContext {
}
let source_range = SourceRange::from(import_stmt);
let module_id = self.open_module(&import_stmt.path, exec_state, source_range).await?;
let meta_nodes = program.non_code_meta.get(i);
let module_id = self
.open_module(&import_stmt.path, meta_nodes, exec_state, source_range)
.await?;
match &import_stmt.selector {
ImportSelector::List { items } => {
@ -205,13 +209,7 @@ impl ExecutorContext {
let source_range = SourceRange::from(&variable_declaration.declaration.init);
let metadata = Metadata { source_range };
let _meta_nodes = if i == 0 {
&program.non_code_meta.start_nodes
} else if let Some(meta) = program.non_code_meta.non_code_nodes.get(&(i - 1)) {
meta
} else {
&Vec::new()
};
let _meta_nodes = program.non_code_meta.get(i);
let memory_item = self
.execute_expr(
@ -281,6 +279,7 @@ impl ExecutorContext {
async fn open_module(
&self,
path: &ImportPath,
non_code_meta: &[Node<NonCodeNode>],
exec_state: &mut ExecState,
source_range: SourceRange,
) -> Result<ModuleId, KclError> {
@ -307,9 +306,9 @@ impl ExecutorContext {
}
let id = exec_state.next_module_id();
let geom =
super::import::import_foreign(resolved_path.expect_path(), None, exec_state, self, source_range)
.await?;
let path = resolved_path.expect_path();
let format = super::import::format_from_annotations(non_code_meta, path, source_range)?;
let geom = super::import::import_foreign(path, format, exec_state, self, source_range).await?;
exec_state.add_module(id, resolved_path, ModuleRepr::Foreign(geom));
Ok(id)
}

View File

@ -2,7 +2,7 @@ use std::{ffi::OsStr, path::Path, str::FromStr};
use anyhow::Result;
use kcmc::{
coord::{Axis, AxisDirectionPair, Direction, System},
coord::{System, KITTYCAD},
each_cmd as mcmd,
format::InputFormat,
ok_response::OkModelingCmdResponse,
@ -15,11 +15,11 @@ use kittycad_modeling_cmds as kcmc;
use serde::{Deserialize, Serialize};
use uuid::Uuid;
use super::ExecutorContext;
use crate::{
errors::{KclError, KclErrorDetails},
execution::{ExecState, ImportedGeometry},
execution::{annotations, kcl_value::UnitLen, ExecState, ExecutorContext, ImportedGeometry},
fs::FileSystem,
parsing::ast::types::{Node, NonCodeNode},
source_range::SourceRange,
};
@ -28,16 +28,7 @@ use crate::{
// * Forward: -Y
// * Up: +Z
// * Handedness: Right
pub const ZOO_COORD_SYSTEM: System = System {
forward: AxisDirectionPair {
axis: Axis::Y,
direction: Direction::Negative,
},
up: AxisDirectionPair {
axis: Axis::Z,
direction: Direction::Positive,
},
};
pub const ZOO_COORD_SYSTEM: System = *KITTYCAD;
pub async fn import_foreign(
file_path: &Path,
@ -54,7 +45,8 @@ pub async fn import_foreign(
}));
}
let ext_format = get_import_format_from_extension(file_path.extension().ok_or_else(|| {
let ext_format =
get_import_format_from_extension(file_path.extension().and_then(OsStr::to_str).ok_or_else(|| {
KclError::Semantic(KclErrorDetails {
message: format!("No file extension found for `{}`", file_path.display()),
source_ranges: vec![source_range],
@ -162,6 +154,131 @@ pub async fn import_foreign(
})
}
pub(super) fn format_from_annotations(
non_code_meta: &[Node<NonCodeNode>],
path: &Path,
import_source_range: SourceRange,
) -> Result<Option<InputFormat>, KclError> {
let Some(props) = annotations::unnamed_properties(non_code_meta.iter().map(|n| &n.value)) else {
return Ok(None);
};
let mut result = None;
for p in props {
if p.key.name == annotations::IMPORT_FORMAT {
result = Some(
get_import_format_from_extension(annotations::expect_ident(&p.value)?).map_err(|_| {
KclError::Semantic(KclErrorDetails {
message: format!(
"Unknown format for import, expected one of: {}",
annotations::IMPORT_FORMAT_VALUES.join(", ")
),
source_ranges: vec![p.as_source_range()],
})
})?,
);
break;
}
}
let mut result = result
.or_else(|| {
path.extension()
.and_then(OsStr::to_str)
.and_then(|ext| get_import_format_from_extension(ext).ok())
})
.ok_or(KclError::Semantic(KclErrorDetails {
message: "Unknown or missing extension, and no specified format for imported file".to_owned(),
source_ranges: vec![import_source_range],
}))?;
for p in props {
match p.key.name.as_str() {
annotations::IMPORT_COORDS => {
set_coords(&mut result, annotations::expect_ident(&p.value)?, p.as_source_range())?;
}
annotations::IMPORT_LENGTH_UNIT => {
set_length_unit(&mut result, annotations::expect_ident(&p.value)?, p.as_source_range())?;
}
annotations::IMPORT_FORMAT => {}
_ => {
return Err(KclError::Semantic(KclErrorDetails {
message: format!(
"Unexpected annotation for import, expected one of: {}, {}, {}",
annotations::IMPORT_FORMAT,
annotations::IMPORT_COORDS,
annotations::IMPORT_LENGTH_UNIT
),
source_ranges: vec![p.as_source_range()],
}))
}
}
}
Ok(Some(result))
}
fn set_coords(fmt: &mut InputFormat, coords_str: &str, source_range: SourceRange) -> Result<(), KclError> {
let mut coords = None;
for (name, val) in annotations::IMPORT_COORDS_VALUES {
if coords_str == name {
coords = Some(*val);
}
}
let Some(coords) = coords else {
return Err(KclError::Semantic(KclErrorDetails {
message: format!(
"Unknown coordinate system: {coords_str}, expected one of: {}",
annotations::IMPORT_COORDS_VALUES
.iter()
.map(|(n, _)| *n)
.collect::<Vec<_>>()
.join(", ")
),
source_ranges: vec![source_range],
}));
};
match fmt {
InputFormat::Obj(opts) => opts.coords = coords,
InputFormat::Ply(opts) => opts.coords = coords,
InputFormat::Stl(opts) => opts.coords = coords,
_ => {
return Err(KclError::Semantic(KclErrorDetails {
message: format!(
"`{}` option cannot be applied to the specified format",
annotations::IMPORT_COORDS
),
source_ranges: vec![source_range],
}))
}
}
Ok(())
}
fn set_length_unit(fmt: &mut InputFormat, units_str: &str, source_range: SourceRange) -> Result<(), KclError> {
let units = UnitLen::from_str(units_str, source_range)?;
match fmt {
InputFormat::Obj(opts) => opts.units = units.into(),
InputFormat::Ply(opts) => opts.units = units.into(),
InputFormat::Stl(opts) => opts.units = units.into(),
_ => {
return Err(KclError::Semantic(KclErrorDetails {
message: format!(
"`{}` option cannot be applied to the specified format",
annotations::IMPORT_LENGTH_UNIT
),
source_ranges: vec![source_range],
}))
}
}
Ok(())
}
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
pub struct PreImportedGeometry {
id: Uuid,
@ -201,10 +318,7 @@ pub async fn send_to_engine(pre: PreImportedGeometry, ctxt: &ExecutorContext) ->
}
/// Get the source format from the extension.
fn get_import_format_from_extension(ext: &OsStr) -> Result<InputFormat> {
let ext = ext
.to_str()
.ok_or_else(|| anyhow::anyhow!("Invalid file extension: `{ext:?}`"))?;
fn get_import_format_from_extension(ext: &str) -> Result<InputFormat> {
let format = match FileImportFormat::from_str(ext) {
Ok(format) => format,
Err(_) => {
@ -291,3 +405,130 @@ fn get_name_of_format(type_: InputFormat) -> &'static str {
InputFormat::Stl(_) => "stl",
}
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn annotations() {
// no annotations
assert!(
format_from_annotations(&[], Path::new("../foo.txt"), SourceRange::default(),)
.unwrap()
.is_none()
);
// no format, no options
let text = "@()\nimport '../foo.gltf' as foo";
let parsed = crate::Program::parse_no_errs(text).unwrap().ast;
let non_code_meta = parsed.non_code_meta.get(0);
let fmt = format_from_annotations(non_code_meta, Path::new("../foo.gltf"), SourceRange::default())
.unwrap()
.unwrap();
assert_eq!(
fmt,
InputFormat::Gltf(kittycad_modeling_cmds::format::gltf::import::Options {})
);
// format, no options
let text = "@(format = gltf)\nimport '../foo.txt' as foo";
let parsed = crate::Program::parse_no_errs(text).unwrap().ast;
let non_code_meta = parsed.non_code_meta.get(0);
let fmt = format_from_annotations(non_code_meta, Path::new("../foo.txt"), SourceRange::default())
.unwrap()
.unwrap();
assert_eq!(
fmt,
InputFormat::Gltf(kittycad_modeling_cmds::format::gltf::import::Options {})
);
// format, no extension (wouldn't parse but might some day)
let fmt = format_from_annotations(non_code_meta, Path::new("../foo"), SourceRange::default())
.unwrap()
.unwrap();
assert_eq!(
fmt,
InputFormat::Gltf(kittycad_modeling_cmds::format::gltf::import::Options {})
);
// format, options
let text = "@(format = obj, coords = vulkan, lengthUnit = ft)\nimport '../foo.txt' as foo";
let parsed = crate::Program::parse_no_errs(text).unwrap().ast;
let non_code_meta = parsed.non_code_meta.get(0);
let fmt = format_from_annotations(non_code_meta, Path::new("../foo.txt"), SourceRange::default())
.unwrap()
.unwrap();
assert_eq!(
fmt,
InputFormat::Obj(kittycad_modeling_cmds::format::obj::import::Options {
coords: *kittycad_modeling_cmds::coord::VULKAN,
units: kittycad_modeling_cmds::units::UnitLength::Feet,
})
);
// no format, options
let text = "@(coords = vulkan, lengthUnit = ft)\nimport '../foo.obj' as foo";
let parsed = crate::Program::parse_no_errs(text).unwrap().ast;
let non_code_meta = parsed.non_code_meta.get(0);
let fmt = format_from_annotations(non_code_meta, Path::new("../foo.obj"), SourceRange::default())
.unwrap()
.unwrap();
assert_eq!(
fmt,
InputFormat::Obj(kittycad_modeling_cmds::format::obj::import::Options {
coords: *kittycad_modeling_cmds::coord::VULKAN,
units: kittycad_modeling_cmds::units::UnitLength::Feet,
})
);
// err - format, options, but no options for specified format
assert_annotation_error(
"@(format = gltf, lengthUnit = ft)\nimport '../foo.txt' as foo",
"../foo.txt",
"`lengthUnit` option cannot be applied",
);
// err - no format, options, but no options for specified format
assert_annotation_error(
"@(lengthUnit = ft)\nimport '../foo.gltf' as foo",
"../foo.gltf",
"lengthUnit` option cannot be applied",
);
// err - bad option
assert_annotation_error(
"@(format = obj, coords = vulkan, lengthUni = ft)\nimport '../foo.txt' as foo",
"../foo.txt",
"Unexpected annotation",
);
// err - bad format
assert_annotation_error(
"@(format = foo)\nimport '../foo.txt' as foo",
"../foo.txt",
"Unknown format for import",
);
// err - bad coord value
assert_annotation_error(
"@(format = gltf, coords = north)\nimport '../foo.txt' as foo",
"../foo.txt",
"Unknown coordinate system",
);
// err - bad unit value
assert_annotation_error(
"@(format = gltf, lengthUnit = gallons)\nimport '../foo.txt' as foo",
"../foo.txt",
"Unexpected value for length units",
);
}
#[track_caller]
fn assert_annotation_error(src: &str, path: &str, expected: &str) {
let parsed = crate::Program::parse_no_errs(src).unwrap().ast;
let non_code_meta = parsed.non_code_meta.get(0);
let err = format_from_annotations(non_code_meta, Path::new(path), SourceRange::default()).unwrap_err();
assert!(
err.message().contains(expected),
"Expected: `{expected}`, found `{}`",
err.message()
);
}
}

View File

@ -8,14 +8,15 @@ use crate::{
errors::KclErrorDetails,
exec::Sketch,
execution::{
Face, Helix, ImportedGeometry, MemoryFunction, Metadata, Plane, SketchSet, Solid, SolidSet, TagIdentifier,
ExecState, Face, Helix, ImportedGeometry, MemoryFunction, Metadata, Plane, SketchSet, Solid, SolidSet,
TagIdentifier,
},
parsing::{
ast::types::{FunctionExpression, KclNone, LiteralValue, TagDeclarator, TagNode},
token::NumericSuffix,
},
std::{args::Arg, FnAsArg},
ExecState, ExecutorContext, KclError, ModuleId, SourceRange,
ExecutorContext, KclError, ModuleId, SourceRange,
};
use super::memory::EnvironmentRef;
@ -674,6 +675,19 @@ impl From<UnitLen> for crate::UnitLength {
}
}
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,
}
}
}
#[derive(Debug, Default, Clone, Copy, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema, Eq)]
#[ts(export)]
#[serde(tag = "type")]

View File

@ -156,18 +156,14 @@ pub(crate) const RETURN_NAME: &str = "__return";
/// including other modules). Multiple interpretation runs should have fresh instances.
///
/// See module docs.
#[derive(Debug, Clone, Deserialize, Serialize, ts_rs::TS, JsonSchema)]
#[ts(export)]
#[serde(rename_all = "camelCase")]
pub struct ProgramMemory {
#[derive(Debug, Clone)]
pub(crate) struct ProgramMemory {
environments: Vec<Environment>,
/// Invariant: current_env.1.is_none()
current_env: EnvironmentRef,
/// Invariant: forall er in call_stack: er.1.is_none()
call_stack: Vec<EnvironmentRef>,
/// Statistics about the memory, should not be used for anything other than meta-info.
#[allow(dead_code)]
#[serde(skip)]
pub(crate) stats: MemoryStats,
}
@ -573,7 +569,7 @@ pub(crate) struct MemoryStats {
mod env {
use super::*;
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
#[derive(Debug, Clone, PartialEq)]
pub(super) struct Environment {
bindings: IndexMap<String, KclValue>,
// invariant: self.parent.is_none() => forall s in self.snapshots: s.parent_snapshot.is_none()
@ -603,7 +599,7 @@ mod env {
}
}
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
#[derive(Debug, Clone, PartialEq)]
struct Snapshot {
/// The version of the owning environment's parent environment corresponding to this snapshot.
parent_snapshot: Option<SnapshotRef>,

View File

@ -39,7 +39,7 @@ pub(crate) use import::{
import_foreign, send_to_engine as send_import_to_engine, PreImportedGeometry, ZOO_COORD_SYSTEM,
};
pub use kcl_value::{KclObjectFields, KclValue, UnitAngle, UnitLen};
pub use memory::{EnvironmentRef, ProgramMemory};
pub use memory::EnvironmentRef;
pub use state::{ExecState, IdGenerator, MetaSettings};
pub(crate) mod annotations;
@ -821,7 +821,7 @@ mod tests {
use pretty_assertions::assert_eq;
use super::*;
use crate::{errors::KclErrorDetails, ModuleId};
use crate::{errors::KclErrorDetails, execution::memory::ProgramMemory, ModuleId};
/// Convenience function to get a JSON value from memory and unwrap.
#[track_caller]
@ -1235,7 +1235,7 @@ fn layer = () => {
const x = 5
// The 10 layers are replicas of each other, with a transform applied to each.
let shape = layer() |> patternTransform(10, transform, %)
let shape = layer() |> patternTransform(instances = 10, transform = transform)
"#;
let result = parse_execute(ast).await;

View File

@ -8,8 +8,8 @@ use uuid::Uuid;
use crate::{
errors::{KclError, KclErrorDetails},
execution::{
annotations, kcl_value, Artifact, ArtifactCommand, ArtifactGraph, ArtifactId, ExecOutcome, ExecutorSettings,
KclValue, Operation, ProgramMemory, UnitAngle, UnitLen,
annotations, kcl_value, memory::ProgramMemory, Artifact, ArtifactCommand, ArtifactGraph, ArtifactId,
ExecOutcome, ExecutorSettings, KclValue, Operation, UnitAngle, UnitLen,
},
modules::{ModuleId, ModuleInfo, ModuleLoader, ModulePath, ModuleRepr},
parsing::ast::types::NonCodeValue,
@ -17,16 +17,14 @@ use crate::{
};
/// State for executing a program.
#[derive(Debug, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
#[derive(Debug, Clone)]
pub struct ExecState {
pub global: GlobalState,
pub mod_local: ModuleState,
pub(super) global: GlobalState,
pub(super) mod_local: ModuleState,
}
#[derive(Debug, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct GlobalState {
#[derive(Debug, Clone)]
pub(super) struct GlobalState {
/// Program variable bindings.
pub memory: ProgramMemory,
/// The stable artifact ID generator.
@ -52,9 +50,8 @@ pub struct GlobalState {
pub mod_loader: ModuleLoader,
}
#[derive(Debug, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct ModuleState {
#[derive(Debug, Clone)]
pub(super) struct ModuleState {
/// The current value of the pipe operator returned from the previous
/// expression. If we're not currently in a pipeline, this will be None.
pub pipe_value: Option<KclValue>,
@ -125,19 +122,19 @@ impl ExecState {
}
}
pub fn memory(&self) -> &ProgramMemory {
pub(crate) fn memory(&self) -> &ProgramMemory {
&self.global.memory
}
pub fn mut_memory(&mut self) -> &mut ProgramMemory {
pub(crate) fn mut_memory(&mut self) -> &mut ProgramMemory {
&mut self.global.memory
}
pub fn next_uuid(&mut self) -> Uuid {
pub(crate) fn next_uuid(&mut self) -> Uuid {
self.global.id_generator.next_uuid()
}
pub fn add_artifact(&mut self, artifact: Artifact) {
pub(crate) fn add_artifact(&mut self, artifact: Artifact) {
let id = artifact.id();
self.global.artifacts.insert(id, artifact);
}

View File

@ -98,9 +98,7 @@ pub use source_range::SourceRange;
// Rather than make executor public and make lots of it pub(crate), just re-export into a new module.
// Ideally we wouldn't export these things at all, they should only be used for testing.
pub mod exec {
pub use crate::execution::{
ArtifactCommand, DefaultPlanes, IdGenerator, KclValue, PlaneType, ProgramMemory, Sketch,
};
pub use crate::execution::{ArtifactCommand, DefaultPlanes, IdGenerator, KclValue, PlaneType, Sketch};
}
#[cfg(target_arch = "wasm32")]

View File

@ -33,9 +33,8 @@ impl ModuleId {
}
}
#[derive(Debug, Clone, Deserialize, Serialize, Default)]
#[serde(rename_all = "camelCase")]
pub struct ModuleLoader {
#[derive(Debug, Clone, Default)]
pub(crate) struct ModuleLoader {
/// The stack of import statements for detecting circular module imports.
/// If this is empty, we're not currently executing an import statement.
pub import_stack: Vec<PathBuf>,

View File

@ -1271,6 +1271,19 @@ impl NonCodeMeta {
.iter()
.any(|(_, nodes)| nodes.iter().any(|node| node.contains(pos)))
}
/// Get the non-code meta immediately before the ith node in the AST that self is attached to.
///
/// Returns an empty slice if there is no non-code metadata associated with the node.
pub fn get(&self, i: usize) -> &[Node<NonCodeNode>] {
if i == 0 {
&self.start_nodes
} else if let Some(meta) = self.non_code_nodes.get(&(i - 1)) {
meta
} else {
&[]
}
}
}
// implement Deserialize manually because we to force the keys of non_code_nodes to be usize
@ -1495,7 +1508,7 @@ impl ImportStatement {
ImportPath::Kcl { filename: s } | ImportPath::Foreign { path: s } => s.split('.'),
_ => return None,
};
let name = parts.next()?;
let path = parts.next()?;
let _ext = parts.next()?;
let rest = parts.next();
@ -1503,7 +1516,7 @@ impl ImportStatement {
return None;
}
Some(name.to_owned())
path.rsplit('/').next().map(str::to_owned)
}
}

View File

@ -102,21 +102,22 @@ async fn execute(test_name: &str, render_to_png: bool) {
if render_to_png {
twenty_twenty::assert_image(format!("tests/{test_name}/rendered_model.png"), &png, 0.99);
}
assert_snapshot(test_name, "Program memory after executing", || {
insta::assert_json_snapshot!("program_memory", exec_state.memory(), {
".environments[].**[].from[]" => rounded_redaction(4),
".environments[].**[].to[]" => rounded_redaction(4),
".environments[].**[].x[]" => rounded_redaction(4),
".environments[].**[].y[]" => rounded_redaction(4),
".environments[].**[].z[]" => rounded_redaction(4),
});
});
let outcome = exec_state.to_wasm_outcome();
assert_common_snapshots(
test_name,
exec_state.mod_local.operations,
exec_state.global.artifact_commands,
exec_state.global.artifact_graph,
outcome.operations,
outcome.artifact_commands,
outcome.artifact_graph,
);
assert_snapshot(test_name, "Variables in memory after executing", || {
insta::assert_json_snapshot!("program_memory", outcome.variables, {
".**[].from[]" => rounded_redaction(4),
".**[].to[]" => rounded_redaction(4),
".**[].x[]" => rounded_redaction(4),
".**[].y[]" => rounded_redaction(4),
".**[].z[]" => rounded_redaction(4),
})
});
}
Err(e) => {
let ok_path_str = format!("tests/{test_name}/program_memory.snap");

View File

@ -358,10 +358,6 @@ impl Args {
Ok(numbers)
}
pub(crate) fn get_pattern_transform_args(&self) -> Result<(u32, FnAsArg<'_>, SolidSet, Option<bool>), KclError> {
FromArgs::from_args(self, 0)
}
pub(crate) fn get_hypotenuse_leg(&self) -> Result<(f64, f64), KclError> {
let numbers = self.get_number_array()?;

View File

@ -134,7 +134,7 @@ async fn inner_chamfer(
EdgeReference::Tag(edge_tag) => args.get_tag_engine_info(exec_state, &edge_tag)?.id,
};
let id = exec_state.global.id_generator.next_uuid();
let id = exec_state.next_uuid();
args.batch_end_cmd(
id,
ModelingCmd::from(mcmd::Solid3dFilletEdge {

View File

@ -27,9 +27,9 @@ pub async fn int(_exec_state: &mut ExecState, args: Args) -> Result<KclValue, Kc
/// startSketchOn('XZ')
/// |> circle({ center = [0, 0], radius = 2 }, %)
/// |> extrude(length = 5)
/// |> patternTransform(n, fn(id) {
/// |> patternTransform(instances = n, transform = fn(id) {
/// return { translate = [4 * id, 0, 0] }
/// }, %)
/// })
/// ```
#[stdlib {
name = "int",

View File

@ -16,7 +16,7 @@ use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use uuid::Uuid;
use super::args::Arg;
use super::{args::Arg, FnAsArg};
use crate::{
errors::{KclError, KclErrorDetails},
execution::{
@ -47,10 +47,14 @@ pub struct LinearPattern3dData {
/// Repeat some 3D solid, changing each repetition slightly.
pub async fn pattern_transform(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let (num_repetitions, transform, extr, use_original) = args.get_pattern_transform_args()?;
let solid_set = args.get_unlabeled_kw_arg("solidSet")?;
let instances: u32 = args.get_kw_arg("instances")?;
let transform: FnAsArg<'_> = args.get_kw_arg("transform")?;
let use_original: Option<bool> = args.get_kw_arg_opt("useOriginal")?;
let solids = inner_pattern_transform(
num_repetitions,
solid_set,
instances,
FunctionParam {
inner: transform.func,
fn_expr: transform.expr,
@ -58,7 +62,6 @@ pub async fn pattern_transform(exec_state: &mut ExecState, args: Args) -> Result
ctx: args.ctx.clone(),
memory: transform.memory,
},
extr,
use_original,
exec_state,
&args,
@ -69,11 +72,14 @@ pub async fn pattern_transform(exec_state: &mut ExecState, args: Args) -> Result
/// Repeat some 2D sketch, changing each repetition slightly.
pub async fn pattern_transform_2d(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let (num_repetitions, transform, sketch, use_original): (u32, super::FnAsArg<'_>, SketchSet, Option<bool>) =
super::args::FromArgs::from_args(&args, 0)?;
let sketch_set = args.get_unlabeled_kw_arg("sketchSet")?;
let instances: u32 = args.get_kw_arg("instances")?;
let transform: FnAsArg<'_> = args.get_kw_arg("transform")?;
let use_original: Option<bool> = args.get_kw_arg_opt("useOriginal")?;
let sketches = inner_pattern_transform_2d(
num_repetitions,
sketch_set,
instances,
FunctionParam {
inner: transform.func,
fn_expr: transform.expr,
@ -81,7 +87,6 @@ pub async fn pattern_transform_2d(exec_state: &mut ExecState, args: Args) -> Res
ctx: args.ctx.clone(),
memory: transform.memory,
},
sketch,
use_original,
exec_state,
&args,
@ -96,7 +101,7 @@ pub async fn pattern_transform_2d(exec_state: &mut ExecState, args: Args) -> Res
/// Transformation function could alter rotation, scale, visibility, position, etc.
///
/// The `patternTransform` call itself takes a number for how many total instances of
/// the shape should be. For example, if you use a circle with `patternTransform(4, transform)`
/// the shape should be. For example, if you use a circle with `patternTransform(instances = 4, transform = f)`
/// then there will be 4 circles: the original, and 3 created by replicating the original and
/// calling the transform function on each.
///
@ -140,7 +145,7 @@ pub async fn pattern_transform_2d(exec_state: &mut ExecState, args: Args) -> Res
/// sketch001 = startSketchOn('XZ')
/// |> circle({ center = [0, 0], radius = 2 }, %)
/// |> extrude(length = 5)
/// |> patternTransform(4, transform, %)
/// |> patternTransform(instances = 4, transform = transform)
/// ```
/// ```no_run
/// // Each instance will be shifted along the X axis,
@ -153,7 +158,7 @@ pub async fn pattern_transform_2d(exec_state: &mut ExecState, args: Args) -> Res
/// sketch001 = startSketchOn('XZ')
/// |> circle({ center = [0, 0], radius = 2 }, %)
/// |> extrude(length = 5)
/// |> patternTransform(4, transform, %)
/// |> patternTransform(instances = 4, transform = transform)
/// ```
/// ```no_run
/// fn cube(length, center) {
@ -192,7 +197,7 @@ pub async fn pattern_transform_2d(exec_state: &mut ExecState, args: Args) -> Res
///
/// myCubes =
/// cube(width, [100,0])
/// |> patternTransform(25, transform, %)
/// |> patternTransform(instances = 25, transform = transform)
/// ```
///
/// ```no_run
@ -228,7 +233,7 @@ pub async fn pattern_transform_2d(exec_state: &mut ExecState, args: Args) -> Res
/// }
/// myCubes =
/// cube(width, [100,100])
/// |> patternTransform(4, transform, %)
/// |> patternTransform(instances = 4, transform = transform)
/// ```
/// ```no_run
/// // Parameters
@ -252,7 +257,7 @@ pub async fn pattern_transform_2d(exec_state: &mut ExecState, args: Args) -> Res
/// }
/// // The vase is 100 layers tall.
/// // The 100 layers are replica of each other, with a slight transformation applied to each.
/// vase = layer() |> patternTransform(100, transform, %)
/// vase = layer() |> patternTransform(instances = 100, transform = transform)
/// ```
/// ```
/// fn transform(i) {
@ -271,33 +276,48 @@ pub async fn pattern_transform_2d(exec_state: &mut ExecState, args: Args) -> Res
/// inscribed: false
/// }, %)
/// |> extrude(length = 4)
/// |> patternTransform(3, transform, %)
/// |> patternTransform(instances = 3, transform = transform)
/// ```
#[stdlib {
name = "patternTransform",
feature_tree_operation = true,
keywords = true,
unlabeled_first = true,
args = {
solid_set = { docs = "The solid(s) to duplicate" },
instances = { docs = "The number of total instances. Must be greater than or equal to 1. This includes the original entity. For example, if instances is 2, there will be two copies -- the original, and one new copy. If instances is 1, this has no effect." },
transform = { docs = "How each replica should be transformed. The transform function takes a single parameter: an integer representing which number replication the transform is for. E.g. the first replica to be transformed will be passed the argument `1`. This simplifies your math: the transform function can rely on id `0` being the original instance passed into the `patternTransform`. See the examples." },
use_original = { docs = "If the target was sketched on an extrusion, setting this will use the original sketch as the target, not the entire joined solid. Defaults to false." },
}
}]
async fn inner_pattern_transform<'a>(
total_instances: u32,
transform_function: FunctionParam<'a>,
solid_set: SolidSet,
instances: u32,
transform: FunctionParam<'a>,
use_original: Option<bool>,
exec_state: &mut ExecState,
args: &'a Args,
) -> Result<Vec<Box<Solid>>, KclError> {
// Build the vec of transforms, one for each repetition.
let mut transform = Vec::with_capacity(usize::try_from(total_instances).unwrap());
if total_instances < 1 {
let mut transform_vec = Vec::with_capacity(usize::try_from(instances).unwrap());
if instances < 1 {
return Err(KclError::Semantic(KclErrorDetails {
source_ranges: vec![args.source_range],
message: MUST_HAVE_ONE_INSTANCE.to_owned(),
}));
}
for i in 1..total_instances {
let t = make_transform::<Box<Solid>>(i, &transform_function, args.source_range, exec_state).await?;
transform.push(t);
for i in 1..instances {
let t = make_transform::<Box<Solid>>(i, &transform, args.source_range, exec_state).await?;
transform_vec.push(t);
}
execute_pattern_transform(transform, solid_set, use_original.unwrap_or_default(), exec_state, args).await
execute_pattern_transform(
transform_vec,
solid_set,
use_original.unwrap_or_default(),
exec_state,
args,
)
.await
}
/// Just like patternTransform, but works on 2D sketches not 3D solids.
@ -310,32 +330,47 @@ async fn inner_pattern_transform<'a>(
/// // Sketch 4 circles.
/// sketch001 = startSketchOn('XZ')
/// |> circle({ center: [0, 0], radius: 2 }, %)
/// |> patternTransform2d(4, transform, %)
/// |> patternTransform2d(instances = 4, transform = transform)
/// ```
#[stdlib {
name = "patternTransform2d",
keywords = true,
unlabeled_first = true,
args = {
sketch_set = { docs = "The sketch(es) to duplicate" },
instances = { docs = "The number of total instances. Must be greater than or equal to 1. This includes the original entity. For example, if instances is 2, there will be two copies -- the original, and one new copy. If instances is 1, this has no effect." },
transform = { docs = "How each replica should be transformed. The transform function takes a single parameter: an integer representing which number replication the transform is for. E.g. the first replica to be transformed will be passed the argument `1`. This simplifies your math: the transform function can rely on id `0` being the original instance passed into the `patternTransform`. See the examples." },
use_original = { docs = "If the target was sketched on an extrusion, setting this will use the original sketch as the target, not the entire joined solid. Defaults to false." },
}
}]
async fn inner_pattern_transform_2d<'a>(
total_instances: u32,
transform_function: FunctionParam<'a>,
solid_set: SketchSet,
sketch_set: SketchSet,
instances: u32,
transform: FunctionParam<'a>,
use_original: Option<bool>,
exec_state: &mut ExecState,
args: &'a Args,
) -> Result<Vec<Box<Sketch>>, KclError> {
// Build the vec of transforms, one for each repetition.
let mut transform = Vec::with_capacity(usize::try_from(total_instances).unwrap());
if total_instances < 1 {
let mut transform_vec = Vec::with_capacity(usize::try_from(instances).unwrap());
if instances < 1 {
return Err(KclError::Semantic(KclErrorDetails {
source_ranges: vec![args.source_range],
message: MUST_HAVE_ONE_INSTANCE.to_owned(),
}));
}
for i in 1..total_instances {
let t = make_transform::<Box<Sketch>>(i, &transform_function, args.source_range, exec_state).await?;
transform.push(t);
for i in 1..instances {
let t = make_transform::<Box<Sketch>>(i, &transform, args.source_range, exec_state).await?;
transform_vec.push(t);
}
execute_pattern_transform(transform, solid_set, use_original.unwrap_or_default(), exec_state, args).await
execute_pattern_transform(
transform_vec,
sketch_set,
use_original.unwrap_or_default(),
exec_state,
args,
)
.await
}
async fn execute_pattern_transform<T: GeometryTrait>(
@ -406,7 +441,7 @@ async fn send_pattern_transform<T: GeometryTrait>(
async fn make_transform<T: GeometryTrait>(
i: u32,
transform_function: &FunctionParam<'_>,
transform: &FunctionParam<'_>,
source_range: SourceRange,
exec_state: &mut ExecState,
) -> Result<Vec<Transform>, KclError> {
@ -416,7 +451,7 @@ async fn make_transform<T: GeometryTrait>(
meta: vec![source_range.into()],
};
let transform_fn_args = vec![Arg::synthetic(repetition_num)];
let transform_fn_return = transform_function.call(exec_state, transform_fn_args).await?;
let transform_fn_return = transform.call(exec_state, transform_fn_args).await?;
// Unpack the returned transform object.
let source_ranges = vec![source_range];

View File

@ -12,7 +12,7 @@ use crate::{
/// Returns the point at the end of the given segment.
pub async fn segment_end(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let tag: TagIdentifier = args.get_data()?;
let tag: TagIdentifier = args.get_unlabeled_kw_arg("tag")?;
let result = inner_segment_end(&tag, exec_state, args.clone())?;
args.make_user_val_from_point(result)
@ -45,6 +45,11 @@ pub async fn segment_end(exec_state: &mut ExecState, args: Args) -> Result<KclVa
/// ```
#[stdlib {
name = "segEnd",
keywords = true,
unlabeled_first = true,
args = {
tag = { docs = "The line segment being queried by its tag"},
}
}]
fn inner_segment_end(tag: &TagIdentifier, exec_state: &mut ExecState, args: Args) -> Result<[f64; 2], KclError> {
let line = args.get_tag_engine_info(exec_state, tag)?;
@ -60,7 +65,7 @@ fn inner_segment_end(tag: &TagIdentifier, exec_state: &mut ExecState, args: Args
/// Returns the segment end of x.
pub async fn segment_end_x(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let tag: TagIdentifier = args.get_data()?;
let tag: TagIdentifier = args.get_unlabeled_kw_arg("tag")?;
let result = inner_segment_end_x(&tag, exec_state, args.clone())?;
Ok(args.make_user_val_from_f64(result))
@ -81,6 +86,11 @@ pub async fn segment_end_x(exec_state: &mut ExecState, args: Args) -> Result<Kcl
/// ```
#[stdlib {
name = "segEndX",
keywords = true,
unlabeled_first = true,
args = {
tag = { docs = "The line segment being queried by its tag"},
}
}]
fn inner_segment_end_x(tag: &TagIdentifier, exec_state: &mut ExecState, args: Args) -> Result<f64, KclError> {
let line = args.get_tag_engine_info(exec_state, tag)?;
@ -96,7 +106,7 @@ fn inner_segment_end_x(tag: &TagIdentifier, exec_state: &mut ExecState, args: Ar
/// Returns the segment end of y.
pub async fn segment_end_y(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let tag: TagIdentifier = args.get_data()?;
let tag: TagIdentifier = args.get_unlabeled_kw_arg("tag")?;
let result = inner_segment_end_y(&tag, exec_state, args.clone())?;
Ok(args.make_user_val_from_f64(result))
@ -118,6 +128,11 @@ pub async fn segment_end_y(exec_state: &mut ExecState, args: Args) -> Result<Kcl
/// ```
#[stdlib {
name = "segEndY",
keywords = true,
unlabeled_first = true,
args = {
tag = { docs = "The line segment being queried by its tag"},
}
}]
fn inner_segment_end_y(tag: &TagIdentifier, exec_state: &mut ExecState, args: Args) -> Result<f64, KclError> {
let line = args.get_tag_engine_info(exec_state, tag)?;
@ -133,7 +148,7 @@ fn inner_segment_end_y(tag: &TagIdentifier, exec_state: &mut ExecState, args: Ar
/// Returns the point at the start of the given segment.
pub async fn segment_start(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let tag: TagIdentifier = args.get_data()?;
let tag: TagIdentifier = args.get_unlabeled_kw_arg("tag")?;
let result = inner_segment_start(&tag, exec_state, args.clone())?;
args.make_user_val_from_point(result)
@ -166,6 +181,11 @@ pub async fn segment_start(exec_state: &mut ExecState, args: Args) -> Result<Kcl
/// ```
#[stdlib {
name = "segStart",
keywords = true,
unlabeled_first = true,
args = {
tag = { docs = "The line segment being queried by its tag"},
}
}]
fn inner_segment_start(tag: &TagIdentifier, exec_state: &mut ExecState, args: Args) -> Result<[f64; 2], KclError> {
let line = args.get_tag_engine_info(exec_state, tag)?;
@ -181,7 +201,7 @@ fn inner_segment_start(tag: &TagIdentifier, exec_state: &mut ExecState, args: Ar
/// Returns the segment start of x.
pub async fn segment_start_x(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let tag: TagIdentifier = args.get_data()?;
let tag: TagIdentifier = args.get_unlabeled_kw_arg("tag")?;
let result = inner_segment_start_x(&tag, exec_state, args.clone())?;
Ok(args.make_user_val_from_f64(result))
@ -202,6 +222,11 @@ pub async fn segment_start_x(exec_state: &mut ExecState, args: Args) -> Result<K
/// ```
#[stdlib {
name = "segStartX",
keywords = true,
unlabeled_first = true,
args = {
tag = { docs = "The line segment being queried by its tag"},
}
}]
fn inner_segment_start_x(tag: &TagIdentifier, exec_state: &mut ExecState, args: Args) -> Result<f64, KclError> {
let line = args.get_tag_engine_info(exec_state, tag)?;
@ -217,7 +242,7 @@ fn inner_segment_start_x(tag: &TagIdentifier, exec_state: &mut ExecState, args:
/// Returns the segment start of y.
pub async fn segment_start_y(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let tag: TagIdentifier = args.get_data()?;
let tag: TagIdentifier = args.get_unlabeled_kw_arg("tag")?;
let result = inner_segment_start_y(&tag, exec_state, args.clone())?;
Ok(args.make_user_val_from_f64(result))
@ -239,6 +264,11 @@ pub async fn segment_start_y(exec_state: &mut ExecState, args: Args) -> Result<K
/// ```
#[stdlib {
name = "segStartY",
keywords = true,
unlabeled_first = true,
args = {
tag = { docs = "The line segment being queried by its tag"},
}
}]
fn inner_segment_start_y(tag: &TagIdentifier, exec_state: &mut ExecState, args: Args) -> Result<f64, KclError> {
let line = args.get_tag_engine_info(exec_state, tag)?;
@ -253,7 +283,7 @@ fn inner_segment_start_y(tag: &TagIdentifier, exec_state: &mut ExecState, args:
}
/// Returns the last segment of x.
pub async fn last_segment_x(_exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let sketch = args.get_sketch()?;
let sketch = args.get_unlabeled_kw_arg("sketch")?;
let result = inner_last_segment_x(sketch, args.clone())?;
Ok(args.make_user_val_from_f64(result))
@ -275,6 +305,11 @@ pub async fn last_segment_x(_exec_state: &mut ExecState, args: Args) -> Result<K
/// ```
#[stdlib {
name = "lastSegX",
keywords = true,
unlabeled_first = true,
args = {
sketch = { docs = "The sketch whose line segment is being queried"},
}
}]
fn inner_last_segment_x(sketch: Sketch, args: Args) -> Result<f64, KclError> {
let last_line = sketch
@ -293,7 +328,7 @@ fn inner_last_segment_x(sketch: Sketch, args: Args) -> Result<f64, KclError> {
/// Returns the last segment of y.
pub async fn last_segment_y(_exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let sketch = args.get_sketch()?;
let sketch = args.get_unlabeled_kw_arg("sketch")?;
let result = inner_last_segment_y(sketch, args.clone())?;
Ok(args.make_user_val_from_f64(result))
@ -315,6 +350,11 @@ pub async fn last_segment_y(_exec_state: &mut ExecState, args: Args) -> Result<K
/// ```
#[stdlib {
name = "lastSegY",
keywords = true,
unlabeled_first = true,
args = {
sketch = { docs = "The sketch whose line segment is being queried"},
}
}]
fn inner_last_segment_y(sketch: Sketch, args: Args) -> Result<f64, KclError> {
let last_line = sketch
@ -333,7 +373,7 @@ fn inner_last_segment_y(sketch: Sketch, args: Args) -> Result<f64, KclError> {
/// Returns the length of the segment.
pub async fn segment_length(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let tag: TagIdentifier = args.get_data()?;
let tag: TagIdentifier = args.get_unlabeled_kw_arg("tag")?;
let result = inner_segment_length(&tag, exec_state, args.clone())?;
Ok(args.make_user_val_from_f64(result))
}
@ -361,6 +401,11 @@ pub async fn segment_length(exec_state: &mut ExecState, args: Args) -> Result<Kc
/// ```
#[stdlib {
name = "segLen",
keywords = true,
unlabeled_first = true,
args = {
tag = { docs = "The line segment being queried by its tag"},
}
}]
fn inner_segment_length(tag: &TagIdentifier, exec_state: &mut ExecState, args: Args) -> Result<f64, KclError> {
let line = args.get_tag_engine_info(exec_state, tag)?;
@ -378,7 +423,7 @@ fn inner_segment_length(tag: &TagIdentifier, exec_state: &mut ExecState, args: A
/// Returns the angle of the segment.
pub async fn segment_angle(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let tag: TagIdentifier = args.get_data()?;
let tag: TagIdentifier = args.get_unlabeled_kw_arg("tag")?;
let result = inner_segment_angle(&tag, exec_state, args.clone())?;
Ok(args.make_user_val_from_f64(result))
@ -401,6 +446,11 @@ pub async fn segment_angle(exec_state: &mut ExecState, args: Args) -> Result<Kcl
/// ```
#[stdlib {
name = "segAng",
keywords = true,
unlabeled_first = true,
args = {
tag = { docs = "The line segment being queried by its tag"},
}
}]
fn inner_segment_angle(tag: &TagIdentifier, exec_state: &mut ExecState, args: Args) -> Result<f64, KclError> {
let line = args.get_tag_engine_info(exec_state, tag)?;
@ -418,7 +468,7 @@ fn inner_segment_angle(tag: &TagIdentifier, exec_state: &mut ExecState, args: Ar
/// Returns the angle coming out of the end of the segment in degrees.
pub async fn tangent_to_end(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let tag: TagIdentifier = args.get_data()?;
let tag: TagIdentifier = args.get_unlabeled_kw_arg("tag")?;
let result = inner_tangent_to_end(&tag, exec_state, args.clone()).await?;
Ok(args.make_user_val_from_f64(result))
@ -496,6 +546,11 @@ pub async fn tangent_to_end(exec_state: &mut ExecState, args: Args) -> Result<Kc
/// ```
#[stdlib {
name = "tangentToEnd",
keywords = true,
unlabeled_first = true,
args = {
tag = { docs = "The line segment being queried by its tag"},
}
}]
async fn inner_tangent_to_end(tag: &TagIdentifier, exec_state: &mut ExecState, args: Args) -> Result<f64, KclError> {
let line = args.get_tag_engine_info(exec_state, tag)?;

View File

@ -218,7 +218,7 @@ async fn straight_line(
}
};
let id = exec_state.global.id_generator.next_uuid();
let id = exec_state.next_uuid();
args.batch_modeling_cmd(
id,
ModelingCmd::from(mcmd::ExtendPath {

View File

@ -5,9 +5,9 @@ use std::path::PathBuf;
use crate::{
engine::new_zoo_client,
errors::ExecErrorWithState,
execution::{ExecutorContext, ExecutorSettings},
execution::{ExecState, ExecutorContext, ExecutorSettings},
settings::types::UnitLength,
ConnectionError, ExecError, ExecState, KclErrorWithOutputs, Program,
ConnectionError, ExecError, KclErrorWithOutputs, Program,
};
#[derive(serde::Deserialize, serde::Serialize)]

View File

@ -1,11 +1,8 @@
---
source: kcl/src/simulation_tests.rs
description: Program memory after executing add_lots.kcl
description: Variables in memory after executing add_lots.kcl
---
{
"environments": [
{
"bindings": {
"HALF_TURN": {
"type": "Number",
"value": 180.0,
@ -1515,30 +1512,4 @@ description: Program memory after executing add_lots.kcl
}
]
}
},
"snapshots": [
{
"parent_snapshot": null,
"data": {
"f": {
"type": "Tombstone",
"value": null,
"__meta": []
},
"x": {
"type": "Tombstone",
"value": null,
"__meta": []
}
}
}
],
"parent": null
}
],
"currentEnv": [
0,
0
],
"callStack": []
}

View File

@ -1,11 +1,8 @@
---
source: kcl/src/simulation_tests.rs
description: Program memory after executing angled_line.kcl
description: Variables in memory after executing angled_line.kcl
---
{
"environments": [
{
"bindings": {
"HALF_TURN": {
"type": "Number",
"value": 180.0,
@ -437,14 +434,4 @@ description: Program memory after executing angled_line.kcl
}
]
}
},
"snapshots": [],
"parent": null
}
],
"currentEnv": [
0,
0
],
"callStack": []
}

View File

@ -1,11 +1,8 @@
---
source: kcl/src/simulation_tests.rs
description: Program memory after executing array_elem_pop.kcl
description: Variables in memory after executing array_elem_pop.kcl
---
{
"environments": [
{
"bindings": {
"HALF_TURN": {
"type": "Number",
"value": 180.0,
@ -159,14 +156,4 @@ description: Program memory after executing array_elem_pop.kcl
}
]
}
},
"snapshots": [],
"parent": null
}
],
"currentEnv": [
0,
0
],
"callStack": []
}

View File

@ -1,11 +1,8 @@
---
source: kcl/src/simulation_tests.rs
description: Program memory after executing array_elem_push.kcl
description: Variables in memory after executing array_elem_push.kcl
---
{
"environments": [
{
"bindings": {
"HALF_TURN": {
"type": "Number",
"value": 180.0,
@ -224,14 +221,4 @@ description: Program memory after executing array_elem_push.kcl
}
]
}
},
"snapshots": [],
"parent": null
}
],
"currentEnv": [
0,
0
],
"callStack": []
}

View File

@ -1,11 +1,8 @@
---
source: kcl/src/simulation_tests.rs
description: Program memory after executing array_range_expr.kcl
description: Variables in memory after executing array_range_expr.kcl
---
{
"environments": [
{
"bindings": {
"HALF_TURN": {
"type": "Number",
"value": 180.0,
@ -381,14 +378,4 @@ description: Program memory after executing array_range_expr.kcl
}
]
}
},
"snapshots": [],
"parent": null
}
],
"currentEnv": [
0,
0
],
"callStack": []
}

View File

@ -1,11 +1,8 @@
---
source: kcl/src/simulation_tests.rs
description: Program memory after executing array_range_negative_expr.kcl
description: Variables in memory after executing array_range_negative_expr.kcl
---
{
"environments": [
{
"bindings": {
"HALF_TURN": {
"type": "Number",
"value": 180.0,
@ -183,14 +180,4 @@ description: Program memory after executing array_range_negative_expr.kcl
}
]
}
},
"snapshots": [],
"parent": null
}
],
"currentEnv": [
0,
0
],
"callStack": []
}

View File

@ -1,11 +1,8 @@
---
source: kcl/src/simulation_tests.rs
description: Program memory after executing artifact_graph_example_code1.kcl
description: Variables in memory after executing artifact_graph_example_code1.kcl
---
{
"environments": [
{
"bindings": {
"HALF_TURN": {
"type": "Number",
"value": 180.0,
@ -1968,14 +1965,4 @@ description: Program memory after executing artifact_graph_example_code1.kcl
]
}
}
},
"snapshots": [],
"parent": null
}
],
"currentEnv": [
0,
0
],
"callStack": []
}

View File

@ -1,11 +1,8 @@
---
source: kcl/src/simulation_tests.rs
description: Program memory after executing artifact_graph_example_code_no_3d.kcl
description: Variables in memory after executing artifact_graph_example_code_no_3d.kcl
---
{
"environments": [
{
"bindings": {
"HALF_TURN": {
"type": "Number",
"value": 180.0,
@ -624,14 +621,4 @@ description: Program memory after executing artifact_graph_example_code_no_3d.kc
]
}
}
},
"snapshots": [],
"parent": null
}
],
"currentEnv": [
0,
0
],
"callStack": []
}

View File

@ -1,12 +1,8 @@
---
source: kcl/src/simulation_tests.rs
description: Program memory after executing artifact_graph_example_code_offset_planes.kcl
snapshot_kind: text
description: Variables in memory after executing artifact_graph_example_code_offset_planes.kcl
---
{
"environments": [
{
"bindings": {
"HALF_TURN": {
"type": "Number",
"value": 180.0,
@ -215,14 +211,4 @@ snapshot_kind: text
]
}
}
},
"snapshots": [],
"parent": null
}
],
"currentEnv": [
0,
0
],
"callStack": []
}

View File

@ -1,11 +1,8 @@
---
source: kcl/src/simulation_tests.rs
description: Program memory after executing artifact_graph_sketch_on_face_etc.kcl
description: Variables in memory after executing artifact_graph_sketch_on_face_etc.kcl
---
{
"environments": [
{
"bindings": {
"HALF_TURN": {
"type": "Number",
"value": 180.0,
@ -4908,14 +4905,4 @@ description: Program memory after executing artifact_graph_sketch_on_face_etc.kc
]
}
}
},
"snapshots": [],
"parent": null
}
],
"currentEnv": [
0,
0
],
"callStack": []
}

View File

@ -1,11 +1,8 @@
---
source: kcl/src/simulation_tests.rs
description: Program memory after executing basic_fillet_cube_close_opposite.kcl
description: Variables in memory after executing basic_fillet_cube_close_opposite.kcl
---
{
"environments": [
{
"bindings": {
"HALF_TURN": {
"type": "Number",
"value": 180.0,
@ -649,14 +646,4 @@ description: Program memory after executing basic_fillet_cube_close_opposite.kcl
}
]
}
},
"snapshots": [],
"parent": null
}
],
"currentEnv": [
0,
0
],
"callStack": []
}

View File

@ -1,11 +1,8 @@
---
source: kcl/src/simulation_tests.rs
description: Program memory after executing basic_fillet_cube_end.kcl
description: Variables in memory after executing basic_fillet_cube_end.kcl
---
{
"environments": [
{
"bindings": {
"HALF_TURN": {
"type": "Number",
"value": 180.0,
@ -520,14 +517,4 @@ description: Program memory after executing basic_fillet_cube_end.kcl
}
]
}
},
"snapshots": [],
"parent": null
}
],
"currentEnv": [
0,
0
],
"callStack": []
}

View File

@ -1,11 +1,8 @@
---
source: kcl/src/simulation_tests.rs
description: Program memory after executing basic_fillet_cube_next_adjacent.kcl
description: Variables in memory after executing basic_fillet_cube_next_adjacent.kcl
---
{
"environments": [
{
"bindings": {
"HALF_TURN": {
"type": "Number",
"value": 180.0,
@ -771,14 +768,4 @@ description: Program memory after executing basic_fillet_cube_next_adjacent.kcl
}
]
}
},
"snapshots": [],
"parent": null
}
],
"currentEnv": [
0,
0
],
"callStack": []
}

View File

@ -1,11 +1,8 @@
---
source: kcl/src/simulation_tests.rs
description: Program memory after executing basic_fillet_cube_previous_adjacent.kcl
description: Variables in memory after executing basic_fillet_cube_previous_adjacent.kcl
---
{
"environments": [
{
"bindings": {
"HALF_TURN": {
"type": "Number",
"value": 180.0,
@ -771,14 +768,4 @@ description: Program memory after executing basic_fillet_cube_previous_adjacent.
}
]
}
},
"snapshots": [],
"parent": null
}
],
"currentEnv": [
0,
0
],
"callStack": []
}

View File

@ -1,11 +1,8 @@
---
source: kcl/src/simulation_tests.rs
description: Program memory after executing basic_fillet_cube_start.kcl
description: Variables in memory after executing basic_fillet_cube_start.kcl
---
{
"environments": [
{
"bindings": {
"HALF_TURN": {
"type": "Number",
"value": 180.0,
@ -520,14 +517,4 @@ description: Program memory after executing basic_fillet_cube_start.kcl
}
]
}
},
"snapshots": [],
"parent": null
}
],
"currentEnv": [
0,
0
],
"callStack": []
}

View File

@ -1,11 +1,8 @@
---
source: kcl/src/simulation_tests.rs
description: Program memory after executing big_number_angle_to_match_length_x.kcl
description: Variables in memory after executing big_number_angle_to_match_length_x.kcl
---
{
"environments": [
{
"bindings": {
"HALF_TURN": {
"type": "Number",
"value": 180.0,
@ -344,14 +341,4 @@ description: Program memory after executing big_number_angle_to_match_length_x.k
}
]
}
},
"snapshots": [],
"parent": null
}
],
"currentEnv": [
0,
0
],
"callStack": []
}

View File

@ -1,11 +1,8 @@
---
source: kcl/src/simulation_tests.rs
description: Program memory after executing big_number_angle_to_match_length_y.kcl
description: Variables in memory after executing big_number_angle_to_match_length_y.kcl
---
{
"environments": [
{
"bindings": {
"HALF_TURN": {
"type": "Number",
"value": 180.0,
@ -344,14 +341,4 @@ description: Program memory after executing big_number_angle_to_match_length_y.k
}
]
}
},
"snapshots": [],
"parent": null
}
],
"currentEnv": [
0,
0
],
"callStack": []
}

View File

@ -1,11 +1,8 @@
---
source: kcl/src/simulation_tests.rs
description: Program memory after executing boolean_logical_and.kcl
description: Variables in memory after executing boolean_logical_and.kcl
---
{
"environments": [
{
"bindings": {
"HALF_TURN": {
"type": "Number",
"value": 180.0,
@ -158,14 +155,4 @@ description: Program memory after executing boolean_logical_and.kcl
}
]
}
},
"snapshots": [],
"parent": null
}
],
"currentEnv": [
0,
0
],
"callStack": []
}

View File

@ -1,11 +1,8 @@
---
source: kcl/src/simulation_tests.rs
description: Program memory after executing boolean_logical_multiple.kcl
description: Variables in memory after executing boolean_logical_multiple.kcl
---
{
"environments": [
{
"bindings": {
"HALF_TURN": {
"type": "Number",
"value": 180.0,
@ -120,14 +117,4 @@ description: Program memory after executing boolean_logical_multiple.kcl
}
]
}
},
"snapshots": [],
"parent": null
}
],
"currentEnv": [
0,
0
],
"callStack": []
}

View File

@ -1,11 +1,8 @@
---
source: kcl/src/simulation_tests.rs
description: Program memory after executing boolean_logical_or.kcl
description: Variables in memory after executing boolean_logical_or.kcl
---
{
"environments": [
{
"bindings": {
"HALF_TURN": {
"type": "Number",
"value": 180.0,
@ -158,14 +155,4 @@ description: Program memory after executing boolean_logical_or.kcl
}
]
}
},
"snapshots": [],
"parent": null
}
],
"currentEnv": [
0,
0
],
"callStack": []
}

View File

@ -1,11 +1,8 @@
---
source: kcl/src/simulation_tests.rs
description: Program memory after executing circle_three_point.kcl
description: Variables in memory after executing circle_three_point.kcl
---
{
"environments": [
{
"bindings": {
"HALF_TURN": {
"type": "Number",
"value": 180.0,
@ -163,14 +160,4 @@ description: Program memory after executing circle_three_point.kcl
]
}
}
},
"snapshots": [],
"parent": null
}
],
"currentEnv": [
0,
0
],
"callStack": []
}

View File

@ -1,12 +1,8 @@
---
source: kcl/src/simulation_tests.rs
description: Program memory after executing circular_pattern3d_a_pattern.kcl
snapshot_kind: text
description: Variables in memory after executing circular_pattern3d_a_pattern.kcl
---
{
"environments": [
{
"bindings": {
"HALF_TURN": {
"type": "Number",
"value": 180.0,
@ -63465,14 +63461,4 @@ snapshot_kind: text
}
]
}
},
"snapshots": [],
"parent": null
}
],
"currentEnv": [
0,
0
],
"callStack": []
}

View File

@ -1,11 +1,8 @@
---
source: kcl/src/simulation_tests.rs
description: Program memory after executing comparisons.kcl
description: Variables in memory after executing comparisons.kcl
---
{
"environments": [
{
"bindings": {
"HALF_TURN": {
"type": "Number",
"value": 180.0,
@ -26,14 +23,4 @@ description: Program memory after executing comparisons.kcl
"value": 0.0,
"__meta": []
}
},
"snapshots": [],
"parent": null
}
],
"currentEnv": [
0,
0
],
"callStack": []
}

View File

@ -1,11 +1,8 @@
---
source: kcl/src/simulation_tests.rs
description: Program memory after executing computed_var.kcl
description: Variables in memory after executing computed_var.kcl
---
{
"environments": [
{
"bindings": {
"HALF_TURN": {
"type": "Number",
"value": 180.0,
@ -184,14 +181,4 @@ description: Program memory after executing computed_var.kcl
}
]
}
},
"snapshots": [],
"parent": null
}
],
"currentEnv": [
0,
0
],
"callStack": []
}

View File

@ -1,11 +1,8 @@
---
source: kcl/src/simulation_tests.rs
description: Program memory after executing cube.kcl
description: Variables in memory after executing cube.kcl
---
{
"environments": [
{
"bindings": {
"HALF_TURN": {
"type": "Number",
"value": 180.0,
@ -948,30 +945,4 @@ description: Program memory after executing cube.kcl
]
}
}
},
"snapshots": [
{
"parent_snapshot": null,
"data": {
"cube": {
"type": "Tombstone",
"value": null,
"__meta": []
},
"myCube": {
"type": "Tombstone",
"value": null,
"__meta": []
}
}
}
],
"parent": null
}
],
"currentEnv": [
0,
0
],
"callStack": []
}

View File

@ -1,11 +1,8 @@
---
source: kcl/src/simulation_tests.rs
description: Program memory after executing double_map_fn.kcl
description: Variables in memory after executing double_map_fn.kcl
---
{
"environments": [
{
"bindings": {
"HALF_TURN": {
"type": "Number",
"value": 180.0,
@ -243,35 +240,4 @@ description: Program memory after executing double_map_fn.kcl
}
]
}
},
"snapshots": [
{
"parent_snapshot": null,
"data": {
"increment": {
"type": "Tombstone",
"value": null,
"__meta": []
},
"xs": {
"type": "Tombstone",
"value": null,
"__meta": []
},
"ys": {
"type": "Tombstone",
"value": null,
"__meta": []
}
}
}
],
"parent": null
}
],
"currentEnv": [
0,
0
],
"callStack": []
}

View File

@ -1,11 +1,8 @@
---
source: kcl/src/simulation_tests.rs
description: Program memory after executing fillet-and-shell.kcl
description: Variables in memory after executing fillet-and-shell.kcl
---
{
"environments": [
{
"bindings": {
"HALF_TURN": {
"type": "Number",
"value": 180.0,
@ -1569,265 +1566,4 @@ description: Program memory after executing fillet-and-shell.kcl
}
]
}
},
"snapshots": [
{
"parent_snapshot": null,
"data": {
"edge1": {
"type": "TagIdentifier",
"type": "TagIdentifier",
"value": "edge1",
"info": {
"type": "TagEngineInfo",
"id": "[uuid]",
"sketch": "[uuid]",
"path": {
"__geoMeta": {
"id": "[uuid]",
"sourceRange": [
833,
881,
0
]
},
"from": [
0.0,
0.0
],
"tag": {
"end": 880,
"start": 874,
"type": "TagDeclarator",
"value": "edge1"
},
"to": [
38.0,
0.0
],
"type": "ToPoint"
},
"surface": {
"faceId": "[uuid]",
"id": "[uuid]",
"sourceRange": [
833,
881,
0
],
"tag": {
"end": 880,
"start": 874,
"type": "TagDeclarator",
"value": "edge1"
},
"type": "extrudePlane"
}
},
"__meta": [
{
"sourceRange": [
874,
880,
0
]
}
]
},
"edge2": {
"type": "TagIdentifier",
"type": "TagIdentifier",
"value": "edge2",
"info": {
"type": "TagEngineInfo",
"id": "[uuid]",
"sketch": "[uuid]",
"path": {
"__geoMeta": {
"id": "[uuid]",
"sourceRange": [
887,
944,
0
]
},
"from": [
38.0,
0.0
],
"tag": {
"end": 943,
"start": 937,
"type": "TagDeclarator",
"value": "edge2"
},
"to": [
38.0,
73.0
],
"type": "ToPoint"
},
"surface": {
"faceId": "[uuid]",
"id": "[uuid]",
"sourceRange": [
887,
944,
0
],
"tag": {
"end": 943,
"start": 937,
"type": "TagDeclarator",
"value": "edge2"
},
"type": "extrudePlane"
}
},
"__meta": [
{
"sourceRange": [
937,
943,
0
]
}
]
},
"edge3": {
"type": "TagIdentifier",
"type": "TagIdentifier",
"value": "edge3",
"info": {
"type": "TagEngineInfo",
"id": "[uuid]",
"sketch": "[uuid]",
"path": {
"__geoMeta": {
"id": "[uuid]",
"sourceRange": [
950,
999,
0
]
},
"from": [
38.0,
73.0
],
"tag": {
"end": 998,
"start": 992,
"type": "TagDeclarator",
"value": "edge3"
},
"to": [
0.0,
73.0
],
"type": "ToPoint"
},
"surface": {
"faceId": "[uuid]",
"id": "[uuid]",
"sourceRange": [
950,
999,
0
],
"tag": {
"end": 998,
"start": 992,
"type": "TagDeclarator",
"value": "edge3"
},
"type": "extrudePlane"
}
},
"__meta": [
{
"sourceRange": [
992,
998,
0
]
}
]
},
"edge4": {
"type": "TagIdentifier",
"type": "TagIdentifier",
"value": "edge4",
"info": {
"type": "TagEngineInfo",
"id": "[uuid]",
"sketch": "[uuid]",
"path": {
"__geoMeta": {
"id": "[uuid]",
"sourceRange": [
1005,
1024,
0
]
},
"from": [
0.0,
73.0
],
"tag": {
"end": 1023,
"start": 1017,
"type": "TagDeclarator",
"value": "edge4"
},
"to": [
0.0,
0.0
],
"type": "ToPoint"
},
"surface": {
"faceId": "[uuid]",
"id": "[uuid]",
"sourceRange": [
1005,
1024,
0
],
"tag": {
"end": 1023,
"start": 1017,
"type": "TagDeclarator",
"value": "edge4"
},
"type": "extrudePlane"
}
},
"__meta": [
{
"sourceRange": [
1017,
1023,
0
]
}
]
},
"m25Screw": {
"type": "Tombstone",
"value": null,
"__meta": []
}
}
}
],
"parent": null
}
],
"currentEnv": [
0,
0
],
"callStack": []
}

View File

@ -1,11 +1,8 @@
---
source: kcl/src/simulation_tests.rs
description: Program memory after executing function_sketch.kcl
description: Variables in memory after executing function_sketch.kcl
---
{
"environments": [
{
"bindings": {
"HALF_TURN": {
"type": "Number",
"value": 180.0,
@ -626,30 +623,4 @@ description: Program memory after executing function_sketch.kcl
]
}
}
},
"snapshots": [
{
"parent_snapshot": null,
"data": {
"box": {
"type": "Tombstone",
"value": null,
"__meta": []
},
"fnBox": {
"type": "Tombstone",
"value": null,
"__meta": []
}
}
}
],
"parent": null
}
],
"currentEnv": [
0,
0
],
"callStack": []
}

View File

@ -1,11 +1,8 @@
---
source: kcl/src/simulation_tests.rs
description: Program memory after executing function_sketch_with_position.kcl
description: Variables in memory after executing function_sketch_with_position.kcl
---
{
"environments": [
{
"bindings": {
"HALF_TURN": {
"type": "Number",
"value": 180.0,
@ -612,30 +609,4 @@ description: Program memory after executing function_sketch_with_position.kcl
]
}
}
},
"snapshots": [
{
"parent_snapshot": null,
"data": {
"box": {
"type": "Tombstone",
"value": null,
"__meta": []
},
"thing": {
"type": "Tombstone",
"value": null,
"__meta": []
}
}
}
],
"parent": null
}
],
"currentEnv": [
0,
0
],
"callStack": []
}

View File

@ -1,12 +1,8 @@
---
source: kcl/src/simulation_tests.rs
description: Program memory after executing helix_ccw.kcl
snapshot_kind: text
description: Variables in memory after executing helix_ccw.kcl
---
{
"environments": [
{
"bindings": {
"HALF_TURN": {
"type": "Number",
"value": 180.0,
@ -158,14 +154,4 @@ snapshot_kind: text
]
}
}
},
"snapshots": [],
"parent": null
}
],
"currentEnv": [
0,
0
],
"callStack": []
}

View File

@ -1,12 +1,8 @@
---
source: kcl/src/simulation_tests.rs
description: Program memory after executing helix_simple.kcl
snapshot_kind: text
description: Variables in memory after executing helix_simple.kcl
---
{
"environments": [
{
"bindings": {
"HALF_TURN": {
"type": "Number",
"value": 180.0,
@ -237,14 +233,4 @@ snapshot_kind: text
]
}
}
},
"snapshots": [],
"parent": null
}
],
"currentEnv": [
0,
0
],
"callStack": []
}

View File

@ -1,12 +1,8 @@
---
source: kcl/src/simulation_tests.rs
description: Program memory after executing i_shape.kcl
snapshot_kind: text
description: Variables in memory after executing i_shape.kcl
---
{
"environments": [
{
"bindings": {
"HALF_TURN": {
"type": "Number",
"value": 180.0,
@ -1988,14 +1984,4 @@ snapshot_kind: text
}
]
}
},
"snapshots": [],
"parent": null
}
],
"currentEnv": [
0,
0
],
"callStack": []
}

View File

@ -1,11 +1,8 @@
---
source: kcl/src/simulation_tests.rs
description: Program memory after executing if_else.kcl
description: Variables in memory after executing if_else.kcl
---
{
"environments": [
{
"bindings": {
"HALF_TURN": {
"type": "Number",
"value": 180.0,
@ -65,14 +62,4 @@ description: Program memory after executing if_else.kcl
}
]
}
},
"snapshots": [],
"parent": null
}
],
"currentEnv": [
0,
0
],
"callStack": []
}

View File

@ -1,11 +1,8 @@
---
source: kcl/src/simulation_tests.rs
description: Program memory after executing import_constant.kcl
description: Variables in memory after executing import_constant.kcl
---
{
"environments": [
{
"bindings": {
"HALF_TURN": {
"type": "Number",
"value": 180.0,
@ -39,53 +36,4 @@ description: Program memory after executing import_constant.kcl
}
]
}
},
"snapshots": [],
"parent": null
},
{
"bindings": {
"HALF_TURN": {
"type": "Number",
"value": 180.0,
"__meta": []
},
"QUARTER_TURN": {
"type": "Number",
"value": 90.0,
"__meta": []
},
"THREE_QUARTER_TURN": {
"type": "Number",
"value": 270.0,
"__meta": []
},
"ZERO": {
"type": "Number",
"value": 0.0,
"__meta": []
},
"three": {
"type": "Number",
"value": 3.0,
"__meta": [
{
"sourceRange": [
15,
16,
1
]
}
]
}
},
"snapshots": [],
"parent": null
}
],
"currentEnv": [
0,
0
],
"callStack": []
}

View File

@ -1,11 +1,8 @@
---
source: kcl/src/simulation_tests.rs
description: Program memory after executing import_export.kcl
description: Variables in memory after executing import_export.kcl
---
{
"environments": [
{
"bindings": {
"HALF_TURN": {
"type": "Number",
"value": 180.0,
@ -39,92 +36,4 @@ description: Program memory after executing import_export.kcl
}
]
}
},
"snapshots": [],
"parent": null
},
{
"bindings": {
"HALF_TURN": {
"type": "Number",
"value": 180.0,
"__meta": []
},
"QUARTER_TURN": {
"type": "Number",
"value": 90.0,
"__meta": []
},
"THREE_QUARTER_TURN": {
"type": "Number",
"value": 270.0,
"__meta": []
},
"ZERO": {
"type": "Number",
"value": 0.0,
"__meta": []
},
"three": {
"type": "Number",
"value": 3.0,
"__meta": [
{
"sourceRange": [
15,
16,
2
]
}
]
}
},
"snapshots": [],
"parent": null
},
{
"bindings": {
"HALF_TURN": {
"type": "Number",
"value": 180.0,
"__meta": []
},
"QUARTER_TURN": {
"type": "Number",
"value": 90.0,
"__meta": []
},
"THREE_QUARTER_TURN": {
"type": "Number",
"value": 270.0,
"__meta": []
},
"ZERO": {
"type": "Number",
"value": 0.0,
"__meta": []
},
"three": {
"type": "Number",
"value": 3.0,
"__meta": [
{
"sourceRange": [
15,
16,
2
]
}
]
}
},
"snapshots": [],
"parent": null
}
],
"currentEnv": [
0,
0
],
"callStack": []
}

View File

@ -1,11 +1,8 @@
---
source: kcl/src/simulation_tests.rs
description: Program memory after executing import_foreign.kcl
description: Variables in memory after executing import_foreign.kcl
---
{
"environments": [
{
"bindings": {
"HALF_TURN": {
"type": "Number",
"value": 180.0,
@ -55,14 +52,4 @@ description: Program memory after executing import_foreign.kcl
}
]
}
},
"snapshots": [],
"parent": null
}
],
"currentEnv": [
0,
0
],
"callStack": []
}

View File

@ -1,11 +1,8 @@
---
source: kcl/src/simulation_tests.rs
description: Program memory after executing import_function_not_sketch.kcl
description: Variables in memory after executing import_function_not_sketch.kcl
---
{
"environments": [
{
"bindings": {
"HALF_TURN": {
"type": "Number",
"value": 180.0,
@ -140,453 +137,4 @@ description: Program memory after executing import_function_not_sketch.kcl
}
]
}
},
"snapshots": [
{
"parent_snapshot": null,
"data": {
"one": {
"type": "Tombstone",
"value": null,
"__meta": []
}
}
}
],
"parent": null
},
{
"bindings": {
"HALF_TURN": {
"type": "Number",
"value": 180.0,
"__meta": []
},
"QUARTER_TURN": {
"type": "Number",
"value": 90.0,
"__meta": []
},
"THREE_QUARTER_TURN": {
"type": "Number",
"value": 270.0,
"__meta": []
},
"ZERO": {
"type": "Number",
"value": 0.0,
"__meta": []
},
"part001": {
"type": "Solid",
"value": {
"type": "Solid",
"id": "[uuid]",
"artifactId": "[uuid]",
"value": [
{
"faceId": "[uuid]",
"id": "[uuid]",
"sourceRange": [
109,
127,
1
],
"tag": null,
"type": "extrudePlane"
},
{
"faceId": "[uuid]",
"id": "[uuid]",
"sourceRange": [
133,
152,
1
],
"tag": null,
"type": "extrudePlane"
},
{
"faceId": "[uuid]",
"id": "[uuid]",
"sourceRange": [
158,
177,
1
],
"tag": null,
"type": "extrudePlane"
},
{
"faceId": "[uuid]",
"id": "[uuid]",
"sourceRange": [
183,
202,
1
],
"tag": null,
"type": "extrudePlane"
},
{
"faceId": "[uuid]",
"id": "[uuid]",
"sourceRange": [
208,
233,
1
],
"tag": null,
"type": "extrudePlane"
},
{
"faceId": "[uuid]",
"id": "[uuid]",
"sourceRange": [
239,
260,
1
],
"tag": null,
"type": "extrudePlane"
},
{
"faceId": "[uuid]",
"id": "[uuid]",
"sourceRange": [
266,
285,
1
],
"tag": null,
"type": "extrudePlane"
},
{
"faceId": "[uuid]",
"id": "[uuid]",
"sourceRange": [
291,
298,
1
],
"tag": null,
"type": "extrudePlane"
}
],
"sketch": {
"type": "Sketch",
"id": "[uuid]",
"paths": [
{
"__geoMeta": {
"id": "[uuid]",
"sourceRange": [
109,
127,
1
]
},
"from": [
4.0,
12.0
],
"tag": null,
"to": [
6.0,
12.0
],
"type": "ToPoint"
},
{
"__geoMeta": {
"id": "[uuid]",
"sourceRange": [
133,
152,
1
]
},
"from": [
6.0,
12.0
],
"tag": null,
"to": [
6.0,
6.0
],
"type": "ToPoint"
},
{
"__geoMeta": {
"id": "[uuid]",
"sourceRange": [
158,
177,
1
]
},
"from": [
6.0,
6.0
],
"tag": null,
"to": [
10.0,
0.0
],
"type": "ToPoint"
},
{
"__geoMeta": {
"id": "[uuid]",
"sourceRange": [
183,
202,
1
]
},
"from": [
10.0,
0.0
],
"tag": null,
"to": [
10.0,
-6.0
],
"type": "ToPoint"
},
{
"__geoMeta": {
"id": "[uuid]",
"sourceRange": [
208,
233,
1
]
},
"from": [
10.0,
-6.0
],
"tag": null,
"to": [
6.25,
-10.5
],
"type": "ToPoint"
},
{
"__geoMeta": {
"id": "[uuid]",
"sourceRange": [
239,
260,
1
]
},
"from": [
6.25,
-10.5
],
"tag": null,
"to": [
6.25,
-16.0
],
"type": "ToPoint"
},
{
"__geoMeta": {
"id": "[uuid]",
"sourceRange": [
266,
285,
1
]
},
"from": [
6.25,
-16.0
],
"tag": null,
"to": [
4.25,
-16.0
],
"type": "ToPoint"
},
{
"__geoMeta": {
"id": "[uuid]",
"sourceRange": [
291,
298,
1
]
},
"from": [
4.25,
-16.0
],
"tag": null,
"to": [
4.0,
12.0
],
"type": "ToPoint"
}
],
"on": {
"type": "plane",
"id": "[uuid]",
"artifactId": "[uuid]",
"value": "XY",
"origin": {
"x": 0.0,
"y": 0.0,
"z": 0.0
},
"xAxis": {
"x": 1.0,
"y": 0.0,
"z": 0.0
},
"yAxis": {
"x": 0.0,
"y": 1.0,
"z": 0.0
},
"zAxis": {
"x": 0.0,
"y": 0.0,
"z": 1.0
},
"units": {
"type": "Mm"
},
"__meta": []
},
"start": {
"from": [
4.0,
12.0
],
"to": [
4.0,
12.0
],
"tag": null,
"__geoMeta": {
"id": "[uuid]",
"sourceRange": [
77,
103,
1
]
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
"__meta": [
{
"sourceRange": [
77,
103,
1
]
}
]
},
"height": 0.0,
"startCapId": null,
"endCapId": null,
"units": {
"type": "Mm"
},
"__meta": [
{
"sourceRange": [
77,
103,
1
]
}
]
}
},
"two": {
"type": "Function",
"expression": {
"body": {
"body": [
{
"argument": {
"end": 388,
"moduleId": 1,
"raw": "5",
"start": 387,
"type": "Literal",
"type": "Literal",
"value": {
"value": 5.0,
"suffix": "None"
}
},
"end": 388,
"moduleId": 1,
"start": 380,
"type": "ReturnStatement",
"type": "ReturnStatement"
}
],
"end": 390,
"moduleId": 1,
"start": 378
},
"end": 390,
"moduleId": 1,
"params": [],
"start": 372,
"type": "FunctionExpression"
},
"memory": [
1,
1
],
"__meta": [
{
"sourceRange": [
372,
390,
1
]
}
]
}
},
"snapshots": [
{
"parent_snapshot": null,
"data": {
"two": {
"type": "Tombstone",
"value": null,
"__meta": []
}
}
}
],
"parent": null
}
],
"currentEnv": [
0,
0
],
"callStack": []
}

View File

@ -1,11 +1,8 @@
---
source: kcl/src/simulation_tests.rs
description: Program memory after executing import_glob.kcl
description: Variables in memory after executing import_glob.kcl
---
{
"environments": [
{
"bindings": {
"HALF_TURN": {
"type": "Number",
"value": 180.0,
@ -88,113 +85,4 @@ description: Program memory after executing import_glob.kcl
}
]
}
},
"snapshots": [],
"parent": null
},
{
"bindings": {
"HALF_TURN": {
"type": "Number",
"value": 180.0,
"__meta": []
},
"QUARTER_TURN": {
"type": "Number",
"value": 90.0,
"__meta": []
},
"THREE_QUARTER_TURN": {
"type": "Number",
"value": 270.0,
"__meta": []
},
"ZERO": {
"type": "Number",
"value": 0.0,
"__meta": []
},
"foo": {
"type": "Function",
"expression": {
"body": {
"body": [
{
"argument": {
"end": 47,
"moduleId": 1,
"raw": "42",
"start": 45,
"type": "Literal",
"type": "Literal",
"value": {
"value": 42.0,
"suffix": "None"
}
},
"end": 47,
"moduleId": 1,
"start": 38,
"type": "ReturnStatement",
"type": "ReturnStatement"
}
],
"end": 49,
"moduleId": 1,
"start": 34
},
"end": 49,
"moduleId": 1,
"params": [],
"start": 31,
"type": "FunctionExpression"
},
"memory": [
1,
1
],
"__meta": [
{
"sourceRange": [
31,
49,
1
]
}
]
},
"three": {
"type": "Number",
"value": 3.0,
"__meta": [
{
"sourceRange": [
15,
16,
1
]
}
]
}
},
"snapshots": [
{
"parent_snapshot": null,
"data": {
"foo": {
"type": "Tombstone",
"value": null,
"__meta": []
}
}
}
],
"parent": null
}
],
"currentEnv": [
0,
0
],
"callStack": []
}

View File

@ -1,11 +1,8 @@
---
source: kcl/src/simulation_tests.rs
description: Program memory after executing import_side_effect.kcl
description: Variables in memory after executing import_side_effect.kcl
---
{
"environments": [
{
"bindings": {
"HALF_TURN": {
"type": "Number",
"value": 180.0,
@ -75,203 +72,4 @@ description: Program memory after executing import_side_effect.kcl
}
]
}
},
"snapshots": [],
"parent": null
},
{
"bindings": {
"HALF_TURN": {
"type": "Number",
"value": 180.0,
"__meta": []
},
"QUARTER_TURN": {
"type": "Number",
"value": 90.0,
"__meta": []
},
"THREE_QUARTER_TURN": {
"type": "Number",
"value": 270.0,
"__meta": []
},
"ZERO": {
"type": "Number",
"value": 0.0,
"__meta": []
},
"foo": {
"type": "Function",
"expression": {
"body": {
"body": [
{
"argument": {
"end": 32,
"moduleId": 1,
"raw": "0",
"start": 31,
"type": "Literal",
"type": "Literal",
"value": {
"value": 0.0,
"suffix": "None"
}
},
"end": 32,
"moduleId": 1,
"start": 24,
"type": "ReturnStatement",
"type": "ReturnStatement"
}
],
"end": 34,
"moduleId": 1,
"start": 22
},
"end": 34,
"moduleId": 1,
"params": [],
"start": 16,
"type": "FunctionExpression"
},
"memory": [
1,
1
],
"__meta": [
{
"sourceRange": [
16,
34,
1
]
}
]
},
"part001": {
"type": "Sketch",
"value": {
"type": "Sketch",
"id": "[uuid]",
"paths": [
{
"__geoMeta": {
"id": "[uuid]",
"sourceRange": [
106,
149,
1
]
},
"ccw": true,
"center": [
0.0,
0.0
],
"from": [
10.0,
0.0
],
"radius": 10.0,
"tag": null,
"to": [
10.0,
0.0
],
"type": "Circle"
}
],
"on": {
"type": "plane",
"id": "[uuid]",
"artifactId": "[uuid]",
"value": "XY",
"origin": {
"x": 0.0,
"y": 0.0,
"z": 0.0
},
"xAxis": {
"x": 1.0,
"y": 0.0,
"z": 0.0
},
"yAxis": {
"x": 0.0,
"y": 1.0,
"z": 0.0
},
"zAxis": {
"x": 0.0,
"y": 0.0,
"z": 1.0
},
"units": {
"type": "Mm"
},
"__meta": []
},
"start": {
"from": [
10.0,
0.0
],
"to": [
10.0,
0.0
],
"tag": null,
"__geoMeta": {
"id": "[uuid]",
"sourceRange": [
106,
149,
1
]
}
},
"artifactId": "[uuid]",
"originalId": "[uuid]",
"units": {
"type": "Mm"
},
"__meta": [
{
"sourceRange": [
106,
149,
1
]
}
]
}
}
},
"snapshots": [
{
"parent_snapshot": null,
"data": {
"foo": {
"type": "Tombstone",
"value": null,
"__meta": []
},
"part001": {
"type": "Tombstone",
"value": null,
"__meta": []
}
}
}
],
"parent": null
}
],
"currentEnv": [
0,
0
],
"callStack": []
}

View File

@ -1,12 +1,8 @@
---
source: kcl/src/simulation_tests.rs
description: Program memory after executing import_whole.kcl
snapshot_kind: text
description: Variables in memory after executing import_whole.kcl
---
{
"environments": [
{
"bindings": {
"HALF_TURN": {
"type": "Number",
"value": 180.0,
@ -171,40 +167,4 @@ snapshot_kind: text
}
]
}
},
"snapshots": [],
"parent": null
},
{
"bindings": {
"HALF_TURN": {
"type": "Number",
"value": 180.0,
"__meta": []
},
"QUARTER_TURN": {
"type": "Number",
"value": 90.0,
"__meta": []
},
"THREE_QUARTER_TURN": {
"type": "Number",
"value": 270.0,
"__meta": []
},
"ZERO": {
"type": "Number",
"value": 0.0,
"__meta": []
}
},
"snapshots": [],
"parent": null
}
],
"currentEnv": [
0,
0
],
"callStack": []
}

View File

@ -1,11 +1,8 @@
---
source: kcl/src/simulation_tests.rs
description: Program memory after executing index_of_array.kcl
description: Variables in memory after executing index_of_array.kcl
---
{
"environments": [
{
"bindings": {
"HALF_TURN": {
"type": "Number",
"value": 180.0,
@ -118,14 +115,4 @@ description: Program memory after executing index_of_array.kcl
}
]
}
},
"snapshots": [],
"parent": null
}
],
"currentEnv": [
0,
0
],
"callStack": []
}

View File

@ -1,12 +1,8 @@
---
source: kcl/src/simulation_tests.rs
description: Program memory after executing kittycad_svg.kcl
snapshot_kind: text
description: Variables in memory after executing kittycad_svg.kcl
---
{
"environments": [
{
"bindings": {
"HALF_TURN": {
"type": "Number",
"value": 180.0,
@ -8852,14 +8848,4 @@ snapshot_kind: text
]
}
}
},
"snapshots": [],
"parent": null
}
],
"currentEnv": [
0,
0
],
"callStack": []
}

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