Compare commits
2 Commits
pierremtb/
...
jtran/fmt-
| Author | SHA1 | Date | |
|---|---|---|---|
| a74771c50d | |||
| cb330b99f0 |
40
.github/ci-cd-scripts/upload-results.sh
vendored
40
.github/ci-cd-scripts/upload-results.sh
vendored
@ -1,41 +1,13 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
if [ -z "${TAB_API_URL:-}" ] || [ -z "${TAB_API_KEY:-}" ]; then
|
BRANCH="${GITHUB_HEAD_REF:-${GITHUB_REF_NAME:-}}"
|
||||||
exit 0
|
COMMIT="${CI_COMMIT_SHA:-${GITHUB_SHA:-}}"
|
||||||
fi
|
|
||||||
|
|
||||||
project="https://github.com/KittyCAD/modeling-app"
|
curl --request POST \
|
||||||
branch="${GITHUB_HEAD_REF:-${GITHUB_REF_NAME:-}}"
|
|
||||||
commit="${CI_COMMIT_SHA:-${GITHUB_SHA:-}}"
|
|
||||||
|
|
||||||
echo "Uploading batch results"
|
|
||||||
curl --silent --request POST \
|
|
||||||
--header "X-API-Key: ${TAB_API_KEY}" \
|
--header "X-API-Key: ${TAB_API_KEY}" \
|
||||||
--form "project=${project}" \
|
--form "project=https://github.com/KittyCAD/modeling-app" \
|
||||||
--form "branch=${branch}" \
|
--form "branch=${BRANCH}" \
|
||||||
--form "commit=${commit}" \
|
--form "commit=${COMMIT}" \
|
||||||
--form "tests=@test-results/junit.xml" \
|
--form "tests=@test-results/junit.xml" \
|
||||||
--form "CI_COMMIT_SHA=${CI_COMMIT_SHA:-}" \
|
|
||||||
--form "CI_PR_NUMBER=${CI_PR_NUMBER:-}" \
|
|
||||||
--form "GITHUB_BASE_REF=${GITHUB_BASE_REF:-}" \
|
|
||||||
--form "GITHUB_EVENT_NAME=${GITHUB_EVENT_NAME:-}" \
|
|
||||||
--form "GITHUB_HEAD_REF=${GITHUB_HEAD_REF:-}" \
|
|
||||||
--form "GITHUB_REF_NAME=${GITHUB_REF_NAME:-}" \
|
|
||||||
--form "GITHUB_REF=${GITHUB_REF:-}" \
|
|
||||||
--form "GITHUB_SHA=${GITHUB_SHA:-}" \
|
|
||||||
--form "GITHUB_WORKFLOW=${GITHUB_WORKFLOW:-}" \
|
|
||||||
--form "RUNNER_ARCH=${RUNNER_ARCH:-}" \
|
|
||||||
${TAB_API_URL}/api/results/bulk
|
${TAB_API_URL}/api/results/bulk
|
||||||
|
|
||||||
echo
|
|
||||||
echo "Sharing updated report"
|
|
||||||
curl --silent --request POST \
|
|
||||||
--header "Content-Type: application/json" \
|
|
||||||
--header "X-API-Key: ${TAB_API_KEY}" \
|
|
||||||
--data "{
|
|
||||||
\"project\": \"${project}\",
|
|
||||||
\"branch\": \"${branch}\",
|
|
||||||
\"commit\": \"${commit}\"
|
|
||||||
}" \
|
|
||||||
${TAB_API_URL}/api/share
|
|
||||||
|
|||||||
68
.github/workflows/build-apps.yml
vendored
68
.github/workflows/build-apps.yml
vendored
@ -7,10 +7,11 @@ on:
|
|||||||
- main
|
- main
|
||||||
tags:
|
tags:
|
||||||
- 'v[0-9]+.[0-9]+.[0-9]+'
|
- 'v[0-9]+.[0-9]+.[0-9]+'
|
||||||
|
- 'nightly-v[0-9]+.[0-9]+.[0-9]+'
|
||||||
|
|
||||||
env:
|
env:
|
||||||
IS_RELEASE: ${{ github.ref_type == 'tag' && startsWith(github.ref_name, 'v') }}
|
IS_RELEASE: ${{ github.ref_type == 'tag' && startsWith(github.ref_name, 'v') }}
|
||||||
IS_STAGING: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }}
|
IS_NIGHTLY: ${{ github.ref_type == 'tag' && startsWith(github.ref_name, 'nightly-v') }}
|
||||||
|
|
||||||
concurrency:
|
concurrency:
|
||||||
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
|
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
|
||||||
@ -91,16 +92,12 @@ jobs:
|
|||||||
if: ${{ steps.wasm.outputs.should-build-wasm == 'true' }}
|
if: ${{ steps.wasm.outputs.should-build-wasm == 'true' }}
|
||||||
run: "npm run build:wasm"
|
run: "npm run build:wasm"
|
||||||
|
|
||||||
- name: Set staging version, product name, release notes, and icons
|
- name: Set nightly version, product name, release notes, and icons
|
||||||
if: ${{ env.IS_STAGING == 'true' }}
|
if: ${{ env.IS_NIGHTLY == 'true' }}
|
||||||
run: |
|
run: |
|
||||||
COMMIT=$(git rev-parse --short HEAD)
|
export VERSION=${GITHUB_REF_NAME#nightly-v}
|
||||||
DATE=$(date +'%-y.%-m.%-d')
|
|
||||||
# TODO: add commit count today on main
|
|
||||||
OFFSET=$(date +'%H%M')
|
|
||||||
export VERSION=$DATE-staging.$OFFSET+$COMMIT
|
|
||||||
npm run files:set-version
|
npm run files:set-version
|
||||||
npm run files:flip-to-staging
|
npm run files:flip-to-nightly
|
||||||
|
|
||||||
- name: Set release version
|
- name: Set release version
|
||||||
if: ${{ env.IS_RELEASE == 'true' }}
|
if: ${{ env.IS_RELEASE == 'true' }}
|
||||||
@ -120,7 +117,7 @@ jobs:
|
|||||||
assets/icon.png
|
assets/icon.png
|
||||||
|
|
||||||
- id: export_version
|
- id: export_version
|
||||||
run: echo "version=`cat package.json | jq -r '.version' | cut -f1 -d"+"`" >> "$GITHUB_OUTPUT"
|
run: echo "version=`cat package.json | jq -r '.version'`" >> "$GITHUB_OUTPUT"
|
||||||
|
|
||||||
- id: export_notes
|
- id: export_notes
|
||||||
run: echo "notes=`cat release-notes.md`" >> "$GITHUB_OUTPUT"
|
run: echo "notes=`cat release-notes.md`" >> "$GITHUB_OUTPUT"
|
||||||
@ -180,7 +177,7 @@ jobs:
|
|||||||
- run: npm install
|
- run: npm install
|
||||||
|
|
||||||
- name: Prepare certificate and variables (Windows only)
|
- name: Prepare certificate and variables (Windows only)
|
||||||
if: ${{ (env.IS_RELEASE == 'true' || env.IS_STAGING == 'true') && matrix.os == 'windows-2022' }}
|
if: ${{ (env.IS_RELEASE == 'true' || env.IS_NIGHTLY == 'true') && matrix.os == 'windows-2022' }}
|
||||||
run: |
|
run: |
|
||||||
echo "${{secrets.SM_CLIENT_CERT_FILE_B64 }}" | base64 --decode > /d/Certificate_pkcs12.p12
|
echo "${{secrets.SM_CLIENT_CERT_FILE_B64 }}" | base64 --decode > /d/Certificate_pkcs12.p12
|
||||||
cat /d/Certificate_pkcs12.p12
|
cat /d/Certificate_pkcs12.p12
|
||||||
@ -195,7 +192,7 @@ jobs:
|
|||||||
shell: bash
|
shell: bash
|
||||||
|
|
||||||
- name: Setup certicate with SSM KSP (Windows only)
|
- name: Setup certicate with SSM KSP (Windows only)
|
||||||
if: ${{ (env.IS_RELEASE == 'true' || env.IS_STAGING == 'true') && matrix.os == 'windows-2022' }}
|
if: ${{ (env.IS_RELEASE == 'true' || env.IS_NIGHTLY == 'true') && matrix.os == 'windows-2022' }}
|
||||||
run: |
|
run: |
|
||||||
curl -X GET https://one.digicert.com/signingmanager/api-ui/v1/releases/smtools-windows-x64.msi/download -H "x-api-key:%SM_API_KEY%" -o smtools-windows-x64.msi
|
curl -X GET https://one.digicert.com/signingmanager/api-ui/v1/releases/smtools-windows-x64.msi/download -H "x-api-key:%SM_API_KEY%" -o smtools-windows-x64.msi
|
||||||
msiexec /i smtools-windows-x64.msi /quiet /qn
|
msiexec /i smtools-windows-x64.msi /quiet /qn
|
||||||
@ -204,17 +201,22 @@ jobs:
|
|||||||
C:\Windows\System32\certutil.exe -csp "DigiCert Signing Manager KSP" -key -user
|
C:\Windows\System32\certutil.exe -csp "DigiCert Signing Manager KSP" -key -user
|
||||||
smksp_cert_sync.exe
|
smksp_cert_sync.exe
|
||||||
smctl windows certsync
|
smctl windows certsync
|
||||||
|
# This last line `smctl windows certsync` was added after windows codesign failures started happening
|
||||||
|
# with nightly-v25.4.10. It looks like `smksp_cert_sync.exe` used to do the sync to the local cert store,
|
||||||
|
# but stopped doing it overnight. This extra call that I randomly got from this azure-related doc page
|
||||||
|
# https://docs.digicert.com/en/digicert-keylocker/code-signing/sign-with-third-party-signing-tools/windows-applications/sign-azure-apps-with-signtool-using-ksp-library.html#sync-certificates--windows-only--618365
|
||||||
|
# seems to be doing that extra sync that we need for scripts/sign-win.js to work.
|
||||||
# TODO: we still need to make sign-win.js errors fail the workflow, see issue #6276
|
# TODO: we still need to make sign-win.js errors fail the workflow, see issue #6276
|
||||||
shell: cmd
|
shell: cmd
|
||||||
|
|
||||||
- name: Build the app (debug)
|
- name: Build the app (debug)
|
||||||
if: ${{ env.IS_RELEASE == 'false' && env.IS_STAGING == 'false' }}
|
if: ${{ env.IS_RELEASE == 'false' && env.IS_NIGHTLY == 'false' }}
|
||||||
# electron-builder doesn't have a concept of release vs debug,
|
# electron-builder doesn't have a concept of release vs debug,
|
||||||
# this is just not doing any codesign or release yml generation, and points to dev infra
|
# this is just not doing any codesign or release yml generation, and points to dev infra
|
||||||
run: npm run tronb:package:dev
|
run: npm run tronb:package:dev
|
||||||
|
|
||||||
- name: Build the app (release)
|
- name: Build the app (release)
|
||||||
if: ${{ env.IS_RELEASE == 'true' || env.IS_STAGING == 'true' }}
|
if: ${{ env.IS_RELEASE == 'true' || env.IS_NIGHTLY == 'true' }}
|
||||||
env:
|
env:
|
||||||
APPLE_ID: ${{ secrets.APPLE_ID }}
|
APPLE_ID: ${{ secrets.APPLE_ID }}
|
||||||
APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }}
|
APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }}
|
||||||
@ -224,7 +226,7 @@ jobs:
|
|||||||
CSC_KEY_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
|
CSC_KEY_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
|
||||||
CSC_KEYCHAIN: ${{ secrets.APPLE_SIGNING_IDENTITY }}
|
CSC_KEYCHAIN: ${{ secrets.APPLE_SIGNING_IDENTITY }}
|
||||||
WINDOWS_CERTIFICATE_THUMBPRINT: ${{ secrets.WINDOWS_CERTIFICATE_THUMBPRINT }}
|
WINDOWS_CERTIFICATE_THUMBPRINT: ${{ secrets.WINDOWS_CERTIFICATE_THUMBPRINT }}
|
||||||
run: npm run tronb:package:${{ env.IS_RELEASE == 'true' && 'prod' || 'dev' }}
|
run: npm run tronb:package:prod
|
||||||
|
|
||||||
- name: List artifacts in out/
|
- name: List artifacts in out/
|
||||||
run: ls -R out
|
run: ls -R out
|
||||||
@ -248,13 +250,13 @@ jobs:
|
|||||||
out/*-x86_64-linux.*
|
out/*-x86_64-linux.*
|
||||||
|
|
||||||
- uses: actions/upload-artifact@v4
|
- uses: actions/upload-artifact@v4
|
||||||
if: ${{ env.IS_RELEASE == 'true' || env.IS_STAGING == 'true' }}
|
if: ${{ env.IS_RELEASE == 'true' || env.IS_NIGHTLY == 'true' }}
|
||||||
with:
|
with:
|
||||||
name: out-yml-${{ matrix.platform }}
|
name: out-yml-${{ matrix.platform }}
|
||||||
path: |
|
path: |
|
||||||
out/latest*.yml
|
out/latest*.yml
|
||||||
|
|
||||||
# TODO: add the 'Build for Mac TestFlight' stage back
|
# TODO: add the 'Build for Mac TestFlight (nightly)' stage back
|
||||||
|
|
||||||
# The steps below are for updater-test builds, only on release
|
# The steps below are for updater-test builds, only on release
|
||||||
|
|
||||||
@ -304,8 +306,7 @@ jobs:
|
|||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-22.04
|
||||||
permissions:
|
permissions:
|
||||||
contents: write
|
contents: write
|
||||||
# Equivalent to IS_RELEASE || IS_STAGING (but we can't access those env vars here)
|
if: ${{ github.ref_type == 'tag' }}
|
||||||
if: ${{ github.ref_type == 'tag' || (github.event_name == 'push' && github.ref == 'refs/heads/main') }}
|
|
||||||
env:
|
env:
|
||||||
VERSION_NO_V: ${{ needs.prepare-files.outputs.version }}
|
VERSION_NO_V: ${{ needs.prepare-files.outputs.version }}
|
||||||
VERSION: ${{ format('v{0}', needs.prepare-files.outputs.version) }}
|
VERSION: ${{ format('v{0}', needs.prepare-files.outputs.version) }}
|
||||||
@ -362,8 +363,8 @@ jobs:
|
|||||||
env:
|
env:
|
||||||
NOTES: ${{ needs.prepare-files.outputs.notes }}
|
NOTES: ${{ needs.prepare-files.outputs.notes }}
|
||||||
PUB_DATE: ${{ github.event.repository.updated_at }}
|
PUB_DATE: ${{ github.event.repository.updated_at }}
|
||||||
WEBSITE_DIR: ${{ env.IS_STAGING == 'true' && 'dl.zoo.dev/releases/modeling-app/staging' || 'dl.zoo.dev/releases/modeling-app' }}
|
WEBSITE_DIR: ${{ env.IS_NIGHTLY == 'true' && 'dl.zoo.dev/releases/modeling-app/nightly' || 'dl.zoo.dev/releases/modeling-app' }}
|
||||||
URL_CODED_NAME: ${{ env.IS_STAGING == 'true' && 'Zoo%20Design%20Studio%20%28Staging%29' || 'Zoo%20Design%20Studio' }}
|
URL_CODED_NAME: ${{ env.IS_NIGHTLY == 'true' && 'Zoo%20Design%20Studio%20%28Nightly%29' || 'Zoo%20Design%20Studio' }}
|
||||||
run: |
|
run: |
|
||||||
RELEASE_DIR=https://${WEBSITE_DIR}
|
RELEASE_DIR=https://${WEBSITE_DIR}
|
||||||
jq --null-input \
|
jq --null-input \
|
||||||
@ -411,27 +412,38 @@ jobs:
|
|||||||
- name: List artifacts
|
- name: List artifacts
|
||||||
run: "ls -R out"
|
run: "ls -R out"
|
||||||
|
|
||||||
|
- name: Set more complete nightly release notes
|
||||||
|
if: ${{ env.IS_NIGHTLY == 'true' }}
|
||||||
|
run: |
|
||||||
|
# Note: preferred going this way instead of a full clone in the checkout step,
|
||||||
|
# see https://github.com/actions/checkout/issues/1471
|
||||||
|
git fetch --prune --unshallow --tags
|
||||||
|
export TAG="nightly-${VERSION}"
|
||||||
|
export PREVIOUS_TAG=$(git tag --list --sort=-committerdate "nightly-v[0-9]*" | head -n2 | tail -n1)
|
||||||
|
export NOTES=$(./scripts/get-nightly-changelog.sh)
|
||||||
|
npm run files:set-notes
|
||||||
|
|
||||||
- name: Authenticate to Google Cloud
|
- name: Authenticate to Google Cloud
|
||||||
if: ${{ env.IS_STAGING == 'true' }}
|
if: ${{ env.IS_NIGHTLY == 'true' }}
|
||||||
uses: 'google-github-actions/auth@v2.1.8'
|
uses: 'google-github-actions/auth@v2.1.8'
|
||||||
with:
|
with:
|
||||||
credentials_json: '${{ secrets.GOOGLE_CLOUD_DL_SA }}'
|
credentials_json: '${{ secrets.GOOGLE_CLOUD_DL_SA }}'
|
||||||
|
|
||||||
- name: Set up Google Cloud SDK
|
- name: Set up Google Cloud SDK
|
||||||
if: ${{ env.IS_STAGING == 'true' }}
|
if: ${{ env.IS_NIGHTLY == 'true' }}
|
||||||
uses: google-github-actions/setup-gcloud@v2.1.4
|
uses: google-github-actions/setup-gcloud@v2.1.4
|
||||||
with:
|
with:
|
||||||
project_id: ${{ env.GOOGLE_CLOUD_PROJECT_ID }}
|
project_id: ${{ env.GOOGLE_CLOUD_PROJECT_ID }}
|
||||||
|
|
||||||
- name: Upload staging files to public bucket
|
- name: Upload nightly files to public bucket
|
||||||
if: ${{ env.IS_STAGING == 'true' }}
|
if: ${{ env.IS_NIGHTLY == 'true' }}
|
||||||
uses: google-github-actions/upload-cloud-storage@v2.2.2
|
uses: google-github-actions/upload-cloud-storage@v2.2.2
|
||||||
with:
|
with:
|
||||||
path: out
|
path: out
|
||||||
glob: '*'
|
glob: '*'
|
||||||
parent: false
|
parent: false
|
||||||
destination: 'dl.kittycad.io/releases/modeling-app/staging'
|
destination: 'dl.kittycad.io/releases/modeling-app/nightly'
|
||||||
|
|
||||||
- name: Invalidate bucket cache on latest*.yml and last_download.json files
|
- name: Invalidate bucket cache on latest*.yml and last_download.json files
|
||||||
if: ${{ env.IS_STAGING == 'true' }}
|
if: ${{ env.IS_NIGHTLY == 'true' }}
|
||||||
run: npm run files:invalidate-bucket:staging
|
run: npm run files:invalidate-bucket:nightly
|
||||||
|
|||||||
2
.github/workflows/cargo-test.yml
vendored
2
.github/workflows/cargo-test.yml
vendored
@ -188,8 +188,6 @@ jobs:
|
|||||||
env:
|
env:
|
||||||
TAB_API_URL: ${{ secrets.TAB_API_URL }}
|
TAB_API_URL: ${{ secrets.TAB_API_URL }}
|
||||||
TAB_API_KEY: ${{ secrets.TAB_API_KEY }}
|
TAB_API_KEY: ${{ secrets.TAB_API_KEY }}
|
||||||
CI_COMMIT_SHA: ${{ github.event.pull_request.head.sha }}
|
|
||||||
CI_PR_NUMBER: ${{ github.event.pull_request.number }}
|
|
||||||
run-wasm-tests:
|
run-wasm-tests:
|
||||||
name: Run wasm tests
|
name: Run wasm tests
|
||||||
strategy:
|
strategy:
|
||||||
|
|||||||
39
.github/workflows/tag-nightly.yml
vendored
Normal file
39
.github/workflows/tag-nightly.yml
vendored
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
name: tag-nightly
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
on:
|
||||||
|
schedule:
|
||||||
|
- cron: '0 4 * * *'
|
||||||
|
# Daily at 04:00 AM UTC
|
||||||
|
# Will checkout the last commit from the default branch (main as of 2023-10-04)
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
tag-nightly:
|
||||||
|
runs-on: ubuntu-22.04
|
||||||
|
steps:
|
||||||
|
- uses: actions/create-github-app-token@v1
|
||||||
|
id: app-token
|
||||||
|
with:
|
||||||
|
app-id: ${{ secrets.MODELING_APP_GH_APP_ID }}
|
||||||
|
private-key: ${{ secrets.MODELING_APP_GH_APP_PRIVATE_KEY }}
|
||||||
|
owner: ${{ github.repository_owner }}
|
||||||
|
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
token: ${{ steps.app-token.outputs.token }}
|
||||||
|
|
||||||
|
- uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version-file: '.nvmrc'
|
||||||
|
|
||||||
|
- run: npm install
|
||||||
|
|
||||||
|
- name: Push tag
|
||||||
|
run: |
|
||||||
|
VERSION_NO_V=$(date +'%-y.%-m.%-d')
|
||||||
|
TAG="nightly-v$VERSION_NO_V"
|
||||||
|
git config --local user.email "github-actions[bot]@users.noreply.github.com"
|
||||||
|
git config --local user.name "github-actions[bot]"
|
||||||
|
git tag $TAG
|
||||||
|
git push origin tag $TAG
|
||||||
@ -1 +0,0 @@
|
|||||||
npm run fmt
|
|
||||||
1
.husky/pre-push
Executable file
1
.husky/pre-push
Executable file
@ -0,0 +1 @@
|
|||||||
|
npm run fmt:check
|
||||||
@ -42,6 +42,8 @@ The 3D view in Design Studio is just a video stream from our hosted geometry eng
|
|||||||
|
|
||||||
We recommend downloading the latest application binary from our [releases](https://github.com/KittyCAD/modeling-app/releases) page. If you don't see your platform or architecture supported there, please file an issue.
|
We recommend downloading the latest application binary from our [releases](https://github.com/KittyCAD/modeling-app/releases) page. If you don't see your platform or architecture supported there, please file an issue.
|
||||||
|
|
||||||
|
If you'd like to try out upcoming changes sooner, you can also download those from our [nightly releases](https://zoo.dev/modeling-app/download/nightly) page.
|
||||||
|
|
||||||
## Developing
|
## Developing
|
||||||
|
|
||||||
Finally, if you'd like to run a development build or contribute to the project, please visit our [contributor guide](CONTRIBUTING.md) to get started.
|
Finally, if you'd like to run a development build or contribute to the project, please visit our [contributor guide](CONTRIBUTING.md) to get started.
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 119 KiB After Width: | Height: | Size: 119 KiB |
|
Before Width: | Height: | Size: 259 KiB After Width: | Height: | Size: 259 KiB |
@ -1,99 +0,0 @@
|
|||||||
---
|
|
||||||
title: "Importing geometry from other CAD systems"
|
|
||||||
excerpt: "Documentation of the KCL language for the Zoo Design Studio."
|
|
||||||
layout: manual
|
|
||||||
---
|
|
||||||
|
|
||||||
`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.,
|
|
||||||
|
|
||||||
```norun
|
|
||||||
import "tests/inputs/cube.obj"
|
|
||||||
|
|
||||||
// Use `cube` just like a KCL object.
|
|
||||||
```
|
|
||||||
|
|
||||||
```kcl
|
|
||||||
import "tests/inputs/cube.sldprt" as cube
|
|
||||||
|
|
||||||
// Use `cube` just like a KCL object.
|
|
||||||
```
|
|
||||||
|
|
||||||
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 attribute. Likewise, you can also specify a coordinate system. E.g.,
|
|
||||||
|
|
||||||
```kcl
|
|
||||||
@(lengthUnit = 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 Design Studio, 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
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Performance deep‑dive for foreign‑file imports
|
|
||||||
|
|
||||||
Parallelized foreign‑file imports now let you overlap file reads, initialization,
|
|
||||||
and rendering. To maximize throughput, you need to understand the three distinct
|
|
||||||
stages—reading, initializing (background render start), and invocation (blocking)
|
|
||||||
—and structure your code to defer blocking operations until the end.
|
|
||||||
|
|
||||||
### Foreign import execution stages
|
|
||||||
|
|
||||||
1. **Import (Read / Initialization) Stage**
|
|
||||||
```kcl
|
|
||||||
import "tests/inputs/cube.step" as cube
|
|
||||||
```
|
|
||||||
- Reads the file from disk and makes its API available.
|
|
||||||
- Starts engine rendering but **does not block** your script.
|
|
||||||
- This kick‑starts the render pipeline while you keep executing other code.
|
|
||||||
|
|
||||||
2. **Invocation (Blocking) Stage**
|
|
||||||
```kcl
|
|
||||||
import "tests/inputs/cube.step" as cube
|
|
||||||
|
|
||||||
cube
|
|
||||||
|> translate(z=10) // ← blocks here only
|
|
||||||
```
|
|
||||||
- Any method call (e.g., `translate`, `scale`, `rotate`) waits for the background render to finish before applying transformations.
|
|
||||||
|
|
||||||
### Best practices
|
|
||||||
|
|
||||||
#### 1. Defer blocking calls
|
|
||||||
|
|
||||||
```kcl
|
|
||||||
import "tests/inputs/cube.step" as cube // 1) Read / Background render starts
|
|
||||||
|
|
||||||
|
|
||||||
// --- perform other operations and calculations here ---
|
|
||||||
|
|
||||||
|
|
||||||
cube
|
|
||||||
|> translate(z=10) // 2) Blocks only here
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 2. Split heavy work into separate modules
|
|
||||||
|
|
||||||
Place computationally expensive or IO‑heavy work into its own module so it can render in parallel while `main.kcl` continues.
|
|
||||||
|
|
||||||
#### Future improvements
|
|
||||||
|
|
||||||
Upcoming releases will auto‑analyse dependencies and only block when truly necessary. Until then, explicit deferral will give you the best performance.
|
|
||||||
|
|
||||||
@ -5,7 +5,7 @@ layout: manual
|
|||||||
---
|
---
|
||||||
|
|
||||||
This is a reference for KCL. If you are learning KCL, you may prefer the [guide]() which explains
|
This is a reference for KCL. If you are learning KCL, you may prefer the [guide]() which explains
|
||||||
things in a more tutorial fashion. See also our documentation of the [standard library](/docs/kcl-std).
|
things in a more tutorial fashion.
|
||||||
|
|
||||||
## Topics
|
## Topics
|
||||||
|
|
||||||
@ -14,8 +14,7 @@ things in a more tutorial fashion. See also our documentation of the [standard l
|
|||||||
* [Values and types](/docs/kcl-lang/types)
|
* [Values and types](/docs/kcl-lang/types)
|
||||||
* [Numeric types and units](/docs/kcl-lang/numeric)
|
* [Numeric types and units](/docs/kcl-lang/numeric)
|
||||||
* [Functions](/docs/kcl-lang/functions)
|
* [Functions](/docs/kcl-lang/functions)
|
||||||
* [Projects and modules](/docs/kcl-lang/modules)
|
* [Projects, modules, and imports](/docs/kcl-lang/modules)
|
||||||
* [Attributes](/docs/kcl-lang/attributes)
|
* [Attributes](/docs/kcl-lang/attributes)
|
||||||
* [Importing geometry from other CAD systems](/docs/kcl-lang/foreign-imports)
|
|
||||||
* [Settings](/docs/kcl-lang/settings)
|
* [Settings](/docs/kcl-lang/settings)
|
||||||
* [Known Issues](/docs/kcl-lang/known-issues)
|
* [Known Issues](/docs/kcl-lang/known-issues)
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
---
|
---
|
||||||
title: "Projects and modules"
|
title: "Modules"
|
||||||
excerpt: "Documentation of the KCL language for the Zoo Design Studio."
|
excerpt: "Documentation of the KCL language for the Zoo Design Studio."
|
||||||
layout: manual
|
layout: manual
|
||||||
---
|
---
|
||||||
@ -264,3 +264,102 @@ cube
|
|||||||
clone(cube)
|
clone(cube)
|
||||||
|> translate(x=20)
|
|> translate(x=20)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 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.,
|
||||||
|
|
||||||
|
```norun
|
||||||
|
import "tests/inputs/cube.obj"
|
||||||
|
|
||||||
|
// Use `cube` just like a KCL object.
|
||||||
|
```
|
||||||
|
|
||||||
|
```kcl
|
||||||
|
import "tests/inputs/cube.sldprt" as cube
|
||||||
|
|
||||||
|
// Use `cube` just like a KCL object.
|
||||||
|
```
|
||||||
|
|
||||||
|
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 attribute. Likewise, you can also specify a coordinate system. E.g.,
|
||||||
|
|
||||||
|
```kcl
|
||||||
|
@(lengthUnit = 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 Design Studio, 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
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Performance deep‑dive for foreign‑file imports
|
||||||
|
|
||||||
|
Parallelized foreign‑file imports now let you overlap file reads, initialization,
|
||||||
|
and rendering. To maximize throughput, you need to understand the three distinct
|
||||||
|
stages—reading, initializing (background render start), and invocation (blocking)
|
||||||
|
—and structure your code to defer blocking operations until the end.
|
||||||
|
|
||||||
|
### Foreign import execution stages
|
||||||
|
|
||||||
|
1. **Import (Read / Initialization) Stage**
|
||||||
|
```kcl
|
||||||
|
import "tests/inputs/cube.step" as cube
|
||||||
|
```
|
||||||
|
- Reads the file from disk and makes its API available.
|
||||||
|
- Starts engine rendering but **does not block** your script.
|
||||||
|
- This kick‑starts the render pipeline while you keep executing other code.
|
||||||
|
|
||||||
|
2. **Invocation (Blocking) Stage**
|
||||||
|
```kcl
|
||||||
|
import "tests/inputs/cube.step" as cube
|
||||||
|
|
||||||
|
cube
|
||||||
|
|> translate(z=10) // ← blocks here only
|
||||||
|
```
|
||||||
|
- Any method call (e.g., `translate`, `scale`, `rotate`) waits for the background render to finish before applying transformations.
|
||||||
|
|
||||||
|
### Best practices
|
||||||
|
|
||||||
|
#### 1. Defer blocking calls
|
||||||
|
|
||||||
|
```kcl
|
||||||
|
import "tests/inputs/cube.step" as cube // 1) Read / Background render starts
|
||||||
|
|
||||||
|
|
||||||
|
// --- perform other operations and calculations here ---
|
||||||
|
|
||||||
|
|
||||||
|
cube
|
||||||
|
|> translate(z=10) // 2) Blocks only here
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 2. Split heavy work into separate modules
|
||||||
|
|
||||||
|
Place computationally expensive or IO‑heavy work into its own module so it can render in parallel while `main.kcl` continues.
|
||||||
|
|
||||||
|
#### Future improvements
|
||||||
|
|
||||||
|
Upcoming releases will auto‑analyse dependencies and only block when truly necessary. Until then, explicit deferral will give you the best performance.
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -28,8 +28,6 @@ Any of the suffixes described above can be used meaning that values with that ty
|
|||||||
|
|
||||||
You can also use `number(Length)`, `number(Angle)`, or `number(Count)`. These types mean a number with any length, angle, or unitless (count) units, respectively (note that `number(_)` and `number(Count)` are equivalent since there is only one kind of unitless-ness).
|
You can also use `number(Length)`, `number(Angle)`, or `number(Count)`. These types mean a number with any length, angle, or unitless (count) units, respectively (note that `number(_)` and `number(Count)` are equivalent since there is only one kind of unitless-ness).
|
||||||
|
|
||||||
Using just `number` means accepting any kind of number, even where the units are unknown by KCL.
|
|
||||||
|
|
||||||
|
|
||||||
## Function calls
|
## Function calls
|
||||||
|
|
||||||
|
|||||||
@ -11,13 +11,7 @@ The value of `pi`, Archimedes’ constant (π).
|
|||||||
PI: number(_?) = 3.14159265358979323846264338327950288_?
|
PI: number(_?) = 3.14159265358979323846264338327950288_?
|
||||||
```
|
```
|
||||||
|
|
||||||
`PI` is a number and is technically a ratio, so you might expect it to have type `number(_)`.
|
|
||||||
However, `PI` is nearly always used for converting between different units - usually degrees to or
|
|
||||||
from radians. Therefore, `PI` is treated a bit specially by KCL and always has unknown units. This
|
|
||||||
means that if you use `PI`, you will need to give KCL some extra information about the units of numbers.
|
|
||||||
Usually you should use type ascription on the result of calculations, e.g., `(2 * PI): number(rad)`.
|
|
||||||
You might prefer to use `units::toRadians` or `units::toDegrees` to convert between angles with
|
|
||||||
different units.
|
|
||||||
|
|
||||||
### Examples
|
### Examples
|
||||||
|
|
||||||
|
|||||||
@ -26,7 +26,7 @@ You can provide more than one sketch to extrude, and they will all be extruded i
|
|||||||
|----------|------|-------------|----------|
|
|----------|------|-------------|----------|
|
||||||
| `sketches` | [`[Sketch]`](/docs/kcl-std/types/std-types-Sketch) | Which sketch or sketches should be extruded | Yes |
|
| `sketches` | [`[Sketch]`](/docs/kcl-std/types/std-types-Sketch) | Which sketch or sketches should be extruded | Yes |
|
||||||
| `length` | [`number`](/docs/kcl-std/types/std-types-number) | How far to extrude the given sketches | Yes |
|
| `length` | [`number`](/docs/kcl-std/types/std-types-number) | How far to extrude the given sketches | Yes |
|
||||||
| `symmetric` | [`bool`](/docs/kcl-std/types/std-types-bool) | If true, the extrusion will happen symmetrically around the sketch. Otherwise, the extrusion will happen on only one side of the sketch. | No |
|
| `symmetric` | [`bool`](/docs/kcl-std/types/std-types-bool) | If true, the extrusion will happen symmetrically around the sketch. Otherwise, the | No |
|
||||||
| `bidirectionalLength` | [`number`](/docs/kcl-std/types/std-types-number) | If specified, will also extrude in the opposite direction to 'distance' to the specified distance. If 'symmetric' is true, this value is ignored. | No |
|
| `bidirectionalLength` | [`number`](/docs/kcl-std/types/std-types-number) | If specified, will also extrude in the opposite direction to 'distance' to the specified distance. If 'symmetric' is true, this value is ignored. | No |
|
||||||
| `tagStart` | [`TagDeclarator`](/docs/kcl-lang/types#TagDeclarator) | A named tag for the face at the start of the extrusion, i.e. the original sketch | No |
|
| `tagStart` | [`TagDeclarator`](/docs/kcl-lang/types#TagDeclarator) | A named tag for the face at the start of the extrusion, i.e. the original sketch | No |
|
||||||
| `tagEnd` | [`TagDeclarator`](/docs/kcl-lang/types#TagDeclarator) | A named tag for the face at the end of the extrusion, i.e. the new face created by extruding the original sketch | No |
|
| `tagEnd` | [`TagDeclarator`](/docs/kcl-lang/types#TagDeclarator) | A named tag for the face at the end of the extrusion, i.e. the new face created by extruding the original sketch | No |
|
||||||
|
|||||||
@ -8,7 +8,7 @@ layout: manual
|
|||||||
Convert a number to centimeters from its current units.
|
Convert a number to centimeters from its current units.
|
||||||
|
|
||||||
```kcl
|
```kcl
|
||||||
units::toCentimeters(@num: number(Length)): number(cm)
|
units::toCentimeters(@num: number(cm)): number(cm)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
@ -17,7 +17,7 @@ units::toCentimeters(@num: number(Length)): number(cm)
|
|||||||
|
|
||||||
| Name | Type | Description | Required |
|
| Name | Type | Description | Required |
|
||||||
|----------|------|-------------|----------|
|
|----------|------|-------------|----------|
|
||||||
| `num` | [`number(Length)`](/docs/kcl-std/types/std-types-number) | A number. | Yes |
|
| `num` | [`number(cm)`](/docs/kcl-std/types/std-types-number) | A number. | Yes |
|
||||||
|
|
||||||
### Returns
|
### Returns
|
||||||
|
|
||||||
|
|||||||
@ -8,7 +8,7 @@ layout: manual
|
|||||||
Converts a number to degrees from its current units.
|
Converts a number to degrees from its current units.
|
||||||
|
|
||||||
```kcl
|
```kcl
|
||||||
units::toDegrees(@num: number(Angle)): number(deg)
|
units::toDegrees(@num: number(deg)): number(deg)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
@ -17,7 +17,7 @@ units::toDegrees(@num: number(Angle)): number(deg)
|
|||||||
|
|
||||||
| Name | Type | Description | Required |
|
| Name | Type | Description | Required |
|
||||||
|----------|------|-------------|----------|
|
|----------|------|-------------|----------|
|
||||||
| `num` | [`number(Angle)`](/docs/kcl-std/types/std-types-number) | A number. | Yes |
|
| `num` | [`number(deg)`](/docs/kcl-std/types/std-types-number) | A number. | Yes |
|
||||||
|
|
||||||
### Returns
|
### Returns
|
||||||
|
|
||||||
|
|||||||
@ -8,7 +8,7 @@ layout: manual
|
|||||||
Convert a number to feet from its current units.
|
Convert a number to feet from its current units.
|
||||||
|
|
||||||
```kcl
|
```kcl
|
||||||
units::toFeet(@num: number(Length)): number(ft)
|
units::toFeet(@num: number(ft)): number(ft)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
@ -17,7 +17,7 @@ units::toFeet(@num: number(Length)): number(ft)
|
|||||||
|
|
||||||
| Name | Type | Description | Required |
|
| Name | Type | Description | Required |
|
||||||
|----------|------|-------------|----------|
|
|----------|------|-------------|----------|
|
||||||
| `num` | [`number(Length)`](/docs/kcl-std/types/std-types-number) | A number. | Yes |
|
| `num` | [`number(ft)`](/docs/kcl-std/types/std-types-number) | A number. | Yes |
|
||||||
|
|
||||||
### Returns
|
### Returns
|
||||||
|
|
||||||
|
|||||||
@ -8,7 +8,7 @@ layout: manual
|
|||||||
Convert a number to inches from its current units.
|
Convert a number to inches from its current units.
|
||||||
|
|
||||||
```kcl
|
```kcl
|
||||||
units::toInches(@num: number(Length)): number(in)
|
units::toInches(@num: number(in)): number(in)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
@ -17,7 +17,7 @@ units::toInches(@num: number(Length)): number(in)
|
|||||||
|
|
||||||
| Name | Type | Description | Required |
|
| Name | Type | Description | Required |
|
||||||
|----------|------|-------------|----------|
|
|----------|------|-------------|----------|
|
||||||
| `num` | [`number(Length)`](/docs/kcl-std/types/std-types-number) | A number. | Yes |
|
| `num` | [`number(in)`](/docs/kcl-std/types/std-types-number) | A number. | Yes |
|
||||||
|
|
||||||
### Returns
|
### Returns
|
||||||
|
|
||||||
|
|||||||
@ -8,7 +8,7 @@ layout: manual
|
|||||||
Convert a number to meters from its current units.
|
Convert a number to meters from its current units.
|
||||||
|
|
||||||
```kcl
|
```kcl
|
||||||
units::toMeters(@num: number(Length)): number(m)
|
units::toMeters(@num: number(m)): number(m)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
@ -17,7 +17,7 @@ units::toMeters(@num: number(Length)): number(m)
|
|||||||
|
|
||||||
| Name | Type | Description | Required |
|
| Name | Type | Description | Required |
|
||||||
|----------|------|-------------|----------|
|
|----------|------|-------------|----------|
|
||||||
| `num` | [`number(Length)`](/docs/kcl-std/types/std-types-number) | A number. | Yes |
|
| `num` | [`number(m)`](/docs/kcl-std/types/std-types-number) | A number. | Yes |
|
||||||
|
|
||||||
### Returns
|
### Returns
|
||||||
|
|
||||||
|
|||||||
@ -8,7 +8,7 @@ layout: manual
|
|||||||
Convert a number to millimeters from its current units.
|
Convert a number to millimeters from its current units.
|
||||||
|
|
||||||
```kcl
|
```kcl
|
||||||
units::toMillimeters(@num: number(Length)): number(mm)
|
units::toMillimeters(@num: number(mm)): number(mm)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
@ -17,7 +17,7 @@ units::toMillimeters(@num: number(Length)): number(mm)
|
|||||||
|
|
||||||
| Name | Type | Description | Required |
|
| Name | Type | Description | Required |
|
||||||
|----------|------|-------------|----------|
|
|----------|------|-------------|----------|
|
||||||
| `num` | [`number(Length)`](/docs/kcl-std/types/std-types-number) | A number. | Yes |
|
| `num` | [`number(mm)`](/docs/kcl-std/types/std-types-number) | A number. | Yes |
|
||||||
|
|
||||||
### Returns
|
### Returns
|
||||||
|
|
||||||
|
|||||||
@ -8,7 +8,7 @@ layout: manual
|
|||||||
Converts a number to radians from its current units.
|
Converts a number to radians from its current units.
|
||||||
|
|
||||||
```kcl
|
```kcl
|
||||||
units::toRadians(@num: number(Angle)): number(rad)
|
units::toRadians(@num: number(rad)): number(rad)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
@ -17,7 +17,7 @@ units::toRadians(@num: number(Angle)): number(rad)
|
|||||||
|
|
||||||
| Name | Type | Description | Required |
|
| Name | Type | Description | Required |
|
||||||
|----------|------|-------------|----------|
|
|----------|------|-------------|----------|
|
||||||
| `num` | [`number(Angle)`](/docs/kcl-std/types/std-types-number) | A number. | Yes |
|
| `num` | [`number(rad)`](/docs/kcl-std/types/std-types-number) | A number. | Yes |
|
||||||
|
|
||||||
### Returns
|
### Returns
|
||||||
|
|
||||||
|
|||||||
@ -8,7 +8,7 @@ layout: manual
|
|||||||
Converts a number to yards from its current units.
|
Converts a number to yards from its current units.
|
||||||
|
|
||||||
```kcl
|
```kcl
|
||||||
units::toYards(@num: number(Length)): number(yd)
|
units::toYards(@num: number(yd)): number(yd)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
@ -17,7 +17,7 @@ units::toYards(@num: number(Length)): number(yd)
|
|||||||
|
|
||||||
| Name | Type | Description | Required |
|
| Name | Type | Description | Required |
|
||||||
|----------|------|-------------|----------|
|
|----------|------|-------------|----------|
|
||||||
| `num` | [`number(Length)`](/docs/kcl-std/types/std-types-number) | A number. | Yes |
|
| `num` | [`number(yd)`](/docs/kcl-std/types/std-types-number) | A number. | Yes |
|
||||||
|
|
||||||
### Returns
|
### Returns
|
||||||
|
|
||||||
|
|||||||
@ -11,8 +11,6 @@ Contains frequently used constants, functions for interacting with the KittyCAD
|
|||||||
|
|
||||||
The standard library is organised into modules (listed below), but most things are always available in KCL programs.
|
The standard library is organised into modules (listed below), but most things are always available in KCL programs.
|
||||||
|
|
||||||
You might also want the [KCL language reference](/docs/kcl-lang) or the [KCL guide]().
|
|
||||||
|
|
||||||
## Modules
|
## Modules
|
||||||
|
|
||||||
* [`array`](/docs/kcl-std/modules/std-array)
|
* [`array`](/docs/kcl-std/modules/std-array)
|
||||||
|
|||||||
@ -8,7 +8,7 @@ layout: manual
|
|||||||
Remove the last element from an array.
|
Remove the last element from an array.
|
||||||
|
|
||||||
```kcl
|
```kcl
|
||||||
pop(@array: [any]): [any]
|
pop(@array: [any]): any
|
||||||
```
|
```
|
||||||
|
|
||||||
Returns a new array with the last element removed.
|
Returns a new array with the last element removed.
|
||||||
@ -21,7 +21,7 @@ Returns a new array with the last element removed.
|
|||||||
|
|
||||||
### Returns
|
### Returns
|
||||||
|
|
||||||
[`[any]`](/docs/kcl-std/types/std-types-any)
|
[`any`](/docs/kcl-std/types/std-types-any) - Any KCL value.
|
||||||
|
|
||||||
|
|
||||||
### Examples
|
### Examples
|
||||||
|
|||||||
@ -11,7 +11,7 @@ Append an element to the end of an array.
|
|||||||
push(
|
push(
|
||||||
@array: [any],
|
@array: [any],
|
||||||
item: any,
|
item: any,
|
||||||
): [any]
|
): any
|
||||||
```
|
```
|
||||||
|
|
||||||
Returns a new array with the element appended.
|
Returns a new array with the element appended.
|
||||||
@ -25,7 +25,7 @@ Returns a new array with the element appended.
|
|||||||
|
|
||||||
### Returns
|
### Returns
|
||||||
|
|
||||||
[`[any]`](/docs/kcl-std/types/std-types-any)
|
[`any`](/docs/kcl-std/types/std-types-any) - Any KCL value.
|
||||||
|
|
||||||
|
|
||||||
### Examples
|
### Examples
|
||||||
|
|||||||
@ -78747,7 +78747,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"required": false,
|
"required": false,
|
||||||
"description": "If true, the extrusion will happen symmetrically around the sketch. Otherwise, the extrusion will happen on only one side of the sketch.",
|
"description": "If true, the extrusion will happen symmetrically around the sketch. Otherwise, the\n extrusion will happen on only one side of the sketch.",
|
||||||
"labelRequired": true
|
"labelRequired": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -126453,7 +126453,7 @@
|
|||||||
"type": {
|
"type": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"enum": [
|
||||||
"Tuple"
|
"MixedArray"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"value": {
|
"value": {
|
||||||
@ -128940,7 +128940,7 @@
|
|||||||
"type": {
|
"type": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"enum": [
|
||||||
"Tuple"
|
"MixedArray"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"value": {
|
"value": {
|
||||||
@ -131431,7 +131431,7 @@
|
|||||||
"type": {
|
"type": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"enum": [
|
||||||
"Tuple"
|
"MixedArray"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"value": {
|
"value": {
|
||||||
@ -203225,7 +203225,7 @@
|
|||||||
"type": {
|
"type": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"enum": [
|
||||||
"Tuple"
|
"MixedArray"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"value": {
|
"value": {
|
||||||
@ -205616,16 +205616,10 @@
|
|||||||
],
|
],
|
||||||
"returnValue": {
|
"returnValue": {
|
||||||
"name": "",
|
"name": "",
|
||||||
"type": "[KclValue]",
|
"type": "KclValue",
|
||||||
"schema": {
|
"schema": {
|
||||||
"$schema": "https://spec.openapis.org/oas/3.0/schema/2019-04-02#/definitions/Schema",
|
"$schema": "https://spec.openapis.org/oas/3.0/schema/2019-04-02#/definitions/Schema",
|
||||||
"title": "Array_of_KclValue",
|
"title": "KclValue",
|
||||||
"type": "array",
|
|
||||||
"items": {
|
|
||||||
"$ref": "#/components/schemas/KclValue"
|
|
||||||
},
|
|
||||||
"definitions": {
|
|
||||||
"KclValue": {
|
|
||||||
"description": "Any KCL value.",
|
"description": "Any KCL value.",
|
||||||
"oneOf": [
|
"oneOf": [
|
||||||
{
|
{
|
||||||
@ -205716,7 +205710,7 @@
|
|||||||
"type": {
|
"type": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"enum": [
|
||||||
"Tuple"
|
"MixedArray"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"value": {
|
"value": {
|
||||||
@ -206013,8 +206007,8 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
},
|
"definitions": {
|
||||||
"NumericType": {
|
"NumericType": {
|
||||||
"oneOf": [
|
"oneOf": [
|
||||||
{
|
{
|
||||||
@ -206423,6 +206417,396 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"KclValue": {
|
||||||
|
"description": "Any KCL value.",
|
||||||
|
"oneOf": [
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"type",
|
||||||
|
"value"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"type": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"Uuid"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"value": {
|
||||||
|
"type": "string",
|
||||||
|
"format": "uuid"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"type",
|
||||||
|
"value"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"type": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"Bool"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"value": {
|
||||||
|
"type": "boolean"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"ty",
|
||||||
|
"type",
|
||||||
|
"value"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"type": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"Number"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"value": {
|
||||||
|
"type": "number",
|
||||||
|
"format": "double"
|
||||||
|
},
|
||||||
|
"ty": {
|
||||||
|
"$ref": "#/components/schemas/NumericType"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"type",
|
||||||
|
"value"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"type": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"String"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"value": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"type",
|
||||||
|
"value"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"type": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"MixedArray"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"value": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/components/schemas/KclValue"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"type",
|
||||||
|
"value"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"type": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"HomArray"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"value": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/components/schemas/KclValue"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"type",
|
||||||
|
"value"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"type": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"Object"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"value": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": {
|
||||||
|
"$ref": "#/components/schemas/KclValue"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"type",
|
||||||
|
"value"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"type": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"TagIdentifier"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"value": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"type",
|
||||||
|
"value"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"type": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"TagDeclarator"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"value": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"digest": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "integer",
|
||||||
|
"format": "uint8",
|
||||||
|
"minimum": 0.0
|
||||||
|
},
|
||||||
|
"maxItems": 32,
|
||||||
|
"minItems": 32,
|
||||||
|
"nullable": true
|
||||||
|
},
|
||||||
|
"start": {
|
||||||
|
"type": "integer",
|
||||||
|
"format": "uint",
|
||||||
|
"minimum": 0.0
|
||||||
|
},
|
||||||
|
"end": {
|
||||||
|
"type": "integer",
|
||||||
|
"format": "uint",
|
||||||
|
"minimum": 0.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"type",
|
||||||
|
"value"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"type": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"Plane"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"value": {
|
||||||
|
"$ref": "#/components/schemas/Plane"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"type",
|
||||||
|
"value"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"type": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"Face"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"value": {
|
||||||
|
"$ref": "#/components/schemas/Face"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"type",
|
||||||
|
"value"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"type": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"Sketch"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"value": {
|
||||||
|
"$ref": "#/components/schemas/Sketch"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"type",
|
||||||
|
"value"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"type": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"Solid"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"value": {
|
||||||
|
"$ref": "#/components/schemas/Solid"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"type",
|
||||||
|
"value"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"type": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"Helix"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"value": {
|
||||||
|
"$ref": "#/components/schemas/Helix"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Data for an imported geometry.",
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"id",
|
||||||
|
"type",
|
||||||
|
"value"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"type": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"ImportedGeometry"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"id": {
|
||||||
|
"description": "The ID of the imported geometry.",
|
||||||
|
"type": "string",
|
||||||
|
"format": "uuid"
|
||||||
|
},
|
||||||
|
"value": {
|
||||||
|
"description": "The original file paths.",
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"type",
|
||||||
|
"value"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"type": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"Function"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"value": {
|
||||||
|
"$ref": "#/components/schemas/FunctionSource"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"type",
|
||||||
|
"value"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"type": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"Module"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"value": {
|
||||||
|
"$ref": "#/components/schemas/ModuleId"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"type"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"type": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"Type"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"type",
|
||||||
|
"value"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"type": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"KclNone"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"value": {
|
||||||
|
"$ref": "#/components/schemas/KclNone"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
"Plane": {
|
"Plane": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"required": [
|
"required": [
|
||||||
@ -213319,7 +213703,7 @@
|
|||||||
"type": {
|
"type": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"enum": [
|
||||||
"Tuple"
|
"MixedArray"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"value": {
|
"value": {
|
||||||
@ -215803,7 +216187,7 @@
|
|||||||
"type": {
|
"type": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"enum": [
|
||||||
"Tuple"
|
"MixedArray"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"value": {
|
"value": {
|
||||||
@ -216193,7 +216577,7 @@
|
|||||||
"type": {
|
"type": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"enum": [
|
||||||
"Tuple"
|
"MixedArray"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"value": {
|
"value": {
|
||||||
@ -218584,16 +218968,10 @@
|
|||||||
],
|
],
|
||||||
"returnValue": {
|
"returnValue": {
|
||||||
"name": "",
|
"name": "",
|
||||||
"type": "[KclValue]",
|
"type": "KclValue",
|
||||||
"schema": {
|
"schema": {
|
||||||
"$schema": "https://spec.openapis.org/oas/3.0/schema/2019-04-02#/definitions/Schema",
|
"$schema": "https://spec.openapis.org/oas/3.0/schema/2019-04-02#/definitions/Schema",
|
||||||
"title": "Array_of_KclValue",
|
"title": "KclValue",
|
||||||
"type": "array",
|
|
||||||
"items": {
|
|
||||||
"$ref": "#/components/schemas/KclValue"
|
|
||||||
},
|
|
||||||
"definitions": {
|
|
||||||
"KclValue": {
|
|
||||||
"description": "Any KCL value.",
|
"description": "Any KCL value.",
|
||||||
"oneOf": [
|
"oneOf": [
|
||||||
{
|
{
|
||||||
@ -218684,7 +219062,7 @@
|
|||||||
"type": {
|
"type": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"enum": [
|
||||||
"Tuple"
|
"MixedArray"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"value": {
|
"value": {
|
||||||
@ -218981,8 +219359,8 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
},
|
"definitions": {
|
||||||
"NumericType": {
|
"NumericType": {
|
||||||
"oneOf": [
|
"oneOf": [
|
||||||
{
|
{
|
||||||
@ -219391,6 +219769,396 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"KclValue": {
|
||||||
|
"description": "Any KCL value.",
|
||||||
|
"oneOf": [
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"type",
|
||||||
|
"value"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"type": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"Uuid"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"value": {
|
||||||
|
"type": "string",
|
||||||
|
"format": "uuid"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"type",
|
||||||
|
"value"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"type": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"Bool"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"value": {
|
||||||
|
"type": "boolean"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"ty",
|
||||||
|
"type",
|
||||||
|
"value"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"type": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"Number"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"value": {
|
||||||
|
"type": "number",
|
||||||
|
"format": "double"
|
||||||
|
},
|
||||||
|
"ty": {
|
||||||
|
"$ref": "#/components/schemas/NumericType"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"type",
|
||||||
|
"value"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"type": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"String"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"value": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"type",
|
||||||
|
"value"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"type": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"MixedArray"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"value": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/components/schemas/KclValue"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"type",
|
||||||
|
"value"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"type": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"HomArray"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"value": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/components/schemas/KclValue"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"type",
|
||||||
|
"value"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"type": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"Object"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"value": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": {
|
||||||
|
"$ref": "#/components/schemas/KclValue"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"type",
|
||||||
|
"value"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"type": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"TagIdentifier"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"value": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"type",
|
||||||
|
"value"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"type": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"TagDeclarator"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"value": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"digest": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "integer",
|
||||||
|
"format": "uint8",
|
||||||
|
"minimum": 0.0
|
||||||
|
},
|
||||||
|
"maxItems": 32,
|
||||||
|
"minItems": 32,
|
||||||
|
"nullable": true
|
||||||
|
},
|
||||||
|
"start": {
|
||||||
|
"type": "integer",
|
||||||
|
"format": "uint",
|
||||||
|
"minimum": 0.0
|
||||||
|
},
|
||||||
|
"end": {
|
||||||
|
"type": "integer",
|
||||||
|
"format": "uint",
|
||||||
|
"minimum": 0.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"type",
|
||||||
|
"value"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"type": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"Plane"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"value": {
|
||||||
|
"$ref": "#/components/schemas/Plane"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"type",
|
||||||
|
"value"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"type": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"Face"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"value": {
|
||||||
|
"$ref": "#/components/schemas/Face"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"type",
|
||||||
|
"value"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"type": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"Sketch"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"value": {
|
||||||
|
"$ref": "#/components/schemas/Sketch"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"type",
|
||||||
|
"value"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"type": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"Solid"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"value": {
|
||||||
|
"$ref": "#/components/schemas/Solid"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"type",
|
||||||
|
"value"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"type": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"Helix"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"value": {
|
||||||
|
"$ref": "#/components/schemas/Helix"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Data for an imported geometry.",
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"id",
|
||||||
|
"type",
|
||||||
|
"value"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"type": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"ImportedGeometry"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"id": {
|
||||||
|
"description": "The ID of the imported geometry.",
|
||||||
|
"type": "string",
|
||||||
|
"format": "uuid"
|
||||||
|
},
|
||||||
|
"value": {
|
||||||
|
"description": "The original file paths.",
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"type",
|
||||||
|
"value"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"type": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"Function"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"value": {
|
||||||
|
"$ref": "#/components/schemas/FunctionSource"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"type",
|
||||||
|
"value"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"type": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"Module"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"value": {
|
||||||
|
"$ref": "#/components/schemas/ModuleId"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"type"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"type": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"Type"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"type",
|
||||||
|
"value"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"type": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"KclNone"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"value": {
|
||||||
|
"$ref": "#/components/schemas/KclNone"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
"Plane": {
|
"Plane": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"required": [
|
"required": [
|
||||||
@ -221191,7 +221959,7 @@
|
|||||||
"type": {
|
"type": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"enum": [
|
||||||
"Tuple"
|
"MixedArray"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"value": {
|
"value": {
|
||||||
@ -223675,7 +224443,7 @@
|
|||||||
"type": {
|
"type": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"enum": [
|
||||||
"Tuple"
|
"MixedArray"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"value": {
|
"value": {
|
||||||
@ -224065,7 +224833,7 @@
|
|||||||
"type": {
|
"type": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"enum": [
|
||||||
"Tuple"
|
"MixedArray"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"value": {
|
"value": {
|
||||||
@ -226552,7 +227320,7 @@
|
|||||||
"type": {
|
"type": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"enum": [
|
||||||
"Tuple"
|
"MixedArray"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"value": {
|
"value": {
|
||||||
@ -229037,7 +229805,7 @@
|
|||||||
"type": {
|
"type": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"enum": [
|
||||||
"Tuple"
|
"MixedArray"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"value": {
|
"value": {
|
||||||
@ -229835,7 +230603,7 @@
|
|||||||
"type": {
|
"type": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"enum": [
|
||||||
"Tuple"
|
"MixedArray"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"value": {
|
"value": {
|
||||||
|
|||||||
@ -7,25 +7,8 @@ layout: manual
|
|||||||
|
|
||||||
An abstract plane.
|
An abstract plane.
|
||||||
|
|
||||||
A plane has a position and orientation in space defined by its origin and axes. A plane is abstract
|
A plane has a position and orientation in space defined by its origin and axes. A plane can be used
|
||||||
in the sense that it is not part of the objects being drawn. A plane can be used to sketch on.
|
to sketch on.
|
||||||
|
|
||||||
A plane can be created in several ways:
|
|
||||||
- you can use one of the default planes, e.g., `XY`.
|
|
||||||
- you can use `offsetPlane` to create a new plane offset from an existing one, e.g., `offsetPlane(XY, offset = 150)`.
|
|
||||||
- you can use negation to create a plane from an existing one which is identical but has an opposite normal
|
|
||||||
e.g., `-XY`.
|
|
||||||
- you can define an entirely custom plane, e.g.,
|
|
||||||
|
|
||||||
```js
|
|
||||||
myXY = {
|
|
||||||
origin = { x = 0, y = 0, z = 0 },
|
|
||||||
xAxis = { x = 1, y = 0, z = 0 },
|
|
||||||
yAxis = { x = 0, y = 1, z = 0 },
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Any object with appropriate `origin`, `xAxis`, and `yAxis` fields can be used as a plane.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -841,40 +841,6 @@ washer = extrude(washerSketch, length = thicknessMax)`
|
|||||||
await editor.expectEditor.toContain('@settings(defaultLengthUnit = yd)')
|
await editor.expectEditor.toContain('@settings(defaultLengthUnit = yd)')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
test('Exiting existing sketch without editing should not delete it', async ({
|
|
||||||
page,
|
|
||||||
editor,
|
|
||||||
homePage,
|
|
||||||
context,
|
|
||||||
toolbar,
|
|
||||||
scene,
|
|
||||||
cmdBar,
|
|
||||||
}) => {
|
|
||||||
await context.folderSetupFn(async (dir) => {
|
|
||||||
const testDir = path.join(dir, 'test')
|
|
||||||
await fsp.mkdir(testDir, { recursive: true })
|
|
||||||
await fsp.writeFile(
|
|
||||||
path.join(testDir, 'main.kcl'),
|
|
||||||
`s1 = startSketchOn(XY)
|
|
||||||
|> startProfile(at = [0, 25])
|
|
||||||
|> xLine(endAbsolute = -15 + 1.5)
|
|
||||||
s2 = startSketchOn(XY)
|
|
||||||
|> startProfile(at = [25, 0])
|
|
||||||
|> yLine(endAbsolute = -15 + 1.5)`,
|
|
||||||
'utf-8'
|
|
||||||
)
|
|
||||||
})
|
|
||||||
|
|
||||||
await homePage.openProject('test')
|
|
||||||
await scene.settled(cmdBar)
|
|
||||||
await toolbar.waitForFeatureTreeToBeBuilt()
|
|
||||||
await toolbar.editSketch(1)
|
|
||||||
await page.waitForTimeout(1000) // Just hang out for a second
|
|
||||||
await toolbar.exitSketch()
|
|
||||||
|
|
||||||
await editor.expectEditor.toContain('s2 = startSketchOn(XY)')
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
|
|
||||||
async function clickExportButton(page: Page) {
|
async function clickExportButton(page: Page) {
|
||||||
|
|||||||
@ -117,10 +117,10 @@
|
|||||||
"circular-deps:diff:nodejs": "npm run circular-deps:diff || node ./scripts/diff.js",
|
"circular-deps:diff:nodejs": "npm run circular-deps:diff || node ./scripts/diff.js",
|
||||||
"files:set-version": "echo \"$(jq --arg v \"$VERSION\" '.version=$v' package.json --indent 2)\" > package.json",
|
"files:set-version": "echo \"$(jq --arg v \"$VERSION\" '.version=$v' package.json --indent 2)\" > package.json",
|
||||||
"files:set-notes": "./scripts/set-files-notes.sh",
|
"files:set-notes": "./scripts/set-files-notes.sh",
|
||||||
"files:flip-to-staging": "./scripts/flip-files-to-staging.sh",
|
"files:flip-to-nightly": "./scripts/flip-files-to-nightly.sh",
|
||||||
"files:flip-to-staging:windows": "powershell -ExecutionPolicy Bypass -File ./scripts/flip-files-to-staging.ps1",
|
"files:flip-to-nightly:windows": "powershell -ExecutionPolicy Bypass -File ./scripts/flip-files-to-nightly.ps1",
|
||||||
"files:invalidate-bucket": "./scripts/invalidate-files-bucket.sh",
|
"files:invalidate-bucket": "./scripts/invalidate-files-bucket.sh",
|
||||||
"files:invalidate-bucket:staging": "./scripts/invalidate-files-bucket.sh --staging",
|
"files:invalidate-bucket:nightly": "./scripts/invalidate-files-bucket.sh --nightly",
|
||||||
"postinstall": "electron-rebuild",
|
"postinstall": "electron-rebuild",
|
||||||
"generate:machine-api": "npx openapi-typescript ./openapi/machine-api.json -o src/lib/machine-api.d.ts",
|
"generate:machine-api": "npx openapi-typescript ./openapi/machine-api.json -o src/lib/machine-api.d.ts",
|
||||||
"generate:samples-manifest": "cd public/kcl-samples && node generate-manifest.js",
|
"generate:samples-manifest": "cd public/kcl-samples && node generate-manifest.js",
|
||||||
|
|||||||
24
rust/Cargo.lock
generated
24
rust/Cargo.lock
generated
@ -1815,7 +1815,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "kcl-bumper"
|
name = "kcl-bumper"
|
||||||
version = "0.1.69"
|
version = "0.1.68"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"clap",
|
"clap",
|
||||||
@ -1826,7 +1826,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "kcl-derive-docs"
|
name = "kcl-derive-docs"
|
||||||
version = "0.1.69"
|
version = "0.1.68"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"Inflector",
|
"Inflector",
|
||||||
"anyhow",
|
"anyhow",
|
||||||
@ -1845,7 +1845,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "kcl-directory-test-macro"
|
name = "kcl-directory-test-macro"
|
||||||
version = "0.1.69"
|
version = "0.1.68"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@ -1854,7 +1854,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "kcl-language-server"
|
name = "kcl-language-server"
|
||||||
version = "0.2.69"
|
version = "0.2.68"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"clap",
|
"clap",
|
||||||
@ -1875,7 +1875,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "kcl-language-server-release"
|
name = "kcl-language-server-release"
|
||||||
version = "0.1.69"
|
version = "0.1.68"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"clap",
|
"clap",
|
||||||
@ -1895,7 +1895,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "kcl-lib"
|
name = "kcl-lib"
|
||||||
version = "0.2.69"
|
version = "0.2.68"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"approx 0.5.1",
|
"approx 0.5.1",
|
||||||
@ -1970,7 +1970,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "kcl-python-bindings"
|
name = "kcl-python-bindings"
|
||||||
version = "0.3.69"
|
version = "0.3.68"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"kcl-lib",
|
"kcl-lib",
|
||||||
@ -1985,7 +1985,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "kcl-test-server"
|
name = "kcl-test-server"
|
||||||
version = "0.1.69"
|
version = "0.1.68"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"hyper 0.14.32",
|
"hyper 0.14.32",
|
||||||
@ -1998,7 +1998,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "kcl-to-core"
|
name = "kcl-to-core"
|
||||||
version = "0.1.69"
|
version = "0.1.68"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"async-trait",
|
"async-trait",
|
||||||
@ -2012,7 +2012,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "kcl-wasm-lib"
|
name = "kcl-wasm-lib"
|
||||||
version = "0.1.69"
|
version = "0.1.68"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"bson",
|
"bson",
|
||||||
@ -2042,9 +2042,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "kittycad"
|
name = "kittycad"
|
||||||
version = "0.3.37"
|
version = "0.3.36"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b48a9698d68c791df76aa020b596c324177a614e38ff3dd67eedd04db76e222f"
|
checksum = "0a345fd2a4cb16205f32bd1aa41715045830c59d78c59927fca6580e2a651ac9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"async-trait",
|
"async-trait",
|
||||||
|
|||||||
@ -35,7 +35,7 @@ console_error_panic_hook = "0.1.7"
|
|||||||
dashmap = { version = "6.1.0" }
|
dashmap = { version = "6.1.0" }
|
||||||
http = "1"
|
http = "1"
|
||||||
indexmap = "2.9.0"
|
indexmap = "2.9.0"
|
||||||
kittycad = { version = "0.3.37", default-features = false, features = ["js", "requests"] }
|
kittycad = { version = "0.3.36", default-features = false, features = ["js", "requests"] }
|
||||||
kittycad-modeling-cmds = { version = "0.2.117", features = ["ts-rs", "websocket"] }
|
kittycad-modeling-cmds = { version = "0.2.117", features = ["ts-rs", "websocket"] }
|
||||||
lazy_static = "1.5.0"
|
lazy_static = "1.5.0"
|
||||||
miette = "7.5.0"
|
miette = "7.5.0"
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
|
|
||||||
[package]
|
[package]
|
||||||
name = "kcl-bumper"
|
name = "kcl-bumper"
|
||||||
version = "0.1.69"
|
version = "0.1.68"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
repository = "https://github.com/KittyCAD/modeling-api"
|
repository = "https://github.com/KittyCAD/modeling-api"
|
||||||
rust-version = "1.76"
|
rust-version = "1.76"
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "kcl-derive-docs"
|
name = "kcl-derive-docs"
|
||||||
description = "A tool for generating documentation from Rust derive macros"
|
description = "A tool for generating documentation from Rust derive macros"
|
||||||
version = "0.1.69"
|
version = "0.1.68"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
repository = "https://github.com/KittyCAD/modeling-app"
|
repository = "https://github.com/KittyCAD/modeling-app"
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "kcl-directory-test-macro"
|
name = "kcl-directory-test-macro"
|
||||||
description = "A tool for generating tests from a directory of kcl files"
|
description = "A tool for generating tests from a directory of kcl files"
|
||||||
version = "0.1.69"
|
version = "0.1.68"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
repository = "https://github.com/KittyCAD/modeling-app"
|
repository = "https://github.com/KittyCAD/modeling-app"
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "kcl-language-server-release"
|
name = "kcl-language-server-release"
|
||||||
version = "0.1.69"
|
version = "0.1.68"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
authors = ["KittyCAD Inc <kcl@kittycad.io>"]
|
authors = ["KittyCAD Inc <kcl@kittycad.io>"]
|
||||||
publish = false
|
publish = false
|
||||||
|
|||||||
@ -42,7 +42,7 @@ impl Build {
|
|||||||
.to_string();
|
.to_string();
|
||||||
|
|
||||||
if !stable {
|
if !stable {
|
||||||
version = format!("{}-staging", version);
|
version = format!("{}-nightly", version);
|
||||||
}
|
}
|
||||||
|
|
||||||
let release_tag = if stable {
|
let release_tag = if stable {
|
||||||
@ -53,7 +53,7 @@ impl Build {
|
|||||||
.replace("refs/tags/", "")
|
.replace("refs/tags/", "")
|
||||||
.to_string()
|
.to_string()
|
||||||
} else {
|
} else {
|
||||||
"staging".to_string()
|
"nightly".to_string()
|
||||||
};
|
};
|
||||||
|
|
||||||
if stable && !release_tag.contains(&version) {
|
if stable && !release_tag.contains(&version) {
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
name = "kcl-language-server"
|
name = "kcl-language-server"
|
||||||
description = "A language server for KCL."
|
description = "A language server for KCL."
|
||||||
authors = ["KittyCAD Inc <kcl@kittycad.io>"]
|
authors = ["KittyCAD Inc <kcl@kittycad.io>"]
|
||||||
version = "0.2.69"
|
version = "0.2.68"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "kcl-lib"
|
name = "kcl-lib"
|
||||||
description = "KittyCAD Language implementation and tools"
|
description = "KittyCAD Language implementation and tools"
|
||||||
version = "0.2.69"
|
version = "0.2.68"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
repository = "https://github.com/KittyCAD/modeling-app"
|
repository = "https://github.com/KittyCAD/modeling-app"
|
||||||
|
|||||||
@ -3,7 +3,6 @@
|
|||||||
use kcl_lib::{bust_cache, ExecError, ExecOutcome};
|
use kcl_lib::{bust_cache, ExecError, ExecOutcome};
|
||||||
use kcmc::{each_cmd as mcmd, ModelingCmd};
|
use kcmc::{each_cmd as mcmd, ModelingCmd};
|
||||||
use kittycad_modeling_cmds as kcmc;
|
use kittycad_modeling_cmds as kcmc;
|
||||||
use pretty_assertions::assert_eq;
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct Variation<'a> {
|
struct Variation<'a> {
|
||||||
@ -248,11 +247,8 @@ extrude(profile001, length = 100)"#
|
|||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
let first = result.first().unwrap();
|
result.first().unwrap();
|
||||||
let last = result.last().unwrap();
|
result.last().unwrap();
|
||||||
|
|
||||||
assert!(first.1 == last.1, "The images should be the same");
|
|
||||||
assert_eq!(first.2, last.2, "The outcomes should be the same");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "artifact-graph")]
|
#[cfg(feature = "artifact-graph")]
|
||||||
@ -554,64 +550,3 @@ extrude(profile001, length = 100)
|
|||||||
"The outcomes artifact graphs should be different"
|
"The outcomes artifact graphs should be different"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test(flavor = "multi_thread")]
|
|
||||||
async fn kcl_test_cache_multi_file_same_code_dont_reexecute_settings_only_change() {
|
|
||||||
let code = r#"import "toBeImported.kcl" as importedCube
|
|
||||||
|
|
||||||
importedCube
|
|
||||||
|
|
||||||
sketch001 = startSketchOn(XZ)
|
|
||||||
profile001 = startProfile(sketch001, at = [-134.53, -56.17])
|
|
||||||
|> angledLine(angle = 0, length = 79.05, tag = $rectangleSegmentA001)
|
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA001) - 90, length = 76.28)
|
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001), tag = $seg01)
|
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)], tag = $seg02)
|
|
||||||
|> close()
|
|
||||||
extrude001 = extrude(profile001, length = 100)
|
|
||||||
sketch003 = startSketchOn(extrude001, face = seg02)
|
|
||||||
sketch002 = startSketchOn(extrude001, face = seg01)
|
|
||||||
"#;
|
|
||||||
|
|
||||||
let other_file = (
|
|
||||||
std::path::PathBuf::from("toBeImported.kcl"),
|
|
||||||
r#"sketch001 = startSketchOn(XZ)
|
|
||||||
profile001 = startProfile(sketch001, at = [281.54, 305.81])
|
|
||||||
|> angledLine(angle = 0, length = 123.43, tag = $rectangleSegmentA001)
|
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA001) - 90, length = 85.99)
|
|
||||||
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001))
|
|
||||||
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|
|
||||||
|> close()
|
|
||||||
extrude(profile001, length = 100)"#
|
|
||||||
.to_string(),
|
|
||||||
);
|
|
||||||
|
|
||||||
let result = cache_test(
|
|
||||||
"multi_file_same_code_dont_reexecute_settings_only_change",
|
|
||||||
vec![
|
|
||||||
Variation {
|
|
||||||
code,
|
|
||||||
other_files: vec![other_file.clone()],
|
|
||||||
settings: &kcl_lib::ExecutorSettings {
|
|
||||||
show_grid: false,
|
|
||||||
..Default::default()
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Variation {
|
|
||||||
code,
|
|
||||||
other_files: vec![other_file],
|
|
||||||
settings: &kcl_lib::ExecutorSettings {
|
|
||||||
show_grid: true,
|
|
||||||
..Default::default()
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
)
|
|
||||||
.await;
|
|
||||||
|
|
||||||
let first = result.first().unwrap();
|
|
||||||
let last = result.last().unwrap();
|
|
||||||
|
|
||||||
assert!(first.1 != last.1, "The images should be different for the grid");
|
|
||||||
assert_eq!(first.2, last.2, "The outcomes should be the same");
|
|
||||||
}
|
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 35 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 109 KiB |
@ -380,21 +380,6 @@ fn generate_function_from_kcl(
|
|||||||
.enumerate()
|
.enumerate()
|
||||||
.filter_map(|(index, example)| generate_example(index, &example.0, &example.1, &example_name))
|
.filter_map(|(index, example)| generate_example(index, &example.0, &example.1, &example_name))
|
||||||
.collect();
|
.collect();
|
||||||
let args = function.args.iter().map(|arg| {
|
|
||||||
let docs = arg.docs.clone();
|
|
||||||
if let Some(docs) = &docs {
|
|
||||||
// We deliberately truncate to one line in the template so that if we are using the docs
|
|
||||||
// from the type, then we only take the summary. However, if there's a newline in the
|
|
||||||
// arg docs, then they would get truncated unintentionally.
|
|
||||||
assert!(!docs.contains('\n'), "Arg docs will get truncated");
|
|
||||||
};
|
|
||||||
json!({
|
|
||||||
"name": arg.name,
|
|
||||||
"type_": arg.ty,
|
|
||||||
"description": docs.or_else(|| arg.ty.as_ref().and_then(|t| super::docs_for_type(t, kcl_std))).unwrap_or_default(),
|
|
||||||
"required": arg.kind.required(),
|
|
||||||
})
|
|
||||||
}).collect::<Vec<_>>();
|
|
||||||
|
|
||||||
let data = json!({
|
let data = json!({
|
||||||
"name": function.preferred_name,
|
"name": function.preferred_name,
|
||||||
@ -404,7 +389,14 @@ fn generate_function_from_kcl(
|
|||||||
"deprecated": function.properties.deprecated,
|
"deprecated": function.properties.deprecated,
|
||||||
"fn_signature": function.preferred_name.clone() + &function.fn_signature(),
|
"fn_signature": function.preferred_name.clone() + &function.fn_signature(),
|
||||||
"examples": examples,
|
"examples": examples,
|
||||||
"args": args,
|
"args": function.args.iter().map(|arg| {
|
||||||
|
json!({
|
||||||
|
"name": arg.name,
|
||||||
|
"type_": arg.ty,
|
||||||
|
"description": arg.docs.clone().or_else(|| arg.ty.as_ref().and_then(|t| super::docs_for_type(t, kcl_std))).unwrap_or_default(),
|
||||||
|
"required": arg.kind.required(),
|
||||||
|
})
|
||||||
|
}).collect::<Vec<_>>(),
|
||||||
"return_value": function.return_type.as_ref().map(|t| {
|
"return_value": function.return_type.as_ref().map(|t| {
|
||||||
json!({
|
json!({
|
||||||
"type_": t,
|
"type_": t,
|
||||||
|
|||||||
@ -167,7 +167,6 @@ impl StdLibFnArg {
|
|||||||
pub fn description(&self, kcl_std: Option<&ModData>) -> Option<String> {
|
pub fn description(&self, kcl_std: Option<&ModData>) -> Option<String> {
|
||||||
// Check if we explicitly gave this stdlib arg a description.
|
// Check if we explicitly gave this stdlib arg a description.
|
||||||
if !self.description.is_empty() {
|
if !self.description.is_empty() {
|
||||||
assert!(!self.description.contains('\n'), "Arg docs will get truncated");
|
|
||||||
return Some(self.description.clone());
|
return Some(self.description.clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -559,7 +559,7 @@ impl From<KclError> for pyo3::PyErr {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// An error which occurred during parsing, etc.
|
/// An error which occurred during parsing, etc.
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize, ts_rs::TS, PartialEq, Eq)]
|
#[derive(Debug, Clone, Serialize, Deserialize, ts_rs::TS)]
|
||||||
#[ts(export)]
|
#[ts(export)]
|
||||||
pub struct CompilationError {
|
pub struct CompilationError {
|
||||||
#[serde(rename = "sourceRange")]
|
#[serde(rename = "sourceRange")]
|
||||||
|
|||||||
@ -118,6 +118,7 @@ pub(super) async fn get_changed_program(old: CacheInformation<'_>, new: CacheInf
|
|||||||
// We know they have the same imports because the ast is the same.
|
// We know they have the same imports because the ast is the same.
|
||||||
// If we have no imports, we can skip this.
|
// If we have no imports, we can skip this.
|
||||||
if !old.ast.has_import_statements() {
|
if !old.ast.has_import_statements() {
|
||||||
|
println!("No imports, no need to check.");
|
||||||
return CacheResult::NoAction(reapply_settings);
|
return CacheResult::NoAction(reapply_settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -278,7 +278,7 @@ impl From<&KclValue> for OpKclValue {
|
|||||||
ty: ty.clone(),
|
ty: ty.clone(),
|
||||||
},
|
},
|
||||||
KclValue::String { value, .. } => Self::String { value: value.clone() },
|
KclValue::String { value, .. } => Self::String { value: value.clone() },
|
||||||
KclValue::Tuple { value, .. } | KclValue::HomArray { value, .. } => {
|
KclValue::MixedArray { value, .. } | KclValue::HomArray { value, .. } => {
|
||||||
let value = value.iter().map(Self::from).collect();
|
let value = value.iter().map(Self::from).collect();
|
||||||
Self::Array { value }
|
Self::Array { value }
|
||||||
}
|
}
|
||||||
|
|||||||
@ -16,13 +16,12 @@ use crate::{
|
|||||||
BodyType, EnvironmentRef, ExecState, ExecutorContext, KclValue, Metadata, PlaneType, TagEngineInfo,
|
BodyType, EnvironmentRef, ExecState, ExecutorContext, KclValue, Metadata, PlaneType, TagEngineInfo,
|
||||||
TagIdentifier,
|
TagIdentifier,
|
||||||
},
|
},
|
||||||
fmt,
|
|
||||||
modules::{ModuleId, ModulePath, ModuleRepr},
|
modules::{ModuleId, ModulePath, ModuleRepr},
|
||||||
parsing::ast::types::{
|
parsing::ast::types::{
|
||||||
Annotation, ArrayExpression, ArrayRangeExpression, AscribedExpression, BinaryExpression, BinaryOperator,
|
Annotation, ArrayExpression, ArrayRangeExpression, BinaryExpression, BinaryOperator, BinaryPart, BodyItem,
|
||||||
BinaryPart, BodyItem, CallExpressionKw, Expr, FunctionExpression, IfExpression, ImportPath, ImportSelector,
|
CallExpressionKw, Expr, FunctionExpression, IfExpression, ImportPath, ImportSelector, ItemVisibility,
|
||||||
ItemVisibility, LiteralIdentifier, LiteralValue, MemberExpression, MemberObject, Name, Node, NodeRef,
|
LiteralIdentifier, LiteralValue, MemberExpression, MemberObject, Name, Node, NodeRef, ObjectExpression,
|
||||||
ObjectExpression, PipeExpression, Program, TagDeclarator, Type, UnaryExpression, UnaryOperator,
|
PipeExpression, Program, TagDeclarator, Type, UnaryExpression, UnaryOperator,
|
||||||
},
|
},
|
||||||
source_range::SourceRange,
|
source_range::SourceRange,
|
||||||
std::{
|
std::{
|
||||||
@ -708,25 +707,17 @@ impl ExecutorContext {
|
|||||||
// TODO this lets us use the label as a variable name, but not as a tag in most cases
|
// TODO this lets us use the label as a variable name, but not as a tag in most cases
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
Expr::AscribedExpression(expr) => expr.get_result(exec_state, self).await?,
|
Expr::AscribedExpression(expr) => {
|
||||||
|
let result = self
|
||||||
|
.execute_expr(&expr.expr, exec_state, metadata, &[], statement_kind)
|
||||||
|
.await?;
|
||||||
|
apply_ascription(&result, &expr.ty, exec_state, expr.into())?
|
||||||
|
}
|
||||||
};
|
};
|
||||||
Ok(item)
|
Ok(item)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Node<AscribedExpression> {
|
|
||||||
#[async_recursion]
|
|
||||||
pub async fn get_result(&self, exec_state: &mut ExecState, ctx: &ExecutorContext) -> Result<KclValue, KclError> {
|
|
||||||
let metadata = Metadata {
|
|
||||||
source_range: SourceRange::from(self),
|
|
||||||
};
|
|
||||||
let result = ctx
|
|
||||||
.execute_expr(&self.expr, exec_state, &metadata, &[], StatementKind::Expression)
|
|
||||||
.await?;
|
|
||||||
apply_ascription(&result, &self.ty, exec_state, self.into())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn apply_ascription(
|
fn apply_ascription(
|
||||||
value: &KclValue,
|
value: &KclValue,
|
||||||
ty: &Node<Type>,
|
ty: &Node<Type>,
|
||||||
@ -767,7 +758,6 @@ impl BinaryPart {
|
|||||||
BinaryPart::UnaryExpression(unary_expression) => unary_expression.get_result(exec_state, ctx).await,
|
BinaryPart::UnaryExpression(unary_expression) => unary_expression.get_result(exec_state, ctx).await,
|
||||||
BinaryPart::MemberExpression(member_expression) => member_expression.get_result(exec_state),
|
BinaryPart::MemberExpression(member_expression) => member_expression.get_result(exec_state),
|
||||||
BinaryPart::IfExpression(e) => e.get_result(exec_state, ctx).await,
|
BinaryPart::IfExpression(e) => e.get_result(exec_state, ctx).await,
|
||||||
BinaryPart::AscribedExpression(e) => e.get_result(exec_state, ctx).await,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -877,7 +867,11 @@ impl Node<MemberExpression> {
|
|||||||
source_ranges: vec![self.clone().into()],
|
source_ranges: vec![self.clone().into()],
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
(KclValue::HomArray { value: arr, .. }, Property::UInt(index), _) => {
|
(
|
||||||
|
KclValue::MixedArray { value: arr, .. } | KclValue::HomArray { value: arr, .. },
|
||||||
|
Property::UInt(index),
|
||||||
|
_,
|
||||||
|
) => {
|
||||||
let value_of_arr = arr.get(index);
|
let value_of_arr = arr.get(index);
|
||||||
if let Some(value) = value_of_arr {
|
if let Some(value) = value_of_arr {
|
||||||
Ok(value.to_owned())
|
Ok(value.to_owned())
|
||||||
@ -888,7 +882,7 @@ impl Node<MemberExpression> {
|
|||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(KclValue::HomArray { .. }, p, _) => {
|
(KclValue::MixedArray { .. } | KclValue::HomArray { .. }, p, _) => {
|
||||||
let t = p.type_name();
|
let t = p.type_name();
|
||||||
let article = article_for(t);
|
let article = article_for(t);
|
||||||
Err(KclError::Semantic(KclErrorDetails {
|
Err(KclError::Semantic(KclErrorDetails {
|
||||||
@ -1176,7 +1170,7 @@ impl Node<UnaryExpression> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let direction = match direction {
|
let direction = match direction {
|
||||||
KclValue::Tuple { value: values, meta } => {
|
KclValue::MixedArray { value: values, meta } => {
|
||||||
let values = values
|
let values = values
|
||||||
.iter()
|
.iter()
|
||||||
.map(|v| match v {
|
.map(|v| match v {
|
||||||
@ -1189,7 +1183,7 @@ impl Node<UnaryExpression> {
|
|||||||
})
|
})
|
||||||
.collect::<Result<Vec<_>, _>>()?;
|
.collect::<Result<Vec<_>, _>>()?;
|
||||||
|
|
||||||
KclValue::Tuple {
|
KclValue::MixedArray {
|
||||||
value: values,
|
value: values,
|
||||||
meta: meta.clone(),
|
meta: meta.clone(),
|
||||||
}
|
}
|
||||||
@ -1557,7 +1551,7 @@ fn update_memory_for_tags_of_geometry(result: &mut KclValue, exec_state: &mut Ex
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
KclValue::Tuple { value, .. } | KclValue::HomArray { value, .. } => {
|
KclValue::MixedArray { value, .. } | KclValue::HomArray { value, .. } => {
|
||||||
for v in value {
|
for v in value {
|
||||||
update_memory_for_tags_of_geometry(v, exec_state)?;
|
update_memory_for_tags_of_geometry(v, exec_state)?;
|
||||||
}
|
}
|
||||||
@ -1601,9 +1595,9 @@ impl Node<ArrayExpression> {
|
|||||||
results.push(value);
|
results.push(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(KclValue::HomArray {
|
Ok(KclValue::MixedArray {
|
||||||
value: results,
|
value: results,
|
||||||
ty: RuntimeType::Primitive(PrimitiveType::Any),
|
meta: vec![self.into()],
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1612,7 +1606,7 @@ impl Node<ArrayRangeExpression> {
|
|||||||
#[async_recursion]
|
#[async_recursion]
|
||||||
pub async fn execute(&self, exec_state: &mut ExecState, ctx: &ExecutorContext) -> Result<KclValue, KclError> {
|
pub async fn execute(&self, exec_state: &mut ExecState, ctx: &ExecutorContext) -> Result<KclValue, KclError> {
|
||||||
let metadata = Metadata::from(&self.start_element);
|
let metadata = Metadata::from(&self.start_element);
|
||||||
let start_val = ctx
|
let start = ctx
|
||||||
.execute_expr(
|
.execute_expr(
|
||||||
&self.start_element,
|
&self.start_element,
|
||||||
exec_state,
|
exec_state,
|
||||||
@ -1621,30 +1615,19 @@ impl Node<ArrayRangeExpression> {
|
|||||||
StatementKind::Expression,
|
StatementKind::Expression,
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
let (start, start_ty) = start_val.as_int_with_ty().ok_or(KclError::Semantic(KclErrorDetails {
|
let start = start.as_int().ok_or(KclError::Semantic(KclErrorDetails {
|
||||||
source_ranges: vec![self.into()],
|
source_ranges: vec![self.into()],
|
||||||
message: format!("Expected int but found {}", start_val.human_friendly_type()),
|
message: format!("Expected int but found {}", start.human_friendly_type()),
|
||||||
}))?;
|
}))?;
|
||||||
let metadata = Metadata::from(&self.end_element);
|
let metadata = Metadata::from(&self.end_element);
|
||||||
let end_val = ctx
|
let end = ctx
|
||||||
.execute_expr(&self.end_element, exec_state, &metadata, &[], StatementKind::Expression)
|
.execute_expr(&self.end_element, exec_state, &metadata, &[], StatementKind::Expression)
|
||||||
.await?;
|
.await?;
|
||||||
let (end, end_ty) = end_val.as_int_with_ty().ok_or(KclError::Semantic(KclErrorDetails {
|
let end = end.as_int().ok_or(KclError::Semantic(KclErrorDetails {
|
||||||
source_ranges: vec![self.into()],
|
source_ranges: vec![self.into()],
|
||||||
message: format!("Expected int but found {}", end_val.human_friendly_type()),
|
message: format!("Expected int but found {}", end.human_friendly_type()),
|
||||||
}))?;
|
}))?;
|
||||||
|
|
||||||
if start_ty != end_ty {
|
|
||||||
let start = start_val.as_ty_f64().unwrap_or(TyF64 { n: 0.0, ty: start_ty });
|
|
||||||
let start = fmt::human_display_number(start.n, start.ty);
|
|
||||||
let end = end_val.as_ty_f64().unwrap_or(TyF64 { n: 0.0, ty: end_ty });
|
|
||||||
let end = fmt::human_display_number(end.n, end.ty);
|
|
||||||
return Err(KclError::Semantic(KclErrorDetails {
|
|
||||||
source_ranges: vec![self.into()],
|
|
||||||
message: format!("Range start and end must be of the same type, but found {start} and {end}"),
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
if end < start {
|
if end < start {
|
||||||
return Err(KclError::Semantic(KclErrorDetails {
|
return Err(KclError::Semantic(KclErrorDetails {
|
||||||
source_ranges: vec![self.into()],
|
source_ranges: vec![self.into()],
|
||||||
@ -1661,17 +1644,16 @@ impl Node<ArrayRangeExpression> {
|
|||||||
let meta = vec![Metadata {
|
let meta = vec![Metadata {
|
||||||
source_range: self.into(),
|
source_range: self.into(),
|
||||||
}];
|
}];
|
||||||
|
Ok(KclValue::MixedArray {
|
||||||
Ok(KclValue::HomArray {
|
|
||||||
value: range
|
value: range
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|num| KclValue::Number {
|
.map(|num| KclValue::Number {
|
||||||
value: num as f64,
|
value: num as f64,
|
||||||
ty: start_ty.clone(),
|
ty: NumericType::count(),
|
||||||
meta: meta.clone(),
|
meta: meta.clone(),
|
||||||
})
|
})
|
||||||
.collect(),
|
.collect(),
|
||||||
ty: RuntimeType::Primitive(PrimitiveType::Number(start_ty)),
|
meta,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1886,7 +1868,7 @@ fn type_check_params_kw(
|
|||||||
arg.value = arg
|
arg.value = arg
|
||||||
.value
|
.value
|
||||||
.coerce(
|
.coerce(
|
||||||
&RuntimeType::from_parsed(ty.inner.clone(), exec_state, arg.source_range).map_err(|e| KclError::Semantic(e.into()))?,
|
&RuntimeType::from_parsed(ty.inner.clone(), exec_state, arg.source_range).unwrap(),
|
||||||
exec_state,
|
exec_state,
|
||||||
)
|
)
|
||||||
.map_err(|e| {
|
.map_err(|e| {
|
||||||
@ -1964,8 +1946,7 @@ fn type_check_params_kw(
|
|||||||
arg.value = arg
|
arg.value = arg
|
||||||
.value
|
.value
|
||||||
.coerce(
|
.coerce(
|
||||||
&RuntimeType::from_parsed(ty.inner.clone(), exec_state, arg.source_range)
|
&RuntimeType::from_parsed(ty.inner.clone(), exec_state, arg.source_range).unwrap(),
|
||||||
.map_err(|e| KclError::Semantic(e.into()))?,
|
|
||||||
exec_state,
|
exec_state,
|
||||||
)
|
)
|
||||||
.map_err(|_| {
|
.map_err(|_| {
|
||||||
@ -2144,8 +2125,7 @@ impl FunctionSource {
|
|||||||
arg.value = arg
|
arg.value = arg
|
||||||
.value
|
.value
|
||||||
.coerce(
|
.coerce(
|
||||||
&RuntimeType::from_parsed(ty.inner.clone(), exec_state, arg.source_range)
|
&RuntimeType::from_parsed(ty.inner.clone(), exec_state, arg.source_range).unwrap(),
|
||||||
.map_err(|e| KclError::Semantic(e.into()))?,
|
|
||||||
exec_state,
|
exec_state,
|
||||||
)
|
)
|
||||||
.map_err(|_| {
|
.map_err(|_| {
|
||||||
@ -2255,10 +2235,9 @@ mod test {
|
|||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::{
|
use crate::{
|
||||||
exec::UnitType,
|
|
||||||
execution::{memory::Stack, parse_execute, ContextType},
|
execution::{memory::Stack, parse_execute, ContextType},
|
||||||
parsing::ast::types::{DefaultParamVal, Identifier, Parameter},
|
parsing::ast::types::{DefaultParamVal, Identifier, Parameter},
|
||||||
ExecutorSettings, UnitLen,
|
ExecutorSettings,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[tokio::test(flavor = "multi_thread")]
|
#[tokio::test(flavor = "multi_thread")]
|
||||||
@ -2412,7 +2391,6 @@ p = {
|
|||||||
yAxis = { x = 0, y = 1, z = 0 },
|
yAxis = { x = 0, y = 1, z = 0 },
|
||||||
zAxis = { x = 0, y = 0, z = 1 }
|
zAxis = { x = 0, y = 0, z = 1 }
|
||||||
}: Plane
|
}: Plane
|
||||||
arr1 = [42]: [number(cm)]
|
|
||||||
"#;
|
"#;
|
||||||
|
|
||||||
let result = parse_execute(program).await.unwrap();
|
let result = parse_execute(program).await.unwrap();
|
||||||
@ -2423,24 +2401,6 @@ arr1 = [42]: [number(cm)]
|
|||||||
.unwrap(),
|
.unwrap(),
|
||||||
KclValue::Plane { .. }
|
KclValue::Plane { .. }
|
||||||
));
|
));
|
||||||
let arr1 = mem
|
|
||||||
.memory
|
|
||||||
.get_from("arr1", result.mem_env, SourceRange::default(), 0)
|
|
||||||
.unwrap();
|
|
||||||
if let KclValue::HomArray { value, ty } = arr1 {
|
|
||||||
assert_eq!(value.len(), 1, "Expected Vec with specific length: found {:?}", value);
|
|
||||||
assert_eq!(*ty, RuntimeType::known_length(UnitLen::Cm));
|
|
||||||
// Compare, ignoring meta.
|
|
||||||
if let KclValue::Number { value, ty, .. } = &value[0] {
|
|
||||||
// Converted from mm to cm.
|
|
||||||
assert_eq!(*value, 4.2);
|
|
||||||
assert_eq!(*ty, NumericType::Known(UnitType::Length(UnitLen::Cm)));
|
|
||||||
} else {
|
|
||||||
panic!("Expected a number; found {:?}", value[0]);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
panic!("Expected HomArray; found {arr1:?}");
|
|
||||||
}
|
|
||||||
|
|
||||||
let program = r#"
|
let program = r#"
|
||||||
a = 42: string
|
a = 42: string
|
||||||
@ -2459,28 +2419,6 @@ a = 42: Plane
|
|||||||
.unwrap_err()
|
.unwrap_err()
|
||||||
.to_string()
|
.to_string()
|
||||||
.contains("could not coerce number value to type Plane"));
|
.contains("could not coerce number value to type Plane"));
|
||||||
|
|
||||||
let program = r#"
|
|
||||||
arr = [0]: [string]
|
|
||||||
"#;
|
|
||||||
let result = parse_execute(program).await;
|
|
||||||
let err = result.unwrap_err();
|
|
||||||
assert!(
|
|
||||||
err.to_string()
|
|
||||||
.contains("could not coerce array (list) value to type [string]"),
|
|
||||||
"Expected error but found {err:?}"
|
|
||||||
);
|
|
||||||
|
|
||||||
let program = r#"
|
|
||||||
mixedArr = [0, "a"]: [number(mm)]
|
|
||||||
"#;
|
|
||||||
let result = parse_execute(program).await;
|
|
||||||
let err = result.unwrap_err();
|
|
||||||
assert!(
|
|
||||||
err.to_string()
|
|
||||||
.contains("could not coerce array (list) value to type [number(mm)]"),
|
|
||||||
"Expected error but found {err:?}"
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test(flavor = "multi_thread")]
|
#[tokio::test(flavor = "multi_thread")]
|
||||||
@ -2700,19 +2638,4 @@ sketch001 = startSketchOn(XY)
|
|||||||
|
|
||||||
parse_execute(ast).await.unwrap();
|
parse_execute(ast).await.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test(flavor = "multi_thread")]
|
|
||||||
async fn ascription_in_binop() {
|
|
||||||
let ast = r#"foo = tan(0): number(rad) - 4deg"#;
|
|
||||||
parse_execute(ast).await.unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tokio::test(flavor = "multi_thread")]
|
|
||||||
async fn neg_sqrt() {
|
|
||||||
let ast = r#"bad = sqrt(-2)"#;
|
|
||||||
|
|
||||||
let e = parse_execute(ast).await.unwrap_err();
|
|
||||||
// Make sure we get a useful error message and not an engine error.
|
|
||||||
assert!(e.message().contains("sqrt"), "Error message: '{}'", e.message());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1239,20 +1239,6 @@ impl Path {
|
|||||||
[TyF64::new(p[0], ty.clone()), TyF64::new(p[1], ty)]
|
[TyF64::new(p[0], ty.clone()), TyF64::new(p[1], ty)]
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The path segment start point and its type.
|
|
||||||
pub fn start_point_components(&self) -> ([f64; 2], NumericType) {
|
|
||||||
let p = &self.get_base().from;
|
|
||||||
let ty: NumericType = self.get_base().units.into();
|
|
||||||
(*p, ty)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The path segment end point and its type.
|
|
||||||
pub fn end_point_components(&self) -> ([f64; 2], NumericType) {
|
|
||||||
let p = &self.get_base().to;
|
|
||||||
let ty: NumericType = self.get_base().units.into();
|
|
||||||
(*p, ty)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Length of this path segment, in cartesian plane.
|
/// Length of this path segment, in cartesian plane.
|
||||||
pub fn length(&self) -> TyF64 {
|
pub fn length(&self) -> TyF64 {
|
||||||
let n = match self {
|
let n = match self {
|
||||||
|
|||||||
@ -48,7 +48,7 @@ pub enum KclValue {
|
|||||||
#[serde(skip)]
|
#[serde(skip)]
|
||||||
meta: Vec<Metadata>,
|
meta: Vec<Metadata>,
|
||||||
},
|
},
|
||||||
Tuple {
|
MixedArray {
|
||||||
value: Vec<KclValue>,
|
value: Vec<KclValue>,
|
||||||
#[serde(skip)]
|
#[serde(skip)]
|
||||||
meta: Vec<Metadata>,
|
meta: Vec<Metadata>,
|
||||||
@ -197,7 +197,7 @@ impl From<KclValue> for Vec<SourceRange> {
|
|||||||
KclValue::Bool { meta, .. } => to_vec_sr(&meta),
|
KclValue::Bool { meta, .. } => to_vec_sr(&meta),
|
||||||
KclValue::Number { meta, .. } => to_vec_sr(&meta),
|
KclValue::Number { meta, .. } => to_vec_sr(&meta),
|
||||||
KclValue::String { meta, .. } => to_vec_sr(&meta),
|
KclValue::String { meta, .. } => to_vec_sr(&meta),
|
||||||
KclValue::Tuple { meta, .. } => to_vec_sr(&meta),
|
KclValue::MixedArray { meta, .. } => to_vec_sr(&meta),
|
||||||
KclValue::HomArray { value, .. } => value.iter().flat_map(Into::<Vec<SourceRange>>::into).collect(),
|
KclValue::HomArray { value, .. } => value.iter().flat_map(Into::<Vec<SourceRange>>::into).collect(),
|
||||||
KclValue::Object { meta, .. } => to_vec_sr(&meta),
|
KclValue::Object { meta, .. } => to_vec_sr(&meta),
|
||||||
KclValue::Module { meta, .. } => to_vec_sr(&meta),
|
KclValue::Module { meta, .. } => to_vec_sr(&meta),
|
||||||
@ -228,7 +228,7 @@ impl From<&KclValue> for Vec<SourceRange> {
|
|||||||
KclValue::Number { meta, .. } => to_vec_sr(meta),
|
KclValue::Number { meta, .. } => to_vec_sr(meta),
|
||||||
KclValue::String { meta, .. } => to_vec_sr(meta),
|
KclValue::String { meta, .. } => to_vec_sr(meta),
|
||||||
KclValue::Uuid { meta, .. } => to_vec_sr(meta),
|
KclValue::Uuid { meta, .. } => to_vec_sr(meta),
|
||||||
KclValue::Tuple { meta, .. } => to_vec_sr(meta),
|
KclValue::MixedArray { meta, .. } => to_vec_sr(meta),
|
||||||
KclValue::HomArray { value, .. } => value.iter().flat_map(Into::<Vec<SourceRange>>::into).collect(),
|
KclValue::HomArray { value, .. } => value.iter().flat_map(Into::<Vec<SourceRange>>::into).collect(),
|
||||||
KclValue::Object { meta, .. } => to_vec_sr(meta),
|
KclValue::Object { meta, .. } => to_vec_sr(meta),
|
||||||
KclValue::Module { meta, .. } => to_vec_sr(meta),
|
KclValue::Module { meta, .. } => to_vec_sr(meta),
|
||||||
@ -252,7 +252,7 @@ impl KclValue {
|
|||||||
KclValue::Bool { value: _, meta } => meta.clone(),
|
KclValue::Bool { value: _, meta } => meta.clone(),
|
||||||
KclValue::Number { meta, .. } => meta.clone(),
|
KclValue::Number { meta, .. } => meta.clone(),
|
||||||
KclValue::String { value: _, meta } => meta.clone(),
|
KclValue::String { value: _, meta } => meta.clone(),
|
||||||
KclValue::Tuple { value: _, meta } => meta.clone(),
|
KclValue::MixedArray { value: _, meta } => meta.clone(),
|
||||||
KclValue::HomArray { value, .. } => value.iter().flat_map(|v| v.metadata()).collect(),
|
KclValue::HomArray { value, .. } => value.iter().flat_map(|v| v.metadata()).collect(),
|
||||||
KclValue::Object { value: _, meta } => meta.clone(),
|
KclValue::Object { value: _, meta } => meta.clone(),
|
||||||
KclValue::TagIdentifier(x) => x.meta.clone(),
|
KclValue::TagIdentifier(x) => x.meta.clone(),
|
||||||
@ -307,7 +307,7 @@ impl KclValue {
|
|||||||
} => "number(Angle)",
|
} => "number(Angle)",
|
||||||
KclValue::Number { .. } => "number",
|
KclValue::Number { .. } => "number",
|
||||||
KclValue::String { .. } => "string (text)",
|
KclValue::String { .. } => "string (text)",
|
||||||
KclValue::Tuple { .. } => "tuple (list)",
|
KclValue::MixedArray { .. } => "mixed array (list)",
|
||||||
KclValue::HomArray { .. } => "array (list)",
|
KclValue::HomArray { .. } => "array (list)",
|
||||||
KclValue::Object { .. } => "object",
|
KclValue::Object { .. } => "object",
|
||||||
KclValue::Module { .. } => "module",
|
KclValue::Module { .. } => "module",
|
||||||
@ -373,7 +373,7 @@ impl KclValue {
|
|||||||
|
|
||||||
/// Put the point into a KCL value.
|
/// Put the point into a KCL value.
|
||||||
pub fn from_point2d(p: [f64; 2], ty: NumericType, meta: Vec<Metadata>) -> Self {
|
pub fn from_point2d(p: [f64; 2], ty: NumericType, meta: Vec<Metadata>) -> Self {
|
||||||
Self::Tuple {
|
Self::MixedArray {
|
||||||
value: vec![
|
value: vec![
|
||||||
Self::Number {
|
Self::Number {
|
||||||
value: p[0],
|
value: p[0],
|
||||||
@ -404,13 +404,6 @@ impl KclValue {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_int_with_ty(&self) -> Option<(i64, NumericType)> {
|
|
||||||
match self {
|
|
||||||
KclValue::Number { value, ty, .. } => crate::try_f64_to_i64(*value).map(|i| (i, ty.clone())),
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn as_object(&self) -> Option<&KclObjectFields> {
|
pub fn as_object(&self) -> Option<&KclObjectFields> {
|
||||||
if let KclValue::Object { value, meta: _ } = &self {
|
if let KclValue::Object { value, meta: _ } = &self {
|
||||||
Some(value)
|
Some(value)
|
||||||
@ -437,7 +430,7 @@ impl KclValue {
|
|||||||
|
|
||||||
pub fn as_array(&self) -> Option<&[KclValue]> {
|
pub fn as_array(&self) -> Option<&[KclValue]> {
|
||||||
match self {
|
match self {
|
||||||
KclValue::Tuple { value, .. } | KclValue::HomArray { value, .. } => Some(value),
|
KclValue::MixedArray { value, .. } | KclValue::HomArray { value, .. } => Some(value),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -609,7 +602,7 @@ impl KclValue {
|
|||||||
KclValue::TagDeclarator(tag) => Some(format!("${}", tag.name)),
|
KclValue::TagDeclarator(tag) => Some(format!("${}", tag.name)),
|
||||||
KclValue::TagIdentifier(tag) => Some(format!("${}", tag.value)),
|
KclValue::TagIdentifier(tag) => Some(format!("${}", tag.value)),
|
||||||
// TODO better Array and Object stringification
|
// TODO better Array and Object stringification
|
||||||
KclValue::Tuple { .. } => Some("[...]".to_owned()),
|
KclValue::MixedArray { .. } => Some("[...]".to_owned()),
|
||||||
KclValue::HomArray { .. } => Some("[...]".to_owned()),
|
KclValue::HomArray { .. } => Some("[...]".to_owned()),
|
||||||
KclValue::Object { .. } => Some("{ ... }".to_owned()),
|
KclValue::Object { .. } => Some("{ ... }".to_owned()),
|
||||||
KclValue::Module { .. }
|
KclValue::Module { .. }
|
||||||
|
|||||||
@ -64,7 +64,7 @@ pub mod typed_path;
|
|||||||
pub(crate) mod types;
|
pub(crate) mod types;
|
||||||
|
|
||||||
/// Outcome of executing a program. This is used in TS.
|
/// Outcome of executing a program. This is used in TS.
|
||||||
#[derive(Debug, Clone, Serialize, ts_rs::TS, PartialEq)]
|
#[derive(Debug, Clone, Serialize, ts_rs::TS)]
|
||||||
#[ts(export)]
|
#[ts(export)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct ExecOutcome {
|
pub struct ExecOutcome {
|
||||||
@ -385,7 +385,6 @@ impl ExecutorContext {
|
|||||||
let (ws, _headers) = client
|
let (ws, _headers) = client
|
||||||
.modeling()
|
.modeling()
|
||||||
.commands_ws(
|
.commands_ws(
|
||||||
None,
|
|
||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
if settings.enable_ssao {
|
if settings.enable_ssao {
|
||||||
@ -654,21 +653,13 @@ impl ExecutorContext {
|
|||||||
keys.sort();
|
keys.sort();
|
||||||
for key in keys {
|
for key in keys {
|
||||||
let (_, id, _, _) = &new_universe[key];
|
let (_, id, _, _) = &new_universe[key];
|
||||||
if let (Some(source0), Some(source1)) =
|
let old_source = old_state.get_source(*id);
|
||||||
(old_state.get_source(*id), new_exec_state.get_source(*id))
|
let new_source = new_exec_state.get_source(*id);
|
||||||
{
|
if old_source != new_source {
|
||||||
if source0.source != source1.source {
|
|
||||||
clear_scene = true;
|
clear_scene = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if !clear_scene {
|
|
||||||
// Return early we don't need to clear the scene.
|
|
||||||
let outcome = old_state.to_exec_outcome(result_env).await;
|
|
||||||
return Ok(outcome);
|
|
||||||
}
|
|
||||||
|
|
||||||
(
|
(
|
||||||
clear_scene,
|
clear_scene,
|
||||||
@ -1941,7 +1932,7 @@ a = []
|
|||||||
notArray = !a";
|
notArray = !a";
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
parse_execute(code5).await.unwrap_err().message(),
|
parse_execute(code5).await.unwrap_err().message(),
|
||||||
"Cannot apply unary operator ! to non-boolean value: array (list)",
|
"Cannot apply unary operator ! to non-boolean value: mixed array (list)",
|
||||||
);
|
);
|
||||||
|
|
||||||
let code6 = "
|
let code6 = "
|
||||||
|
|||||||
@ -28,10 +28,6 @@ pub enum RuntimeType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl RuntimeType {
|
impl RuntimeType {
|
||||||
pub fn any() -> Self {
|
|
||||||
RuntimeType::Primitive(PrimitiveType::Any)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn edge() -> Self {
|
pub fn edge() -> Self {
|
||||||
RuntimeType::Primitive(PrimitiveType::Edge)
|
RuntimeType::Primitive(PrimitiveType::Edge)
|
||||||
}
|
}
|
||||||
@ -76,10 +72,6 @@ impl RuntimeType {
|
|||||||
RuntimeType::Primitive(PrimitiveType::Tag)
|
RuntimeType::Primitive(PrimitiveType::Tag)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn tag_identifier() -> Self {
|
|
||||||
RuntimeType::Primitive(PrimitiveType::TagId)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn bool() -> Self {
|
pub fn bool() -> Self {
|
||||||
RuntimeType::Primitive(PrimitiveType::Boolean)
|
RuntimeType::Primitive(PrimitiveType::Boolean)
|
||||||
}
|
}
|
||||||
@ -170,16 +162,11 @@ impl RuntimeType {
|
|||||||
source_range: SourceRange,
|
source_range: SourceRange,
|
||||||
) -> Result<Self, CompilationError> {
|
) -> Result<Self, CompilationError> {
|
||||||
Ok(match value {
|
Ok(match value {
|
||||||
AstPrimitiveType::Any => RuntimeType::Primitive(PrimitiveType::Any),
|
|
||||||
AstPrimitiveType::String => RuntimeType::Primitive(PrimitiveType::String),
|
AstPrimitiveType::String => RuntimeType::Primitive(PrimitiveType::String),
|
||||||
AstPrimitiveType::Boolean => RuntimeType::Primitive(PrimitiveType::Boolean),
|
AstPrimitiveType::Boolean => RuntimeType::Primitive(PrimitiveType::Boolean),
|
||||||
AstPrimitiveType::Number(suffix) => {
|
AstPrimitiveType::Number(suffix) => RuntimeType::Primitive(PrimitiveType::Number(
|
||||||
let ty = match suffix {
|
NumericType::from_parsed(suffix, &exec_state.mod_local.settings),
|
||||||
NumericSuffix::None => NumericType::Any,
|
)),
|
||||||
_ => NumericType::from_parsed(suffix, &exec_state.mod_local.settings),
|
|
||||||
};
|
|
||||||
RuntimeType::Primitive(PrimitiveType::Number(ty))
|
|
||||||
}
|
|
||||||
AstPrimitiveType::Named(name) => Self::from_alias(&name.name, exec_state, source_range)?,
|
AstPrimitiveType::Named(name) => Self::from_alias(&name.name, exec_state, source_range)?,
|
||||||
AstPrimitiveType::Tag => RuntimeType::Primitive(PrimitiveType::Tag),
|
AstPrimitiveType::Tag => RuntimeType::Primitive(PrimitiveType::Tag),
|
||||||
})
|
})
|
||||||
@ -216,7 +203,7 @@ impl RuntimeType {
|
|||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
.join(" or "),
|
.join(" or "),
|
||||||
RuntimeType::Tuple(tys) => format!(
|
RuntimeType::Tuple(tys) => format!(
|
||||||
"a tuple with values of types ({})",
|
"an array with values of types ({})",
|
||||||
tys.iter().map(Self::human_friendly_type).collect::<Vec<_>>().join(", ")
|
tys.iter().map(Self::human_friendly_type).collect::<Vec<_>>().join(", ")
|
||||||
),
|
),
|
||||||
RuntimeType::Object(_) => format!("an object with fields {}", self),
|
RuntimeType::Object(_) => format!("an object with fields {}", self),
|
||||||
@ -228,7 +215,6 @@ impl RuntimeType {
|
|||||||
use RuntimeType::*;
|
use RuntimeType::*;
|
||||||
|
|
||||||
match (self, sup) {
|
match (self, sup) {
|
||||||
(_, Primitive(PrimitiveType::Any)) => true,
|
|
||||||
(Primitive(t1), Primitive(t2)) => t1.subtype(t2),
|
(Primitive(t1), Primitive(t2)) => t1.subtype(t2),
|
||||||
(Array(t1, l1), Array(t2, l2)) => t1.subtype(t2) && l1.subtype(*l2),
|
(Array(t1, l1), Array(t2, l2)) => t1.subtype(t2) && l1.subtype(*l2),
|
||||||
(Tuple(t1), Tuple(t2)) => t1.len() == t2.len() && t1.iter().zip(t2).all(|(t1, t2)| t1.subtype(t2)),
|
(Tuple(t1), Tuple(t2)) => t1.len() == t2.len() && t1.iter().zip(t2).all(|(t1, t2)| t1.subtype(t2)),
|
||||||
@ -279,7 +265,7 @@ impl RuntimeType {
|
|||||||
.map(|t| t.display_multiple())
|
.map(|t| t.display_multiple())
|
||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
.join(" or "),
|
.join(" or "),
|
||||||
RuntimeType::Tuple(_) => "tuples".to_owned(),
|
RuntimeType::Tuple(_) => "arrays".to_owned(),
|
||||||
RuntimeType::Object(_) => format!("objects with fields {self}"),
|
RuntimeType::Object(_) => format!("objects with fields {self}"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -296,7 +282,7 @@ impl fmt::Display for RuntimeType {
|
|||||||
},
|
},
|
||||||
RuntimeType::Tuple(ts) => write!(
|
RuntimeType::Tuple(ts) => write!(
|
||||||
f,
|
f,
|
||||||
"({})",
|
"[{}]",
|
||||||
ts.iter().map(|t| t.to_string()).collect::<Vec<_>>().join(", ")
|
ts.iter().map(|t| t.to_string()).collect::<Vec<_>>().join(", ")
|
||||||
),
|
),
|
||||||
RuntimeType::Union(ts) => write!(
|
RuntimeType::Union(ts) => write!(
|
||||||
@ -347,13 +333,10 @@ impl ArrayLen {
|
|||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub enum PrimitiveType {
|
pub enum PrimitiveType {
|
||||||
Any,
|
|
||||||
Number(NumericType),
|
Number(NumericType),
|
||||||
String,
|
String,
|
||||||
Boolean,
|
Boolean,
|
||||||
Tag,
|
Tag,
|
||||||
// Annoyingly some functions only want a TagIdentifier, not any kind of tag.
|
|
||||||
TagId,
|
|
||||||
Sketch,
|
Sketch,
|
||||||
Solid,
|
Solid,
|
||||||
Plane,
|
Plane,
|
||||||
@ -368,7 +351,6 @@ pub enum PrimitiveType {
|
|||||||
impl PrimitiveType {
|
impl PrimitiveType {
|
||||||
fn display_multiple(&self) -> String {
|
fn display_multiple(&self) -> String {
|
||||||
match self {
|
match self {
|
||||||
PrimitiveType::Any => "any values".to_owned(),
|
|
||||||
PrimitiveType::Number(NumericType::Known(unit)) => format!("numbers({unit})"),
|
PrimitiveType::Number(NumericType::Known(unit)) => format!("numbers({unit})"),
|
||||||
PrimitiveType::Number(_) => "numbers".to_owned(),
|
PrimitiveType::Number(_) => "numbers".to_owned(),
|
||||||
PrimitiveType::String => "strings".to_owned(),
|
PrimitiveType::String => "strings".to_owned(),
|
||||||
@ -383,15 +365,12 @@ impl PrimitiveType {
|
|||||||
PrimitiveType::Axis3d => "3d axes".to_owned(),
|
PrimitiveType::Axis3d => "3d axes".to_owned(),
|
||||||
PrimitiveType::ImportedGeometry => "imported geometries".to_owned(),
|
PrimitiveType::ImportedGeometry => "imported geometries".to_owned(),
|
||||||
PrimitiveType::Tag => "tags".to_owned(),
|
PrimitiveType::Tag => "tags".to_owned(),
|
||||||
PrimitiveType::TagId => "tag identifiers".to_owned(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn subtype(&self, other: &PrimitiveType) -> bool {
|
fn subtype(&self, other: &PrimitiveType) -> bool {
|
||||||
match (self, other) {
|
match (self, other) {
|
||||||
(_, PrimitiveType::Any) => true,
|
|
||||||
(PrimitiveType::Number(n1), PrimitiveType::Number(n2)) => n1.subtype(n2),
|
(PrimitiveType::Number(n1), PrimitiveType::Number(n2)) => n1.subtype(n2),
|
||||||
(PrimitiveType::TagId, PrimitiveType::Tag) => true,
|
|
||||||
(t1, t2) => t1 == t2,
|
(t1, t2) => t1 == t2,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -400,7 +379,6 @@ impl PrimitiveType {
|
|||||||
impl fmt::Display for PrimitiveType {
|
impl fmt::Display for PrimitiveType {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
PrimitiveType::Any => write!(f, "any"),
|
|
||||||
PrimitiveType::Number(NumericType::Known(unit)) => write!(f, "number({unit})"),
|
PrimitiveType::Number(NumericType::Known(unit)) => write!(f, "number({unit})"),
|
||||||
PrimitiveType::Number(NumericType::Unknown) => write!(f, "number(unknown units)"),
|
PrimitiveType::Number(NumericType::Unknown) => write!(f, "number(unknown units)"),
|
||||||
PrimitiveType::Number(NumericType::Default { .. }) => write!(f, "number(default units)"),
|
PrimitiveType::Number(NumericType::Default { .. }) => write!(f, "number(default units)"),
|
||||||
@ -408,7 +386,6 @@ impl fmt::Display for PrimitiveType {
|
|||||||
PrimitiveType::String => write!(f, "string"),
|
PrimitiveType::String => write!(f, "string"),
|
||||||
PrimitiveType::Boolean => write!(f, "bool"),
|
PrimitiveType::Boolean => write!(f, "bool"),
|
||||||
PrimitiveType::Tag => write!(f, "tag"),
|
PrimitiveType::Tag => write!(f, "tag"),
|
||||||
PrimitiveType::TagId => write!(f, "tag identifier"),
|
|
||||||
PrimitiveType::Sketch => write!(f, "Sketch"),
|
PrimitiveType::Sketch => write!(f, "Sketch"),
|
||||||
PrimitiveType::Solid => write!(f, "Solid"),
|
PrimitiveType::Solid => write!(f, "Solid"),
|
||||||
PrimitiveType::Plane => write!(f, "Plane"),
|
PrimitiveType::Plane => write!(f, "Plane"),
|
||||||
@ -686,7 +663,6 @@ impl NumericType {
|
|||||||
// We don't have enough information to coerce.
|
// We don't have enough information to coerce.
|
||||||
(Unknown, _) => Err(CoercionError::from(val).with_explicit(self.example_ty().unwrap_or("mm".to_owned()))),
|
(Unknown, _) => Err(CoercionError::from(val).with_explicit(self.example_ty().unwrap_or("mm".to_owned()))),
|
||||||
(_, Unknown) => Err(val.into()),
|
(_, Unknown) => Err(val.into()),
|
||||||
|
|
||||||
(Any, _) => Ok(KclValue::Number {
|
(Any, _) => Ok(KclValue::Number {
|
||||||
value: *value,
|
value: *value,
|
||||||
ty: self.clone(),
|
ty: self.clone(),
|
||||||
@ -1018,9 +994,9 @@ impl KclValue {
|
|||||||
self_ty.subtype(ty)
|
self_ty.subtype(ty)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Coerce `self` to a new value which has `ty` as its closest supertype.
|
/// Coerce `self` to a new value which has `ty` as it's closest supertype.
|
||||||
///
|
///
|
||||||
/// If the result is Ok, then:
|
/// If the result is Some, then:
|
||||||
/// - result.principal_type().unwrap().subtype(ty)
|
/// - result.principal_type().unwrap().subtype(ty)
|
||||||
///
|
///
|
||||||
/// If self.principal_type() == ty then result == self
|
/// If self.principal_type() == ty then result == self
|
||||||
@ -1040,11 +1016,10 @@ impl KclValue {
|
|||||||
exec_state: &mut ExecState,
|
exec_state: &mut ExecState,
|
||||||
) -> Result<KclValue, CoercionError> {
|
) -> Result<KclValue, CoercionError> {
|
||||||
let value = match self {
|
let value = match self {
|
||||||
KclValue::Tuple { value, .. } | KclValue::HomArray { value, .. } if value.len() == 1 => &value[0],
|
KclValue::MixedArray { value, .. } | KclValue::HomArray { value, .. } if value.len() == 1 => &value[0],
|
||||||
_ => self,
|
_ => self,
|
||||||
};
|
};
|
||||||
match ty {
|
match ty {
|
||||||
PrimitiveType::Any => Ok(value.clone()),
|
|
||||||
PrimitiveType::Number(ty) => ty.coerce(value),
|
PrimitiveType::Number(ty) => ty.coerce(value),
|
||||||
PrimitiveType::String => match value {
|
PrimitiveType::String => match value {
|
||||||
KclValue::String { .. } => Ok(value.clone()),
|
KclValue::String { .. } => Ok(value.clone()),
|
||||||
@ -1184,10 +1159,6 @@ impl KclValue {
|
|||||||
KclValue::ImportedGeometry { .. } => Ok(value.clone()),
|
KclValue::ImportedGeometry { .. } => Ok(value.clone()),
|
||||||
_ => Err(self.into()),
|
_ => Err(self.into()),
|
||||||
},
|
},
|
||||||
PrimitiveType::TagId => match value {
|
|
||||||
KclValue::TagIdentifier { .. } => Ok(value.clone()),
|
|
||||||
_ => Err(self.into()),
|
|
||||||
},
|
|
||||||
PrimitiveType::Tag => match value {
|
PrimitiveType::Tag => match value {
|
||||||
KclValue::TagDeclarator { .. } | KclValue::TagIdentifier { .. } | KclValue::Uuid { .. } => {
|
KclValue::TagDeclarator { .. } | KclValue::TagIdentifier { .. } | KclValue::Uuid { .. } => {
|
||||||
Ok(value.clone())
|
Ok(value.clone())
|
||||||
@ -1207,49 +1178,41 @@ impl KclValue {
|
|||||||
exec_state: &mut ExecState,
|
exec_state: &mut ExecState,
|
||||||
allow_shrink: bool,
|
allow_shrink: bool,
|
||||||
) -> Result<KclValue, CoercionError> {
|
) -> Result<KclValue, CoercionError> {
|
||||||
|
if len.satisfied(1, false).is_some() && self.has_type(ty) {
|
||||||
|
return Ok(KclValue::HomArray {
|
||||||
|
value: vec![self.clone()],
|
||||||
|
ty: ty.clone(),
|
||||||
|
});
|
||||||
|
}
|
||||||
match self {
|
match self {
|
||||||
KclValue::HomArray { value, ty: aty, .. } => {
|
KclValue::HomArray { value, ty: aty } => {
|
||||||
let satisfied_len = len.satisfied(value.len(), allow_shrink);
|
|
||||||
|
|
||||||
if aty.subtype(ty) {
|
if aty.subtype(ty) {
|
||||||
// If the element type is a subtype of the target type and
|
len.satisfied(value.len(), allow_shrink)
|
||||||
// the length constraint is satisfied, we can just return
|
|
||||||
// the values unchanged, only adjusting the length. The new
|
|
||||||
// array element type should preserve its type because the
|
|
||||||
// target type oftentimes includes an unknown type as a way
|
|
||||||
// to say that the caller doesn't care.
|
|
||||||
return satisfied_len
|
|
||||||
.map(|len| KclValue::HomArray {
|
.map(|len| KclValue::HomArray {
|
||||||
value: value[..len].to_vec(),
|
value: value[..len].to_vec(),
|
||||||
ty: aty.clone(),
|
ty: aty.clone(),
|
||||||
})
|
})
|
||||||
.ok_or(self.into());
|
.ok_or(self.into())
|
||||||
}
|
} else {
|
||||||
|
Err(self.into())
|
||||||
// Ignore the array type, and coerce the elements of the array.
|
|
||||||
if let Some(satisfied_len) = satisfied_len {
|
|
||||||
let value_result = value
|
|
||||||
.iter()
|
|
||||||
.take(satisfied_len)
|
|
||||||
.map(|v| v.coerce(ty, exec_state))
|
|
||||||
.collect::<Result<Vec<_>, _>>();
|
|
||||||
|
|
||||||
if let Ok(value) = value_result {
|
|
||||||
// We were able to coerce all the elements.
|
|
||||||
return Ok(KclValue::HomArray { value, ty: ty.clone() });
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
KclValue::MixedArray { value, .. } => {
|
||||||
// As a last resort, try to flatten the array.
|
// Check if we have a nested homogeneous array that we can flatten.
|
||||||
let mut values = Vec::new();
|
let mut values = Vec::new();
|
||||||
for item in value {
|
for item in value {
|
||||||
if let KclValue::HomArray { value: inner_value, .. } = item {
|
if let KclValue::HomArray {
|
||||||
// Flatten elements.
|
ty: inner_ty,
|
||||||
for item in inner_value {
|
value: inner_value,
|
||||||
values.push(item.coerce(ty, exec_state)?);
|
} = item
|
||||||
|
{
|
||||||
|
if inner_ty.subtype(ty) {
|
||||||
|
values.extend(inner_value.iter().cloned());
|
||||||
|
} else {
|
||||||
|
values.push(item.clone());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
values.push(item.coerce(ty, exec_state)?);
|
values.push(item.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1257,22 +1220,9 @@ impl KclValue {
|
|||||||
.satisfied(values.len(), allow_shrink)
|
.satisfied(values.len(), allow_shrink)
|
||||||
.ok_or(CoercionError::from(self))?;
|
.ok_or(CoercionError::from(self))?;
|
||||||
|
|
||||||
assert!(len <= values.len());
|
let value = values[..len]
|
||||||
values.truncate(len);
|
|
||||||
|
|
||||||
Ok(KclValue::HomArray {
|
|
||||||
value: values,
|
|
||||||
ty: ty.clone(),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
KclValue::Tuple { value, .. } => {
|
|
||||||
let len = len
|
|
||||||
.satisfied(value.len(), allow_shrink)
|
|
||||||
.ok_or(CoercionError::from(self))?;
|
|
||||||
let value = value
|
|
||||||
.iter()
|
.iter()
|
||||||
.map(|item| item.coerce(ty, exec_state))
|
.map(|v| v.coerce(ty, exec_state))
|
||||||
.take(len)
|
|
||||||
.collect::<Result<Vec<_>, _>>()?;
|
.collect::<Result<Vec<_>, _>>()?;
|
||||||
|
|
||||||
Ok(KclValue::HomArray { value, ty: ty.clone() })
|
Ok(KclValue::HomArray { value, ty: ty.clone() })
|
||||||
@ -1281,32 +1231,28 @@ impl KclValue {
|
|||||||
value: Vec::new(),
|
value: Vec::new(),
|
||||||
ty: ty.clone(),
|
ty: ty.clone(),
|
||||||
}),
|
}),
|
||||||
_ if len.satisfied(1, false).is_some() => Ok(KclValue::HomArray {
|
|
||||||
value: vec![self.coerce(ty, exec_state)?],
|
|
||||||
ty: ty.clone(),
|
|
||||||
}),
|
|
||||||
_ => Err(self.into()),
|
_ => Err(self.into()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn coerce_to_tuple_type(&self, tys: &[RuntimeType], exec_state: &mut ExecState) -> Result<KclValue, CoercionError> {
|
fn coerce_to_tuple_type(&self, tys: &[RuntimeType], exec_state: &mut ExecState) -> Result<KclValue, CoercionError> {
|
||||||
match self {
|
match self {
|
||||||
KclValue::Tuple { value, .. } | KclValue::HomArray { value, .. } if value.len() == tys.len() => {
|
KclValue::MixedArray { value, .. } | KclValue::HomArray { value, .. } if value.len() == tys.len() => {
|
||||||
let mut result = Vec::new();
|
let mut result = Vec::new();
|
||||||
for (i, t) in tys.iter().enumerate() {
|
for (i, t) in tys.iter().enumerate() {
|
||||||
result.push(value[i].coerce(t, exec_state)?);
|
result.push(value[i].coerce(t, exec_state)?);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(KclValue::Tuple {
|
Ok(KclValue::MixedArray {
|
||||||
value: result,
|
value: result,
|
||||||
meta: Vec::new(),
|
meta: Vec::new(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
KclValue::KclNone { meta, .. } if tys.is_empty() => Ok(KclValue::Tuple {
|
KclValue::KclNone { meta, .. } if tys.is_empty() => Ok(KclValue::MixedArray {
|
||||||
value: Vec::new(),
|
value: Vec::new(),
|
||||||
meta: meta.clone(),
|
meta: meta.clone(),
|
||||||
}),
|
}),
|
||||||
value if tys.len() == 1 && value.has_type(&tys[0]) => Ok(KclValue::Tuple {
|
value if tys.len() == 1 && value.has_type(&tys[0]) => Ok(KclValue::MixedArray {
|
||||||
value: vec![value.clone()],
|
value: vec![value.clone()],
|
||||||
meta: Vec::new(),
|
meta: Vec::new(),
|
||||||
}),
|
}),
|
||||||
@ -1366,7 +1312,7 @@ impl KclValue {
|
|||||||
KclValue::Face { .. } => Some(RuntimeType::Primitive(PrimitiveType::Face)),
|
KclValue::Face { .. } => Some(RuntimeType::Primitive(PrimitiveType::Face)),
|
||||||
KclValue::Helix { .. } => Some(RuntimeType::Primitive(PrimitiveType::Helix)),
|
KclValue::Helix { .. } => Some(RuntimeType::Primitive(PrimitiveType::Helix)),
|
||||||
KclValue::ImportedGeometry(..) => Some(RuntimeType::Primitive(PrimitiveType::ImportedGeometry)),
|
KclValue::ImportedGeometry(..) => Some(RuntimeType::Primitive(PrimitiveType::ImportedGeometry)),
|
||||||
KclValue::Tuple { value, .. } => Some(RuntimeType::Tuple(
|
KclValue::MixedArray { value, .. } => Some(RuntimeType::Tuple(
|
||||||
value.iter().map(|v| v.principal_type()).collect::<Option<Vec<_>>>()?,
|
value.iter().map(|v| v.principal_type()).collect::<Option<Vec<_>>>()?,
|
||||||
)),
|
)),
|
||||||
KclValue::HomArray { ty, value, .. } => {
|
KclValue::HomArray { ty, value, .. } => {
|
||||||
@ -1402,7 +1348,7 @@ mod test {
|
|||||||
value: "hello".to_owned(),
|
value: "hello".to_owned(),
|
||||||
meta: Vec::new(),
|
meta: Vec::new(),
|
||||||
},
|
},
|
||||||
KclValue::Tuple {
|
KclValue::MixedArray {
|
||||||
value: Vec::new(),
|
value: Vec::new(),
|
||||||
meta: Vec::new(),
|
meta: Vec::new(),
|
||||||
},
|
},
|
||||||
@ -1471,26 +1417,6 @@ mod test {
|
|||||||
let aty1 = RuntimeType::Array(Box::new(ty.clone()), ArrayLen::Known(1));
|
let aty1 = RuntimeType::Array(Box::new(ty.clone()), ArrayLen::Known(1));
|
||||||
let aty0 = RuntimeType::Array(Box::new(ty.clone()), ArrayLen::NonEmpty);
|
let aty0 = RuntimeType::Array(Box::new(ty.clone()), ArrayLen::NonEmpty);
|
||||||
|
|
||||||
match v {
|
|
||||||
KclValue::Tuple { .. } | KclValue::HomArray { .. } => {
|
|
||||||
// These will not get wrapped if possible.
|
|
||||||
assert_coerce_results(
|
|
||||||
v,
|
|
||||||
&aty,
|
|
||||||
&KclValue::HomArray {
|
|
||||||
value: vec![],
|
|
||||||
ty: ty.clone(),
|
|
||||||
},
|
|
||||||
&mut exec_state,
|
|
||||||
);
|
|
||||||
// Coercing an empty tuple or array to an array of length 1
|
|
||||||
// should fail.
|
|
||||||
v.coerce(&aty1, &mut exec_state).unwrap_err();
|
|
||||||
// Coercing an empty tuple or array to an array that's
|
|
||||||
// non-empty should fail.
|
|
||||||
v.coerce(&aty0, &mut exec_state).unwrap_err();
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
assert_coerce_results(
|
assert_coerce_results(
|
||||||
v,
|
v,
|
||||||
&aty,
|
&aty,
|
||||||
@ -1524,15 +1450,13 @@ mod test {
|
|||||||
assert_coerce_results(
|
assert_coerce_results(
|
||||||
v,
|
v,
|
||||||
&tty,
|
&tty,
|
||||||
&KclValue::Tuple {
|
&KclValue::MixedArray {
|
||||||
value: vec![v.clone()],
|
value: vec![v.clone()],
|
||||||
meta: Vec::new(),
|
meta: Vec::new(),
|
||||||
},
|
},
|
||||||
&mut exec_state,
|
&mut exec_state,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for v in &values[1..] {
|
for v in &values[1..] {
|
||||||
// Not a subtype
|
// Not a subtype
|
||||||
@ -1579,7 +1503,7 @@ mod test {
|
|||||||
assert_coerce_results(
|
assert_coerce_results(
|
||||||
&none,
|
&none,
|
||||||
&tty,
|
&tty,
|
||||||
&KclValue::Tuple {
|
&KclValue::MixedArray {
|
||||||
value: Vec::new(),
|
value: Vec::new(),
|
||||||
meta: Vec::new(),
|
meta: Vec::new(),
|
||||||
},
|
},
|
||||||
@ -1710,7 +1634,7 @@ mod test {
|
|||||||
],
|
],
|
||||||
ty: RuntimeType::Primitive(PrimitiveType::Number(NumericType::count())),
|
ty: RuntimeType::Primitive(PrimitiveType::Number(NumericType::count())),
|
||||||
};
|
};
|
||||||
let mixed1 = KclValue::Tuple {
|
let mixed1 = KclValue::MixedArray {
|
||||||
value: vec![
|
value: vec![
|
||||||
KclValue::Number {
|
KclValue::Number {
|
||||||
value: 0.0,
|
value: 0.0,
|
||||||
@ -1725,7 +1649,7 @@ mod test {
|
|||||||
],
|
],
|
||||||
meta: Vec::new(),
|
meta: Vec::new(),
|
||||||
};
|
};
|
||||||
let mixed2 = KclValue::Tuple {
|
let mixed2 = KclValue::MixedArray {
|
||||||
value: vec![
|
value: vec![
|
||||||
KclValue::Number {
|
KclValue::Number {
|
||||||
value: 0.0,
|
value: 0.0,
|
||||||
@ -1815,7 +1739,7 @@ mod test {
|
|||||||
],
|
],
|
||||||
ty: RuntimeType::Primitive(PrimitiveType::Number(NumericType::count())),
|
ty: RuntimeType::Primitive(PrimitiveType::Number(NumericType::count())),
|
||||||
};
|
};
|
||||||
let mixed0 = KclValue::Tuple {
|
let mixed0 = KclValue::MixedArray {
|
||||||
value: vec![],
|
value: vec![],
|
||||||
meta: Vec::new(),
|
meta: Vec::new(),
|
||||||
};
|
};
|
||||||
@ -2232,7 +2156,7 @@ d = cos(30)
|
|||||||
async fn coerce_nested_array() {
|
async fn coerce_nested_array() {
|
||||||
let mut exec_state = ExecState::new(&crate::ExecutorContext::new_mock().await);
|
let mut exec_state = ExecState::new(&crate::ExecutorContext::new_mock().await);
|
||||||
|
|
||||||
let mixed1 = KclValue::HomArray {
|
let mixed1 = KclValue::MixedArray {
|
||||||
value: vec![
|
value: vec![
|
||||||
KclValue::Number {
|
KclValue::Number {
|
||||||
value: 0.0,
|
value: 0.0,
|
||||||
@ -2260,7 +2184,7 @@ d = cos(30)
|
|||||||
ty: RuntimeType::Primitive(PrimitiveType::Number(NumericType::count())),
|
ty: RuntimeType::Primitive(PrimitiveType::Number(NumericType::count())),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
ty: RuntimeType::any(),
|
meta: Vec::new(),
|
||||||
};
|
};
|
||||||
|
|
||||||
// Principal types
|
// Principal types
|
||||||
|
|||||||
@ -150,7 +150,6 @@ impl BinaryPart {
|
|||||||
unary_expression.get_hover_value_for_position(pos, code, opts)
|
unary_expression.get_hover_value_for_position(pos, code, opts)
|
||||||
}
|
}
|
||||||
BinaryPart::IfExpression(e) => e.get_hover_value_for_position(pos, code, opts),
|
BinaryPart::IfExpression(e) => e.get_hover_value_for_position(pos, code, opts),
|
||||||
BinaryPart::AscribedExpression(e) => e.expr.get_hover_value_for_position(pos, code, opts),
|
|
||||||
BinaryPart::MemberExpression(member_expression) => {
|
BinaryPart::MemberExpression(member_expression) => {
|
||||||
member_expression.get_hover_value_for_position(pos, code, opts)
|
member_expression.get_hover_value_for_position(pos, code, opts)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -162,7 +162,6 @@ impl BinaryPart {
|
|||||||
BinaryPart::UnaryExpression(ue) => ue.compute_digest(),
|
BinaryPart::UnaryExpression(ue) => ue.compute_digest(),
|
||||||
BinaryPart::MemberExpression(me) => me.compute_digest(),
|
BinaryPart::MemberExpression(me) => me.compute_digest(),
|
||||||
BinaryPart::IfExpression(e) => e.compute_digest(),
|
BinaryPart::IfExpression(e) => e.compute_digest(),
|
||||||
BinaryPart::AscribedExpression(e) => e.compute_digest(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -226,7 +225,6 @@ impl PrimitiveType {
|
|||||||
pub fn compute_digest(&mut self) -> Digest {
|
pub fn compute_digest(&mut self) -> Digest {
|
||||||
let mut hasher = Sha256::new();
|
let mut hasher = Sha256::new();
|
||||||
match self {
|
match self {
|
||||||
PrimitiveType::Any => hasher.update(b"any"),
|
|
||||||
PrimitiveType::Named(id) => hasher.update(id.compute_digest()),
|
PrimitiveType::Named(id) => hasher.update(id.compute_digest()),
|
||||||
PrimitiveType::String => hasher.update(b"string"),
|
PrimitiveType::String => hasher.update(b"string"),
|
||||||
PrimitiveType::Number(suffix) => hasher.update(suffix.digestable_id()),
|
PrimitiveType::Number(suffix) => hasher.update(suffix.digestable_id()),
|
||||||
|
|||||||
@ -52,7 +52,6 @@ impl BinaryPart {
|
|||||||
BinaryPart::UnaryExpression(unary_expression) => unary_expression.module_id,
|
BinaryPart::UnaryExpression(unary_expression) => unary_expression.module_id,
|
||||||
BinaryPart::MemberExpression(member_expression) => member_expression.module_id,
|
BinaryPart::MemberExpression(member_expression) => member_expression.module_id,
|
||||||
BinaryPart::IfExpression(e) => e.module_id,
|
BinaryPart::IfExpression(e) => e.module_id,
|
||||||
BinaryPart::AscribedExpression(e) => e.module_id,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1215,7 +1215,6 @@ impl From<&BinaryPart> for Expr {
|
|||||||
BinaryPart::UnaryExpression(unary_expression) => Expr::UnaryExpression(unary_expression.clone()),
|
BinaryPart::UnaryExpression(unary_expression) => Expr::UnaryExpression(unary_expression.clone()),
|
||||||
BinaryPart::MemberExpression(member_expression) => Expr::MemberExpression(member_expression.clone()),
|
BinaryPart::MemberExpression(member_expression) => Expr::MemberExpression(member_expression.clone()),
|
||||||
BinaryPart::IfExpression(e) => Expr::IfExpression(e.clone()),
|
BinaryPart::IfExpression(e) => Expr::IfExpression(e.clone()),
|
||||||
BinaryPart::AscribedExpression(e) => Expr::AscribedExpression(e.clone()),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1282,7 +1281,6 @@ pub enum BinaryPart {
|
|||||||
UnaryExpression(BoxNode<UnaryExpression>),
|
UnaryExpression(BoxNode<UnaryExpression>),
|
||||||
MemberExpression(BoxNode<MemberExpression>),
|
MemberExpression(BoxNode<MemberExpression>),
|
||||||
IfExpression(BoxNode<IfExpression>),
|
IfExpression(BoxNode<IfExpression>),
|
||||||
AscribedExpression(BoxNode<AscribedExpression>),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<BinaryPart> for SourceRange {
|
impl From<BinaryPart> for SourceRange {
|
||||||
@ -1308,7 +1306,6 @@ impl BinaryPart {
|
|||||||
BinaryPart::UnaryExpression(unary_expression) => unary_expression.get_constraint_level(),
|
BinaryPart::UnaryExpression(unary_expression) => unary_expression.get_constraint_level(),
|
||||||
BinaryPart::MemberExpression(member_expression) => member_expression.get_constraint_level(),
|
BinaryPart::MemberExpression(member_expression) => member_expression.get_constraint_level(),
|
||||||
BinaryPart::IfExpression(e) => e.get_constraint_level(),
|
BinaryPart::IfExpression(e) => e.get_constraint_level(),
|
||||||
BinaryPart::AscribedExpression(e) => e.expr.get_constraint_level(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1327,7 +1324,6 @@ impl BinaryPart {
|
|||||||
}
|
}
|
||||||
BinaryPart::MemberExpression(_) => {}
|
BinaryPart::MemberExpression(_) => {}
|
||||||
BinaryPart::IfExpression(e) => e.replace_value(source_range, new_value),
|
BinaryPart::IfExpression(e) => e.replace_value(source_range, new_value),
|
||||||
BinaryPart::AscribedExpression(e) => e.expr.replace_value(source_range, new_value),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1340,7 +1336,6 @@ impl BinaryPart {
|
|||||||
BinaryPart::UnaryExpression(unary_expression) => unary_expression.start,
|
BinaryPart::UnaryExpression(unary_expression) => unary_expression.start,
|
||||||
BinaryPart::MemberExpression(member_expression) => member_expression.start,
|
BinaryPart::MemberExpression(member_expression) => member_expression.start,
|
||||||
BinaryPart::IfExpression(e) => e.start,
|
BinaryPart::IfExpression(e) => e.start,
|
||||||
BinaryPart::AscribedExpression(e) => e.start,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1353,7 +1348,6 @@ impl BinaryPart {
|
|||||||
BinaryPart::UnaryExpression(unary_expression) => unary_expression.end,
|
BinaryPart::UnaryExpression(unary_expression) => unary_expression.end,
|
||||||
BinaryPart::MemberExpression(member_expression) => member_expression.end,
|
BinaryPart::MemberExpression(member_expression) => member_expression.end,
|
||||||
BinaryPart::IfExpression(e) => e.end,
|
BinaryPart::IfExpression(e) => e.end,
|
||||||
BinaryPart::AscribedExpression(e) => e.end,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1375,7 +1369,6 @@ impl BinaryPart {
|
|||||||
member_expression.rename_identifiers(old_name, new_name)
|
member_expression.rename_identifiers(old_name, new_name)
|
||||||
}
|
}
|
||||||
BinaryPart::IfExpression(ref mut if_expression) => if_expression.rename_identifiers(old_name, new_name),
|
BinaryPart::IfExpression(ref mut if_expression) => if_expression.rename_identifiers(old_name, new_name),
|
||||||
BinaryPart::AscribedExpression(ref mut e) => e.expr.rename_identifiers(old_name, new_name),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3186,8 +3179,6 @@ impl PipeExpression {
|
|||||||
#[ts(export)]
|
#[ts(export)]
|
||||||
#[serde(tag = "p_type")]
|
#[serde(tag = "p_type")]
|
||||||
pub enum PrimitiveType {
|
pub enum PrimitiveType {
|
||||||
/// The super type of all other types.
|
|
||||||
Any,
|
|
||||||
/// A string type.
|
/// A string type.
|
||||||
String,
|
String,
|
||||||
/// A number type.
|
/// A number type.
|
||||||
@ -3204,7 +3195,6 @@ pub enum PrimitiveType {
|
|||||||
impl PrimitiveType {
|
impl PrimitiveType {
|
||||||
pub fn primitive_from_str(s: &str, suffix: Option<NumericSuffix>) -> Option<Self> {
|
pub fn primitive_from_str(s: &str, suffix: Option<NumericSuffix>) -> Option<Self> {
|
||||||
match (s, suffix) {
|
match (s, suffix) {
|
||||||
("any", None) => Some(PrimitiveType::Any),
|
|
||||||
("string", None) => Some(PrimitiveType::String),
|
("string", None) => Some(PrimitiveType::String),
|
||||||
("bool", None) => Some(PrimitiveType::Boolean),
|
("bool", None) => Some(PrimitiveType::Boolean),
|
||||||
("tag", None) => Some(PrimitiveType::Tag),
|
("tag", None) => Some(PrimitiveType::Tag),
|
||||||
@ -3218,7 +3208,6 @@ impl PrimitiveType {
|
|||||||
impl fmt::Display for PrimitiveType {
|
impl fmt::Display for PrimitiveType {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
PrimitiveType::Any => write!(f, "any"),
|
|
||||||
PrimitiveType::Number(suffix) => {
|
PrimitiveType::Number(suffix) => {
|
||||||
write!(f, "number")?;
|
write!(f, "number")?;
|
||||||
if *suffix != NumericSuffix::None {
|
if *suffix != NumericSuffix::None {
|
||||||
|
|||||||
@ -582,26 +582,6 @@ fn binary_operator(i: &mut TokenSlice) -> PResult<BinaryOperator> {
|
|||||||
"<=" => BinaryOperator::Lte,
|
"<=" => BinaryOperator::Lte,
|
||||||
"|" => BinaryOperator::Or,
|
"|" => BinaryOperator::Or,
|
||||||
"&" => BinaryOperator::And,
|
"&" => BinaryOperator::And,
|
||||||
"||" => {
|
|
||||||
ParseContext::err(
|
|
||||||
CompilationError::err(
|
|
||||||
token.as_source_range(),
|
|
||||||
"`||` is not an operator, did you mean to use `|`?",
|
|
||||||
)
|
|
||||||
.with_suggestion("Replace `||` with `|`", "|", None, Tag::None),
|
|
||||||
);
|
|
||||||
BinaryOperator::Or
|
|
||||||
}
|
|
||||||
"&&" => {
|
|
||||||
ParseContext::err(
|
|
||||||
CompilationError::err(
|
|
||||||
token.as_source_range(),
|
|
||||||
"`&&` is not an operator, did you mean to use `&`?",
|
|
||||||
)
|
|
||||||
.with_suggestion("Replace `&&` with `&`", "&", None, Tag::None),
|
|
||||||
);
|
|
||||||
BinaryOperator::And
|
|
||||||
}
|
|
||||||
_ => {
|
_ => {
|
||||||
return Err(CompilationError::fatal(
|
return Err(CompilationError::fatal(
|
||||||
token.as_source_range(),
|
token.as_source_range(),
|
||||||
@ -631,7 +611,8 @@ fn operand(i: &mut TokenSlice) -> PResult<BinaryPart> {
|
|||||||
| Expr::ArrayExpression(_)
|
| Expr::ArrayExpression(_)
|
||||||
| Expr::ArrayRangeExpression(_)
|
| Expr::ArrayRangeExpression(_)
|
||||||
| Expr::ObjectExpression(_)
|
| Expr::ObjectExpression(_)
|
||||||
| Expr::LabelledExpression(..) => return Err(CompilationError::fatal(source_range, TODO_783)),
|
| Expr::LabelledExpression(..)
|
||||||
|
| Expr::AscribedExpression(..) => return Err(CompilationError::fatal(source_range, TODO_783)),
|
||||||
Expr::None(_) => {
|
Expr::None(_) => {
|
||||||
return Err(CompilationError::fatal(
|
return Err(CompilationError::fatal(
|
||||||
source_range,
|
source_range,
|
||||||
@ -657,7 +638,6 @@ fn operand(i: &mut TokenSlice) -> PResult<BinaryPart> {
|
|||||||
Expr::CallExpressionKw(x) => BinaryPart::CallExpressionKw(x),
|
Expr::CallExpressionKw(x) => BinaryPart::CallExpressionKw(x),
|
||||||
Expr::MemberExpression(x) => BinaryPart::MemberExpression(x),
|
Expr::MemberExpression(x) => BinaryPart::MemberExpression(x),
|
||||||
Expr::IfExpression(x) => BinaryPart::IfExpression(x),
|
Expr::IfExpression(x) => BinaryPart::IfExpression(x),
|
||||||
Expr::AscribedExpression(x) => BinaryPart::AscribedExpression(x),
|
|
||||||
};
|
};
|
||||||
Ok(expr)
|
Ok(expr)
|
||||||
})
|
})
|
||||||
@ -2068,7 +2048,7 @@ fn expr_allowed_in_pipe_expr(i: &mut TokenSlice) -> PResult<Expr> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn possible_operands(i: &mut TokenSlice) -> PResult<Expr> {
|
fn possible_operands(i: &mut TokenSlice) -> PResult<Expr> {
|
||||||
let mut expr = alt((
|
alt((
|
||||||
unary_expression.map(Box::new).map(Expr::UnaryExpression),
|
unary_expression.map(Box::new).map(Expr::UnaryExpression),
|
||||||
bool_value.map(Expr::Literal),
|
bool_value.map(Expr::Literal),
|
||||||
member_expression.map(Box::new).map(Expr::MemberExpression),
|
member_expression.map(Box::new).map(Expr::MemberExpression),
|
||||||
@ -2081,14 +2061,7 @@ fn possible_operands(i: &mut TokenSlice) -> PResult<Expr> {
|
|||||||
.context(expected(
|
.context(expected(
|
||||||
"a KCL value which can be used as an argument/operand to an operator",
|
"a KCL value which can be used as an argument/operand to an operator",
|
||||||
))
|
))
|
||||||
.parse_next(i)?;
|
.parse_next(i)
|
||||||
|
|
||||||
let ty = opt((colon, opt(whitespace), argument_type)).parse_next(i)?;
|
|
||||||
if let Some((_, _, ty)) = ty {
|
|
||||||
expr = Expr::AscribedExpression(Box::new(AscribedExpression::new(expr, ty)))
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(expr)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parse an item visibility specifier, e.g. export.
|
/// Parse an item visibility specifier, e.g. export.
|
||||||
@ -2757,9 +2730,9 @@ fn labeled_argument(i: &mut TokenSlice) -> PResult<LabeledArg> {
|
|||||||
|
|
||||||
/// A type of a function argument.
|
/// A type of a function argument.
|
||||||
/// This can be:
|
/// This can be:
|
||||||
/// - a primitive type, e.g. `number` or `string` or `bool`
|
/// - a primitive type, e.g. 'number' or 'string' or 'bool'
|
||||||
/// - an array type, e.g. `[number]` or `[string]` or `[bool]`
|
/// - an array type, e.g. 'number[]' or 'string[]' or 'bool[]'
|
||||||
/// - an object type, e.g. `{x: number, y: number}` or `{name: string, age: number}`
|
/// - an object type, e.g. '{x: number, y: number}' or '{name: string, age: number}'
|
||||||
fn argument_type(i: &mut TokenSlice) -> PResult<Node<Type>> {
|
fn argument_type(i: &mut TokenSlice) -> PResult<Node<Type>> {
|
||||||
let type_ = alt((
|
let type_ = alt((
|
||||||
// Object types
|
// Object types
|
||||||
@ -4538,13 +4511,6 @@ export fn cos(num: number(rad)): number(_) {}"#;
|
|||||||
assert_eq!(errs.len(), 3, "found: {errs:#?}");
|
assert_eq!(errs.len(), 3, "found: {errs:#?}");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn error_double_and() {
|
|
||||||
let (_, errs) = assert_no_fatal("foo = true && false");
|
|
||||||
assert_eq!(errs.len(), 1, "found: {errs:#?}");
|
|
||||||
assert!(errs[0].message.contains("`&&`") && errs[0].message.contains("`&`") && errs[0].suggestion.is_some());
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn error_type_ascription() {
|
fn error_type_ascription() {
|
||||||
let (_, errs) = assert_no_fatal("a + b: number");
|
let (_, errs) = assert_no_fatal("a + b: number");
|
||||||
|
|||||||
@ -181,7 +181,7 @@ fn word(i: &mut Input<'_>) -> PResult<Token> {
|
|||||||
|
|
||||||
fn operator(i: &mut Input<'_>) -> PResult<Token> {
|
fn operator(i: &mut Input<'_>) -> PResult<Token> {
|
||||||
let (value, range) = alt((
|
let (value, range) = alt((
|
||||||
">=", "<=", "==", "=>", "!=", "|>", "*", "+", "-", "/", "%", "=", "<", ">", r"\", "^", "||", "&&", "|", "&",
|
">=", "<=", "==", "=>", "!=", "|>", "*", "+", "-", "/", "%", "=", "<", ">", r"\", "^", "|", "&",
|
||||||
))
|
))
|
||||||
.with_span()
|
.with_span()
|
||||||
.parse_next(i)?;
|
.parse_next(i)?;
|
||||||
|
|||||||
@ -363,27 +363,6 @@ mod cube_with_error {
|
|||||||
super::execute(TEST_NAME, true).await
|
super::execute(TEST_NAME, true).await
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mod any_type {
|
|
||||||
const TEST_NAME: &str = "any_type";
|
|
||||||
|
|
||||||
/// Test parsing KCL.
|
|
||||||
#[test]
|
|
||||||
fn parse() {
|
|
||||||
super::parse(TEST_NAME)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Test that parsing and unparsing KCL produces the original KCL input.
|
|
||||||
#[tokio::test(flavor = "multi_thread")]
|
|
||||||
async fn unparse() {
|
|
||||||
super::unparse(TEST_NAME).await
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Test that KCL is executed correctly.
|
|
||||||
#[tokio::test(flavor = "multi_thread")]
|
|
||||||
async fn kcl_test_execute() {
|
|
||||||
super::execute(TEST_NAME, false).await
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mod artifact_graph_example_code1 {
|
mod artifact_graph_example_code1 {
|
||||||
const TEST_NAME: &str = "artifact_graph_example_code1";
|
const TEST_NAME: &str = "artifact_graph_example_code1";
|
||||||
|
|
||||||
@ -594,48 +573,6 @@ mod array_range_negative_expr {
|
|||||||
super::execute(TEST_NAME, false).await
|
super::execute(TEST_NAME, false).await
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mod array_range_with_units {
|
|
||||||
const TEST_NAME: &str = "array_range_with_units";
|
|
||||||
|
|
||||||
/// Test parsing KCL.
|
|
||||||
#[test]
|
|
||||||
fn parse() {
|
|
||||||
super::parse(TEST_NAME)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Test that parsing and unparsing KCL produces the original KCL input.
|
|
||||||
#[tokio::test(flavor = "multi_thread")]
|
|
||||||
async fn unparse() {
|
|
||||||
super::unparse(TEST_NAME).await
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Test that KCL is executed correctly.
|
|
||||||
#[tokio::test(flavor = "multi_thread")]
|
|
||||||
async fn kcl_test_execute() {
|
|
||||||
super::execute(TEST_NAME, false).await
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mod array_range_mismatch_units {
|
|
||||||
const TEST_NAME: &str = "array_range_mismatch_units";
|
|
||||||
|
|
||||||
/// Test parsing KCL.
|
|
||||||
#[test]
|
|
||||||
fn parse() {
|
|
||||||
super::parse(TEST_NAME)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Test that parsing and unparsing KCL produces the original KCL input.
|
|
||||||
#[tokio::test(flavor = "multi_thread")]
|
|
||||||
async fn unparse() {
|
|
||||||
super::unparse(TEST_NAME).await
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Test that KCL is executed correctly.
|
|
||||||
#[tokio::test(flavor = "multi_thread")]
|
|
||||||
async fn kcl_test_execute() {
|
|
||||||
super::execute(TEST_NAME, false).await
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mod sketch_in_object {
|
mod sketch_in_object {
|
||||||
const TEST_NAME: &str = "sketch_in_object";
|
const TEST_NAME: &str = "sketch_in_object";
|
||||||
|
|
||||||
@ -1207,27 +1144,6 @@ mod array_elem_push_fail {
|
|||||||
super::execute(TEST_NAME, false).await
|
super::execute(TEST_NAME, false).await
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mod array_push_item_wrong_type {
|
|
||||||
const TEST_NAME: &str = "array_push_item_wrong_type";
|
|
||||||
|
|
||||||
/// Test parsing KCL.
|
|
||||||
#[test]
|
|
||||||
fn parse() {
|
|
||||||
super::parse(TEST_NAME)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Test that parsing and unparsing KCL produces the original KCL input.
|
|
||||||
#[tokio::test(flavor = "multi_thread")]
|
|
||||||
async fn unparse() {
|
|
||||||
super::unparse(TEST_NAME).await
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Test that KCL is executed correctly.
|
|
||||||
#[tokio::test(flavor = "multi_thread")]
|
|
||||||
async fn kcl_test_execute() {
|
|
||||||
super::execute(TEST_NAME, false).await
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mod sketch_on_face {
|
mod sketch_on_face {
|
||||||
const TEST_NAME: &str = "sketch_on_face";
|
const TEST_NAME: &str = "sketch_on_face";
|
||||||
|
|
||||||
|
|||||||
@ -408,9 +408,12 @@ impl Args {
|
|||||||
})?;
|
})?;
|
||||||
|
|
||||||
T::from_kcl_val(&arg).ok_or_else(|| {
|
T::from_kcl_val(&arg).ok_or_else(|| {
|
||||||
KclError::Internal(KclErrorDetails {
|
KclError::Semantic(KclErrorDetails {
|
||||||
source_ranges: vec![self.source_range],
|
source_ranges: vec![self.source_range],
|
||||||
message: "Mismatch between type coercion and value extraction (this isn't your fault).\nTo assist in bug-reporting, expected type: {ty:?}; actual value: {arg:?}".to_owned(),
|
message: format!(
|
||||||
|
"This function expected the input argument to be {}",
|
||||||
|
ty.human_friendly_type(),
|
||||||
|
),
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -557,23 +560,24 @@ impl Args {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn make_kcl_val_from_point(&self, p: [f64; 2], ty: NumericType) -> Result<KclValue, KclError> {
|
pub(crate) fn make_user_val_from_point(&self, p: [TyF64; 2]) -> Result<KclValue, KclError> {
|
||||||
let meta = Metadata {
|
let meta = Metadata {
|
||||||
source_range: self.source_range,
|
source_range: self.source_range,
|
||||||
};
|
};
|
||||||
let x = KclValue::Number {
|
let x = KclValue::Number {
|
||||||
value: p[0],
|
value: p[0].n,
|
||||||
meta: vec![meta],
|
meta: vec![meta],
|
||||||
ty: ty.clone(),
|
ty: p[0].ty.clone(),
|
||||||
};
|
};
|
||||||
let y = KclValue::Number {
|
let y = KclValue::Number {
|
||||||
value: p[1],
|
value: p[1].n,
|
||||||
meta: vec![meta],
|
meta: vec![meta],
|
||||||
ty: ty.clone(),
|
ty: p[1].ty.clone(),
|
||||||
};
|
};
|
||||||
let ty = RuntimeType::Primitive(PrimitiveType::Number(ty));
|
Ok(KclValue::MixedArray {
|
||||||
|
value: vec![x, y],
|
||||||
Ok(KclValue::HomArray { value: vec![x, y], ty })
|
meta: vec![meta],
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn make_user_val_from_f64_with_type(&self, f: TyF64) -> KclValue {
|
pub(super) fn make_user_val_from_f64_with_type(&self, f: TyF64) -> KclValue {
|
||||||
@ -795,7 +799,7 @@ impl<'a> FromKclValue<'a> for Vec<TagIdentifier> {
|
|||||||
let tags = value.iter().map(|v| v.get_tag_identifier().unwrap()).collect();
|
let tags = value.iter().map(|v| v.get_tag_identifier().unwrap()).collect();
|
||||||
Some(tags)
|
Some(tags)
|
||||||
}
|
}
|
||||||
KclValue::Tuple { value, .. } => {
|
KclValue::MixedArray { value, .. } => {
|
||||||
let tags = value.iter().map(|v| v.get_tag_identifier().unwrap()).collect();
|
let tags = value.iter().map(|v| v.get_tag_identifier().unwrap()).collect();
|
||||||
Some(tags)
|
Some(tags)
|
||||||
}
|
}
|
||||||
@ -1135,11 +1139,8 @@ impl_from_kcl_for_vec!(TyF64);
|
|||||||
|
|
||||||
impl<'a> FromKclValue<'a> for SourceRange {
|
impl<'a> FromKclValue<'a> for SourceRange {
|
||||||
fn from_kcl_val(arg: &'a KclValue) -> Option<Self> {
|
fn from_kcl_val(arg: &'a KclValue) -> Option<Self> {
|
||||||
let value = match arg {
|
let KclValue::MixedArray { value, meta: _ } = arg else {
|
||||||
KclValue::Tuple { value, .. } | KclValue::HomArray { value, .. } => value,
|
|
||||||
_ => {
|
|
||||||
return None;
|
return None;
|
||||||
}
|
|
||||||
};
|
};
|
||||||
if value.len() != 3 {
|
if value.len() != 3 {
|
||||||
return None;
|
return None;
|
||||||
@ -1336,7 +1337,7 @@ impl<'a> FromKclValue<'a> for TyF64 {
|
|||||||
impl<'a> FromKclValue<'a> for [TyF64; 2] {
|
impl<'a> FromKclValue<'a> for [TyF64; 2] {
|
||||||
fn from_kcl_val(arg: &'a KclValue) -> Option<Self> {
|
fn from_kcl_val(arg: &'a KclValue) -> Option<Self> {
|
||||||
match arg {
|
match arg {
|
||||||
KclValue::Tuple { value, meta: _ } | KclValue::HomArray { value, .. } => {
|
KclValue::MixedArray { value, meta: _ } | KclValue::HomArray { value, .. } => {
|
||||||
if value.len() != 2 {
|
if value.len() != 2 {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
@ -1353,7 +1354,7 @@ impl<'a> FromKclValue<'a> for [TyF64; 2] {
|
|||||||
impl<'a> FromKclValue<'a> for [TyF64; 3] {
|
impl<'a> FromKclValue<'a> for [TyF64; 3] {
|
||||||
fn from_kcl_val(arg: &'a KclValue) -> Option<Self> {
|
fn from_kcl_val(arg: &'a KclValue) -> Option<Self> {
|
||||||
match arg {
|
match arg {
|
||||||
KclValue::Tuple { value, meta: _ } | KclValue::HomArray { value, .. } => {
|
KclValue::MixedArray { value, meta: _ } | KclValue::HomArray { value, .. } => {
|
||||||
if value.len() != 3 {
|
if value.len() != 3 {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,7 +9,6 @@ use crate::{
|
|||||||
errors::{KclError, KclErrorDetails},
|
errors::{KclError, KclErrorDetails},
|
||||||
execution::{
|
execution::{
|
||||||
kcl_value::{FunctionSource, KclValue},
|
kcl_value::{FunctionSource, KclValue},
|
||||||
types::RuntimeType,
|
|
||||||
ExecState,
|
ExecState,
|
||||||
},
|
},
|
||||||
source_range::SourceRange,
|
source_range::SourceRange,
|
||||||
@ -20,11 +19,9 @@ use crate::{
|
|||||||
pub async fn map(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
pub async fn map(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
||||||
let array: Vec<KclValue> = args.get_unlabeled_kw_arg("array")?;
|
let array: Vec<KclValue> = args.get_unlabeled_kw_arg("array")?;
|
||||||
let f: &FunctionSource = args.get_kw_arg("f")?;
|
let f: &FunctionSource = args.get_kw_arg("f")?;
|
||||||
|
let meta = vec![args.source_range.into()];
|
||||||
let new_array = inner_map(array, f, exec_state, &args).await?;
|
let new_array = inner_map(array, f, exec_state, &args).await?;
|
||||||
Ok(KclValue::HomArray {
|
Ok(KclValue::MixedArray { value: new_array, meta })
|
||||||
value: new_array,
|
|
||||||
ty: RuntimeType::any(),
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Apply a function to every element of a list.
|
/// Apply a function to every element of a list.
|
||||||
@ -260,31 +257,6 @@ async fn call_reduce_closure(
|
|||||||
Ok(out)
|
Ok(out)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn push(_exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
|
||||||
let array = args.get_unlabeled_kw_arg("array")?;
|
|
||||||
let item: KclValue = args.get_kw_arg("item")?;
|
|
||||||
|
|
||||||
let KclValue::HomArray { value: values, ty } = array else {
|
|
||||||
let meta = vec![args.source_range];
|
|
||||||
let actual_type = array.human_friendly_type();
|
|
||||||
return Err(KclError::Semantic(KclErrorDetails {
|
|
||||||
source_ranges: meta,
|
|
||||||
message: format!("You can't push to a value of type {actual_type}, only an array"),
|
|
||||||
}));
|
|
||||||
};
|
|
||||||
let ty = if item.has_type(&ty) {
|
|
||||||
ty
|
|
||||||
} else {
|
|
||||||
// The user pushed an item with a type that differs from the array's
|
|
||||||
// element type.
|
|
||||||
RuntimeType::any()
|
|
||||||
};
|
|
||||||
|
|
||||||
let new_array = inner_push(values, item);
|
|
||||||
|
|
||||||
Ok(KclValue::HomArray { value: new_array, ty })
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Append an element to the end of an array.
|
/// Append an element to the end of an array.
|
||||||
///
|
///
|
||||||
/// Returns a new array with the element appended.
|
/// Returns a new array with the element appended.
|
||||||
@ -304,26 +276,28 @@ pub async fn push(_exec_state: &mut ExecState, args: Args) -> Result<KclValue, K
|
|||||||
},
|
},
|
||||||
tags = ["array"]
|
tags = ["array"]
|
||||||
}]
|
}]
|
||||||
fn inner_push(mut array: Vec<KclValue>, item: KclValue) -> Vec<KclValue> {
|
async fn inner_push(mut array: Vec<KclValue>, item: KclValue, args: &Args) -> Result<KclValue, KclError> {
|
||||||
array.push(item);
|
array.push(item);
|
||||||
|
Ok(KclValue::MixedArray {
|
||||||
array
|
value: array,
|
||||||
|
meta: vec![args.source_range.into()],
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn pop(_exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
pub async fn push(_exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
||||||
let array = args.get_unlabeled_kw_arg("array")?;
|
// Extract the array and the element from the arguments
|
||||||
let KclValue::HomArray { value: values, ty } = array else {
|
let val: KclValue = args.get_unlabeled_kw_arg("array")?;
|
||||||
|
let item = args.get_kw_arg("item")?;
|
||||||
|
|
||||||
let meta = vec![args.source_range];
|
let meta = vec![args.source_range];
|
||||||
let actual_type = array.human_friendly_type();
|
let KclValue::MixedArray { value: array, meta: _ } = val else {
|
||||||
|
let actual_type = val.human_friendly_type();
|
||||||
return Err(KclError::Semantic(KclErrorDetails {
|
return Err(KclError::Semantic(KclErrorDetails {
|
||||||
source_ranges: meta,
|
source_ranges: meta,
|
||||||
message: format!("You can't pop from a value of type {actual_type}, only an array"),
|
message: format!("You can't push to a value of type {actual_type}, only an array"),
|
||||||
}));
|
}));
|
||||||
};
|
};
|
||||||
|
inner_push(array, item, &args).await
|
||||||
let new_array = inner_pop(values, &args)?;
|
|
||||||
|
|
||||||
Ok(KclValue::HomArray { value: new_array, ty })
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Remove the last element from an array.
|
/// Remove the last element from an array.
|
||||||
@ -346,7 +320,7 @@ pub async fn pop(_exec_state: &mut ExecState, args: Args) -> Result<KclValue, Kc
|
|||||||
},
|
},
|
||||||
tags = ["array"]
|
tags = ["array"]
|
||||||
}]
|
}]
|
||||||
fn inner_pop(array: Vec<KclValue>, args: &Args) -> Result<Vec<KclValue>, KclError> {
|
async fn inner_pop(array: Vec<KclValue>, args: &Args) -> Result<KclValue, KclError> {
|
||||||
if array.is_empty() {
|
if array.is_empty() {
|
||||||
return Err(KclError::Semantic(KclErrorDetails {
|
return Err(KclError::Semantic(KclErrorDetails {
|
||||||
message: "Cannot pop from an empty array".to_string(),
|
message: "Cannot pop from an empty array".to_string(),
|
||||||
@ -357,5 +331,24 @@ fn inner_pop(array: Vec<KclValue>, args: &Args) -> Result<Vec<KclValue>, KclErro
|
|||||||
// Create a new array with all elements except the last one
|
// Create a new array with all elements except the last one
|
||||||
let new_array = array[..array.len() - 1].to_vec();
|
let new_array = array[..array.len() - 1].to_vec();
|
||||||
|
|
||||||
Ok(new_array)
|
Ok(KclValue::MixedArray {
|
||||||
|
value: new_array,
|
||||||
|
meta: vec![args.source_range.into()],
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn pop(_exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
||||||
|
// Extract the array from the arguments
|
||||||
|
let val = args.get_unlabeled_kw_arg("array")?;
|
||||||
|
|
||||||
|
let meta = vec![args.source_range];
|
||||||
|
let KclValue::MixedArray { value: array, meta: _ } = val else {
|
||||||
|
let actual_type = val.human_friendly_type();
|
||||||
|
return Err(KclError::Semantic(KclErrorDetails {
|
||||||
|
source_ranges: meta,
|
||||||
|
message: format!("You can't pop from a value of type {actual_type}, only an array"),
|
||||||
|
}));
|
||||||
|
};
|
||||||
|
|
||||||
|
inner_pop(array, &args).await
|
||||||
}
|
}
|
||||||
|
|||||||
@ -14,7 +14,7 @@ use crate::{
|
|||||||
|
|
||||||
/// Get the opposite edge to the edge given.
|
/// Get the opposite edge to the edge given.
|
||||||
pub async fn get_opposite_edge(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
pub async fn get_opposite_edge(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
||||||
let input_edge = args.get_unlabeled_kw_arg_typed("edge", &RuntimeType::tag_identifier(), exec_state)?;
|
let input_edge = args.get_unlabeled_kw_arg_typed("edge", &RuntimeType::edge(), exec_state)?;
|
||||||
|
|
||||||
let edge = inner_get_opposite_edge(input_edge, exec_state, args.clone()).await?;
|
let edge = inner_get_opposite_edge(input_edge, exec_state, args.clone()).await?;
|
||||||
Ok(KclValue::Uuid {
|
Ok(KclValue::Uuid {
|
||||||
@ -98,7 +98,7 @@ async fn inner_get_opposite_edge(
|
|||||||
|
|
||||||
/// Get the next adjacent edge to the edge given.
|
/// Get the next adjacent edge to the edge given.
|
||||||
pub async fn get_next_adjacent_edge(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
pub async fn get_next_adjacent_edge(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
||||||
let input_edge = args.get_unlabeled_kw_arg_typed("edge", &RuntimeType::tag_identifier(), exec_state)?;
|
let input_edge = args.get_unlabeled_kw_arg_typed("edge", &RuntimeType::edge(), exec_state)?;
|
||||||
|
|
||||||
let edge = inner_get_next_adjacent_edge(input_edge, exec_state, args.clone()).await?;
|
let edge = inner_get_next_adjacent_edge(input_edge, exec_state, args.clone()).await?;
|
||||||
Ok(KclValue::Uuid {
|
Ok(KclValue::Uuid {
|
||||||
@ -191,7 +191,7 @@ async fn inner_get_next_adjacent_edge(
|
|||||||
|
|
||||||
/// Get the previous adjacent edge to the edge given.
|
/// Get the previous adjacent edge to the edge given.
|
||||||
pub async fn get_previous_adjacent_edge(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
pub async fn get_previous_adjacent_edge(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
||||||
let input_edge = args.get_unlabeled_kw_arg_typed("edge", &RuntimeType::tag_identifier(), exec_state)?;
|
let input_edge = args.get_unlabeled_kw_arg_typed("edge", &RuntimeType::edge(), exec_state)?;
|
||||||
|
|
||||||
let edge = inner_get_previous_adjacent_edge(input_edge, exec_state, args.clone()).await?;
|
let edge = inner_get_previous_adjacent_edge(input_edge, exec_state, args.clone()).await?;
|
||||||
Ok(KclValue::Uuid {
|
Ok(KclValue::Uuid {
|
||||||
|
|||||||
@ -152,7 +152,8 @@ pub async fn extrude(exec_state: &mut ExecState, args: Args) -> Result<KclValue,
|
|||||||
args = {
|
args = {
|
||||||
sketches = { docs = "Which sketch or sketches should be extruded"},
|
sketches = { docs = "Which sketch or sketches should be extruded"},
|
||||||
length = { docs = "How far to extrude the given sketches"},
|
length = { docs = "How far to extrude the given sketches"},
|
||||||
symmetric = { docs = "If true, the extrusion will happen symmetrically around the sketch. Otherwise, the extrusion will happen on only one side of the sketch." },
|
symmetric = { docs = "If true, the extrusion will happen symmetrically around the sketch. Otherwise, the
|
||||||
|
extrusion will happen on only one side of the sketch." },
|
||||||
bidirectional_length = { docs = "If specified, will also extrude in the opposite direction to 'distance' to the specified distance. If 'symmetric' is true, this value is ignored."},
|
bidirectional_length = { docs = "If specified, will also extrude in the opposite direction to 'distance' to the specified distance. If 'symmetric' is true, this value is ignored."},
|
||||||
tag_start = { docs = "A named tag for the face at the start of the extrusion, i.e. the original sketch" },
|
tag_start = { docs = "A named tag for the face at the start of the extrusion, i.e. the original sketch" },
|
||||||
tag_end = { docs = "A named tag for the face at the end of the extrusion, i.e. the new face created by extruding the original sketch" },
|
tag_end = { docs = "A named tag for the face at the end of the extrusion, i.e. the new face created by extruding the original sketch" },
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
errors::{KclError, KclErrorDetails},
|
errors::KclError,
|
||||||
execution::{
|
execution::{
|
||||||
types::{ArrayLen, NumericType, RuntimeType},
|
types::{ArrayLen, NumericType, RuntimeType},
|
||||||
ExecState, KclValue,
|
ExecState, KclValue,
|
||||||
@ -54,17 +54,6 @@ pub async fn tan(exec_state: &mut ExecState, args: Args) -> Result<KclValue, Kcl
|
|||||||
/// Compute the square root of a number.
|
/// Compute the square root of a number.
|
||||||
pub async fn sqrt(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
pub async fn sqrt(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
||||||
let input: TyF64 = args.get_unlabeled_kw_arg_typed("input", &RuntimeType::num_any(), exec_state)?;
|
let input: TyF64 = args.get_unlabeled_kw_arg_typed("input", &RuntimeType::num_any(), exec_state)?;
|
||||||
|
|
||||||
if input.n < 0.0 {
|
|
||||||
return Err(KclError::Semantic(KclErrorDetails {
|
|
||||||
source_ranges: vec![args.source_range],
|
|
||||||
message: format!(
|
|
||||||
"Attempt to take square root (`sqrt`) of a number less than zero ({})",
|
|
||||||
input.n
|
|
||||||
),
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
let result = input.n.sqrt();
|
let result = input.n.sqrt();
|
||||||
|
|
||||||
Ok(args.make_user_val_from_f64_with_type(TyF64::new(result, exec_state.current_default_units())))
|
Ok(args.make_user_val_from_f64_with_type(TyF64::new(result, exec_state.current_default_units())))
|
||||||
|
|||||||
@ -452,7 +452,7 @@ async fn make_transform<T: GeometryTrait>(
|
|||||||
})?;
|
})?;
|
||||||
let transforms = match transform_fn_return {
|
let transforms = match transform_fn_return {
|
||||||
KclValue::Object { value, meta: _ } => vec![value],
|
KclValue::Object { value, meta: _ } => vec![value],
|
||||||
KclValue::Tuple { value, .. } | KclValue::HomArray { value, .. } => {
|
KclValue::MixedArray { value, meta: _ } => {
|
||||||
let transforms: Vec<_> = value
|
let transforms: Vec<_> = value
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|val| {
|
.map(|val| {
|
||||||
@ -671,44 +671,12 @@ impl GeometryTrait for Solid {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::execution::types::{NumericType, PrimitiveType};
|
use crate::execution::types::NumericType;
|
||||||
|
|
||||||
#[tokio::test(flavor = "multi_thread")]
|
#[tokio::test(flavor = "multi_thread")]
|
||||||
async fn test_array_to_point3d() {
|
async fn test_array_to_point3d() {
|
||||||
let mut exec_state = ExecState::new(&ExecutorContext::new_mock().await);
|
let mut exec_state = ExecState::new(&ExecutorContext::new_mock().await);
|
||||||
let input = KclValue::HomArray {
|
let input = KclValue::MixedArray {
|
||||||
value: vec![
|
|
||||||
KclValue::Number {
|
|
||||||
value: 1.1,
|
|
||||||
meta: Default::default(),
|
|
||||||
ty: NumericType::mm(),
|
|
||||||
},
|
|
||||||
KclValue::Number {
|
|
||||||
value: 2.2,
|
|
||||||
meta: Default::default(),
|
|
||||||
ty: NumericType::mm(),
|
|
||||||
},
|
|
||||||
KclValue::Number {
|
|
||||||
value: 3.3,
|
|
||||||
meta: Default::default(),
|
|
||||||
ty: NumericType::mm(),
|
|
||||||
},
|
|
||||||
],
|
|
||||||
ty: RuntimeType::Primitive(PrimitiveType::Number(NumericType::mm())),
|
|
||||||
};
|
|
||||||
let expected = [
|
|
||||||
TyF64::new(1.1, NumericType::mm()),
|
|
||||||
TyF64::new(2.2, NumericType::mm()),
|
|
||||||
TyF64::new(3.3, NumericType::mm()),
|
|
||||||
];
|
|
||||||
let actual = array_to_point3d(&input, Vec::new(), &mut exec_state);
|
|
||||||
assert_eq!(actual.unwrap(), expected);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tokio::test(flavor = "multi_thread")]
|
|
||||||
async fn test_tuple_to_point3d() {
|
|
||||||
let mut exec_state = ExecState::new(&ExecutorContext::new_mock().await);
|
|
||||||
let input = KclValue::Tuple {
|
|
||||||
value: vec![
|
value: vec![
|
||||||
KclValue::Number {
|
KclValue::Number {
|
||||||
value: 1.1,
|
value: 1.1,
|
||||||
|
|||||||
@ -17,9 +17,9 @@ use crate::{
|
|||||||
/// Returns the point at the end of the given segment.
|
/// Returns the point at the end of the given segment.
|
||||||
pub async fn segment_end(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
pub async fn segment_end(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
||||||
let tag: TagIdentifier = args.get_unlabeled_kw_arg("tag")?;
|
let tag: TagIdentifier = args.get_unlabeled_kw_arg("tag")?;
|
||||||
let pt = inner_segment_end(&tag, exec_state, args.clone())?;
|
let result = inner_segment_end(&tag, exec_state, args.clone())?;
|
||||||
|
|
||||||
args.make_kcl_val_from_point([pt[0].n, pt[1].n], pt[0].ty.clone())
|
args.make_user_val_from_point(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Compute the ending point of the provided line segment.
|
/// Compute the ending point of the provided line segment.
|
||||||
@ -64,11 +64,8 @@ fn inner_segment_end(tag: &TagIdentifier, exec_state: &mut ExecState, args: Args
|
|||||||
source_ranges: vec![args.source_range],
|
source_ranges: vec![args.source_range],
|
||||||
})
|
})
|
||||||
})?;
|
})?;
|
||||||
let (p, ty) = path.end_point_components();
|
|
||||||
// Docs generation isn't smart enough to handle ([f64; 2], NumericType).
|
|
||||||
let point = [TyF64::new(p[0], ty.clone()), TyF64::new(p[1], ty)];
|
|
||||||
|
|
||||||
Ok(point)
|
Ok(path.get_to().clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the segment end of x.
|
/// Returns the segment end of x.
|
||||||
@ -159,9 +156,9 @@ fn inner_segment_end_y(tag: &TagIdentifier, exec_state: &mut ExecState, args: Ar
|
|||||||
/// Returns the point at the start of the given segment.
|
/// Returns the point at the start of the given segment.
|
||||||
pub async fn segment_start(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
pub async fn segment_start(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
||||||
let tag: TagIdentifier = args.get_unlabeled_kw_arg("tag")?;
|
let tag: TagIdentifier = args.get_unlabeled_kw_arg("tag")?;
|
||||||
let pt = inner_segment_start(&tag, exec_state, args.clone())?;
|
let result = inner_segment_start(&tag, exec_state, args.clone())?;
|
||||||
|
|
||||||
args.make_kcl_val_from_point([pt[0].n, pt[1].n], pt[0].ty.clone())
|
args.make_user_val_from_point(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Compute the starting point of the provided line segment.
|
/// Compute the starting point of the provided line segment.
|
||||||
@ -206,11 +203,8 @@ fn inner_segment_start(tag: &TagIdentifier, exec_state: &mut ExecState, args: Ar
|
|||||||
source_ranges: vec![args.source_range],
|
source_ranges: vec![args.source_range],
|
||||||
})
|
})
|
||||||
})?;
|
})?;
|
||||||
let (p, ty) = path.start_point_components();
|
|
||||||
// Docs generation isn't smart enough to handle ([f64; 2], NumericType).
|
|
||||||
let point = [TyF64::new(p[0], ty.clone()), TyF64::new(p[1], ty)];
|
|
||||||
|
|
||||||
Ok(point)
|
Ok(path.get_from().to_owned())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the segment start of x.
|
/// Returns the segment start of x.
|
||||||
|
|||||||
@ -2,11 +2,11 @@ use std::fmt::Write;
|
|||||||
|
|
||||||
use crate::parsing::{
|
use crate::parsing::{
|
||||||
ast::types::{
|
ast::types::{
|
||||||
Annotation, ArrayExpression, ArrayRangeExpression, AscribedExpression, BinaryExpression, BinaryOperator,
|
Annotation, ArrayExpression, ArrayRangeExpression, BinaryExpression, BinaryOperator, BinaryPart, BodyItem,
|
||||||
BinaryPart, BodyItem, CallExpressionKw, CommentStyle, DefaultParamVal, Expr, FormatOptions, FunctionExpression,
|
CallExpressionKw, CommentStyle, DefaultParamVal, Expr, FormatOptions, FunctionExpression, IfExpression,
|
||||||
IfExpression, ImportSelector, ImportStatement, ItemVisibility, LabeledArg, Literal, LiteralIdentifier,
|
ImportSelector, ImportStatement, ItemVisibility, LabeledArg, Literal, LiteralIdentifier, LiteralValue,
|
||||||
LiteralValue, MemberExpression, MemberObject, Node, NonCodeNode, NonCodeValue, ObjectExpression, Parameter,
|
MemberExpression, MemberObject, Node, NonCodeNode, NonCodeValue, ObjectExpression, Parameter, PipeExpression,
|
||||||
PipeExpression, Program, TagDeclarator, TypeDeclaration, UnaryExpression, VariableDeclaration, VariableKind,
|
Program, TagDeclarator, TypeDeclaration, UnaryExpression, VariableDeclaration, VariableKind,
|
||||||
},
|
},
|
||||||
deprecation, DeprecationKind, PIPE_OPERATOR,
|
deprecation, DeprecationKind, PIPE_OPERATOR,
|
||||||
};
|
};
|
||||||
@ -308,27 +308,23 @@ impl Expr {
|
|||||||
result += &e.label.name;
|
result += &e.label.name;
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
Expr::AscribedExpression(e) => e.recast(options, indentation_level, ctxt),
|
Expr::AscribedExpression(e) => {
|
||||||
Expr::None(_) => {
|
let mut result = e.expr.recast(options, indentation_level, ctxt);
|
||||||
unimplemented!("there is no literal None, see https://github.com/KittyCAD/modeling-app/issues/1115")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl AscribedExpression {
|
|
||||||
fn recast(&self, options: &FormatOptions, indentation_level: usize, ctxt: ExprContext) -> String {
|
|
||||||
let mut result = self.expr.recast(options, indentation_level, ctxt);
|
|
||||||
if matches!(
|
if matches!(
|
||||||
self.expr,
|
e.expr,
|
||||||
Expr::BinaryExpression(..) | Expr::PipeExpression(..) | Expr::UnaryExpression(..)
|
Expr::BinaryExpression(..) | Expr::PipeExpression(..) | Expr::UnaryExpression(..)
|
||||||
) {
|
) {
|
||||||
result = format!("({result})");
|
result = format!("({result})");
|
||||||
}
|
}
|
||||||
result += ": ";
|
result += ": ";
|
||||||
result += &self.ty.to_string();
|
result += &e.ty.to_string();
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
Expr::None(_) => {
|
||||||
|
unimplemented!("there is no literal None, see https://github.com/KittyCAD/modeling-app/issues/1115")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BinaryPart {
|
impl BinaryPart {
|
||||||
@ -349,7 +345,6 @@ impl BinaryPart {
|
|||||||
BinaryPart::UnaryExpression(unary_expression) => unary_expression.recast(options),
|
BinaryPart::UnaryExpression(unary_expression) => unary_expression.recast(options),
|
||||||
BinaryPart::MemberExpression(member_expression) => member_expression.recast(),
|
BinaryPart::MemberExpression(member_expression) => member_expression.recast(),
|
||||||
BinaryPart::IfExpression(e) => e.recast(options, indentation_level, ExprContext::Other),
|
BinaryPart::IfExpression(e) => e.recast(options, indentation_level, ExprContext::Other),
|
||||||
BinaryPart::AscribedExpression(e) => e.recast(options, indentation_level, ExprContext::Other),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -727,7 +722,6 @@ impl UnaryExpression {
|
|||||||
| BinaryPart::Name(_)
|
| BinaryPart::Name(_)
|
||||||
| BinaryPart::MemberExpression(_)
|
| BinaryPart::MemberExpression(_)
|
||||||
| BinaryPart::IfExpression(_)
|
| BinaryPart::IfExpression(_)
|
||||||
| BinaryPart::AscribedExpression(_)
|
|
||||||
| BinaryPart::CallExpressionKw(_) => {
|
| BinaryPart::CallExpressionKw(_) => {
|
||||||
format!("{}{}", &self.operator, self.argument.recast(options, 0))
|
format!("{}{}", &self.operator, self.argument.recast(options, 0))
|
||||||
}
|
}
|
||||||
|
|||||||
@ -221,7 +221,6 @@ impl<'tree> From<&'tree types::BinaryPart> for Node<'tree> {
|
|||||||
types::BinaryPart::UnaryExpression(ue) => ue.as_ref().into(),
|
types::BinaryPart::UnaryExpression(ue) => ue.as_ref().into(),
|
||||||
types::BinaryPart::MemberExpression(me) => me.as_ref().into(),
|
types::BinaryPart::MemberExpression(me) => me.as_ref().into(),
|
||||||
types::BinaryPart::IfExpression(e) => e.as_ref().into(),
|
types::BinaryPart::IfExpression(e) => e.as_ref().into(),
|
||||||
types::BinaryPart::AscribedExpression(e) => e.as_ref().into(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,14 +7,6 @@ import Point2d from "std::types"
|
|||||||
|
|
||||||
/// The value of `pi`, Archimedes’ constant (π).
|
/// The value of `pi`, Archimedes’ constant (π).
|
||||||
///
|
///
|
||||||
/// `PI` is a number and is technically a ratio, so you might expect it to have type `number(_)`.
|
|
||||||
/// However, `PI` is nearly always used for converting between different units - usually degrees to or
|
|
||||||
/// from radians. Therefore, `PI` is treated a bit specially by KCL and always has unknown units. This
|
|
||||||
/// means that if you use `PI`, you will need to give KCL some extra information about the units of numbers.
|
|
||||||
/// Usually you should use type ascription on the result of calculations, e.g., `(2 * PI): number(rad)`.
|
|
||||||
/// You might prefer to use `units::toRadians` or `units::toDegrees` to convert between angles with
|
|
||||||
/// different units.
|
|
||||||
///
|
|
||||||
/// ```
|
/// ```
|
||||||
/// circumference = 70
|
/// circumference = 70
|
||||||
///
|
///
|
||||||
|
|||||||
@ -5,8 +5,6 @@
|
|||||||
///
|
///
|
||||||
/// The standard library is organised into modules (listed below), but most things are always available
|
/// The standard library is organised into modules (listed below), but most things are always available
|
||||||
/// in KCL programs.
|
/// in KCL programs.
|
||||||
///
|
|
||||||
/// You might also want the [KCL language reference](/docs/kcl-lang) or the [KCL guide]().
|
|
||||||
|
|
||||||
@no_std
|
@no_std
|
||||||
@settings(defaultLengthUnit = mm, kclVersion = 1.0)
|
@settings(defaultLengthUnit = mm, kclVersion = 1.0)
|
||||||
|
|||||||
@ -165,25 +165,8 @@ export type tag
|
|||||||
|
|
||||||
/// An abstract plane.
|
/// An abstract plane.
|
||||||
///
|
///
|
||||||
/// A plane has a position and orientation in space defined by its origin and axes. A plane is abstract
|
/// A plane has a position and orientation in space defined by its origin and axes. A plane can be used
|
||||||
/// in the sense that it is not part of the objects being drawn. A plane can be used to sketch on.
|
/// to sketch on.
|
||||||
///
|
|
||||||
/// A plane can be created in several ways:
|
|
||||||
/// - you can use one of the default planes, e.g., `XY`.
|
|
||||||
/// - you can use `offsetPlane` to create a new plane offset from an existing one, e.g., `offsetPlane(XY, offset = 150)`.
|
|
||||||
/// - you can use negation to create a plane from an existing one which is identical but has an opposite normal
|
|
||||||
/// e.g., `-XY`.
|
|
||||||
/// - you can define an entirely custom plane, e.g.,
|
|
||||||
///
|
|
||||||
/// ```kcl,inline,norun
|
|
||||||
/// myXY = {
|
|
||||||
/// origin = { x = 0, y = 0, z = 0 },
|
|
||||||
/// xAxis = { x = 1, y = 0, z = 0 },
|
|
||||||
/// yAxis = { x = 0, y = 1, z = 0 },
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
///
|
|
||||||
/// Any object with appropriate `origin`, `xAxis`, and `yAxis` fields can be used as a plane.
|
|
||||||
@(impl = std_rust)
|
@(impl = std_rust)
|
||||||
export type Plane
|
export type Plane
|
||||||
|
|
||||||
|
|||||||
@ -11,32 +11,32 @@
|
|||||||
@settings(defaultLengthUnit = mm, kclVersion = 1.0)
|
@settings(defaultLengthUnit = mm, kclVersion = 1.0)
|
||||||
|
|
||||||
/// Convert a number to millimeters from its current units.
|
/// Convert a number to millimeters from its current units.
|
||||||
export fn toMillimeters(@num: number(Length)): number(mm) {
|
export fn toMillimeters(@num: number(mm)): number(mm) {
|
||||||
return num
|
return num
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Convert a number to centimeters from its current units.
|
/// Convert a number to centimeters from its current units.
|
||||||
export fn toCentimeters(@num: number(Length)): number(cm) {
|
export fn toCentimeters(@num: number(cm)): number(cm) {
|
||||||
return num
|
return num
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Convert a number to meters from its current units.
|
/// Convert a number to meters from its current units.
|
||||||
export fn toMeters(@num: number(Length)): number(m) {
|
export fn toMeters(@num: number(m)): number(m) {
|
||||||
return num
|
return num
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Convert a number to inches from its current units.
|
/// Convert a number to inches from its current units.
|
||||||
export fn toInches(@num: number(Length)): number(in) {
|
export fn toInches(@num: number(in)): number(in) {
|
||||||
return num
|
return num
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Convert a number to feet from its current units.
|
/// Convert a number to feet from its current units.
|
||||||
export fn toFeet(@num: number(Length)): number(ft) {
|
export fn toFeet(@num: number(ft)): number(ft) {
|
||||||
return num
|
return num
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Converts a number to yards from its current units.
|
/// Converts a number to yards from its current units.
|
||||||
export fn toYards(@num: number(Length)): number(yd) {
|
export fn toYards(@num: number(yd)): number(yd) {
|
||||||
return num
|
return num
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -54,7 +54,7 @@ export fn toYards(@num: number(Length)): number(yd) {
|
|||||||
///
|
///
|
||||||
/// example = extrude(exampleSketch, length = 5)
|
/// example = extrude(exampleSketch, length = 5)
|
||||||
/// ```
|
/// ```
|
||||||
export fn toRadians(@num: number(Angle)): number(rad) {
|
export fn toRadians(@num: number(rad)): number(rad) {
|
||||||
return num
|
return num
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -72,6 +72,6 @@ export fn toRadians(@num: number(Angle)): number(rad) {
|
|||||||
///
|
///
|
||||||
/// example = extrude(exampleSketch, length = 5)
|
/// example = extrude(exampleSketch, length = 5)
|
||||||
/// ```
|
/// ```
|
||||||
export fn toDegrees(@num: number(Angle)): number(deg) {
|
export fn toDegrees(@num: number(deg)): number(deg) {
|
||||||
return num
|
return num
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,32 +0,0 @@
|
|||||||
---
|
|
||||||
source: kcl-lib/src/simulation_tests.rs
|
|
||||||
description: Artifact commands any_type.kcl
|
|
||||||
---
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "edge_lines_visible",
|
|
||||||
"hidden": false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "object_visible",
|
|
||||||
"object_id": "[uuid]",
|
|
||||||
"hidden": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "object_visible",
|
|
||||||
"object_id": "[uuid]",
|
|
||||||
"hidden": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
@ -1,6 +0,0 @@
|
|||||||
---
|
|
||||||
source: kcl-lib/src/simulation_tests.rs
|
|
||||||
description: Artifact graph flowchart any_type.kcl
|
|
||||||
extension: md
|
|
||||||
snapshot_kind: binary
|
|
||||||
---
|
|
||||||
@ -1,3 +0,0 @@
|
|||||||
```mermaid
|
|
||||||
flowchart LR
|
|
||||||
```
|
|
||||||
@ -1,921 +0,0 @@
|
|||||||
---
|
|
||||||
source: kcl-lib/src/simulation_tests.rs
|
|
||||||
description: Result of parsing any_type.kcl
|
|
||||||
---
|
|
||||||
{
|
|
||||||
"Ok": {
|
|
||||||
"body": [
|
|
||||||
{
|
|
||||||
"commentStart": 0,
|
|
||||||
"declaration": {
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"id": {
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"name": "id",
|
|
||||||
"start": 0,
|
|
||||||
"type": "Identifier"
|
|
||||||
},
|
|
||||||
"init": {
|
|
||||||
"body": {
|
|
||||||
"body": [
|
|
||||||
{
|
|
||||||
"argument": {
|
|
||||||
"abs_path": false,
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"name": {
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"name": "x",
|
|
||||||
"start": 0,
|
|
||||||
"type": "Identifier"
|
|
||||||
},
|
|
||||||
"path": [],
|
|
||||||
"start": 0,
|
|
||||||
"type": "Name",
|
|
||||||
"type": "Name"
|
|
||||||
},
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"start": 0,
|
|
||||||
"type": "ReturnStatement",
|
|
||||||
"type": "ReturnStatement"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"start": 0
|
|
||||||
},
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"params": [
|
|
||||||
{
|
|
||||||
"type": "Parameter",
|
|
||||||
"identifier": {
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"name": "x",
|
|
||||||
"start": 0,
|
|
||||||
"type": "Identifier"
|
|
||||||
},
|
|
||||||
"labeled": false
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"start": 0,
|
|
||||||
"type": "FunctionExpression",
|
|
||||||
"type": "FunctionExpression"
|
|
||||||
},
|
|
||||||
"start": 0,
|
|
||||||
"type": "VariableDeclarator"
|
|
||||||
},
|
|
||||||
"end": 0,
|
|
||||||
"kind": "fn",
|
|
||||||
"start": 0,
|
|
||||||
"type": "VariableDeclaration",
|
|
||||||
"type": "VariableDeclaration"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"commentStart": 0,
|
|
||||||
"declaration": {
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"id": {
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"name": "singleton",
|
|
||||||
"start": 0,
|
|
||||||
"type": "Identifier"
|
|
||||||
},
|
|
||||||
"init": {
|
|
||||||
"body": {
|
|
||||||
"body": [
|
|
||||||
{
|
|
||||||
"argument": {
|
|
||||||
"commentStart": 0,
|
|
||||||
"elements": [
|
|
||||||
{
|
|
||||||
"abs_path": false,
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"name": {
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"name": "x",
|
|
||||||
"start": 0,
|
|
||||||
"type": "Identifier"
|
|
||||||
},
|
|
||||||
"path": [],
|
|
||||||
"start": 0,
|
|
||||||
"type": "Name",
|
|
||||||
"type": "Name"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"end": 0,
|
|
||||||
"start": 0,
|
|
||||||
"type": "ArrayExpression",
|
|
||||||
"type": "ArrayExpression"
|
|
||||||
},
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"start": 0,
|
|
||||||
"type": "ReturnStatement",
|
|
||||||
"type": "ReturnStatement"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"start": 0
|
|
||||||
},
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"params": [
|
|
||||||
{
|
|
||||||
"type": "Parameter",
|
|
||||||
"identifier": {
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"name": "x",
|
|
||||||
"start": 0,
|
|
||||||
"type": "Identifier"
|
|
||||||
},
|
|
||||||
"labeled": false
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"start": 0,
|
|
||||||
"type": "FunctionExpression",
|
|
||||||
"type": "FunctionExpression"
|
|
||||||
},
|
|
||||||
"start": 0,
|
|
||||||
"type": "VariableDeclarator"
|
|
||||||
},
|
|
||||||
"end": 0,
|
|
||||||
"kind": "fn",
|
|
||||||
"start": 0,
|
|
||||||
"type": "VariableDeclaration",
|
|
||||||
"type": "VariableDeclaration"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"commentStart": 0,
|
|
||||||
"declaration": {
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"id": {
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"name": "len",
|
|
||||||
"start": 0,
|
|
||||||
"type": "Identifier"
|
|
||||||
},
|
|
||||||
"init": {
|
|
||||||
"body": {
|
|
||||||
"body": [
|
|
||||||
{
|
|
||||||
"argument": {
|
|
||||||
"arguments": [
|
|
||||||
{
|
|
||||||
"type": "LabeledArg",
|
|
||||||
"label": {
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"name": "initial",
|
|
||||||
"start": 0,
|
|
||||||
"type": "Identifier"
|
|
||||||
},
|
|
||||||
"arg": {
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"raw": "0",
|
|
||||||
"start": 0,
|
|
||||||
"type": "Literal",
|
|
||||||
"type": "Literal",
|
|
||||||
"value": {
|
|
||||||
"value": 0.0,
|
|
||||||
"suffix": "None"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "LabeledArg",
|
|
||||||
"label": {
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"name": "f",
|
|
||||||
"start": 0,
|
|
||||||
"type": "Identifier"
|
|
||||||
},
|
|
||||||
"arg": {
|
|
||||||
"body": {
|
|
||||||
"body": [
|
|
||||||
{
|
|
||||||
"argument": {
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"left": {
|
|
||||||
"abs_path": false,
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"name": {
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"name": "accum",
|
|
||||||
"start": 0,
|
|
||||||
"type": "Identifier"
|
|
||||||
},
|
|
||||||
"path": [],
|
|
||||||
"start": 0,
|
|
||||||
"type": "Name",
|
|
||||||
"type": "Name"
|
|
||||||
},
|
|
||||||
"operator": "+",
|
|
||||||
"right": {
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"raw": "1",
|
|
||||||
"start": 0,
|
|
||||||
"type": "Literal",
|
|
||||||
"type": "Literal",
|
|
||||||
"value": {
|
|
||||||
"value": 1.0,
|
|
||||||
"suffix": "None"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"start": 0,
|
|
||||||
"type": "BinaryExpression",
|
|
||||||
"type": "BinaryExpression"
|
|
||||||
},
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"start": 0,
|
|
||||||
"type": "ReturnStatement",
|
|
||||||
"type": "ReturnStatement"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"start": 0
|
|
||||||
},
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"params": [
|
|
||||||
{
|
|
||||||
"type": "Parameter",
|
|
||||||
"identifier": {
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"name": "_",
|
|
||||||
"start": 0,
|
|
||||||
"type": "Identifier"
|
|
||||||
},
|
|
||||||
"labeled": false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "Parameter",
|
|
||||||
"identifier": {
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"name": "accum",
|
|
||||||
"start": 0,
|
|
||||||
"type": "Identifier"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"start": 0,
|
|
||||||
"type": "FunctionExpression",
|
|
||||||
"type": "FunctionExpression"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"callee": {
|
|
||||||
"abs_path": false,
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"name": {
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"name": "reduce",
|
|
||||||
"start": 0,
|
|
||||||
"type": "Identifier"
|
|
||||||
},
|
|
||||||
"path": [],
|
|
||||||
"start": 0,
|
|
||||||
"type": "Name"
|
|
||||||
},
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"start": 0,
|
|
||||||
"type": "CallExpressionKw",
|
|
||||||
"type": "CallExpressionKw",
|
|
||||||
"unlabeled": {
|
|
||||||
"abs_path": false,
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"name": {
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"name": "a",
|
|
||||||
"start": 0,
|
|
||||||
"type": "Identifier"
|
|
||||||
},
|
|
||||||
"path": [],
|
|
||||||
"start": 0,
|
|
||||||
"type": "Name",
|
|
||||||
"type": "Name"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"start": 0,
|
|
||||||
"type": "ReturnStatement",
|
|
||||||
"type": "ReturnStatement"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"start": 0
|
|
||||||
},
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"params": [
|
|
||||||
{
|
|
||||||
"type": "Parameter",
|
|
||||||
"identifier": {
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"name": "a",
|
|
||||||
"start": 0,
|
|
||||||
"type": "Identifier"
|
|
||||||
},
|
|
||||||
"labeled": false
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"start": 0,
|
|
||||||
"type": "FunctionExpression",
|
|
||||||
"type": "FunctionExpression"
|
|
||||||
},
|
|
||||||
"start": 0,
|
|
||||||
"type": "VariableDeclarator"
|
|
||||||
},
|
|
||||||
"end": 0,
|
|
||||||
"kind": "fn",
|
|
||||||
"start": 0,
|
|
||||||
"type": "VariableDeclaration",
|
|
||||||
"type": "VariableDeclaration"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"commentStart": 0,
|
|
||||||
"declaration": {
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"id": {
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"name": "one",
|
|
||||||
"start": 0,
|
|
||||||
"type": "Identifier"
|
|
||||||
},
|
|
||||||
"init": {
|
|
||||||
"callee": {
|
|
||||||
"abs_path": false,
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"name": {
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"name": "id",
|
|
||||||
"start": 0,
|
|
||||||
"type": "Identifier"
|
|
||||||
},
|
|
||||||
"path": [],
|
|
||||||
"start": 0,
|
|
||||||
"type": "Name"
|
|
||||||
},
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"start": 0,
|
|
||||||
"type": "CallExpressionKw",
|
|
||||||
"type": "CallExpressionKw",
|
|
||||||
"unlabeled": {
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"raw": "1",
|
|
||||||
"start": 0,
|
|
||||||
"type": "Literal",
|
|
||||||
"type": "Literal",
|
|
||||||
"value": {
|
|
||||||
"value": 1.0,
|
|
||||||
"suffix": "None"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"start": 0,
|
|
||||||
"type": "VariableDeclarator"
|
|
||||||
},
|
|
||||||
"end": 0,
|
|
||||||
"kind": "const",
|
|
||||||
"start": 0,
|
|
||||||
"type": "VariableDeclaration",
|
|
||||||
"type": "VariableDeclaration"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"commentStart": 0,
|
|
||||||
"declaration": {
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"id": {
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"name": "a",
|
|
||||||
"start": 0,
|
|
||||||
"type": "Identifier"
|
|
||||||
},
|
|
||||||
"init": {
|
|
||||||
"callee": {
|
|
||||||
"abs_path": false,
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"name": {
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"name": "id",
|
|
||||||
"start": 0,
|
|
||||||
"type": "Identifier"
|
|
||||||
},
|
|
||||||
"path": [],
|
|
||||||
"start": 0,
|
|
||||||
"type": "Name"
|
|
||||||
},
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"start": 0,
|
|
||||||
"type": "CallExpressionKw",
|
|
||||||
"type": "CallExpressionKw",
|
|
||||||
"unlabeled": {
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"raw": "\"a\"",
|
|
||||||
"start": 0,
|
|
||||||
"type": "Literal",
|
|
||||||
"type": "Literal",
|
|
||||||
"value": "a"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"start": 0,
|
|
||||||
"type": "VariableDeclarator"
|
|
||||||
},
|
|
||||||
"end": 0,
|
|
||||||
"kind": "const",
|
|
||||||
"start": 0,
|
|
||||||
"type": "VariableDeclaration",
|
|
||||||
"type": "VariableDeclaration"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"commentStart": 0,
|
|
||||||
"declaration": {
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"id": {
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"name": "arr1",
|
|
||||||
"start": 0,
|
|
||||||
"type": "Identifier"
|
|
||||||
},
|
|
||||||
"init": {
|
|
||||||
"callee": {
|
|
||||||
"abs_path": false,
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"name": {
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"name": "singleton",
|
|
||||||
"start": 0,
|
|
||||||
"type": "Identifier"
|
|
||||||
},
|
|
||||||
"path": [],
|
|
||||||
"start": 0,
|
|
||||||
"type": "Name"
|
|
||||||
},
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"start": 0,
|
|
||||||
"type": "CallExpressionKw",
|
|
||||||
"type": "CallExpressionKw",
|
|
||||||
"unlabeled": {
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"raw": "1",
|
|
||||||
"start": 0,
|
|
||||||
"type": "Literal",
|
|
||||||
"type": "Literal",
|
|
||||||
"value": {
|
|
||||||
"value": 1.0,
|
|
||||||
"suffix": "None"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"start": 0,
|
|
||||||
"type": "VariableDeclarator"
|
|
||||||
},
|
|
||||||
"end": 0,
|
|
||||||
"kind": "const",
|
|
||||||
"start": 0,
|
|
||||||
"type": "VariableDeclaration",
|
|
||||||
"type": "VariableDeclaration"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"commentStart": 0,
|
|
||||||
"declaration": {
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"id": {
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"name": "len0",
|
|
||||||
"start": 0,
|
|
||||||
"type": "Identifier"
|
|
||||||
},
|
|
||||||
"init": {
|
|
||||||
"callee": {
|
|
||||||
"abs_path": false,
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"name": {
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"name": "len",
|
|
||||||
"start": 0,
|
|
||||||
"type": "Identifier"
|
|
||||||
},
|
|
||||||
"path": [],
|
|
||||||
"start": 0,
|
|
||||||
"type": "Name"
|
|
||||||
},
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"start": 0,
|
|
||||||
"type": "CallExpressionKw",
|
|
||||||
"type": "CallExpressionKw",
|
|
||||||
"unlabeled": {
|
|
||||||
"commentStart": 0,
|
|
||||||
"elements": [],
|
|
||||||
"end": 0,
|
|
||||||
"start": 0,
|
|
||||||
"type": "ArrayExpression",
|
|
||||||
"type": "ArrayExpression"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"start": 0,
|
|
||||||
"type": "VariableDeclarator"
|
|
||||||
},
|
|
||||||
"end": 0,
|
|
||||||
"kind": "const",
|
|
||||||
"start": 0,
|
|
||||||
"type": "VariableDeclaration",
|
|
||||||
"type": "VariableDeclaration"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"commentStart": 0,
|
|
||||||
"declaration": {
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"id": {
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"name": "len1",
|
|
||||||
"start": 0,
|
|
||||||
"type": "Identifier"
|
|
||||||
},
|
|
||||||
"init": {
|
|
||||||
"callee": {
|
|
||||||
"abs_path": false,
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"name": {
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"name": "len",
|
|
||||||
"start": 0,
|
|
||||||
"type": "Identifier"
|
|
||||||
},
|
|
||||||
"path": [],
|
|
||||||
"start": 0,
|
|
||||||
"type": "Name"
|
|
||||||
},
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"start": 0,
|
|
||||||
"type": "CallExpressionKw",
|
|
||||||
"type": "CallExpressionKw",
|
|
||||||
"unlabeled": {
|
|
||||||
"commentStart": 0,
|
|
||||||
"elements": [
|
|
||||||
{
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"raw": "1",
|
|
||||||
"start": 0,
|
|
||||||
"type": "Literal",
|
|
||||||
"type": "Literal",
|
|
||||||
"value": {
|
|
||||||
"value": 1.0,
|
|
||||||
"suffix": "None"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"end": 0,
|
|
||||||
"start": 0,
|
|
||||||
"type": "ArrayExpression",
|
|
||||||
"type": "ArrayExpression"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"start": 0,
|
|
||||||
"type": "VariableDeclarator"
|
|
||||||
},
|
|
||||||
"end": 0,
|
|
||||||
"kind": "const",
|
|
||||||
"start": 0,
|
|
||||||
"type": "VariableDeclaration",
|
|
||||||
"type": "VariableDeclaration"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"expression": {
|
|
||||||
"arguments": [
|
|
||||||
{
|
|
||||||
"type": "LabeledArg",
|
|
||||||
"label": {
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"name": "isEqualTo",
|
|
||||||
"start": 0,
|
|
||||||
"type": "Identifier"
|
|
||||||
},
|
|
||||||
"arg": {
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"raw": "1",
|
|
||||||
"start": 0,
|
|
||||||
"type": "Literal",
|
|
||||||
"type": "Literal",
|
|
||||||
"value": {
|
|
||||||
"value": 1.0,
|
|
||||||
"suffix": "None"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"callee": {
|
|
||||||
"abs_path": false,
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"name": {
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"name": "assert",
|
|
||||||
"start": 0,
|
|
||||||
"type": "Identifier"
|
|
||||||
},
|
|
||||||
"path": [],
|
|
||||||
"start": 0,
|
|
||||||
"type": "Name"
|
|
||||||
},
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"start": 0,
|
|
||||||
"type": "CallExpressionKw",
|
|
||||||
"type": "CallExpressionKw",
|
|
||||||
"unlabeled": {
|
|
||||||
"abs_path": false,
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"name": {
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"name": "one",
|
|
||||||
"start": 0,
|
|
||||||
"type": "Identifier"
|
|
||||||
},
|
|
||||||
"path": [],
|
|
||||||
"start": 0,
|
|
||||||
"type": "Name",
|
|
||||||
"type": "Name"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"start": 0,
|
|
||||||
"type": "ExpressionStatement",
|
|
||||||
"type": "ExpressionStatement"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"expression": {
|
|
||||||
"arguments": [
|
|
||||||
{
|
|
||||||
"type": "LabeledArg",
|
|
||||||
"label": {
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"name": "isEqualTo",
|
|
||||||
"start": 0,
|
|
||||||
"type": "Identifier"
|
|
||||||
},
|
|
||||||
"arg": {
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"raw": "0",
|
|
||||||
"start": 0,
|
|
||||||
"type": "Literal",
|
|
||||||
"type": "Literal",
|
|
||||||
"value": {
|
|
||||||
"value": 0.0,
|
|
||||||
"suffix": "None"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"callee": {
|
|
||||||
"abs_path": false,
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"name": {
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"name": "assert",
|
|
||||||
"start": 0,
|
|
||||||
"type": "Identifier"
|
|
||||||
},
|
|
||||||
"path": [],
|
|
||||||
"start": 0,
|
|
||||||
"type": "Name"
|
|
||||||
},
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"start": 0,
|
|
||||||
"type": "CallExpressionKw",
|
|
||||||
"type": "CallExpressionKw",
|
|
||||||
"unlabeled": {
|
|
||||||
"abs_path": false,
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"name": {
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"name": "len0",
|
|
||||||
"start": 0,
|
|
||||||
"type": "Identifier"
|
|
||||||
},
|
|
||||||
"path": [],
|
|
||||||
"start": 0,
|
|
||||||
"type": "Name",
|
|
||||||
"type": "Name"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"preComments": [
|
|
||||||
"// TODO: we cannot currently assert on strings.",
|
|
||||||
"// assert(a, isEqualTo = \"a\")",
|
|
||||||
"// TODO: we cannot currently assert on arrays.",
|
|
||||||
"// assert(arr1, isEqualTo = [1])"
|
|
||||||
],
|
|
||||||
"start": 0,
|
|
||||||
"type": "ExpressionStatement",
|
|
||||||
"type": "ExpressionStatement"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"expression": {
|
|
||||||
"arguments": [
|
|
||||||
{
|
|
||||||
"type": "LabeledArg",
|
|
||||||
"label": {
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"name": "isEqualTo",
|
|
||||||
"start": 0,
|
|
||||||
"type": "Identifier"
|
|
||||||
},
|
|
||||||
"arg": {
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"raw": "1",
|
|
||||||
"start": 0,
|
|
||||||
"type": "Literal",
|
|
||||||
"type": "Literal",
|
|
||||||
"value": {
|
|
||||||
"value": 1.0,
|
|
||||||
"suffix": "None"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"callee": {
|
|
||||||
"abs_path": false,
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"name": {
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"name": "assert",
|
|
||||||
"start": 0,
|
|
||||||
"type": "Identifier"
|
|
||||||
},
|
|
||||||
"path": [],
|
|
||||||
"start": 0,
|
|
||||||
"type": "Name"
|
|
||||||
},
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"start": 0,
|
|
||||||
"type": "CallExpressionKw",
|
|
||||||
"type": "CallExpressionKw",
|
|
||||||
"unlabeled": {
|
|
||||||
"abs_path": false,
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"name": {
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"name": "len1",
|
|
||||||
"start": 0,
|
|
||||||
"type": "Identifier"
|
|
||||||
},
|
|
||||||
"path": [],
|
|
||||||
"start": 0,
|
|
||||||
"type": "Name",
|
|
||||||
"type": "Name"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"start": 0,
|
|
||||||
"type": "ExpressionStatement",
|
|
||||||
"type": "ExpressionStatement"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"nonCodeMeta": {
|
|
||||||
"nonCodeNodes": {
|
|
||||||
"0": [
|
|
||||||
{
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"start": 0,
|
|
||||||
"type": "NonCodeNode",
|
|
||||||
"value": {
|
|
||||||
"type": "newLine"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"1": [
|
|
||||||
{
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"start": 0,
|
|
||||||
"type": "NonCodeNode",
|
|
||||||
"value": {
|
|
||||||
"type": "newLine"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"2": [
|
|
||||||
{
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"start": 0,
|
|
||||||
"type": "NonCodeNode",
|
|
||||||
"value": {
|
|
||||||
"type": "newLine"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"7": [
|
|
||||||
{
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"start": 0,
|
|
||||||
"type": "NonCodeNode",
|
|
||||||
"value": {
|
|
||||||
"type": "newLine"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"10": [
|
|
||||||
{
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"start": 0,
|
|
||||||
"type": "NonCodeNode",
|
|
||||||
"value": {
|
|
||||||
"type": "newLine"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"startNodes": []
|
|
||||||
},
|
|
||||||
"start": 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,32 +0,0 @@
|
|||||||
fn id(@x: any): any {
|
|
||||||
return x
|
|
||||||
}
|
|
||||||
|
|
||||||
fn singleton(@x: any): [any; 1] {
|
|
||||||
return [x]
|
|
||||||
}
|
|
||||||
|
|
||||||
fn len(@a: [any]): number(_) {
|
|
||||||
return reduce(
|
|
||||||
a,
|
|
||||||
initial = 0,
|
|
||||||
f = fn(@_, accum) {
|
|
||||||
return accum + 1
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
one = id(1)
|
|
||||||
a = id("a")
|
|
||||||
arr1 = singleton(1)
|
|
||||||
len0 = len([])
|
|
||||||
len1 = len([1])
|
|
||||||
|
|
||||||
assert(one, isEqualTo = 1)
|
|
||||||
// TODO: we cannot currently assert on strings.
|
|
||||||
// assert(a, isEqualTo = "a")
|
|
||||||
// TODO: we cannot currently assert on arrays.
|
|
||||||
// assert(arr1, isEqualTo = [1])
|
|
||||||
assert(len0, isEqualTo = 0)
|
|
||||||
assert(len1, isEqualTo = 1)
|
|
||||||
|
|
||||||
@ -1,184 +0,0 @@
|
|||||||
---
|
|
||||||
source: kcl-lib/src/simulation_tests.rs
|
|
||||||
description: Operations executed any_type.kcl
|
|
||||||
---
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"type": "GroupBegin",
|
|
||||||
"group": {
|
|
||||||
"type": "FunctionCall",
|
|
||||||
"name": null,
|
|
||||||
"functionSourceRange": [],
|
|
||||||
"unlabeledArg": {
|
|
||||||
"value": {
|
|
||||||
"type": "Number",
|
|
||||||
"value": 1.0,
|
|
||||||
"ty": {
|
|
||||||
"type": "Default",
|
|
||||||
"len": {
|
|
||||||
"type": "Mm"
|
|
||||||
},
|
|
||||||
"angle": {
|
|
||||||
"type": "Degrees"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"sourceRange": []
|
|
||||||
},
|
|
||||||
"labeledArgs": {
|
|
||||||
"accum": {
|
|
||||||
"value": {
|
|
||||||
"type": "Number",
|
|
||||||
"value": 0.0,
|
|
||||||
"ty": {
|
|
||||||
"type": "Default",
|
|
||||||
"len": {
|
|
||||||
"type": "Mm"
|
|
||||||
},
|
|
||||||
"angle": {
|
|
||||||
"type": "Degrees"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"sourceRange": []
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"sourceRange": []
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "GroupBegin",
|
|
||||||
"group": {
|
|
||||||
"type": "FunctionCall",
|
|
||||||
"name": "id",
|
|
||||||
"functionSourceRange": [],
|
|
||||||
"unlabeledArg": {
|
|
||||||
"value": {
|
|
||||||
"type": "Number",
|
|
||||||
"value": 1.0,
|
|
||||||
"ty": {
|
|
||||||
"type": "Default",
|
|
||||||
"len": {
|
|
||||||
"type": "Mm"
|
|
||||||
},
|
|
||||||
"angle": {
|
|
||||||
"type": "Degrees"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"sourceRange": []
|
|
||||||
},
|
|
||||||
"labeledArgs": {}
|
|
||||||
},
|
|
||||||
"sourceRange": []
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "GroupBegin",
|
|
||||||
"group": {
|
|
||||||
"type": "FunctionCall",
|
|
||||||
"name": "id",
|
|
||||||
"functionSourceRange": [],
|
|
||||||
"unlabeledArg": {
|
|
||||||
"value": {
|
|
||||||
"type": "String",
|
|
||||||
"value": "a"
|
|
||||||
},
|
|
||||||
"sourceRange": []
|
|
||||||
},
|
|
||||||
"labeledArgs": {}
|
|
||||||
},
|
|
||||||
"sourceRange": []
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "GroupBegin",
|
|
||||||
"group": {
|
|
||||||
"type": "FunctionCall",
|
|
||||||
"name": "singleton",
|
|
||||||
"functionSourceRange": [],
|
|
||||||
"unlabeledArg": {
|
|
||||||
"value": {
|
|
||||||
"type": "Number",
|
|
||||||
"value": 1.0,
|
|
||||||
"ty": {
|
|
||||||
"type": "Default",
|
|
||||||
"len": {
|
|
||||||
"type": "Mm"
|
|
||||||
},
|
|
||||||
"angle": {
|
|
||||||
"type": "Degrees"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"sourceRange": []
|
|
||||||
},
|
|
||||||
"labeledArgs": {}
|
|
||||||
},
|
|
||||||
"sourceRange": []
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "GroupBegin",
|
|
||||||
"group": {
|
|
||||||
"type": "FunctionCall",
|
|
||||||
"name": "len",
|
|
||||||
"functionSourceRange": [],
|
|
||||||
"unlabeledArg": {
|
|
||||||
"value": {
|
|
||||||
"type": "Array",
|
|
||||||
"value": []
|
|
||||||
},
|
|
||||||
"sourceRange": []
|
|
||||||
},
|
|
||||||
"labeledArgs": {}
|
|
||||||
},
|
|
||||||
"sourceRange": []
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "GroupBegin",
|
|
||||||
"group": {
|
|
||||||
"type": "FunctionCall",
|
|
||||||
"name": "len",
|
|
||||||
"functionSourceRange": [],
|
|
||||||
"unlabeledArg": {
|
|
||||||
"value": {
|
|
||||||
"type": "Array",
|
|
||||||
"value": [
|
|
||||||
{
|
|
||||||
"type": "Number",
|
|
||||||
"value": 1.0,
|
|
||||||
"ty": {
|
|
||||||
"type": "Default",
|
|
||||||
"len": {
|
|
||||||
"type": "Mm"
|
|
||||||
},
|
|
||||||
"angle": {
|
|
||||||
"type": "Degrees"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"sourceRange": []
|
|
||||||
},
|
|
||||||
"labeledArgs": {}
|
|
||||||
},
|
|
||||||
"sourceRange": []
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "GroupEnd"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "GroupEnd"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "GroupEnd"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "GroupEnd"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "GroupEnd"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "GroupEnd"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
@ -1,69 +0,0 @@
|
|||||||
---
|
|
||||||
source: kcl-lib/src/simulation_tests.rs
|
|
||||||
description: Variables in memory after executing any_type.kcl
|
|
||||||
---
|
|
||||||
{
|
|
||||||
"a": {
|
|
||||||
"type": "String",
|
|
||||||
"value": "a"
|
|
||||||
},
|
|
||||||
"arr1": {
|
|
||||||
"type": "HomArray",
|
|
||||||
"value": [
|
|
||||||
{
|
|
||||||
"type": "Number",
|
|
||||||
"value": 1.0,
|
|
||||||
"ty": {
|
|
||||||
"type": "Default",
|
|
||||||
"len": {
|
|
||||||
"type": "Mm"
|
|
||||||
},
|
|
||||||
"angle": {
|
|
||||||
"type": "Degrees"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"id": {
|
|
||||||
"type": "Function",
|
|
||||||
"value": null
|
|
||||||
},
|
|
||||||
"len": {
|
|
||||||
"type": "Function",
|
|
||||||
"value": null
|
|
||||||
},
|
|
||||||
"len0": {
|
|
||||||
"type": "Number",
|
|
||||||
"value": 0.0,
|
|
||||||
"ty": {
|
|
||||||
"type": "Known",
|
|
||||||
"type": "Count"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"len1": {
|
|
||||||
"type": "Number",
|
|
||||||
"value": 1.0,
|
|
||||||
"ty": {
|
|
||||||
"type": "Known",
|
|
||||||
"type": "Count"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"one": {
|
|
||||||
"type": "Number",
|
|
||||||
"value": 1.0,
|
|
||||||
"ty": {
|
|
||||||
"type": "Default",
|
|
||||||
"len": {
|
|
||||||
"type": "Mm"
|
|
||||||
},
|
|
||||||
"angle": {
|
|
||||||
"type": "Degrees"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"singleton": {
|
|
||||||
"type": "Function",
|
|
||||||
"value": null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,35 +0,0 @@
|
|||||||
---
|
|
||||||
source: kcl-lib/src/simulation_tests.rs
|
|
||||||
description: Result of unparsing any_type.kcl
|
|
||||||
---
|
|
||||||
fn id(@x: any): any {
|
|
||||||
return x
|
|
||||||
}
|
|
||||||
|
|
||||||
fn singleton(@x: any): [any; 1] {
|
|
||||||
return [x]
|
|
||||||
}
|
|
||||||
|
|
||||||
fn len(@a: [any]): number(_) {
|
|
||||||
return reduce(
|
|
||||||
a,
|
|
||||||
initial = 0,
|
|
||||||
f = fn(@_, accum) {
|
|
||||||
return accum + 1
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
one = id(1)
|
|
||||||
a = id("a")
|
|
||||||
arr1 = singleton(1)
|
|
||||||
len0 = len([])
|
|
||||||
len1 = len([1])
|
|
||||||
|
|
||||||
assert(one, isEqualTo = 1)
|
|
||||||
// TODO: we cannot currently assert on strings.
|
|
||||||
// assert(a, isEqualTo = "a")
|
|
||||||
// TODO: we cannot currently assert on arrays.
|
|
||||||
// assert(arr1, isEqualTo = [1])
|
|
||||||
assert(len0, isEqualTo = 0)
|
|
||||||
assert(len1, isEqualTo = 1)
|
|
||||||
@ -4,7 +4,7 @@ description: Variables in memory after executing array_elem_pop.kcl
|
|||||||
---
|
---
|
||||||
{
|
{
|
||||||
"arr": {
|
"arr": {
|
||||||
"type": "HomArray",
|
"type": "MixedArray",
|
||||||
"value": [
|
"value": [
|
||||||
{
|
{
|
||||||
"type": "Number",
|
"type": "Number",
|
||||||
@ -48,7 +48,7 @@ description: Variables in memory after executing array_elem_pop.kcl
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"new_arr1": {
|
"new_arr1": {
|
||||||
"type": "HomArray",
|
"type": "MixedArray",
|
||||||
"value": [
|
"value": [
|
||||||
{
|
{
|
||||||
"type": "Number",
|
"type": "Number",
|
||||||
@ -79,7 +79,7 @@ description: Variables in memory after executing array_elem_pop.kcl
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"new_arr2": {
|
"new_arr2": {
|
||||||
"type": "HomArray",
|
"type": "MixedArray",
|
||||||
"value": [
|
"value": [
|
||||||
{
|
{
|
||||||
"type": "Number",
|
"type": "Number",
|
||||||
@ -97,7 +97,7 @@ description: Variables in memory after executing array_elem_pop.kcl
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"new_arr3": {
|
"new_arr3": {
|
||||||
"type": "HomArray",
|
"type": "MixedArray",
|
||||||
"value": []
|
"value": []
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,7 +4,7 @@ description: Variables in memory after executing array_elem_push.kcl
|
|||||||
---
|
---
|
||||||
{
|
{
|
||||||
"arr": {
|
"arr": {
|
||||||
"type": "HomArray",
|
"type": "MixedArray",
|
||||||
"value": [
|
"value": [
|
||||||
{
|
{
|
||||||
"type": "Number",
|
"type": "Number",
|
||||||
@ -48,7 +48,7 @@ description: Variables in memory after executing array_elem_push.kcl
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"new_arr1": {
|
"new_arr1": {
|
||||||
"type": "HomArray",
|
"type": "MixedArray",
|
||||||
"value": [
|
"value": [
|
||||||
{
|
{
|
||||||
"type": "Number",
|
"type": "Number",
|
||||||
@ -105,7 +105,7 @@ description: Variables in memory after executing array_elem_push.kcl
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"new_arr2": {
|
"new_arr2": {
|
||||||
"type": "HomArray",
|
"type": "MixedArray",
|
||||||
"value": [
|
"value": [
|
||||||
{
|
{
|
||||||
"type": "Number",
|
"type": "Number",
|
||||||
|
|||||||
@ -1,32 +0,0 @@
|
|||||||
---
|
|
||||||
source: kcl-lib/src/simulation_tests.rs
|
|
||||||
description: Artifact commands array_push_item_wrong_type.kcl
|
|
||||||
---
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "edge_lines_visible",
|
|
||||||
"hidden": false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "object_visible",
|
|
||||||
"object_id": "[uuid]",
|
|
||||||
"hidden": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "object_visible",
|
|
||||||
"object_id": "[uuid]",
|
|
||||||
"hidden": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
@ -1,6 +0,0 @@
|
|||||||
---
|
|
||||||
source: kcl-lib/src/simulation_tests.rs
|
|
||||||
description: Artifact graph flowchart array_push_item_wrong_type.kcl
|
|
||||||
extension: md
|
|
||||||
snapshot_kind: binary
|
|
||||||
---
|
|
||||||
@ -1,3 +0,0 @@
|
|||||||
```mermaid
|
|
||||||
flowchart LR
|
|
||||||
```
|
|
||||||
@ -1,269 +0,0 @@
|
|||||||
---
|
|
||||||
source: kcl-lib/src/simulation_tests.rs
|
|
||||||
description: Result of parsing array_push_item_wrong_type.kcl
|
|
||||||
---
|
|
||||||
{
|
|
||||||
"Ok": {
|
|
||||||
"body": [
|
|
||||||
{
|
|
||||||
"commentStart": 0,
|
|
||||||
"declaration": {
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"id": {
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"name": "arr",
|
|
||||||
"start": 0,
|
|
||||||
"type": "Identifier"
|
|
||||||
},
|
|
||||||
"init": {
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"expr": {
|
|
||||||
"commentStart": 0,
|
|
||||||
"elements": [
|
|
||||||
{
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"raw": "1",
|
|
||||||
"start": 0,
|
|
||||||
"type": "Literal",
|
|
||||||
"type": "Literal",
|
|
||||||
"value": {
|
|
||||||
"value": 1.0,
|
|
||||||
"suffix": "None"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"raw": "2",
|
|
||||||
"start": 0,
|
|
||||||
"type": "Literal",
|
|
||||||
"type": "Literal",
|
|
||||||
"value": {
|
|
||||||
"value": 2.0,
|
|
||||||
"suffix": "None"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"end": 0,
|
|
||||||
"start": 0,
|
|
||||||
"type": "ArrayExpression",
|
|
||||||
"type": "ArrayExpression"
|
|
||||||
},
|
|
||||||
"start": 0,
|
|
||||||
"ty": {
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"len": "None",
|
|
||||||
"start": 0,
|
|
||||||
"ty": {
|
|
||||||
"Count": null,
|
|
||||||
"p_type": "Number",
|
|
||||||
"type": "Primitive"
|
|
||||||
},
|
|
||||||
"type": "Array"
|
|
||||||
},
|
|
||||||
"type": "AscribedExpression",
|
|
||||||
"type": "AscribedExpression"
|
|
||||||
},
|
|
||||||
"start": 0,
|
|
||||||
"type": "VariableDeclarator"
|
|
||||||
},
|
|
||||||
"end": 0,
|
|
||||||
"kind": "const",
|
|
||||||
"start": 0,
|
|
||||||
"type": "VariableDeclaration",
|
|
||||||
"type": "VariableDeclaration"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"commentStart": 0,
|
|
||||||
"declaration": {
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"id": {
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"name": "arrPrime",
|
|
||||||
"start": 0,
|
|
||||||
"type": "Identifier"
|
|
||||||
},
|
|
||||||
"init": {
|
|
||||||
"arguments": [
|
|
||||||
{
|
|
||||||
"type": "LabeledArg",
|
|
||||||
"label": {
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"name": "item",
|
|
||||||
"start": 0,
|
|
||||||
"type": "Identifier"
|
|
||||||
},
|
|
||||||
"arg": {
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"raw": "4mm",
|
|
||||||
"start": 0,
|
|
||||||
"type": "Literal",
|
|
||||||
"type": "Literal",
|
|
||||||
"value": {
|
|
||||||
"value": 4.0,
|
|
||||||
"suffix": "Mm"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"callee": {
|
|
||||||
"abs_path": false,
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"name": {
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"name": "push",
|
|
||||||
"start": 0,
|
|
||||||
"type": "Identifier"
|
|
||||||
},
|
|
||||||
"path": [],
|
|
||||||
"start": 0,
|
|
||||||
"type": "Name"
|
|
||||||
},
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"start": 0,
|
|
||||||
"type": "CallExpressionKw",
|
|
||||||
"type": "CallExpressionKw",
|
|
||||||
"unlabeled": {
|
|
||||||
"abs_path": false,
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"name": {
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"name": "arr",
|
|
||||||
"start": 0,
|
|
||||||
"type": "Identifier"
|
|
||||||
},
|
|
||||||
"path": [],
|
|
||||||
"start": 0,
|
|
||||||
"type": "Name",
|
|
||||||
"type": "Name"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"start": 0,
|
|
||||||
"type": "VariableDeclarator"
|
|
||||||
},
|
|
||||||
"end": 0,
|
|
||||||
"kind": "const",
|
|
||||||
"start": 0,
|
|
||||||
"type": "VariableDeclaration",
|
|
||||||
"type": "VariableDeclaration"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"expression": {
|
|
||||||
"arguments": [
|
|
||||||
{
|
|
||||||
"type": "LabeledArg",
|
|
||||||
"label": {
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"name": "isEqualTo",
|
|
||||||
"start": 0,
|
|
||||||
"type": "Identifier"
|
|
||||||
},
|
|
||||||
"arg": {
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"raw": "4mm",
|
|
||||||
"start": 0,
|
|
||||||
"type": "Literal",
|
|
||||||
"type": "Literal",
|
|
||||||
"value": {
|
|
||||||
"value": 4.0,
|
|
||||||
"suffix": "Mm"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "LabeledArg",
|
|
||||||
"label": {
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"name": "error",
|
|
||||||
"start": 0,
|
|
||||||
"type": "Identifier"
|
|
||||||
},
|
|
||||||
"arg": {
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"raw": "\"should have been added to the end of the array\"",
|
|
||||||
"start": 0,
|
|
||||||
"type": "Literal",
|
|
||||||
"type": "Literal",
|
|
||||||
"value": "should have been added to the end of the array"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"callee": {
|
|
||||||
"abs_path": false,
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"name": {
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"name": "assert",
|
|
||||||
"start": 0,
|
|
||||||
"type": "Identifier"
|
|
||||||
},
|
|
||||||
"path": [],
|
|
||||||
"start": 0,
|
|
||||||
"type": "Name"
|
|
||||||
},
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"start": 0,
|
|
||||||
"type": "CallExpressionKw",
|
|
||||||
"type": "CallExpressionKw",
|
|
||||||
"unlabeled": {
|
|
||||||
"commentStart": 0,
|
|
||||||
"computed": false,
|
|
||||||
"end": 0,
|
|
||||||
"object": {
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"name": "arrPrime",
|
|
||||||
"start": 0,
|
|
||||||
"type": "Identifier",
|
|
||||||
"type": "Identifier"
|
|
||||||
},
|
|
||||||
"property": {
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"raw": "2",
|
|
||||||
"start": 0,
|
|
||||||
"type": "Literal",
|
|
||||||
"type": "Literal",
|
|
||||||
"value": {
|
|
||||||
"value": 2.0,
|
|
||||||
"suffix": "None"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"start": 0,
|
|
||||||
"type": "MemberExpression",
|
|
||||||
"type": "MemberExpression"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"start": 0,
|
|
||||||
"type": "ExpressionStatement",
|
|
||||||
"type": "ExpressionStatement"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"start": 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,3 +0,0 @@
|
|||||||
arr = [1, 2]: [number(_)]
|
|
||||||
arrPrime = push(arr, item = 4mm)
|
|
||||||
assert(arrPrime[2], isEqualTo = 4mm, error = "should have been added to the end of the array")
|
|
||||||
@ -1,5 +0,0 @@
|
|||||||
---
|
|
||||||
source: kcl-lib/src/simulation_tests.rs
|
|
||||||
description: Operations executed array_push_item_wrong_type.kcl
|
|
||||||
---
|
|
||||||
[]
|
|
||||||
@ -1,57 +0,0 @@
|
|||||||
---
|
|
||||||
source: kcl-lib/src/simulation_tests.rs
|
|
||||||
description: Variables in memory after executing array_push_item_wrong_type.kcl
|
|
||||||
---
|
|
||||||
{
|
|
||||||
"arr": {
|
|
||||||
"type": "HomArray",
|
|
||||||
"value": [
|
|
||||||
{
|
|
||||||
"type": "Number",
|
|
||||||
"value": 1.0,
|
|
||||||
"ty": {
|
|
||||||
"type": "Known",
|
|
||||||
"type": "Count"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "Number",
|
|
||||||
"value": 2.0,
|
|
||||||
"ty": {
|
|
||||||
"type": "Known",
|
|
||||||
"type": "Count"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"arrPrime": {
|
|
||||||
"type": "HomArray",
|
|
||||||
"value": [
|
|
||||||
{
|
|
||||||
"type": "Number",
|
|
||||||
"value": 1.0,
|
|
||||||
"ty": {
|
|
||||||
"type": "Known",
|
|
||||||
"type": "Count"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "Number",
|
|
||||||
"value": 2.0,
|
|
||||||
"ty": {
|
|
||||||
"type": "Known",
|
|
||||||
"type": "Count"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "Number",
|
|
||||||
"value": 4.0,
|
|
||||||
"ty": {
|
|
||||||
"type": "Known",
|
|
||||||
"type": "Length",
|
|
||||||
"type": "Mm"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,7 +0,0 @@
|
|||||||
---
|
|
||||||
source: kcl-lib/src/simulation_tests.rs
|
|
||||||
description: Result of unparsing array_push_item_wrong_type.kcl
|
|
||||||
---
|
|
||||||
arr = [1, 2]: [number(_)]
|
|
||||||
arrPrime = push(arr, item = 4mm)
|
|
||||||
assert(arrPrime[2], isEqualTo = 4mm, error = "should have been added to the end of the array")
|
|
||||||
@ -30,281 +30,181 @@ description: Variables in memory after executing array_range_expr.kcl
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"r1": {
|
"r1": {
|
||||||
"type": "HomArray",
|
"type": "MixedArray",
|
||||||
"value": [
|
"value": [
|
||||||
{
|
{
|
||||||
"type": "Number",
|
"type": "Number",
|
||||||
"value": 0.0,
|
"value": 0.0,
|
||||||
"ty": {
|
"ty": {
|
||||||
"type": "Default",
|
"type": "Known",
|
||||||
"len": {
|
"type": "Count"
|
||||||
"type": "Mm"
|
|
||||||
},
|
|
||||||
"angle": {
|
|
||||||
"type": "Degrees"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "Number",
|
"type": "Number",
|
||||||
"value": 1.0,
|
"value": 1.0,
|
||||||
"ty": {
|
"ty": {
|
||||||
"type": "Default",
|
"type": "Known",
|
||||||
"len": {
|
"type": "Count"
|
||||||
"type": "Mm"
|
|
||||||
},
|
|
||||||
"angle": {
|
|
||||||
"type": "Degrees"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "Number",
|
"type": "Number",
|
||||||
"value": 2.0,
|
"value": 2.0,
|
||||||
"ty": {
|
"ty": {
|
||||||
"type": "Default",
|
"type": "Known",
|
||||||
"len": {
|
"type": "Count"
|
||||||
"type": "Mm"
|
|
||||||
},
|
|
||||||
"angle": {
|
|
||||||
"type": "Degrees"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "Number",
|
"type": "Number",
|
||||||
"value": 3.0,
|
"value": 3.0,
|
||||||
"ty": {
|
"ty": {
|
||||||
"type": "Default",
|
"type": "Known",
|
||||||
"len": {
|
"type": "Count"
|
||||||
"type": "Mm"
|
|
||||||
},
|
|
||||||
"angle": {
|
|
||||||
"type": "Degrees"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "Number",
|
"type": "Number",
|
||||||
"value": 4.0,
|
"value": 4.0,
|
||||||
"ty": {
|
"ty": {
|
||||||
"type": "Default",
|
"type": "Known",
|
||||||
"len": {
|
"type": "Count"
|
||||||
"type": "Mm"
|
|
||||||
},
|
|
||||||
"angle": {
|
|
||||||
"type": "Degrees"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"r2": {
|
"r2": {
|
||||||
"type": "HomArray",
|
"type": "MixedArray",
|
||||||
"value": [
|
"value": [
|
||||||
{
|
{
|
||||||
"type": "Number",
|
"type": "Number",
|
||||||
"value": 0.0,
|
"value": 0.0,
|
||||||
"ty": {
|
"ty": {
|
||||||
"type": "Default",
|
"type": "Known",
|
||||||
"len": {
|
"type": "Count"
|
||||||
"type": "Mm"
|
|
||||||
},
|
|
||||||
"angle": {
|
|
||||||
"type": "Degrees"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "Number",
|
"type": "Number",
|
||||||
"value": 1.0,
|
"value": 1.0,
|
||||||
"ty": {
|
"ty": {
|
||||||
"type": "Default",
|
"type": "Known",
|
||||||
"len": {
|
"type": "Count"
|
||||||
"type": "Mm"
|
|
||||||
},
|
|
||||||
"angle": {
|
|
||||||
"type": "Degrees"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "Number",
|
"type": "Number",
|
||||||
"value": 2.0,
|
"value": 2.0,
|
||||||
"ty": {
|
"ty": {
|
||||||
"type": "Default",
|
"type": "Known",
|
||||||
"len": {
|
"type": "Count"
|
||||||
"type": "Mm"
|
|
||||||
},
|
|
||||||
"angle": {
|
|
||||||
"type": "Degrees"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "Number",
|
"type": "Number",
|
||||||
"value": 3.0,
|
"value": 3.0,
|
||||||
"ty": {
|
"ty": {
|
||||||
"type": "Default",
|
"type": "Known",
|
||||||
"len": {
|
"type": "Count"
|
||||||
"type": "Mm"
|
|
||||||
},
|
|
||||||
"angle": {
|
|
||||||
"type": "Degrees"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "Number",
|
"type": "Number",
|
||||||
"value": 4.0,
|
"value": 4.0,
|
||||||
"ty": {
|
"ty": {
|
||||||
"type": "Default",
|
"type": "Known",
|
||||||
"len": {
|
"type": "Count"
|
||||||
"type": "Mm"
|
|
||||||
},
|
|
||||||
"angle": {
|
|
||||||
"type": "Degrees"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"r3": {
|
"r3": {
|
||||||
"type": "HomArray",
|
"type": "MixedArray",
|
||||||
"value": [
|
"value": [
|
||||||
{
|
{
|
||||||
"type": "Number",
|
"type": "Number",
|
||||||
"value": 0.0,
|
"value": 0.0,
|
||||||
"ty": {
|
"ty": {
|
||||||
"type": "Default",
|
"type": "Known",
|
||||||
"len": {
|
"type": "Count"
|
||||||
"type": "Mm"
|
|
||||||
},
|
|
||||||
"angle": {
|
|
||||||
"type": "Degrees"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "Number",
|
"type": "Number",
|
||||||
"value": 1.0,
|
"value": 1.0,
|
||||||
"ty": {
|
"ty": {
|
||||||
"type": "Default",
|
"type": "Known",
|
||||||
"len": {
|
"type": "Count"
|
||||||
"type": "Mm"
|
|
||||||
},
|
|
||||||
"angle": {
|
|
||||||
"type": "Degrees"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "Number",
|
"type": "Number",
|
||||||
"value": 2.0,
|
"value": 2.0,
|
||||||
"ty": {
|
"ty": {
|
||||||
"type": "Default",
|
"type": "Known",
|
||||||
"len": {
|
"type": "Count"
|
||||||
"type": "Mm"
|
|
||||||
},
|
|
||||||
"angle": {
|
|
||||||
"type": "Degrees"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "Number",
|
"type": "Number",
|
||||||
"value": 3.0,
|
"value": 3.0,
|
||||||
"ty": {
|
"ty": {
|
||||||
"type": "Default",
|
"type": "Known",
|
||||||
"len": {
|
"type": "Count"
|
||||||
"type": "Mm"
|
|
||||||
},
|
|
||||||
"angle": {
|
|
||||||
"type": "Degrees"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "Number",
|
"type": "Number",
|
||||||
"value": 4.0,
|
"value": 4.0,
|
||||||
"ty": {
|
"ty": {
|
||||||
"type": "Default",
|
"type": "Known",
|
||||||
"len": {
|
"type": "Count"
|
||||||
"type": "Mm"
|
|
||||||
},
|
|
||||||
"angle": {
|
|
||||||
"type": "Degrees"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "Number",
|
"type": "Number",
|
||||||
"value": 5.0,
|
"value": 5.0,
|
||||||
"ty": {
|
"ty": {
|
||||||
"type": "Default",
|
"type": "Known",
|
||||||
"len": {
|
"type": "Count"
|
||||||
"type": "Mm"
|
|
||||||
},
|
|
||||||
"angle": {
|
|
||||||
"type": "Degrees"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"r4": {
|
"r4": {
|
||||||
"type": "HomArray",
|
"type": "MixedArray",
|
||||||
"value": [
|
"value": [
|
||||||
{
|
{
|
||||||
"type": "Number",
|
"type": "Number",
|
||||||
"value": 1.0,
|
"value": 1.0,
|
||||||
"ty": {
|
"ty": {
|
||||||
"type": "Default",
|
"type": "Known",
|
||||||
"len": {
|
"type": "Count"
|
||||||
"type": "Mm"
|
|
||||||
},
|
|
||||||
"angle": {
|
|
||||||
"type": "Degrees"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "Number",
|
"type": "Number",
|
||||||
"value": 2.0,
|
"value": 2.0,
|
||||||
"ty": {
|
"ty": {
|
||||||
"type": "Default",
|
"type": "Known",
|
||||||
"len": {
|
"type": "Count"
|
||||||
"type": "Mm"
|
|
||||||
},
|
|
||||||
"angle": {
|
|
||||||
"type": "Degrees"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "Number",
|
"type": "Number",
|
||||||
"value": 3.0,
|
"value": 3.0,
|
||||||
"ty": {
|
"ty": {
|
||||||
"type": "Default",
|
"type": "Known",
|
||||||
"len": {
|
"type": "Count"
|
||||||
"type": "Mm"
|
|
||||||
},
|
|
||||||
"angle": {
|
|
||||||
"type": "Degrees"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "Number",
|
"type": "Number",
|
||||||
"value": 4.0,
|
"value": 4.0,
|
||||||
"ty": {
|
"ty": {
|
||||||
"type": "Default",
|
"type": "Known",
|
||||||
"len": {
|
"type": "Count"
|
||||||
"type": "Mm"
|
|
||||||
},
|
|
||||||
"angle": {
|
|
||||||
"type": "Degrees"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
@ -1,32 +0,0 @@
|
|||||||
---
|
|
||||||
source: kcl-lib/src/simulation_tests.rs
|
|
||||||
description: Artifact commands array_range_mismatch_units.kcl
|
|
||||||
---
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "edge_lines_visible",
|
|
||||||
"hidden": false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "object_visible",
|
|
||||||
"object_id": "[uuid]",
|
|
||||||
"hidden": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmdId": "[uuid]",
|
|
||||||
"range": [],
|
|
||||||
"command": {
|
|
||||||
"type": "object_visible",
|
|
||||||
"object_id": "[uuid]",
|
|
||||||
"hidden": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
@ -1,6 +0,0 @@
|
|||||||
---
|
|
||||||
source: kcl-lib/src/simulation_tests.rs
|
|
||||||
description: Artifact graph flowchart array_range_mismatch_units.kcl
|
|
||||||
extension: md
|
|
||||||
snapshot_kind: binary
|
|
||||||
---
|
|
||||||
@ -1,3 +0,0 @@
|
|||||||
```mermaid
|
|
||||||
flowchart LR
|
|
||||||
```
|
|
||||||
@ -1,125 +0,0 @@
|
|||||||
---
|
|
||||||
source: kcl-lib/src/simulation_tests.rs
|
|
||||||
description: Result of parsing array_range_mismatch_units.kcl
|
|
||||||
---
|
|
||||||
{
|
|
||||||
"Ok": {
|
|
||||||
"body": [
|
|
||||||
{
|
|
||||||
"commentStart": 0,
|
|
||||||
"declaration": {
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"id": {
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"name": "a",
|
|
||||||
"start": 0,
|
|
||||||
"type": "Identifier"
|
|
||||||
},
|
|
||||||
"init": {
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"endElement": {
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"raw": "3cm",
|
|
||||||
"start": 0,
|
|
||||||
"type": "Literal",
|
|
||||||
"type": "Literal",
|
|
||||||
"value": {
|
|
||||||
"value": 3.0,
|
|
||||||
"suffix": "Cm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"endInclusive": true,
|
|
||||||
"start": 0,
|
|
||||||
"startElement": {
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"raw": "1mm",
|
|
||||||
"start": 0,
|
|
||||||
"type": "Literal",
|
|
||||||
"type": "Literal",
|
|
||||||
"value": {
|
|
||||||
"value": 1.0,
|
|
||||||
"suffix": "Mm"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"type": "ArrayRangeExpression",
|
|
||||||
"type": "ArrayRangeExpression"
|
|
||||||
},
|
|
||||||
"start": 0,
|
|
||||||
"type": "VariableDeclarator"
|
|
||||||
},
|
|
||||||
"end": 0,
|
|
||||||
"kind": "const",
|
|
||||||
"start": 0,
|
|
||||||
"type": "VariableDeclaration",
|
|
||||||
"type": "VariableDeclaration"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"expression": {
|
|
||||||
"arguments": [
|
|
||||||
{
|
|
||||||
"type": "LabeledArg",
|
|
||||||
"label": {
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"name": "error",
|
|
||||||
"start": 0,
|
|
||||||
"type": "Identifier"
|
|
||||||
},
|
|
||||||
"arg": {
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"raw": "\"shouldn't make it here\"",
|
|
||||||
"start": 0,
|
|
||||||
"type": "Literal",
|
|
||||||
"type": "Literal",
|
|
||||||
"value": "shouldn't make it here"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"callee": {
|
|
||||||
"abs_path": false,
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"name": {
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"name": "assertIs",
|
|
||||||
"start": 0,
|
|
||||||
"type": "Identifier"
|
|
||||||
},
|
|
||||||
"path": [],
|
|
||||||
"start": 0,
|
|
||||||
"type": "Name"
|
|
||||||
},
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"start": 0,
|
|
||||||
"type": "CallExpressionKw",
|
|
||||||
"type": "CallExpressionKw",
|
|
||||||
"unlabeled": {
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"raw": "false",
|
|
||||||
"start": 0,
|
|
||||||
"type": "Literal",
|
|
||||||
"type": "Literal",
|
|
||||||
"value": false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"start": 0,
|
|
||||||
"type": "ExpressionStatement",
|
|
||||||
"type": "ExpressionStatement"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"commentStart": 0,
|
|
||||||
"end": 0,
|
|
||||||
"start": 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,14 +0,0 @@
|
|||||||
---
|
|
||||||
source: kcl-lib/src/simulation_tests.rs
|
|
||||||
description: Error from executing array_range_mismatch_units.kcl
|
|
||||||
---
|
|
||||||
KCL Semantic error
|
|
||||||
|
|
||||||
× semantic: Range start and end must be of the same type, but found 1:
|
|
||||||
│ number(mm) and 3: number(cm)
|
|
||||||
╭─[1:5]
|
|
||||||
1 │ a = [1mm..3cm]
|
|
||||||
· ─────┬────
|
|
||||||
· ╰── tests/array_range_mismatch_units/input.kcl
|
|
||||||
2 │ assertIs(false, error = "shouldn't make it here")
|
|
||||||
╰────
|
|
||||||
@ -1,2 +0,0 @@
|
|||||||
a = [1mm..3cm]
|
|
||||||
assertIs(false, error = "shouldn't make it here")
|
|
||||||
@ -1,5 +0,0 @@
|
|||||||
---
|
|
||||||
source: kcl-lib/src/simulation_tests.rs
|
|
||||||
description: Operations executed array_range_mismatch_units.kcl
|
|
||||||
---
|
|
||||||
[]
|
|
||||||
@ -1,6 +0,0 @@
|
|||||||
---
|
|
||||||
source: kcl-lib/src/simulation_tests.rs
|
|
||||||
description: Result of unparsing array_range_mismatch_units.kcl
|
|
||||||
---
|
|
||||||
a = [1mm..3cm]
|
|
||||||
assertIs(false, error = "shouldn't make it here")
|
|
||||||
@ -4,149 +4,94 @@ description: Variables in memory after executing array_range_negative_expr.kcl
|
|||||||
---
|
---
|
||||||
{
|
{
|
||||||
"xs": {
|
"xs": {
|
||||||
"type": "HomArray",
|
"type": "MixedArray",
|
||||||
"value": [
|
"value": [
|
||||||
{
|
{
|
||||||
"type": "Number",
|
"type": "Number",
|
||||||
"value": -5.0,
|
"value": -5.0,
|
||||||
"ty": {
|
"ty": {
|
||||||
"type": "Default",
|
"type": "Known",
|
||||||
"len": {
|
"type": "Count"
|
||||||
"type": "Mm"
|
|
||||||
},
|
|
||||||
"angle": {
|
|
||||||
"type": "Degrees"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "Number",
|
"type": "Number",
|
||||||
"value": -4.0,
|
"value": -4.0,
|
||||||
"ty": {
|
"ty": {
|
||||||
"type": "Default",
|
"type": "Known",
|
||||||
"len": {
|
"type": "Count"
|
||||||
"type": "Mm"
|
|
||||||
},
|
|
||||||
"angle": {
|
|
||||||
"type": "Degrees"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "Number",
|
"type": "Number",
|
||||||
"value": -3.0,
|
"value": -3.0,
|
||||||
"ty": {
|
"ty": {
|
||||||
"type": "Default",
|
"type": "Known",
|
||||||
"len": {
|
"type": "Count"
|
||||||
"type": "Mm"
|
|
||||||
},
|
|
||||||
"angle": {
|
|
||||||
"type": "Degrees"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "Number",
|
"type": "Number",
|
||||||
"value": -2.0,
|
"value": -2.0,
|
||||||
"ty": {
|
"ty": {
|
||||||
"type": "Default",
|
"type": "Known",
|
||||||
"len": {
|
"type": "Count"
|
||||||
"type": "Mm"
|
|
||||||
},
|
|
||||||
"angle": {
|
|
||||||
"type": "Degrees"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "Number",
|
"type": "Number",
|
||||||
"value": -1.0,
|
"value": -1.0,
|
||||||
"ty": {
|
"ty": {
|
||||||
"type": "Default",
|
"type": "Known",
|
||||||
"len": {
|
"type": "Count"
|
||||||
"type": "Mm"
|
|
||||||
},
|
|
||||||
"angle": {
|
|
||||||
"type": "Degrees"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "Number",
|
"type": "Number",
|
||||||
"value": 0.0,
|
"value": 0.0,
|
||||||
"ty": {
|
"ty": {
|
||||||
"type": "Default",
|
"type": "Known",
|
||||||
"len": {
|
"type": "Count"
|
||||||
"type": "Mm"
|
|
||||||
},
|
|
||||||
"angle": {
|
|
||||||
"type": "Degrees"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "Number",
|
"type": "Number",
|
||||||
"value": 1.0,
|
"value": 1.0,
|
||||||
"ty": {
|
"ty": {
|
||||||
"type": "Default",
|
"type": "Known",
|
||||||
"len": {
|
"type": "Count"
|
||||||
"type": "Mm"
|
|
||||||
},
|
|
||||||
"angle": {
|
|
||||||
"type": "Degrees"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "Number",
|
"type": "Number",
|
||||||
"value": 2.0,
|
"value": 2.0,
|
||||||
"ty": {
|
"ty": {
|
||||||
"type": "Default",
|
"type": "Known",
|
||||||
"len": {
|
"type": "Count"
|
||||||
"type": "Mm"
|
|
||||||
},
|
|
||||||
"angle": {
|
|
||||||
"type": "Degrees"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "Number",
|
"type": "Number",
|
||||||
"value": 3.0,
|
"value": 3.0,
|
||||||
"ty": {
|
"ty": {
|
||||||
"type": "Default",
|
"type": "Known",
|
||||||
"len": {
|
"type": "Count"
|
||||||
"type": "Mm"
|
|
||||||
},
|
|
||||||
"angle": {
|
|
||||||
"type": "Degrees"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "Number",
|
"type": "Number",
|
||||||
"value": 4.0,
|
"value": 4.0,
|
||||||
"ty": {
|
"ty": {
|
||||||
"type": "Default",
|
"type": "Known",
|
||||||
"len": {
|
"type": "Count"
|
||||||
"type": "Mm"
|
|
||||||
},
|
|
||||||
"angle": {
|
|
||||||
"type": "Degrees"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "Number",
|
"type": "Number",
|
||||||
"value": 5.0,
|
"value": 5.0,
|
||||||
"ty": {
|
"ty": {
|
||||||
"type": "Default",
|
"type": "Known",
|
||||||
"len": {
|
"type": "Count"
|
||||||
"type": "Mm"
|
|
||||||
},
|
|
||||||
"angle": {
|
|
||||||
"type": "Degrees"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user