Compare commits

...

4 Commits

Author SHA1 Message Date
3541036685 Replace std lib math constants with actual constants
Signed-off-by: Nick Cameron <nrc@ncameron.org>
2025-01-22 09:12:26 +13:00
965cb18059 Parse units on numeric literals and keep them in the AST (#5061)
* Code changes

Signed-off-by: Nick Cameron <nrc@ncameron.org>

* test changes

Signed-off-by: Nick Cameron <nrc@ncameron.org>

* Frontend changes

Signed-off-by: Nick Cameron <nrc@ncameron.org>

* Refactor asNum

Co-authored-by: Jonathan Tran <jonnytran@gmail.com>

---------

Signed-off-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
2025-01-22 08:29:30 +13:00
a022b8ef6c Fix suggestion for updating function decl syntax for anon functions (#5088)
Signed-off-by: Nick Cameron <nrc@ncameron.org>
2025-01-22 07:10:07 +13:00
4d24bf7c94 Add API Call ID log for debugging (#5107) 2025-01-20 19:49:02 +00:00
231 changed files with 16812 additions and 4178 deletions

View File

@ -4,9 +4,11 @@ excerpt: "Return the value of Eulers number `e`."
layout: manual
---
**WARNING:** This function is deprecated.
Return the value of Eulers number `e`.
**DEPRECATED** use E
```js
e() -> number

View File

@ -39,7 +39,6 @@ layout: manual
* [`close`](kcl/close)
* [`cm`](kcl/cm)
* [`cos`](kcl/cos)
* [`e`](kcl/e)
* [`extrude`](kcl/extrude)
* [`fillet`](kcl/fillet)
* [`floor`](kcl/floor)
@ -78,7 +77,6 @@ layout: manual
* [`patternLinear3d`](kcl/patternLinear3d)
* [`patternTransform`](kcl/patternTransform)
* [`patternTransform2d`](kcl/patternTransform2d)
* [`pi`](kcl/pi)
* [`polar`](kcl/polar)
* [`polygon`](kcl/polygon)
* [`pop`](kcl/pop)
@ -110,7 +108,6 @@ layout: manual
* [`tangentialArc`](kcl/tangentialArc)
* [`tangentialArcTo`](kcl/tangentialArcTo)
* [`tangentialArcToRelative`](kcl/tangentialArcToRelative)
* [`tau`](kcl/tau)
* [`toDegrees`](kcl/toDegrees)
* [`toRadians`](kcl/toRadians)
* [`xLine`](kcl/xLine)

View File

@ -4,9 +4,11 @@ excerpt: "Return the value of `pi`. Archimedes constant (π)."
layout: manual
---
**WARNING:** This function is deprecated.
Return the value of `pi`. Archimedes constant (π).
**DEPRECATED** use PI
```js
pi() -> number

View File

@ -76,7 +76,7 @@ assertEqual(sum, 6, 0.00001, "1 + 2 + 3 summed is 6")
// Declare a function that sketches a decagon.
fn decagon(radius) {
// Each side of the decagon is turned this many degrees from the previous angle.
stepAngle = 1 / 10 * tau()
stepAngle = 1 / 10 * TAU
// Start the decagon sketch at this point.
startOfDecagonSketch = startSketchOn('XY')
@ -97,7 +97,7 @@ fn decagon(radius) {
/* The `decagon` above is basically like this pseudo-code:
fn decagon(radius):
stepAngle = (1/10) * tau()
stepAngle = (1/10) * TAU
plane = startSketchOn('XY')
startOfDecagonSketch = startProfileAt([(cos(0)*radius), (sin(0) * radius)], plane)

View File

@ -65161,7 +65161,7 @@
{
"name": "e",
"summary": "Return the value of Eulers number `e`.",
"description": "",
"description": "**DEPRECATED** use E",
"tags": [
"math"
],
@ -65180,7 +65180,7 @@
"labelRequired": true
},
"unpublished": false,
"deprecated": false,
"deprecated": true,
"examples": [
"exampleSketch = startSketchOn(\"XZ\")\n |> startProfileAt([0, 0], %)\n |> angledLine({ angle = 30, length = 2 * e() ^ 2 }, %)\n |> yLineTo(0, %)\n |> close(%)\n\nexample = extrude(10, exampleSketch)"
]
@ -133801,7 +133801,7 @@
{
"name": "pi",
"summary": "Return the value of `pi`. Archimedes constant (π).",
"description": "",
"description": "**DEPRECATED** use PI",
"tags": [
"math"
],
@ -133820,7 +133820,7 @@
"labelRequired": true
},
"unpublished": false,
"deprecated": false,
"deprecated": true,
"examples": [
"circumference = 70\n\nexampleSketch = startSketchOn(\"XZ\")\n |> circle({\n center = [0, 0],\n radius = circumference / (2 * pi())\n }, %)\n\nexample = extrude(5, exampleSketch)"
]
@ -164365,7 +164365,7 @@
"examples": [
"// This function adds two numbers.\nfn add(a, b) {\n return a + b\n}\n\n// This function adds an array of numbers.\n// It uses the `reduce` function, to call the `add` function on every\n// element of the `arr` parameter. The starting value is 0.\nfn sum(arr) {\n return reduce(arr, 0, add)\n}\n\n/* The above is basically like this pseudo-code:\nfn sum(arr):\n sumSoFar = 0\n for i in arr:\n sumSoFar = add(sumSoFar, i)\n return sumSoFar */\n\n\n// We use `assertEqual` to check that our `sum` function gives the\n// expected result. It's good to check your work!\nassertEqual(sum([1, 2, 3]), 6, 0.00001, \"1 + 2 + 3 summed is 6\")",
"// This example works just like the previous example above, but it uses\n// an anonymous `add` function as its parameter, instead of declaring a\n// named function outside.\narr = [1, 2, 3]\nsum = reduce(arr, 0, fn(i, result_so_far) {\n return i + result_so_far\n})\n\n// We use `assertEqual` to check that our `sum` function gives the\n// expected result. It's good to check your work!\nassertEqual(sum, 6, 0.00001, \"1 + 2 + 3 summed is 6\")",
"// Declare a function that sketches a decagon.\nfn decagon(radius) {\n // Each side of the decagon is turned this many degrees from the previous angle.\n stepAngle = 1 / 10 * tau()\n\n // Start the decagon sketch at this point.\n startOfDecagonSketch = startSketchOn('XY')\n |> startProfileAt([cos(0) * radius, sin(0) * radius], %)\n\n // Use a `reduce` to draw the remaining decagon sides.\n // For each number in the array 1..10, run the given function,\n // which takes a partially-sketched decagon and adds one more edge to it.\n fullDecagon = reduce([1..10], startOfDecagonSketch, fn(i, partialDecagon) {\n // Draw one edge of the decagon.\n x = cos(stepAngle * i) * radius\n y = sin(stepAngle * i) * radius\n return lineTo([x, y], partialDecagon)\n })\n\n return fullDecagon\n}\n\n/* The `decagon` above is basically like this pseudo-code:\nfn decagon(radius):\n stepAngle = (1/10) * tau()\n plane = startSketchOn('XY')\n startOfDecagonSketch = startProfileAt([(cos(0)*radius), (sin(0) * radius)], plane)\n\n // Here's the reduce part.\n partialDecagon = startOfDecagonSketch\n for i in [1..10]:\n x = cos(stepAngle * i) * radius\n y = sin(stepAngle * i) * radius\n partialDecagon = lineTo([x, y], partialDecagon)\n fullDecagon = partialDecagon // it's now full\n return fullDecagon */\n\n\n// Use the `decagon` function declared above, to sketch a decagon with radius 5.\ndecagon(5.0)\n |> close(%)"
"// Declare a function that sketches a decagon.\nfn decagon(radius) {\n // Each side of the decagon is turned this many degrees from the previous angle.\n stepAngle = 1 / 10 * TAU\n\n // Start the decagon sketch at this point.\n startOfDecagonSketch = startSketchOn('XY')\n |> startProfileAt([cos(0) * radius, sin(0) * radius], %)\n\n // Use a `reduce` to draw the remaining decagon sides.\n // For each number in the array 1..10, run the given function,\n // which takes a partially-sketched decagon and adds one more edge to it.\n fullDecagon = reduce([1..10], startOfDecagonSketch, fn(i, partialDecagon) {\n // Draw one edge of the decagon.\n x = cos(stepAngle * i) * radius\n y = sin(stepAngle * i) * radius\n return lineTo([x, y], partialDecagon)\n })\n\n return fullDecagon\n}\n\n/* The `decagon` above is basically like this pseudo-code:\nfn decagon(radius):\n stepAngle = (1/10) * TAU\n plane = startSketchOn('XY')\n startOfDecagonSketch = startProfileAt([(cos(0)*radius), (sin(0) * radius)], plane)\n\n // Here's the reduce part.\n partialDecagon = startOfDecagonSketch\n for i in [1..10]:\n x = cos(stepAngle * i) * radius\n y = sin(stepAngle * i) * radius\n partialDecagon = lineTo([x, y], partialDecagon)\n fullDecagon = partialDecagon // it's now full\n return fullDecagon */\n\n\n// Use the `decagon` function declared above, to sketch a decagon with radius 5.\ndecagon(5.0)\n |> close(%)"
]
},
{
@ -207096,7 +207096,7 @@
{
"name": "tau",
"summary": "Return the value of `tau`. The full circle constant (τ). Equal to 2π.",
"description": "",
"description": "**DEPRECATED** use TAU",
"tags": [
"math"
],
@ -207115,7 +207115,7 @@
"labelRequired": true
},
"unpublished": false,
"deprecated": false,
"deprecated": true,
"examples": [
"exampleSketch = startSketchOn(\"XZ\")\n |> startProfileAt([0, 0], %)\n |> angledLine({ angle = 50, length = 10 * tau() }, %)\n |> yLineTo(0, %)\n |> close(%)\n\nexample = extrude(5, exampleSketch)"
]
@ -207157,7 +207157,7 @@
"unpublished": false,
"deprecated": false,
"examples": [
"exampleSketch = startSketchOn(\"XZ\")\n |> startProfileAt([0, 0], %)\n |> angledLine({\n angle = 50,\n length = 70 * cos(toDegrees(pi() / 4))\n }, %)\n |> yLineTo(0, %)\n |> close(%)\n\nexample = extrude(5, exampleSketch)"
"exampleSketch = startSketchOn(\"XZ\")\n |> startProfileAt([0, 0], %)\n |> angledLine({\n angle = 50,\n length = 70 * cos(toDegrees(PI / 4))\n }, %)\n |> yLineTo(0, %)\n |> close(%)\n\nexample = extrude(5, exampleSketch)"
]
},
{

View File

@ -4,9 +4,11 @@ excerpt: "Return the value of `tau`. The full circle constant (τ). Equal to 2π
layout: manual
---
**WARNING:** This function is deprecated.
Return the value of `tau`. The full circle constant (τ). Equal to 2π.
**DEPRECATED** use TAU
```js
tau() -> number

View File

@ -35,7 +35,7 @@ exampleSketch = startSketchOn("XZ")
|> startProfileAt([0, 0], %)
|> angledLine({
angle = 50,
length = 70 * cos(toDegrees(pi() / 4))
length = 70 * cos(toDegrees(PI / 4))
}, %)
|> yLineTo(0, %)
|> close(%)

View File

@ -1398,23 +1398,23 @@ export class SceneEntities {
const arg0 = arg(kclCircle3PointArgs[0])
if (!arg0) return kclManager.ast
arg0[0].value = points[0].x
arg0[0].value = { value: points[0].x, suffix: 'None' }
arg0[0].raw = points[0].x.toString()
arg0[1].value = points[0].y
arg0[1].value = { value: points[0].y, suffix: 'None' }
arg0[1].raw = points[0].y.toString()
const arg1 = arg(kclCircle3PointArgs[1])
if (!arg1) return kclManager.ast
arg1[0].value = points[1].x
arg1[0].value = { value: points[1].x, suffix: 'None' }
arg1[0].raw = points[1].x.toString()
arg1[1].value = points[1].y
arg1[1].value = { value: points[1].y, suffix: 'None' }
arg1[1].raw = points[1].y.toString()
const arg2 = arg(kclCircle3PointArgs[2])
if (!arg2) return kclManager.ast
arg2[0].value = points[2].x
arg2[0].value = { value: points[2].x, suffix: 'None' }
arg2[0].raw = points[2].x.toString()
arg2[1].value = points[2].y
arg2[1].value = { value: points[2].y, suffix: 'None' }
arg2[1].raw = points[2].y.toString()
const astSnapshot = structuredClone(kclManager.ast)

View File

@ -24,7 +24,10 @@ describe('testing AST', () => {
type: 'Literal',
start: 0,
end: 1,
value: 5,
value: {
suffix: 'None',
value: 5,
},
raw: '5',
},
operator: '+',
@ -32,7 +35,10 @@ describe('testing AST', () => {
type: 'Literal',
start: 3,
end: 4,
value: 6,
value: {
suffix: 'None',
value: 6,
},
raw: '6',
},
},

View File

@ -39,7 +39,7 @@ describe('Testing createLiteral', () => {
it('should create a literal', () => {
const result = createLiteral(5)
expect(result.type).toBe('Literal')
expect(result.value).toBe(5)
expect((result as any).value.value).toBe(5)
})
})
describe('Testing createIdentifier', () => {
@ -56,7 +56,7 @@ describe('Testing createCallExpression', () => {
expect(result.callee.type).toBe('Identifier')
expect(result.callee.name).toBe('myFunc')
expect(result.arguments[0].type).toBe('Literal')
expect((result.arguments[0] as any).value).toBe(5)
expect((result.arguments[0] as any).value.value).toBe(5)
})
})
describe('Testing createObjectExpression', () => {
@ -68,7 +68,7 @@ describe('Testing createObjectExpression', () => {
expect(result.properties[0].type).toBe('ObjectProperty')
expect(result.properties[0].key.name).toBe('myProp')
expect(result.properties[0].value.type).toBe('Literal')
expect((result.properties[0].value as any).value).toBe(5)
expect((result.properties[0].value as any).value.value).toBe(5)
})
})
describe('Testing createArrayExpression', () => {
@ -76,7 +76,7 @@ describe('Testing createArrayExpression', () => {
const result = createArrayExpression([createLiteral(5)])
expect(result.type).toBe('ArrayExpression')
expect(result.elements[0].type).toBe('Literal')
expect((result.elements[0] as any).value).toBe(5)
expect((result.elements[0] as any).value.value).toBe(5)
})
})
describe('Testing createPipeSubstitution', () => {
@ -93,7 +93,7 @@ describe('Testing createVariableDeclaration', () => {
expect(result.declaration.id.type).toBe('Identifier')
expect(result.declaration.id.name).toBe('myVar')
expect(result.declaration.init.type).toBe('Literal')
expect((result.declaration.init as any).value).toBe(5)
expect((result.declaration.init as any).value.value).toBe(5)
})
})
describe('Testing createPipeExpression', () => {
@ -101,7 +101,7 @@ describe('Testing createPipeExpression', () => {
const result = createPipeExpression([createLiteral(5)])
expect(result.type).toBe('PipeExpression')
expect(result.body[0].type).toBe('Literal')
expect((result.body[0] as any).value).toBe(5)
expect((result.body[0] as any).value.value).toBe(5)
})
})

View File

@ -743,14 +743,18 @@ export function splitPathAtPipeExpression(pathToNode: PathToNode): {
return splitPathAtPipeExpression(pathToNode.slice(0, -1))
}
export function createLiteral(value: LiteralValue): Node<Literal> {
export function createLiteral(value: LiteralValue | number): Node<Literal> {
const raw = `${value}`
if (typeof value === 'number') {
value = { value, suffix: 'None' }
}
return {
type: 'Literal',
start: 0,
end: 0,
moduleId: 0,
value,
raw: `${value}`,
raw,
}
}

View File

@ -660,7 +660,7 @@ myNestedVar = [
enter: (node, path) => {
if (
node.type === 'Literal' &&
String(node.value) === literalOfInterest
String((node as any).value.value) === literalOfInterest
) {
pathToNode = path
} else if (

View File

@ -717,16 +717,6 @@ function isTypeInArrayExp(
return node.elements.some((el) => isTypeInValue(el, syntaxType))
}
export function isValueZero(val?: Expr): boolean {
return (
(val?.type === 'Literal' && Number(val.value) === 0) ||
(val?.type === 'UnaryExpression' &&
val.operator === '-' &&
val.argument.type === 'Literal' &&
Number(val.argument.value) === 0)
)
}
export function isLinesParallelAndConstrained(
ast: Program,
artifactGraph: ArtifactGraph,

View File

@ -1014,6 +1014,11 @@ class EngineConnection extends EventTarget {
this.pingPongSpan.pong = new Date()
break
case 'modeling_session_data':
let api_call_id = resp.data?.session?.api_call_id
console.log(`API Call ID: ${api_call_id}`)
break
// Only fires on successful authentication.
case 'ice_server_info':
let ice_servers = resp.data?.ice_servers

View File

@ -20,12 +20,12 @@ import {
sketchFromKclValue,
Literal,
SourceRange,
LiteralValue,
} from '../wasm'
import {
getNodeFromPath,
getNodeFromPathCurry,
getNodePathFromSourceRange,
isValueZero,
} from '../queryAst'
import {
createArrayExpression,
@ -79,11 +79,32 @@ export type ConstraintType =
| 'setAngleBetween'
const REF_NUM_ERR = new Error('Referenced segment does not have a to value')
function asNum(val: LiteralValue): number | Error {
if (typeof val === 'object') return val.value
return REF_NUM_ERR
}
function forceNum(arg: Literal): number {
if (typeof arg.value === 'boolean' || typeof arg.value === 'string') {
return Number(arg.value)
} else {
return arg.value.value
}
}
function isUndef(val: any): val is undefined {
return typeof val === 'undefined'
}
function isNum(val: any): val is number {
return typeof val === 'number'
function isValueZero(val?: Expr): boolean {
return (
(val?.type === 'Literal' && forceNum(val) === 0) ||
(val?.type === 'UnaryExpression' &&
val.operator === '-' &&
val.argument.type === 'Literal' &&
Number(val.argument.value) === 0)
)
}
function createCallWrapper(
@ -190,7 +211,7 @@ const xyLineSetLength =
: referenceSeg
? segRef
: args[0].expr
const literalARg = getArgLiteralVal(args[0].expr)
const literalARg = asNum(args[0].expr.value)
if (err(literalARg)) return literalARg
return createCallWrapper(xOrY, lineVal, tag, literalARg)
}
@ -211,13 +232,14 @@ const basicAngledLineCreateNode =
referencedSegment: path,
}) => {
const refAng = path ? getAngle(path?.from, path?.to) : 0
if (!isNum(args[0].expr.value)) return REF_NUM_ERR
const argValue = asNum(args[0].expr.value)
if (err(argValue)) return argValue
const nonForcedAng =
varValToUse === 'ang'
? inputs[0].expr
: referenceSeg === 'ang'
? getClosesAngleDirection(
args[0].expr.value,
argValue,
refAng,
createSegAngle(referenceSegName)
)
@ -230,8 +252,8 @@ const basicAngledLineCreateNode =
: args[1].expr
const shouldForceAng = valToForce === 'ang' && forceValueUsedInTransform
const shouldForceLen = valToForce === 'len' && forceValueUsedInTransform
const literalArg = getArgLiteralVal(
valToForce === 'ang' ? args[0].expr : args[1].expr
const literalArg = asNum(
valToForce === 'ang' ? args[0].expr.value : args[1].expr.value
)
if (err(literalArg)) return literalArg
return createCallWrapper(
@ -283,7 +305,7 @@ const getMinAndSegAngVals = (
}
const getSignedLeg = (arg: Literal, legLenVal: BinaryPart) =>
Number(arg.value) < 0 ? createUnaryExpression(legLenVal) : legLenVal
forceNum(arg) < 0 ? createUnaryExpression(legLenVal) : legLenVal
const getLegAng = (ang: number, legAngleVal: BinaryPart) => {
const normalisedAngle = ((ang % 360) + 360) % 360 // between 0 and 360
@ -322,8 +344,7 @@ const setHorzVertDistanceCreateNode =
referencedSegment,
}) => {
const refNum = referencedSegment?.to?.[index]
const literalArg = getArgLiteralVal(args?.[index].expr)
if (err(literalArg)) return literalArg
const literalArg = asNum(args?.[index].expr.value)
if (isUndef(refNum) || err(literalArg)) return REF_NUM_ERR
const valueUsedInTransform = roundOff(literalArg - refNum, 2)
@ -352,7 +373,7 @@ const setHorzVertDistanceForAngleLineCreateNode =
referencedSegment,
}) => {
const refNum = referencedSegment?.to?.[index]
const literalArg = getArgLiteralVal(args?.[1].expr)
const literalArg = asNum(args?.[1].expr.value)
if (isUndef(refNum) || err(literalArg)) return REF_NUM_ERR
const valueUsedInTransform = roundOff(literalArg - refNum, 2)
const binExp = createBinaryExpressionWithUnary([
@ -374,8 +395,8 @@ const setAbsDistanceCreateNode =
index = xOrY === 'x' ? 0 : 1
): CreateStdLibSketchCallExpr =>
({ tag, forceValueUsedInTransform, rawArgs: args }) => {
const literalArg = getArgLiteralVal(args?.[index].expr)
if (err(literalArg)) return REF_NUM_ERR
const literalArg = asNum(args?.[index].expr.value)
if (err(literalArg)) return literalArg
const valueUsedInTransform = roundOff(literalArg, 2)
const val = forceValueUsedInTransform || createLiteral(valueUsedInTransform)
if (isXOrYLine) {
@ -396,8 +417,8 @@ const setAbsDistanceCreateNode =
const setAbsDistanceForAngleLineCreateNode =
(xOrY: 'x' | 'y'): CreateStdLibSketchCallExpr =>
({ tag, forceValueUsedInTransform, inputs, rawArgs: args }) => {
const literalArg = getArgLiteralVal(args?.[1].expr)
if (err(literalArg)) return REF_NUM_ERR
const literalArg = asNum(args?.[1].expr.value)
if (err(literalArg)) return literalArg
const valueUsedInTransform = roundOff(literalArg, 2)
const val = forceValueUsedInTransform || createLiteral(valueUsedInTransform)
return createCallWrapper(
@ -419,7 +440,7 @@ const setHorVertDistanceForXYLines =
}) => {
const index = xOrY === 'x' ? 0 : 1
const refNum = referencedSegment?.to?.[index]
const literalArg = getArgLiteralVal(args?.[index].expr)
const literalArg = asNum(args?.[index].expr.value)
if (isUndef(refNum) || err(literalArg)) return REF_NUM_ERR
const valueUsedInTransform = roundOff(literalArg - refNum, 2)
const makeBinExp = createBinaryExpressionWithUnary([
@ -445,9 +466,9 @@ const setHorzVertDistanceConstraintLineCreateNode =
])
const makeBinExp = (index: 0 | 1) => {
const arg = getArgLiteralVal(args?.[index].expr)
const arg = asNum(args?.[index].expr.value)
const refNum = referencedSegment?.to?.[index]
if (err(arg) || !isNum(refNum)) return REF_NUM_ERR
if (err(arg) || isUndef(refNum)) return REF_NUM_ERR
return createBinaryExpressionWithUnary([
createSegEnd(referenceSegName, isX),
createLiteral(roundOff(arg - refNum, 2)),
@ -468,9 +489,9 @@ const setAngledIntersectLineForLines: CreateStdLibSketchCallExpr = ({
forceValueUsedInTransform,
rawArgs: args,
}) => {
const val = args[1].expr.value,
angle = args[0].expr.value
if (!isNum(val) || !isNum(angle)) return REF_NUM_ERR
const val = asNum(args[1].expr.value),
angle = asNum(args[0].expr.value)
if (err(val) || err(angle)) return REF_NUM_ERR
const valueUsedInTransform = roundOff(val, 2)
const varNamMap: { [key: number]: string } = {
0: 'ZERO',
@ -498,8 +519,8 @@ const setAngledIntersectForAngledLines: CreateStdLibSketchCallExpr = ({
inputs,
rawArgs: args,
}) => {
const val = args[1].expr.value
if (!isNum(val)) return REF_NUM_ERR
const val = asNum(args[1].expr.value)
if (err(val)) return val
const valueUsedInTransform = roundOff(val, 2)
return intersectCallWrapper({
fnName: 'angledLineThatIntersects',
@ -524,8 +545,8 @@ const setAngleBetweenCreateNode =
const refAngle = referencedSegment
? getAngle(referencedSegment?.from, referencedSegment?.to)
: 0
const val = args[0].expr.value
if (!isNum(val)) return REF_NUM_ERR
const val = asNum(args[0].expr.value)
if (err(val)) return val
let valueUsedInTransform = roundOff(normaliseAngle(val - refAngle))
let firstHalfValue = createSegAngle(referenceSegName)
if (Math.abs(valueUsedInTransform) > 90) {
@ -706,13 +727,11 @@ const transformMap: TransformMap = {
createPipeSubstitution(),
]
)
if (!isNum(args[0].expr.value)) return REF_NUM_ERR
const val = asNum(args[0].expr.value)
if (err(val)) return val
return createCallWrapper(
'angledLineToX',
[
getAngleLengthSign(args[0].expr.value, angleToMatchLengthXCall),
inputs[0].expr,
],
[getAngleLengthSign(val, angleToMatchLengthXCall), inputs[0].expr],
tag
)
},
@ -739,13 +758,11 @@ const transformMap: TransformMap = {
createPipeSubstitution(),
]
)
if (!isNum(args[0].expr.value)) return REF_NUM_ERR
const val = asNum(args[0].expr.value)
if (err(val)) return val
return createCallWrapper(
'angledLineToY',
[
getAngleLengthSign(args[0].expr.value, angleToMatchLengthYCall),
inputs[1].expr,
],
[getAngleLengthSign(val, angleToMatchLengthYCall), inputs[1].expr],
tag
)
},
@ -763,7 +780,7 @@ const transformMap: TransformMap = {
forceValueUsedInTransform,
rawArgs: args,
}) => {
const val = getArgLiteralVal(args[0].expr)
const val = asNum(args[0].expr.value)
if (err(val)) return val
return createCallWrapper(
'angledLineToY',
@ -844,7 +861,7 @@ const transformMap: TransformMap = {
tooltip: 'yLine',
createNode: ({ inputs, tag, rawArgs: args }) => {
const expr = inputs[1].expr
if (Number(args[0].expr.value) >= 0)
if (forceNum(args[0].expr) >= 0)
return createCallWrapper('yLine', expr, tag)
if (isExprBinaryPart(expr))
return createCallWrapper('yLine', createUnaryExpression(expr), tag)
@ -856,7 +873,7 @@ const transformMap: TransformMap = {
tooltip: 'xLine',
createNode: ({ inputs, tag, rawArgs: args }) => {
const expr = inputs[1].expr
if (Number(args[0].expr.value) >= 0)
if (forceNum(args[0].expr) >= 0)
return createCallWrapper('xLine', expr, tag)
if (isExprBinaryPart(expr))
return createCallWrapper('xLine', createUnaryExpression(expr), tag)
@ -900,10 +917,11 @@ const transformMap: TransformMap = {
referenceSegName,
getInputOfType(inputs, 'xRelative').expr
)
if (!isNum(args[0].expr.value)) return REF_NUM_ERR
const val = asNum(args[0].expr.value)
if (err(val)) return val
return createCallWrapper(
'angledLineOfXLength',
[getLegAng(args[0].expr.value, legAngle), minVal],
[getLegAng(val, legAngle), minVal],
tag
)
},
@ -912,7 +930,7 @@ const transformMap: TransformMap = {
tooltip: 'xLine',
createNode: ({ inputs, tag, rawArgs: args }) => {
const expr = inputs[1].expr
if (Number(args[0].expr.value) >= 0)
if (forceNum(args[0].expr) >= 0)
return createCallWrapper('xLine', expr, tag)
if (isExprBinaryPart(expr))
return createCallWrapper('xLine', createUnaryExpression(expr), tag)
@ -953,10 +971,11 @@ const transformMap: TransformMap = {
inputs[1].expr,
'legAngY'
)
if (!isNum(args[0].expr.value)) return REF_NUM_ERR
const val = asNum(args[0].expr.value)
if (err(val)) return val
return createCallWrapper(
'angledLineOfXLength',
[getLegAng(args[0].expr.value, legAngle), minVal],
[getLegAng(val, legAngle), minVal],
tag
)
},
@ -965,7 +984,7 @@ const transformMap: TransformMap = {
tooltip: 'yLine',
createNode: ({ inputs, tag, rawArgs: args }) => {
const expr = inputs[1].expr
if (Number(args[0].expr.value) >= 0)
if (forceNum(args[0].expr) >= 0)
return createCallWrapper('yLine', expr, tag)
if (isExprBinaryPart(expr))
return createCallWrapper('yLine', createUnaryExpression(expr), tag)
@ -1005,13 +1024,11 @@ const transformMap: TransformMap = {
createPipeSubstitution(),
]
)
if (!isNum(args[0].expr.value)) return REF_NUM_ERR
const val = asNum(args[0].expr.value)
if (err(val)) return val
return createCallWrapper(
'angledLineToX',
[
getAngleLengthSign(args[0].expr.value, angleToMatchLengthXCall),
inputs[1].expr,
],
[getAngleLengthSign(val, angleToMatchLengthXCall), inputs[1].expr],
tag
)
},
@ -1057,13 +1074,11 @@ const transformMap: TransformMap = {
createPipeSubstitution(),
]
)
if (!isNum(args[0].expr.value)) return REF_NUM_ERR
const val = asNum(args[0].expr.value)
if (err(val)) return val
return createCallWrapper(
'angledLineToY',
[
getAngleLengthSign(args[0].expr.value, angleToMatchLengthXCall),
inputs[1].expr,
],
[getAngleLengthSign(val, angleToMatchLengthXCall), inputs[1].expr],
tag
)
},
@ -1080,7 +1095,7 @@ const transformMap: TransformMap = {
equalLength: {
tooltip: 'xLine',
createNode: ({ referenceSegName, tag, rawArgs: args }) => {
const argVal = getArgLiteralVal(args[0].expr)
const argVal = asNum(args[0].expr.value)
if (err(argVal)) return argVal
const segLen = createSegLen(referenceSegName)
if (argVal > 0) return createCallWrapper('xLine', segLen, tag, argVal)
@ -1118,7 +1133,7 @@ const transformMap: TransformMap = {
equalLength: {
tooltip: 'yLine',
createNode: ({ referenceSegName, tag, rawArgs: args }) => {
const argVal = getArgLiteralVal(args[0].expr)
const argVal = asNum(args[0].expr.value)
if (err(argVal)) return argVal
let segLen = createSegLen(referenceSegName)
if (argVal < 0) segLen = createUnaryExpression(segLen)
@ -1823,11 +1838,6 @@ function createLastSeg(isX: boolean): Node<CallExpression> {
])
}
function getArgLiteralVal(arg: Literal): number | Error {
if (!isNum(arg.value)) return REF_NUM_ERR
return arg.value
}
export type ConstraintLevel = 'free' | 'partial' | 'full'
export function getConstraintLevelFromSourceRange(

View File

@ -370,8 +370,6 @@ impl From<KclError> for pyo3::PyErr {
pub struct CompilationError {
#[serde(rename = "sourceRange")]
pub source_range: SourceRange,
#[serde(rename = "contextRange")]
pub context_range: Option<SourceRange>,
pub message: String,
pub suggestion: Option<Suggestion>,
pub severity: Severity,
@ -382,7 +380,6 @@ impl CompilationError {
pub(crate) fn err(source_range: SourceRange, message: impl ToString) -> CompilationError {
CompilationError {
source_range,
context_range: None,
message: message.to_string(),
suggestion: None,
severity: Severity::Error,
@ -393,7 +390,6 @@ impl CompilationError {
pub(crate) fn fatal(source_range: SourceRange, message: impl ToString) -> CompilationError {
CompilationError {
source_range,
context_range: None,
message: message.to_string(),
suggestion: None,
severity: Severity::Fatal,
@ -402,22 +398,18 @@ impl CompilationError {
}
pub(crate) fn with_suggestion(
source_range: SourceRange,
context_range: Option<SourceRange>,
message: impl ToString,
suggestion: Option<(impl ToString, impl ToString)>,
self,
suggestion_title: impl ToString,
suggestion_insert: impl ToString,
tag: Tag,
) -> CompilationError {
CompilationError {
source_range,
context_range,
message: message.to_string(),
suggestion: suggestion.map(|(t, i)| Suggestion {
title: t.to_string(),
insert: i.to_string(),
suggestion: Some(Suggestion {
title: suggestion_title.to_string(),
insert: suggestion_insert.to_string(),
}),
severity: Severity::Error,
tag,
..self
}
}

View File

@ -929,13 +929,13 @@ impl Property {
LiteralIdentifier::Literal(literal) => {
let value = literal.value.clone();
match value {
LiteralValue::Number(x) => {
if let Some(x) = crate::try_f64_to_usize(x) {
LiteralValue::Number { value, .. } => {
if let Some(x) = crate::try_f64_to_usize(value) {
Ok(Property::UInt(x))
} else {
Err(KclError::Semantic(KclErrorDetails {
source_ranges: property_sr,
message: format!("{x} is not a valid index, indices must be whole numbers >= 0"),
message: format!("{value} is not a valid index, indices must be whole numbers >= 0"),
}))
}
}

View File

@ -288,7 +288,7 @@ impl KclValue {
pub(crate) fn from_literal(literal: LiteralValue, meta: Vec<Metadata>) -> Self {
match literal {
LiteralValue::Number(value) => KclValue::Number { value, meta },
LiteralValue::Number { value, .. } => KclValue::Number { value, meta },
LiteralValue::String(value) => KclValue::String { value, meta },
LiteralValue::Bool(value) => KclValue::Bool { value, meta },
}

View File

@ -434,10 +434,13 @@ impl Environment {
Self {
// Prelude
bindings: IndexMap::from([
("ZERO".to_string(), KclValue::from_number(0.0, NO_META)),
("QUARTER_TURN".to_string(), KclValue::from_number(90.0, NO_META)),
("HALF_TURN".to_string(), KclValue::from_number(180.0, NO_META)),
("THREE_QUARTER_TURN".to_string(), KclValue::from_number(270.0, NO_META)),
("ZERO".to_owned(), KclValue::from_number(0.0, NO_META)),
("QUARTER_TURN".to_owned(), KclValue::from_number(90.0, NO_META)),
("HALF_TURN".to_owned(), KclValue::from_number(180.0, NO_META)),
("THREE_QUARTER_TURN".to_owned(), KclValue::from_number(270.0, NO_META)),
("PI".to_owned(), KclValue::from_number(std::f64::consts::PI, NO_META)),
("E".to_owned(), KclValue::from_number(std::f64::consts::E, NO_META)),
("TAU".to_owned(), KclValue::from_number(std::f64::consts::TAU, NO_META)),
]),
parent: None,
}
@ -3344,7 +3347,7 @@ let shape = layer() |> patternTransform(10, transform, %)
#[tokio::test(flavor = "multi_thread")]
async fn test_math_execute_with_pi() {
let ast = r#"const myVar = pi() * 2"#;
let ast = r#"const myVar = PI * 2"#;
let (_, _, exec_state) = parse_execute(ast).await.unwrap();
assert_eq!(
std::f64::consts::TAU,

View File

@ -163,7 +163,7 @@ fn get_xyz(point: &ObjectExpression) -> Option<(f64, f64, f64)> {
fn unlitafy(lit: &LiteralValue) -> Option<f64> {
Some(match lit {
LiteralValue::Number(value) => *value,
LiteralValue::Number { value, .. } => *value,
_ => {
return None;
}

View File

@ -1,6 +1,6 @@
use sha2::{Digest as DigestTrait, Sha256};
use super::types::{DefaultParamVal, ItemVisibility, LabelledExpression, VariableKind};
use super::types::{DefaultParamVal, ItemVisibility, LabelledExpression, LiteralValue, VariableKind};
use crate::parsing::ast::types::{
ArrayExpression, ArrayRangeExpression, BinaryExpression, BinaryPart, BodyItem, CallExpression, CallExpressionKw,
ElseIf, Expr, ExpressionStatement, FnArgType, FunctionExpression, Identifier, IfExpression, ImportItem,
@ -277,6 +277,26 @@ impl Literal {
});
}
impl LiteralValue {
fn digestable_id(&self) -> Vec<u8> {
match self {
LiteralValue::Number { value, suffix } => {
let mut result: Vec<u8> = value.to_ne_bytes().into();
result.extend((*suffix as u32).to_ne_bytes());
result
}
LiteralValue::String(st) => st.as_bytes().into(),
LiteralValue::Bool(b) => {
if *b {
vec![1]
} else {
vec![0]
}
}
}
}
}
impl Identifier {
compute_digest!(|slf, hasher| {
let name = slf.name.as_bytes();

View File

@ -18,6 +18,8 @@ use crate::{
Program,
};
use super::types::LiteralValue;
type Point3d = kcmc::shared::Point3d<f64>;
#[derive(Debug)]
@ -201,8 +203,8 @@ fn create_start_sketch_on(
"startProfileAt",
vec![
ArrayExpression::new(vec![
Literal::new(round_before_recast(start[0]).into()).into(),
Literal::new(round_before_recast(start[1]).into()).into(),
Literal::new(LiteralValue::from_f64_no_uom(round_before_recast(start[0]))).into(),
Literal::new(LiteralValue::from_f64_no_uom(round_before_recast(start[1]))).into(),
])
.into(),
PipeSubstitution::new().into(),
@ -221,8 +223,8 @@ fn create_start_sketch_on(
"line",
vec![
ArrayExpression::new(vec![
Literal::new(round_before_recast(end[0]).into()).into(),
Literal::new(round_before_recast(end[1]).into()).into(),
Literal::new(LiteralValue::from_f64_no_uom(round_before_recast(end[0]))).into(),
Literal::new(LiteralValue::from_f64_no_uom(round_before_recast(end[1]))).into(),
])
.into(),
PipeSubstitution::new().into(),
@ -254,8 +256,8 @@ fn create_start_sketch_on(
"line",
vec![
ArrayExpression::new(vec![
Literal::new(round_before_recast(line[0]).into()).into(),
Literal::new(round_before_recast(line[1]).into()).into(),
Literal::new(LiteralValue::from_f64_no_uom(round_before_recast(line[0]))).into(),
Literal::new(LiteralValue::from_f64_no_uom(round_before_recast(line[1]))).into(),
])
.into(),
PipeSubstitution::new().into(),

View File

@ -1,31 +1,49 @@
use std::fmt;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use serde_json::Value as JValue;
use super::Node;
use crate::parsing::ast::types::{Expr, Literal};
use crate::parsing::{
ast::types::{Expr, Literal},
token::NumericSuffix,
};
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
#[ts(export)]
#[serde(untagged, rename_all = "snake_case")]
pub enum LiteralValue {
Number(f64),
Number { value: f64, suffix: NumericSuffix },
String(String),
Bool(bool),
}
impl LiteralValue {
pub fn digestable_id(&self) -> Vec<u8> {
pub fn from_f64_no_uom(value: f64) -> Self {
LiteralValue::Number {
value,
suffix: NumericSuffix::None,
}
}
}
impl fmt::Display for LiteralValue {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
LiteralValue::Number(frac) => frac.to_ne_bytes().into(),
LiteralValue::String(st) => st.as_bytes().into(),
LiteralValue::Bool(b) => {
if *b {
vec![1]
LiteralValue::Number { value, suffix } => {
let int_value = *value as u64;
if int_value as f64 == *value {
write!(f, "{int_value}")?;
} else {
vec![0]
write!(f, "{value}")?;
}
if *suffix != NumericSuffix::None {
write!(f, "{suffix}")?;
}
Ok(())
}
LiteralValue::String(s) => write!(f, "\"{s}\""),
LiteralValue::Bool(b) => write!(f, "{b}"),
}
}
}
@ -36,49 +54,12 @@ impl From<Node<Literal>> for Expr {
}
}
impl From<LiteralValue> for JValue {
fn from(value: LiteralValue) -> Self {
match value {
LiteralValue::Number(x) => x.into(),
LiteralValue::String(x) => x.into(),
LiteralValue::Bool(b) => b.into(),
}
}
}
impl From<f64> for LiteralValue {
fn from(value: f64) -> Self {
Self::Number(value)
}
}
impl From<i64> for LiteralValue {
fn from(value: i64) -> Self {
Self::Number(value as f64)
}
}
impl From<String> for LiteralValue {
fn from(value: String) -> Self {
Self::String(value)
}
}
impl From<u32> for LiteralValue {
fn from(value: u32) -> Self {
Self::Number(value as f64)
}
}
impl From<u16> for LiteralValue {
fn from(value: u16) -> Self {
Self::Number(value as f64)
}
}
impl From<u8> for LiteralValue {
fn from(value: u8) -> Self {
Self::Number(value as f64)
}
}
impl From<&'static str> for LiteralValue {
fn from(value: &'static str) -> Self {
// TODO: Make this Cow<str>

View File

@ -13,7 +13,6 @@ use anyhow::Result;
use parse_display::{Display, FromStr};
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use serde_json::Value as JValue;
use tower_lsp::lsp_types::{
CompletionItem, CompletionItemKind, DocumentSymbol, FoldingRange, FoldingRangeKind, Range as LspRange, SymbolKind,
};
@ -1867,7 +1866,7 @@ impl Node<Literal> {
impl Literal {
pub fn new(value: LiteralValue) -> Node<Self> {
Node::no_src(Self {
raw: JValue::from(value.clone()).to_string(),
raw: value.to_string(),
value,
digest: None,
})
@ -1878,7 +1877,7 @@ impl From<Node<Literal>> for KclValue {
fn from(literal: Node<Literal>) -> Self {
let meta = vec![literal.metadata()];
match literal.inner.value {
LiteralValue::Number(value) => KclValue::Number { value, meta },
LiteralValue::Number { value, .. } => KclValue::Number { value, meta },
LiteralValue::String(value) => KclValue::String { value, meta },
LiteralValue::Bool(value) => KclValue::Bool { value, meta },
}

View File

@ -126,7 +126,13 @@ impl From<BinaryOperator> for BinaryExpressionToken {
#[cfg(test)]
mod tests {
use super::*;
use crate::{parsing::ast::types::Literal, source_range::ModuleId};
use crate::{
parsing::{
ast::types::{Literal, LiteralValue},
token::NumericSuffix,
},
source_range::ModuleId,
};
#[test]
fn parse_and_evaluate() {
@ -134,7 +140,10 @@ mod tests {
fn lit(n: u8) -> BinaryPart {
BinaryPart::Literal(Box::new(Node::new(
Literal {
value: n.into(),
value: LiteralValue::Number {
value: n as f64,
suffix: NumericSuffix::None,
},
raw: n.to_string(),
digest: None,
},

View File

@ -483,7 +483,7 @@ pub(crate) fn unsigned_number_literal(i: &mut TokenSlice) -> PResult<Node<Litera
let (value, token) = any
.try_map(|token: Token| match token.token_type {
TokenType::Number => {
let x: f64 = token.numeric_value().ok_or_else(|| {
let value: f64 = token.numeric_value().ok_or_else(|| {
CompilationError::fatal(token.as_source_range(), format!("Invalid float: {}", token.value))
})?;
@ -494,7 +494,13 @@ pub(crate) fn unsigned_number_literal(i: &mut TokenSlice) -> PResult<Node<Litera
));
}
Ok((LiteralValue::Number(x), token))
Ok((
LiteralValue::Number {
value,
suffix: token.numeric_suffix(),
},
token,
))
}
_ => Err(CompilationError::fatal(token.as_source_range(), "invalid literal")),
})
@ -844,13 +850,13 @@ fn object_property(i: &mut TokenSlice) -> PResult<Node<ObjectProperty>> {
};
if sep.token_type == TokenType::Colon {
ParseContext::warn(CompilationError::with_suggestion(
sep.into(),
Some(result.as_source_range()),
"Using `:` to initialize objects is deprecated, prefer using `=`.",
Some(("Replace `:` with `=`", " =")),
Tag::Deprecated,
));
ParseContext::warn(
CompilationError::err(
sep.into(),
"Using `:` to initialize objects is deprecated, prefer using `=`.",
)
.with_suggestion("Replace `:` with `=`", " =", Tag::Deprecated),
);
}
Ok(result)
@ -1069,9 +1075,19 @@ fn function_expr(i: &mut TokenSlice) -> PResult<Expr> {
let fn_tok = opt(fun).parse_next(i)?;
ignore_whitespace(i);
let (result, has_arrow) = function_decl.parse_next(i)?;
if fn_tok.is_none() && !has_arrow {
let err = CompilationError::fatal(result.as_source_range(), "Anonymous function requires `fn` before `(`");
return Err(ErrMode::Cut(err.into()));
if fn_tok.is_none() {
if has_arrow {
ParseContext::warn(
CompilationError::err(
result.as_source_range().start_as_range(),
"Missing `fn` in function declaration",
)
.with_suggestion("Add `fn`", "fn", Tag::None),
);
} else {
let err = CompilationError::fatal(result.as_source_range(), "Anonymous function requires `fn` before `(`");
return Err(ErrMode::Cut(err.into()));
}
}
Ok(Expr::FunctionExpression(Box::new(result)))
}
@ -1113,18 +1129,16 @@ fn function_decl(i: &mut TokenSlice) -> PResult<(Node<FunctionExpression>, bool)
open.module_id,
);
let has_arrow = if let Some(arrow) = arrow {
ParseContext::warn(CompilationError::with_suggestion(
arrow.as_source_range(),
Some(result.as_source_range()),
"Unnecessary `=>` in function declaration",
Some(("Remove `=>`", "")),
Tag::Unnecessary,
));
true
} else {
false
};
let has_arrow =
if let Some(arrow) = arrow {
ParseContext::warn(
CompilationError::err(arrow.as_source_range(), "Unnecessary `=>` in function declaration")
.with_suggestion("Remove `=>`", "", Tag::Unnecessary),
);
true
} else {
false
};
Ok((result, has_arrow))
}
@ -1825,67 +1839,60 @@ fn declaration(i: &mut TokenSlice) -> PResult<BoxNode<VariableDeclaration>> {
ignore_whitespace(i);
let val = if kind == VariableKind::Fn {
let eq = opt(equals).parse_next(i)?;
ignore_whitespace(i);
let val =
if kind == VariableKind::Fn {
let eq = opt(equals).parse_next(i)?;
ignore_whitespace(i);
let val = function_decl
.map(|t| Box::new(t.0))
.map(Expr::FunctionExpression)
.context(expected("a KCL function expression, like () { return 1 }"))
.parse_next(i);
let val = function_decl
.map(|t| Box::new(t.0))
.map(Expr::FunctionExpression)
.context(expected("a KCL function expression, like () { return 1 }"))
.parse_next(i);
if let Some(t) = eq {
let ctxt_end = val.as_ref().map(|e| e.end()).unwrap_or(t.end);
ParseContext::warn(CompilationError::with_suggestion(
t.as_source_range(),
Some(SourceRange::new(id.start, ctxt_end, id.module_id)),
"Unnecessary `=` in function declaration",
Some(("Remove `=`", "")),
Tag::Unnecessary,
));
if let Some(t) = eq {
ParseContext::warn(
CompilationError::err(t.as_source_range(), "Unnecessary `=` in function declaration")
.with_suggestion("Remove `=`", "", Tag::Unnecessary),
);
}
val
} else {
equals(i)?;
ignore_whitespace(i);
let val = expression
.try_map(|val| {
// Function bodies can be used if and only if declaring a function.
// Check the 'if' direction:
if matches!(val, Expr::FunctionExpression(_)) {
return Err(CompilationError::fatal(
SourceRange::new(start, dec_end, id.module_id),
format!("Expected a `fn` variable kind, found: `{}`", kind),
));
}
Ok(val)
})
.context(expected("a KCL value, which is being bound to a variable"))
.parse_next(i);
if let Some((_, tok)) = decl_token {
ParseContext::warn(
CompilationError::err(
tok.as_source_range(),
format!(
"Using `{}` to declare constants is deprecated; no keyword is required",
tok.value
),
)
.with_suggestion(format!("Remove `{}`", tok.value), "", Tag::Deprecated),
);
}
val
}
val
} else {
equals(i)?;
ignore_whitespace(i);
let val = expression
.try_map(|val| {
// Function bodies can be used if and only if declaring a function.
// Check the 'if' direction:
if matches!(val, Expr::FunctionExpression(_)) {
return Err(CompilationError::fatal(
SourceRange::new(start, dec_end, id.module_id),
format!("Expected a `fn` variable kind, found: `{}`", kind),
));
}
Ok(val)
})
.context(expected("a KCL value, which is being bound to a variable"))
.parse_next(i);
if let Some((_, tok)) = decl_token {
ParseContext::warn(CompilationError::with_suggestion(
tok.as_source_range(),
Some(SourceRange::new(
id.start,
val.as_ref().map(|e| e.end()).unwrap_or(dec_end),
id.module_id,
)),
format!(
"Using `{}` to declare constants is deprecated; no keyword is required",
tok.value
),
Some((format!("Remove `{}`", tok.value), "")),
Tag::Deprecated,
));
}
val
}
.map_err(|e| e.cut())?;
.map_err(|e| e.cut())?;
let end = val.end();
Ok(Box::new(Node {
@ -2856,7 +2863,10 @@ mySk1 = startSketchAt([0, 0])"#;
ReturnStatement {
argument: Expr::Literal(Box::new(Node::new(
Literal {
value: 2u32.into(),
value: LiteralValue::Number {
value: 2.0,
suffix: NumericSuffix::None
},
raw: "2".to_owned(),
digest: None,
},
@ -3057,7 +3067,15 @@ mySk1 = startSketchAt([0, 0])"#;
match &rhs.right {
BinaryPart::Literal(lit) => {
assert!(lit.start == 9 && lit.end == 10);
assert!(lit.value == 3u32.into() && &lit.raw == "3" && lit.digest.is_none());
assert!(
lit.value
== LiteralValue::Number {
value: 3.0,
suffix: NumericSuffix::None
}
&& &lit.raw == "3"
&& lit.digest.is_none()
);
}
_ => panic!(),
}
@ -3128,11 +3146,23 @@ mySk1 = startSketchAt([0, 0])"#;
let BinaryPart::Literal(left) = actual.inner.left else {
panic!("should be expression");
};
assert_eq!(left.value, 1u32.into());
assert_eq!(
left.value,
LiteralValue::Number {
value: 1.0,
suffix: NumericSuffix::None
}
);
let BinaryPart::Literal(right) = actual.inner.right else {
panic!("should be expression");
};
assert_eq!(right.value, 2u32.into());
assert_eq!(
right.value,
LiteralValue::Number {
value: 2.0,
suffix: NumericSuffix::None
}
);
}
}
@ -3449,7 +3479,10 @@ mySk1 = startSketchAt([0, 0])"#;
operator: BinaryOperator::Add,
left: BinaryPart::Literal(Box::new(Node::new(
Literal {
value: 5u32.into(),
value: LiteralValue::Number {
value: 5.0,
suffix: NumericSuffix::None,
},
raw: "5".to_owned(),
digest: None,
},
@ -3498,7 +3531,10 @@ mySk1 = startSketchAt([0, 0])"#;
BinaryExpression {
left: BinaryPart::Literal(Box::new(Node::new(
Literal {
value: 5u32.into(),
value: LiteralValue::Number {
value: 5.0,
suffix: NumericSuffix::None,
},
raw: "5".to_string(),
digest: None,
},
@ -3509,7 +3545,10 @@ mySk1 = startSketchAt([0, 0])"#;
operator: BinaryOperator::Add,
right: BinaryPart::Literal(Box::new(Node::new(
Literal {
value: 6u32.into(),
value: LiteralValue::Number {
value: 6.0,
suffix: NumericSuffix::None,
},
raw: "6".to_string(),
digest: None,
},
@ -4345,6 +4384,20 @@ sketch001 = startSketchOn('XZ') |> startProfileAt([90.45, 119.09, %)"#;
return 0
}"#
);
let some_program_string = r#"myMap = map([0..5], (n) => {
return n * 2
})"#;
let (_, errs) = assert_no_err(some_program_string);
assert_eq!(errs.len(), 2);
let replaced = errs[0].apply_suggestion(some_program_string).unwrap();
let replaced = errs[1].apply_suggestion(&replaced).unwrap();
assert_eq!(
replaced,
r#"myMap = map([0..5], fn(n) {
return n * 2
})"#
);
}
#[test]

View File

@ -1,8 +1,6 @@
---
source: kcl/src/parsing/parser.rs
assertion_line: 3851
expression: actual
snapshot_kind: text
---
{
"type": "BinaryExpression",
@ -10,7 +8,10 @@ snapshot_kind: text
"left": {
"type": "Literal",
"type": "Literal",
"value": 1.0,
"value": {
"value": 1.0,
"suffix": "None"
},
"raw": "1",
"start": 0,
"end": 1
@ -18,7 +19,10 @@ snapshot_kind: text
"right": {
"type": "Literal",
"type": "Literal",
"value": 2.0,
"value": {
"value": 2.0,
"suffix": "None"
},
"raw": "2",
"start": 4,
"end": 5

View File

@ -1,8 +1,6 @@
---
source: kcl/src/parsing/parser.rs
assertion_line: 3852
expression: actual
snapshot_kind: text
---
{
"type": "BinaryExpression",
@ -10,7 +8,10 @@ snapshot_kind: text
"left": {
"type": "Literal",
"type": "Literal",
"value": 1.0,
"value": {
"value": 1.0,
"suffix": "None"
},
"raw": "1",
"start": 0,
"end": 1
@ -18,7 +19,10 @@ snapshot_kind: text
"right": {
"type": "Literal",
"type": "Literal",
"value": 2.0,
"value": {
"value": 2.0,
"suffix": "None"
},
"raw": "2",
"start": 2,
"end": 3

View File

@ -1,8 +1,6 @@
---
source: kcl/src/parsing/parser.rs
assertion_line: 3853
expression: actual
snapshot_kind: text
---
{
"type": "BinaryExpression",
@ -10,7 +8,10 @@ snapshot_kind: text
"left": {
"type": "Literal",
"type": "Literal",
"value": 1.0,
"value": {
"value": 1.0,
"suffix": "None"
},
"raw": "1",
"start": 0,
"end": 1
@ -18,7 +19,10 @@ snapshot_kind: text
"right": {
"type": "Literal",
"type": "Literal",
"value": 2.0,
"value": {
"value": 2.0,
"suffix": "None"
},
"raw": "2",
"start": 3,
"end": 4

View File

@ -1,8 +1,6 @@
---
source: kcl/src/parsing/parser.rs
assertion_line: 3854
expression: actual
snapshot_kind: text
---
{
"type": "BinaryExpression",
@ -10,7 +8,10 @@ snapshot_kind: text
"left": {
"type": "Literal",
"type": "Literal",
"value": 1.0,
"value": {
"value": 1.0,
"suffix": "None"
},
"raw": "1",
"start": 0,
"end": 1
@ -22,7 +23,10 @@ snapshot_kind: text
"left": {
"type": "Literal",
"type": "Literal",
"value": 2.0,
"value": {
"value": 2.0,
"suffix": "None"
},
"raw": "2",
"start": 4,
"end": 5
@ -30,7 +34,10 @@ snapshot_kind: text
"right": {
"type": "Literal",
"type": "Literal",
"value": 3.0,
"value": {
"value": 3.0,
"suffix": "None"
},
"raw": "3",
"start": 8,
"end": 9

View File

@ -1,8 +1,6 @@
---
source: kcl/src/parsing/parser.rs
assertion_line: 3855
expression: actual
snapshot_kind: text
---
{
"type": "BinaryExpression",
@ -10,7 +8,10 @@ snapshot_kind: text
"left": {
"type": "Literal",
"type": "Literal",
"value": 1.0,
"value": {
"value": 1.0,
"suffix": "None"
},
"raw": "1",
"start": 0,
"end": 1
@ -22,7 +23,10 @@ snapshot_kind: text
"left": {
"type": "Literal",
"type": "Literal",
"value": 2.0,
"value": {
"value": 2.0,
"suffix": "None"
},
"raw": "2",
"start": 6,
"end": 7
@ -30,7 +34,10 @@ snapshot_kind: text
"right": {
"type": "Literal",
"type": "Literal",
"value": 3.0,
"value": {
"value": 3.0,
"suffix": "None"
},
"raw": "3",
"start": 10,
"end": 11

View File

@ -1,8 +1,6 @@
---
source: kcl/src/parsing/parser.rs
assertion_line: 3856
expression: actual
snapshot_kind: text
---
{
"type": "BinaryExpression",
@ -14,7 +12,10 @@ snapshot_kind: text
"left": {
"type": "Literal",
"type": "Literal",
"value": 1.0,
"value": {
"value": 1.0,
"suffix": "None"
},
"raw": "1",
"start": 0,
"end": 1
@ -26,7 +27,10 @@ snapshot_kind: text
"left": {
"type": "Literal",
"type": "Literal",
"value": 2.0,
"value": {
"value": 2.0,
"suffix": "None"
},
"raw": "2",
"start": 6,
"end": 7
@ -34,7 +38,10 @@ snapshot_kind: text
"right": {
"type": "Literal",
"type": "Literal",
"value": 3.0,
"value": {
"value": 3.0,
"suffix": "None"
},
"raw": "3",
"start": 10,
"end": 11
@ -48,7 +55,10 @@ snapshot_kind: text
"right": {
"type": "Literal",
"type": "Literal",
"value": 4.0,
"value": {
"value": 4.0,
"suffix": "None"
},
"raw": "4",
"start": 16,
"end": 17

View File

@ -1,8 +1,6 @@
---
source: kcl/src/parsing/parser.rs
assertion_line: 3857
expression: actual
snapshot_kind: text
---
{
"type": "BinaryExpression",
@ -10,7 +8,10 @@ snapshot_kind: text
"left": {
"type": "Literal",
"type": "Literal",
"value": 1.0,
"value": {
"value": 1.0,
"suffix": "None"
},
"raw": "1",
"start": 0,
"end": 1
@ -26,7 +27,10 @@ snapshot_kind: text
"left": {
"type": "Literal",
"type": "Literal",
"value": 2.0,
"value": {
"value": 2.0,
"suffix": "None"
},
"raw": "2",
"start": 6,
"end": 7
@ -34,7 +38,10 @@ snapshot_kind: text
"right": {
"type": "Literal",
"type": "Literal",
"value": 3.0,
"value": {
"value": 3.0,
"suffix": "None"
},
"raw": "3",
"start": 10,
"end": 11
@ -45,7 +52,10 @@ snapshot_kind: text
"right": {
"type": "Literal",
"type": "Literal",
"value": 4.0,
"value": {
"value": 4.0,
"suffix": "None"
},
"raw": "4",
"start": 16,
"end": 17

View File

@ -1,8 +1,6 @@
---
source: kcl/src/parsing/parser.rs
assertion_line: 3858
expression: actual
snapshot_kind: text
---
{
"type": "BinaryExpression",
@ -10,7 +8,10 @@ snapshot_kind: text
"left": {
"type": "Literal",
"type": "Literal",
"value": 1.0,
"value": {
"value": 1.0,
"suffix": "None"
},
"raw": "1",
"start": 0,
"end": 1
@ -30,7 +31,10 @@ snapshot_kind: text
"left": {
"type": "Literal",
"type": "Literal",
"value": 2.0,
"value": {
"value": 2.0,
"suffix": "None"
},
"raw": "2",
"start": 7,
"end": 8
@ -38,7 +42,10 @@ snapshot_kind: text
"right": {
"type": "Literal",
"type": "Literal",
"value": 3.0,
"value": {
"value": 3.0,
"suffix": "None"
},
"raw": "3",
"start": 11,
"end": 12
@ -49,7 +56,10 @@ snapshot_kind: text
"right": {
"type": "Literal",
"type": "Literal",
"value": 4.0,
"value": {
"value": 4.0,
"suffix": "None"
},
"raw": "4",
"start": 17,
"end": 18
@ -60,7 +70,10 @@ snapshot_kind: text
"right": {
"type": "Literal",
"type": "Literal",
"value": 5.0,
"value": {
"value": 5.0,
"suffix": "None"
},
"raw": "5",
"start": 21,
"end": 22

View File

@ -1,8 +1,6 @@
---
source: kcl/src/parsing/parser.rs
assertion_line: 3859
expression: actual
snapshot_kind: text
---
{
"type": "BinaryExpression",
@ -10,7 +8,10 @@ snapshot_kind: text
"left": {
"type": "Literal",
"type": "Literal",
"value": 1.0,
"value": {
"value": 1.0,
"suffix": "None"
},
"raw": "1",
"start": 0,
"end": 1
@ -22,7 +23,10 @@ snapshot_kind: text
"left": {
"type": "Literal",
"type": "Literal",
"value": 2.0,
"value": {
"value": 2.0,
"suffix": "None"
},
"raw": "2",
"start": 8,
"end": 9
@ -30,7 +34,10 @@ snapshot_kind: text
"right": {
"type": "Literal",
"type": "Literal",
"value": 3.0,
"value": {
"value": 3.0,
"suffix": "None"
},
"raw": "3",
"start": 12,
"end": 13

View File

@ -1,8 +1,6 @@
---
source: kcl/src/parsing/parser.rs
assertion_line: 3860
expression: actual
snapshot_kind: text
---
{
"type": "BinaryExpression",
@ -49,7 +47,10 @@ snapshot_kind: text
"right": {
"type": "Literal",
"type": "Literal",
"value": 6.0,
"value": {
"value": 6.0,
"suffix": "None"
},
"raw": "6",
"start": 21,
"end": 22

View File

@ -1,8 +1,6 @@
---
source: kcl/src/parsing/parser.rs
assertion_line: 3861
expression: actual
snapshot_kind: text
---
{
"type": "BinaryExpression",
@ -10,7 +8,10 @@ snapshot_kind: text
"left": {
"type": "Literal",
"type": "Literal",
"value": 2.0,
"value": {
"value": 2.0,
"suffix": "None"
},
"raw": "2",
"start": 0,
"end": 1
@ -18,7 +19,10 @@ snapshot_kind: text
"right": {
"type": "Literal",
"type": "Literal",
"value": 3.0,
"value": {
"value": 3.0,
"suffix": "None"
},
"raw": "3",
"start": 7,
"end": 8

View File

@ -25,7 +25,10 @@ expression: actual
"start": 27,
"type": "Literal",
"type": "Literal",
"value": 0.0
"value": {
"value": 0.0,
"suffix": "None"
}
},
{
"end": 31,
@ -33,7 +36,10 @@ expression: actual
"start": 30,
"type": "Literal",
"type": "Literal",
"value": 0.0
"value": {
"value": 0.0,
"suffix": "None"
}
}
],
"end": 32,
@ -63,7 +69,10 @@ expression: actual
"start": 47,
"type": "Literal",
"type": "Literal",
"value": 0.0
"value": {
"value": 0.0,
"suffix": "None"
}
},
{
"end": 52,
@ -71,7 +80,10 @@ expression: actual
"start": 50,
"type": "Literal",
"type": "Literal",
"value": 10.0
"value": {
"value": 10.0,
"suffix": "None"
}
}
],
"end": 53,
@ -108,7 +120,10 @@ expression: actual
"start": 81,
"type": "Literal",
"type": "Literal",
"value": 5.0
"value": {
"value": 5.0,
"suffix": "None"
}
},
"end": 82,
"operator": "-",
@ -122,7 +137,10 @@ expression: actual
"start": 84,
"type": "Literal",
"type": "Literal",
"value": 5.0
"value": {
"value": 5.0,
"suffix": "None"
}
}
],
"end": 86,
@ -158,7 +176,10 @@ expression: actual
"start": 104,
"type": "Literal",
"type": "Literal",
"value": 5.0
"value": {
"value": 5.0,
"suffix": "None"
}
},
{
"argument": {
@ -167,7 +188,10 @@ expression: actual
"start": 108,
"type": "Literal",
"type": "Literal",
"value": 15.0
"value": {
"value": 15.0,
"suffix": "None"
}
},
"end": 110,
"operator": "-",
@ -207,7 +231,10 @@ expression: actual
"start": 131,
"type": "Literal",
"type": "Literal",
"value": 10.0
"value": {
"value": 10.0,
"suffix": "None"
}
},
{
"end": 136,

View File

@ -1,8 +1,6 @@
---
source: kcl/src/parsing/parser.rs
assertion_line: 3964
expression: actual
snapshot_kind: text
---
{
"body": [
@ -31,7 +29,10 @@ snapshot_kind: text
"start": 14,
"type": "Literal",
"type": "Literal",
"value": 0.0
"value": {
"value": 0.0,
"suffix": "None"
}
},
{
"argument": {
@ -40,7 +41,10 @@ snapshot_kind: text
"start": 18,
"type": "Literal",
"type": "Literal",
"value": 1.0
"value": {
"value": 1.0,
"suffix": "None"
}
},
"end": 19,
"operator": "-",

View File

@ -21,7 +21,10 @@ expression: actual
"start": 14,
"type": "Literal",
"type": "Literal",
"value": 10.0
"value": {
"value": 10.0,
"suffix": "None"
}
},
"endInclusive": true,
"start": 10,
@ -31,7 +34,10 @@ expression: actual
"start": 11,
"type": "Literal",
"type": "Literal",
"value": 0.0
"value": {
"value": 0.0,
"suffix": "None"
}
},
"type": "ArrayRangeExpression",
"type": "ArrayRangeExpression"

View File

@ -23,7 +23,10 @@ expression: actual
"start": 50,
"type": "Literal",
"type": "Literal",
"value": 2.0
"value": {
"value": 2.0,
"suffix": "None"
}
},
"end": 51,
"start": 43,

View File

@ -25,7 +25,10 @@ expression: actual
"start": 26,
"type": "Literal",
"type": "Literal",
"value": 0.0
"value": {
"value": 0.0,
"suffix": "None"
}
},
{
"end": 29,
@ -33,7 +36,10 @@ expression: actual
"start": 28,
"type": "Literal",
"type": "Literal",
"value": 0.0
"value": {
"value": 0.0,
"suffix": "None"
}
}
],
"end": 30,
@ -63,7 +69,10 @@ expression: actual
"start": 51,
"type": "Literal",
"type": "Literal",
"value": 0.0
"value": {
"value": 0.0,
"suffix": "None"
}
},
{
"end": 55,
@ -71,7 +80,10 @@ expression: actual
"start": 54,
"type": "Literal",
"type": "Literal",
"value": 1.0
"value": {
"value": 1.0,
"suffix": "None"
}
}
],
"end": 56,
@ -114,7 +126,10 @@ expression: actual
"start": 89,
"type": "Literal",
"type": "Literal",
"value": 1.0
"value": {
"value": 1.0,
"suffix": "None"
}
},
{
"end": 93,
@ -122,7 +137,10 @@ expression: actual
"start": 92,
"type": "Literal",
"type": "Literal",
"value": 1.0
"value": {
"value": 1.0,
"suffix": "None"
}
}
],
"end": 94,
@ -158,7 +176,10 @@ expression: actual
"start": 118,
"type": "Literal",
"type": "Literal",
"value": 1.0
"value": {
"value": 1.0,
"suffix": "None"
}
},
{
"end": 122,
@ -166,7 +187,10 @@ expression: actual
"start": 121,
"type": "Literal",
"type": "Literal",
"value": 0.0
"value": {
"value": 0.0,
"suffix": "None"
}
}
],
"end": 123,

View File

@ -25,7 +25,10 @@ expression: actual
"start": 26,
"type": "Literal",
"type": "Literal",
"value": 0.0
"value": {
"value": 0.0,
"suffix": "None"
}
},
{
"end": 29,
@ -33,7 +36,10 @@ expression: actual
"start": 28,
"type": "Literal",
"type": "Literal",
"value": 0.0
"value": {
"value": 0.0,
"suffix": "None"
}
}
],
"end": 30,
@ -63,7 +69,10 @@ expression: actual
"start": 43,
"type": "Literal",
"type": "Literal",
"value": 1.0
"value": {
"value": 1.0,
"suffix": "None"
}
},
{
"end": 47,
@ -71,7 +80,10 @@ expression: actual
"start": 46,
"type": "Literal",
"type": "Literal",
"value": 1.0
"value": {
"value": 1.0,
"suffix": "None"
}
}
],
"end": 48,

View File

@ -23,7 +23,10 @@ expression: actual
"start": 10,
"type": "Literal",
"type": "Literal",
"value": 1.0
"value": {
"value": 1.0,
"suffix": "None"
}
}
],
"callee": {
@ -45,7 +48,10 @@ expression: actual
"start": 18,
"type": "Literal",
"type": "Literal",
"value": 2.0
"value": {
"value": 2.0,
"suffix": "None"
}
},
{
"end": 22,

View File

@ -46,7 +46,10 @@ expression: actual
"start": 34,
"type": "Literal",
"type": "Literal",
"value": 0.0
"value": {
"value": 0.0,
"suffix": "None"
}
},
{
"end": 38,

View File

@ -1,8 +1,6 @@
---
source: kcl/src/parsing/parser.rs
assertion_line: 3996
expression: actual
snapshot_kind: text
---
{
"body": [
@ -31,7 +29,10 @@ snapshot_kind: text
"start": 14,
"type": "Literal",
"type": "Literal",
"value": 0.0
"value": {
"value": 0.0,
"suffix": "None"
}
},
{
"end": 18,
@ -39,7 +40,10 @@ snapshot_kind: text
"start": 17,
"type": "Literal",
"type": "Literal",
"value": 1.0
"value": {
"value": 1.0,
"suffix": "None"
}
}
],
"end": 19,

View File

@ -1,8 +1,6 @@
---
source: kcl/src/parsing/parser.rs
assertion_line: 3997
expression: actual
snapshot_kind: text
---
{
"body": [
@ -31,7 +29,10 @@ snapshot_kind: text
"start": 14,
"type": "Literal",
"type": "Literal",
"value": 0.0
"value": {
"value": 0.0,
"suffix": "None"
}
},
{
"end": 18,
@ -39,7 +40,10 @@ snapshot_kind: text
"start": 17,
"type": "Literal",
"type": "Literal",
"value": 1.0
"value": {
"value": 1.0,
"suffix": "None"
}
}
],
"end": 19,
@ -66,7 +70,10 @@ snapshot_kind: text
"start": 28,
"type": "Literal",
"type": "Literal",
"value": 3.0
"value": {
"value": 3.0,
"suffix": "None"
}
},
{
"end": 32,
@ -74,7 +81,10 @@ snapshot_kind: text
"start": 31,
"type": "Literal",
"type": "Literal",
"value": 3.0
"value": {
"value": 3.0,
"suffix": "None"
}
}
],
"end": 33,

View File

@ -1,8 +1,6 @@
---
source: kcl/src/parsing/parser.rs
assertion_line: 3998
expression: actual
snapshot_kind: text
---
{
"body": [
@ -31,7 +29,10 @@ snapshot_kind: text
"start": 12,
"type": "Literal",
"type": "Literal",
"value": 0.0
"value": {
"value": 0.0,
"suffix": "None"
}
},
{
"end": 16,
@ -39,7 +40,10 @@ snapshot_kind: text
"start": 15,
"type": "Literal",
"type": "Literal",
"value": 1.0
"value": {
"value": 1.0,
"suffix": "None"
}
}
],
"end": 17,

View File

@ -1,8 +1,6 @@
---
source: kcl/src/parsing/parser.rs
assertion_line: 3999
expression: actual
snapshot_kind: text
---
{
"body": [
@ -31,7 +29,10 @@ snapshot_kind: text
"start": 14,
"type": "Literal",
"type": "Literal",
"value": 0.0
"value": {
"value": 0.0,
"suffix": "None"
}
},
{
"end": 18,
@ -39,7 +40,10 @@ snapshot_kind: text
"start": 17,
"type": "Literal",
"type": "Literal",
"value": 1.0
"value": {
"value": 1.0,
"suffix": "None"
}
}
],
"end": 19,
@ -66,7 +70,10 @@ snapshot_kind: text
"start": 28,
"type": "Literal",
"type": "Literal",
"value": 3.0
"value": {
"value": 3.0,
"suffix": "None"
}
},
{
"end": 32,
@ -74,7 +81,10 @@ snapshot_kind: text
"start": 31,
"type": "Literal",
"type": "Literal",
"value": 3.0
"value": {
"value": 3.0,
"suffix": "None"
}
}
],
"end": 33,

View File

@ -1,8 +1,6 @@
---
source: kcl/src/parsing/parser.rs
assertion_line: 4000
expression: actual
snapshot_kind: text
---
{
"body": [
@ -31,7 +29,10 @@ snapshot_kind: text
"start": 14,
"type": "Literal",
"type": "Literal",
"value": 0.0
"value": {
"value": 0.0,
"suffix": "None"
}
},
{
"end": 18,
@ -39,7 +40,10 @@ snapshot_kind: text
"start": 17,
"type": "Literal",
"type": "Literal",
"value": 1.0
"value": {
"value": 1.0,
"suffix": "None"
}
}
],
"end": 19,
@ -66,7 +70,10 @@ snapshot_kind: text
"start": 27,
"type": "Literal",
"type": "Literal",
"value": 3.0
"value": {
"value": 3.0,
"suffix": "None"
}
},
{
"end": 31,
@ -74,7 +81,10 @@ snapshot_kind: text
"start": 30,
"type": "Literal",
"type": "Literal",
"value": 3.0
"value": {
"value": 3.0,
"suffix": "None"
}
}
],
"end": 32,

View File

@ -23,7 +23,10 @@ expression: actual
"start": 26,
"type": "Literal",
"type": "Literal",
"value": 0.0
"value": {
"value": 0.0,
"suffix": "None"
}
},
{
"end": 29,
@ -31,7 +34,10 @@ expression: actual
"start": 28,
"type": "Literal",
"type": "Literal",
"value": 0.0
"value": {
"value": 0.0,
"suffix": "None"
}
}
],
"end": 30,

View File

@ -1,8 +1,6 @@
---
source: kcl/src/parsing/parser.rs
assertion_line: 4002
expression: actual
snapshot_kind: text
---
{
"body": [
@ -16,7 +14,10 @@ snapshot_kind: text
"start": 4,
"type": "Literal",
"type": "Literal",
"value": 5.0
"value": {
"value": 5.0,
"suffix": "None"
}
},
{
"end": 14,

View File

@ -1,8 +1,6 @@
---
source: kcl/src/parsing/parser.rs
assertion_line: 4003
expression: actual
snapshot_kind: text
---
{
"body": [
@ -16,7 +14,10 @@ snapshot_kind: text
"start": 0,
"type": "Literal",
"type": "Literal",
"value": 5.0
"value": {
"value": 5.0,
"suffix": "None"
}
},
"operator": "+",
"right": {

View File

@ -1,8 +1,6 @@
---
source: kcl/src/parsing/parser.rs
assertion_line: 4004
expression: actual
snapshot_kind: text
---
{
"body": [
@ -18,7 +16,10 @@ snapshot_kind: text
"start": 6,
"type": "Literal",
"type": "Literal",
"value": 0.0
"value": {
"value": 0.0,
"suffix": "None"
}
},
{
"end": 10,

View File

@ -60,7 +60,10 @@ expression: actual
"start": 62,
"type": "Literal",
"type": "Literal",
"value": 0.0
"value": {
"value": 0.0,
"suffix": "None"
}
},
{
"end": 66,
@ -68,7 +71,10 @@ expression: actual
"start": 65,
"type": "Literal",
"type": "Literal",
"value": 0.0
"value": {
"value": 0.0,
"suffix": "None"
}
}
],
"end": 67,
@ -93,7 +99,10 @@ expression: actual
"start": 77,
"type": "Literal",
"type": "Literal",
"value": 22.0
"value": {
"value": 22.0,
"suffix": "None"
}
}
}
],
@ -127,7 +136,10 @@ expression: actual
"start": 101,
"type": "Literal",
"type": "Literal",
"value": 14.0
"value": {
"value": 14.0,
"suffix": "None"
}
},
{
"end": 106,

View File

@ -32,7 +32,10 @@ expression: actual
"start": 43,
"type": "Literal",
"type": "Literal",
"value": 360.0
"value": {
"value": 360.0,
"suffix": "None"
}
}
],
"callee": {

View File

@ -21,7 +21,10 @@ expression: actual
"start": 28,
"type": "Literal",
"type": "Literal",
"value": 1.0
"value": {
"value": 1.0,
"suffix": "None"
}
},
{
"end": 80,
@ -29,7 +32,10 @@ expression: actual
"start": 79,
"type": "Literal",
"type": "Literal",
"value": 3.0
"value": {
"value": 3.0,
"suffix": "None"
}
}
],
"end": 91,

View File

@ -21,7 +21,10 @@ expression: actual
"start": 28,
"type": "Literal",
"type": "Literal",
"value": 1.0
"value": {
"value": 1.0,
"suffix": "None"
}
},
{
"end": 44,
@ -29,7 +32,10 @@ expression: actual
"start": 43,
"type": "Literal",
"type": "Literal",
"value": 2.0
"value": {
"value": 2.0,
"suffix": "None"
}
}
],
"end": 91,

View File

@ -49,7 +49,10 @@ expression: actual
"start": 29,
"type": "Literal",
"type": "Literal",
"value": 1.0
"value": {
"value": 1.0,
"suffix": "None"
}
}
},
{
@ -68,7 +71,10 @@ expression: actual
"start": 68,
"type": "Literal",
"type": "Literal",
"value": 3.0
"value": {
"value": 3.0,
"suffix": "None"
}
}
}
],

View File

@ -49,7 +49,10 @@ expression: actual
"start": 29,
"type": "Literal",
"type": "Literal",
"value": 1.0
"value": {
"value": 1.0,
"suffix": "None"
}
}
},
{
@ -68,7 +71,10 @@ expression: actual
"start": 68,
"type": "Literal",
"type": "Literal",
"value": 3.0
"value": {
"value": 3.0,
"suffix": "None"
}
}
}
],

View File

@ -21,7 +21,10 @@ expression: actual
"start": 12,
"type": "Literal",
"type": "Literal",
"value": 5.0
"value": {
"value": 5.0,
"suffix": "None"
}
},
{
"argument": {
@ -32,7 +35,10 @@ expression: actual
"start": 24,
"type": "Literal",
"type": "Literal",
"value": 5.0
"value": {
"value": 5.0,
"suffix": "None"
}
},
{
"end": 28,
@ -40,7 +46,10 @@ expression: actual
"start": 27,
"type": "Literal",
"type": "Literal",
"value": 4.0
"value": {
"value": 4.0,
"suffix": "None"
}
}
],
"callee": {

View File

@ -23,7 +23,10 @@ expression: actual
"start": 8,
"type": "Literal",
"type": "Literal",
"value": 4.0
"value": {
"value": 4.0,
"suffix": "None"
}
},
"operator": "^",
"right": {
@ -32,7 +35,10 @@ expression: actual
"start": 12,
"type": "Literal",
"type": "Literal",
"value": 2.0
"value": {
"value": 2.0,
"suffix": "None"
}
},
"start": 8,
"type": "BinaryExpression",
@ -49,7 +55,10 @@ expression: actual
"start": 16,
"type": "Literal",
"type": "Literal",
"value": 3.0
"value": {
"value": 3.0,
"suffix": "None"
}
},
"operator": "^",
"right": {
@ -58,7 +67,10 @@ expression: actual
"start": 20,
"type": "Literal",
"type": "Literal",
"value": 2.0
"value": {
"value": 2.0,
"suffix": "None"
}
},
"start": 16,
"type": "BinaryExpression",
@ -71,7 +83,10 @@ expression: actual
"start": 24,
"type": "Literal",
"type": "Literal",
"value": 2.0
"value": {
"value": 2.0,
"suffix": "None"
}
},
"start": 16,
"type": "BinaryExpression",

View File

@ -35,7 +35,10 @@ expression: actual
"start": 57,
"type": "Literal",
"type": "Literal",
"value": 4.0
"value": {
"value": 4.0,
"suffix": "None"
}
},
"start": 57,
"type": "ExpressionStatement",
@ -56,7 +59,10 @@ expression: actual
"start": 26,
"type": "Literal",
"type": "Literal",
"value": 3.0
"value": {
"value": 3.0,
"suffix": "None"
}
},
"start": 26,
"type": "ExpressionStatement",

View File

@ -59,7 +59,10 @@ expression: actual
"start": 73,
"type": "Literal",
"type": "Literal",
"value": 4.0
"value": {
"value": 4.0,
"suffix": "None"
}
},
"start": 73,
"type": "ExpressionStatement",
@ -83,7 +86,10 @@ expression: actual
"start": 104,
"type": "Literal",
"type": "Literal",
"value": 5.0
"value": {
"value": 5.0,
"suffix": "None"
}
},
"start": 104,
"type": "ExpressionStatement",
@ -104,7 +110,10 @@ expression: actual
"start": 26,
"type": "Literal",
"type": "Literal",
"value": 3.0
"value": {
"value": 3.0,
"suffix": "None"
}
},
"start": 26,
"type": "ExpressionStatement",

View File

@ -21,7 +21,10 @@ expression: actual
"start": 8,
"type": "Literal",
"type": "Literal",
"value": 3.0
"value": {
"value": 3.0,
"suffix": "None"
}
},
"operator": "==",
"right": {
@ -30,7 +33,10 @@ expression: actual
"start": 13,
"type": "Literal",
"type": "Literal",
"value": 3.0
"value": {
"value": 3.0,
"suffix": "None"
}
},
"start": 8,
"type": "BinaryExpression",

View File

@ -21,7 +21,10 @@ expression: actual
"start": 8,
"type": "Literal",
"type": "Literal",
"value": 3.0
"value": {
"value": 3.0,
"suffix": "None"
}
},
"operator": "!=",
"right": {
@ -30,7 +33,10 @@ expression: actual
"start": 13,
"type": "Literal",
"type": "Literal",
"value": 3.0
"value": {
"value": 3.0,
"suffix": "None"
}
},
"start": 8,
"type": "BinaryExpression",

View File

@ -19,7 +19,10 @@ expression: actual
"start": 4,
"type": "Literal",
"type": "Literal",
"value": 4.0
"value": {
"value": 4.0,
"suffix": "None"
}
},
"start": 0,
"type": "VariableDeclarator"

View File

@ -34,7 +34,10 @@ expression: actual
"start": 17,
"type": "Literal",
"type": "Literal",
"value": 10.0
"value": {
"value": 10.0,
"suffix": "None"
}
},
{
"end": 23,
@ -42,7 +45,10 @@ expression: actual
"start": 21,
"type": "Literal",
"type": "Literal",
"value": 10.0
"value": {
"value": 10.0,
"suffix": "None"
}
}
],
"end": 24,
@ -67,7 +73,10 @@ expression: actual
"start": 34,
"type": "Literal",
"type": "Literal",
"value": 5.0
"value": {
"value": 5.0,
"suffix": "None"
}
}
}
],

View File

@ -19,7 +19,10 @@ expression: actual
"start": 4,
"type": "Literal",
"type": "Literal",
"value": 3.0
"value": {
"value": 3.0,
"suffix": "None"
}
},
"start": 0,
"type": "VariableDeclarator"
@ -76,7 +79,10 @@ expression: actual
"start": 28,
"type": "Literal",
"type": "Literal",
"value": 4.0
"value": {
"value": 4.0,
"suffix": "None"
}
}
}
],

View File

@ -24,7 +24,10 @@ expression: actual
"start": 20,
"type": "Literal",
"type": "Literal",
"value": 5.0
"value": {
"value": 5.0,
"suffix": "None"
}
},
{
"end": 24,
@ -32,7 +35,10 @@ expression: actual
"start": 23,
"type": "Literal",
"type": "Literal",
"value": 4.0
"value": {
"value": 4.0,
"suffix": "None"
}
}
],
"callee": {
@ -58,7 +64,10 @@ expression: actual
"start": 27,
"type": "Literal",
"type": "Literal",
"value": 5.0
"value": {
"value": 5.0,
"suffix": "None"
}
}
],
"callee": {

View File

@ -23,7 +23,10 @@ expression: actual
"start": 8,
"type": "Literal",
"type": "Literal",
"value": 5.0
"value": {
"value": 5.0,
"suffix": "None"
}
},
"operator": "+",
"right": {
@ -32,7 +35,10 @@ expression: actual
"start": 12,
"type": "Literal",
"type": "Literal",
"value": 6.0
"value": {
"value": 6.0,
"suffix": "None"
}
},
"start": 8,
"type": "BinaryExpression",
@ -46,7 +52,10 @@ expression: actual
"start": 24,
"type": "Literal",
"type": "Literal",
"value": 45.0
"value": {
"value": 45.0,
"suffix": "None"
}
},
{
"end": 29,

View File

@ -21,7 +21,10 @@ expression: actual
"start": 8,
"type": "Literal",
"type": "Literal",
"value": 1.0
"value": {
"value": 1.0,
"suffix": "None"
}
},
"operator": "*",
"right": {
@ -32,7 +35,10 @@ expression: actual
"start": 13,
"type": "Literal",
"type": "Literal",
"value": 3.0
"value": {
"value": 3.0,
"suffix": "None"
}
},
"operator": "-",
"right": {
@ -41,7 +47,10 @@ expression: actual
"start": 17,
"type": "Literal",
"type": "Literal",
"value": 4.0
"value": {
"value": 4.0,
"suffix": "None"
}
},
"start": 13,
"type": "BinaryExpression",

View File

@ -19,7 +19,10 @@ expression: actual
"start": 4,
"type": "Literal",
"type": "Literal",
"value": 1.0
"value": {
"value": 1.0,
"suffix": "None"
}
},
"start": 0,
"type": "VariableDeclarator"

View File

@ -32,7 +32,10 @@ expression: actual
"start": 11,
"type": "Literal",
"type": "Literal",
"value": 1.0
"value": {
"value": 1.0,
"suffix": "None"
}
}
},
{
@ -51,7 +54,10 @@ expression: actual
"start": 17,
"type": "Literal",
"type": "Literal",
"value": 2.0
"value": {
"value": 2.0,
"suffix": "None"
}
}
}
],
@ -85,7 +91,10 @@ expression: actual
"start": 34,
"type": "Literal",
"type": "Literal",
"value": 1.0
"value": {
"value": 1.0,
"suffix": "None"
}
},
"operator": "-",
"right": {

View File

@ -32,7 +32,10 @@ expression: actual
"start": 11,
"type": "Literal",
"type": "Literal",
"value": 1.0
"value": {
"value": 1.0,
"suffix": "None"
}
}
},
{
@ -51,7 +54,10 @@ expression: actual
"start": 17,
"type": "Literal",
"type": "Literal",
"value": 2.0
"value": {
"value": 2.0,
"suffix": "None"
}
}
}
],
@ -85,7 +91,10 @@ expression: actual
"start": 35,
"type": "Literal",
"type": "Literal",
"value": 1.0
"value": {
"value": 1.0,
"suffix": "None"
}
},
"operator": "-",
"right": {

View File

@ -32,7 +32,10 @@ expression: actual
"start": 11,
"type": "Literal",
"type": "Literal",
"value": 1.0
"value": {
"value": 1.0,
"suffix": "None"
}
}
},
{
@ -51,7 +54,10 @@ expression: actual
"start": 17,
"type": "Literal",
"type": "Literal",
"value": 2.0
"value": {
"value": 2.0,
"suffix": "None"
}
}
}
],
@ -108,7 +114,10 @@ expression: actual
"start": 45,
"type": "Literal",
"type": "Literal",
"value": 1.0
"value": {
"value": 1.0,
"suffix": "None"
}
},
"start": 34,
"type": "BinaryExpression",

View File

@ -32,7 +32,10 @@ expression: actual
"start": 11,
"type": "Literal",
"type": "Literal",
"value": 1.0
"value": {
"value": 1.0,
"suffix": "None"
}
}
},
{
@ -51,7 +54,10 @@ expression: actual
"start": 17,
"type": "Literal",
"type": "Literal",
"value": 2.0
"value": {
"value": 2.0,
"suffix": "None"
}
}
}
],
@ -87,7 +93,10 @@ expression: actual
"start": 35,
"type": "Literal",
"type": "Literal",
"value": 1.0
"value": {
"value": 1.0,
"suffix": "None"
}
},
"operator": "-",
"right": {
@ -122,7 +131,10 @@ expression: actual
"start": 49,
"type": "Literal",
"type": "Literal",
"value": 0.0
"value": {
"value": 0.0,
"suffix": "None"
}
}
],
"end": 51,

View File

@ -1,8 +1,6 @@
---
source: kcl/src/parsing/parser.rs
assertion_line: 4674
expression: actual
snapshot_kind: text
---
{
"body": [
@ -23,7 +21,10 @@ snapshot_kind: text
"start": 6,
"type": "Literal",
"type": "Literal",
"value": 1.0
"value": {
"value": 1.0,
"suffix": "None"
}
},
{
"arguments": [

View File

@ -1,7 +1,6 @@
---
source: kcl/src/parsing/parser.rs
expression: actual
snapshot_kind: text
---
{
"body": [
@ -24,7 +23,10 @@ snapshot_kind: text
"start": 22,
"type": "Literal",
"type": "Literal",
"value": 1.0
"value": {
"value": 1.0,
"suffix": "None"
}
},
"end": 23,
"start": 15,

View File

@ -1,7 +1,6 @@
---
source: kcl/src/parsing/parser.rs
expression: actual
snapshot_kind: text
---
{
"body": [
@ -24,7 +23,10 @@ snapshot_kind: text
"start": 23,
"type": "Literal",
"type": "Literal",
"value": 1.0
"value": {
"value": 1.0,
"suffix": "None"
}
},
"end": 24,
"start": 16,

View File

@ -1,7 +1,6 @@
---
source: kcl/src/parsing/parser.rs
expression: actual
snapshot_kind: text
---
{
"body": [
@ -24,7 +23,10 @@ snapshot_kind: text
"start": 32,
"type": "Literal",
"type": "Literal",
"value": 1.0
"value": {
"value": 1.0,
"suffix": "None"
}
},
"end": 33,
"start": 25,
@ -52,7 +54,10 @@ snapshot_kind: text
"default_value": {
"type": "Literal",
"type": "Literal",
"value": 2.0,
"value": {
"value": 2.0,
"suffix": "None"
},
"raw": "2"
}
}

View File

@ -1,7 +1,6 @@
---
source: kcl/src/parsing/parser.rs
expression: actual
snapshot_kind: text
---
{
"body": [
@ -24,7 +23,10 @@ snapshot_kind: text
"start": 24,
"type": "Literal",
"type": "Literal",
"value": 1.0
"value": {
"value": 1.0,
"suffix": "None"
}
},
"end": 25,
"start": 17,
@ -48,7 +50,10 @@ snapshot_kind: text
"default_value": {
"type": "Literal",
"type": "Literal",
"value": 2.0,
"value": {
"value": 2.0,
"suffix": "None"
},
"raw": "2"
}
}

View File

@ -32,7 +32,10 @@ expression: actual
"start": 11,
"type": "Literal",
"type": "Literal",
"value": 1.0
"value": {
"value": 1.0,
"suffix": "None"
}
}
},
{
@ -51,7 +54,10 @@ expression: actual
"start": 17,
"type": "Literal",
"type": "Literal",
"value": 2.0
"value": {
"value": 2.0,
"suffix": "None"
}
}
}
],
@ -110,7 +116,10 @@ expression: actual
"start": 46,
"type": "Literal",
"type": "Literal",
"value": 1.0
"value": {
"value": 1.0,
"suffix": "None"
}
},
"start": 35,
"type": "BinaryExpression",
@ -122,7 +131,10 @@ expression: actual
"start": 49,
"type": "Literal",
"type": "Literal",
"value": 0.0
"value": {
"value": 0.0,
"suffix": "None"
}
}
],
"end": 51,

View File

@ -32,7 +32,10 @@ expression: actual
"start": 11,
"type": "Literal",
"type": "Literal",
"value": 1.0
"value": {
"value": 1.0,
"suffix": "None"
}
}
},
{
@ -51,7 +54,10 @@ expression: actual
"start": 17,
"type": "Literal",
"type": "Literal",
"value": 2.0
"value": {
"value": 2.0,
"suffix": "None"
}
}
}
],
@ -110,7 +116,10 @@ expression: actual
"start": 45,
"type": "Literal",
"type": "Literal",
"value": 1.0
"value": {
"value": 1.0,
"suffix": "None"
}
},
"start": 35,
"type": "BinaryExpression",
@ -122,7 +131,10 @@ expression: actual
"start": 48,
"type": "Literal",
"type": "Literal",
"value": 0.0
"value": {
"value": 0.0,
"suffix": "None"
}
}
],
"end": 50,

View File

@ -21,7 +21,10 @@ expression: actual
"start": 9,
"type": "Literal",
"type": "Literal",
"value": 1.0
"value": {
"value": 1.0,
"suffix": "None"
}
},
"operator": "-",
"right": {

View File

@ -23,7 +23,10 @@ expression: actual
"start": 6,
"type": "Literal",
"type": "Literal",
"value": 1.0
"value": {
"value": 1.0,
"suffix": "None"
}
},
"operator": "+",
"right": {
@ -32,7 +35,10 @@ expression: actual
"start": 10,
"type": "Literal",
"type": "Literal",
"value": 2.0
"value": {
"value": 2.0,
"suffix": "None"
}
},
"start": 6,
"type": "BinaryExpression",
@ -45,7 +51,10 @@ expression: actual
"start": 14,
"type": "Literal",
"type": "Literal",
"value": 3.0
"value": {
"value": 3.0,
"suffix": "None"
}
},
"start": 6,
"type": "BinaryExpression",

View File

@ -23,7 +23,10 @@ expression: actual
"start": 7,
"type": "Literal",
"type": "Literal",
"value": 3.0
"value": {
"value": 3.0,
"suffix": "None"
}
},
"operator": "*",
"right": {
@ -32,7 +35,10 @@ expression: actual
"start": 11,
"type": "Literal",
"type": "Literal",
"value": 1.0
"value": {
"value": 1.0,
"suffix": "None"
}
},
"start": 7,
"type": "BinaryExpression",
@ -45,7 +51,10 @@ expression: actual
"start": 15,
"type": "Literal",
"type": "Literal",
"value": 2.0
"value": {
"value": 2.0,
"suffix": "None"
}
},
"start": 7,
"type": "BinaryExpression",

View File

@ -43,7 +43,10 @@ expression: actual
"start": 21,
"type": "Literal",
"type": "Literal",
"value": 0.0
"value": {
"value": 0.0,
"suffix": "None"
}
}
],
"end": 24,

View File

@ -32,7 +32,10 @@ expression: actual
"start": 11,
"type": "Literal",
"type": "Literal",
"value": 1.0
"value": {
"value": 1.0,
"suffix": "None"
}
}
},
{
@ -51,7 +54,10 @@ expression: actual
"start": 17,
"type": "Literal",
"type": "Literal",
"value": 2.0
"value": {
"value": 2.0,
"suffix": "None"
}
}
}
],

View File

@ -29,7 +29,10 @@ expression: actual
"start": 9,
"type": "Literal",
"type": "Literal",
"value": 0.0
"value": {
"value": 0.0,
"suffix": "None"
}
},
"start": 6,
"type": "MemberExpression",

View File

@ -46,7 +46,10 @@ expression: actual
"start": 33,
"type": "Literal",
"type": "Literal",
"value": 0.0
"value": {
"value": 0.0,
"suffix": "None"
}
},
{
"argument": {

View File

@ -5,6 +5,8 @@ use std::{fmt, iter::Enumerate, num::NonZeroUsize, str::FromStr};
use anyhow::Result;
use parse_display::Display;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use tokeniser::Input;
use tower_lsp::lsp_types::SemanticTokenType;
use winnow::{
@ -28,7 +30,8 @@ pub(crate) use tokeniser::RESERVED_WORDS;
// Note the ordering, it's important that `m` comes after `mm` and `cm`.
pub const NUM_SUFFIXES: [&str; 9] = ["mm", "cm", "m", "inch", "in", "ft", "yd", "deg", "rad"];
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
#[derive(Clone, Copy, Debug, Eq, PartialEq, Serialize, Deserialize, ts_rs::TS, JsonSchema)]
#[repr(u32)]
pub enum NumericSuffix {
None,
Count,
@ -72,6 +75,23 @@ impl FromStr for NumericSuffix {
}
}
impl fmt::Display for NumericSuffix {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
NumericSuffix::None => Ok(()),
NumericSuffix::Count => write!(f, "_"),
NumericSuffix::Mm => write!(f, "mm"),
NumericSuffix::Cm => write!(f, "cm"),
NumericSuffix::M => write!(f, "m"),
NumericSuffix::Inch => write!(f, "in"),
NumericSuffix::Ft => write!(f, "ft"),
NumericSuffix::Yd => write!(f, "yd"),
NumericSuffix::Deg => write!(f, "deg"),
NumericSuffix::Rad => write!(f, "rad"),
}
}
}
#[derive(Clone, Debug, PartialEq)]
pub(crate) struct TokenStream {
tokens: Vec<Token>,

View File

@ -76,6 +76,12 @@ impl SourceRange {
self.0[0]
}
/// Get the start of the range as a zero-length SourceRange, effectively collapse `self` to it's
/// start.
pub fn start_as_range(&self) -> Self {
Self([self.0[0], self.0[0], self.0[2]])
}
/// Get the end of the range.
pub fn end(&self) -> usize {
self.0[1]

View File

@ -141,7 +141,7 @@ pub async fn reduce(exec_state: &mut ExecState, args: Args) -> Result<KclValue,
/// // Declare a function that sketches a decagon.
/// fn decagon(radius) {
/// // Each side of the decagon is turned this many degrees from the previous angle.
/// stepAngle = (1/10) * tau()
/// stepAngle = (1/10) * TAU
///
/// // Start the decagon sketch at this point.
/// startOfDecagonSketch = startSketchOn('XY')
@ -164,7 +164,7 @@ pub async fn reduce(exec_state: &mut ExecState, args: Args) -> Result<KclValue,
/// /*
/// The `decagon` above is basically like this pseudo-code:
/// fn decagon(radius):
/// stepAngle = (1/10) * tau()
/// stepAngle = (1/10) * TAU
/// plane = startSketchOn('XY')
/// startOfDecagonSketch = startProfileAt([(cos(0)*radius), (sin(0) * radius)], plane)
///

View File

@ -145,6 +145,8 @@ pub async fn pi(_exec_state: &mut ExecState, args: Args) -> Result<KclValue, Kcl
/// Return the value of `pi`. Archimedes constant (π).
///
/// **DEPRECATED** use PI
///
/// ```no_run
/// circumference = 70
///
@ -156,6 +158,7 @@ pub async fn pi(_exec_state: &mut ExecState, args: Args) -> Result<KclValue, Kcl
#[stdlib {
name = "pi",
tags = ["math"],
deprecated = true,
}]
fn inner_pi() -> Result<f64, KclError> {
Ok(std::f64::consts::PI)
@ -693,6 +696,8 @@ pub async fn e(_exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclE
/// Return the value of Eulers number `e`.
///
/// **DEPRECATED** use E
///
/// ```no_run
/// exampleSketch = startSketchOn("XZ")
/// |> startProfileAt([0, 0], %)
@ -708,6 +713,7 @@ pub async fn e(_exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclE
#[stdlib {
name = "e",
tags = ["math"],
deprecated = true,
}]
fn inner_e() -> Result<f64, KclError> {
Ok(std::f64::consts::E)
@ -722,6 +728,8 @@ pub async fn tau(_exec_state: &mut ExecState, args: Args) -> Result<KclValue, Kc
/// Return the value of `tau`. The full circle constant (τ). Equal to 2π.
///
/// **DEPRECATED** use TAU
///
/// ```no_run
/// exampleSketch = startSketchOn("XZ")
/// |> startProfileAt([0, 0], %)
@ -737,6 +745,7 @@ pub async fn tau(_exec_state: &mut ExecState, args: Args) -> Result<KclValue, Kc
#[stdlib {
name = "tau",
tags = ["math"],
deprecated = true,
}]
fn inner_tau() -> Result<f64, KclError> {
Ok(std::f64::consts::TAU)
@ -787,7 +796,7 @@ pub async fn to_degrees(_exec_state: &mut ExecState, args: Args) -> Result<KclVa
/// |> startProfileAt([0, 0], %)
/// |> angledLine({
/// angle = 50,
/// length = 70 * cos(toDegrees(pi()/4)),
/// length = 70 * cos(toDegrees(PI/4)),
/// }, %)
/// |> yLineTo(0, %)
/// |> close(%)

View File

@ -373,11 +373,11 @@ impl VariableDeclaration {
impl Literal {
fn recast(&self) -> String {
match self.value {
LiteralValue::Number(x) => {
if self.raw.contains('.') && x.fract() == 0.0 {
format!("{x:?}")
LiteralValue::Number { value, suffix } => {
if self.raw.contains('.') && value.fract() == 0.0 {
format!("{value:?}{suffix}")
} else {
self.raw.clone()
format!("{}{suffix}", self.raw)
}
}
LiteralValue::String(ref s) => {

File diff suppressed because it is too large Load Diff

View File

@ -1,22 +1,36 @@
---
source: kcl/src/simulation_tests.rs
description: Program memory after executing add_lots.kcl
snapshot_kind: text
---
{
"environments": [
{
"bindings": {
"E": {
"type": "Number",
"value": 2.718281828459045,
"__meta": []
},
"HALF_TURN": {
"type": "Number",
"value": 180.0,
"__meta": []
},
"PI": {
"type": "Number",
"value": 3.141592653589793,
"__meta": []
},
"QUARTER_TURN": {
"type": "Number",
"value": 90.0,
"__meta": []
},
"TAU": {
"type": "Number",
"value": 6.283185307179586,
"__meta": []
},
"THREE_QUARTER_TURN": {
"type": "Number",
"value": 270.0,
@ -49,7 +63,10 @@ snapshot_kind: text
"start": 23,
"type": "Literal",
"type": "Literal",
"value": 2.0
"value": {
"value": 2.0,
"suffix": "None"
}
},
"start": 19,
"type": "BinaryExpression",
@ -83,16 +100,31 @@ snapshot_kind: text
"environments": [
{
"bindings": {
"E": {
"type": "Number",
"value": 2.718281828459045,
"__meta": []
},
"HALF_TURN": {
"type": "Number",
"value": 180.0,
"__meta": []
},
"PI": {
"type": "Number",
"value": 3.141592653589793,
"__meta": []
},
"QUARTER_TURN": {
"type": "Number",
"value": 90.0,
"__meta": []
},
"TAU": {
"type": "Number",
"value": 6.283185307179586,
"__meta": []
},
"THREE_QUARTER_TURN": {
"type": "Number",
"value": 270.0,

View File

@ -48,7 +48,10 @@ description: Result of parsing angled_line.kcl
"start": 51,
"type": "Literal",
"type": "Literal",
"value": 4.83
"value": {
"value": 4.83,
"suffix": "None"
}
},
{
"end": 62,
@ -56,7 +59,10 @@ description: Result of parsing angled_line.kcl
"start": 57,
"type": "Literal",
"type": "Literal",
"value": 12.56
"value": {
"value": 12.56,
"suffix": "None"
}
}
],
"end": 63,
@ -92,7 +98,10 @@ description: Result of parsing angled_line.kcl
"start": 79,
"type": "Literal",
"type": "Literal",
"value": 15.1
"value": {
"value": 15.1,
"suffix": "None"
}
},
{
"end": 89,
@ -100,7 +109,10 @@ description: Result of parsing angled_line.kcl
"start": 85,
"type": "Literal",
"type": "Literal",
"value": 2.48
"value": {
"value": 2.48,
"suffix": "None"
}
}
],
"end": 90,
@ -136,7 +148,10 @@ description: Result of parsing angled_line.kcl
"start": 106,
"type": "Literal",
"type": "Literal",
"value": 3.15
"value": {
"value": 3.15,
"suffix": "None"
}
},
{
"argument": {
@ -145,7 +160,10 @@ description: Result of parsing angled_line.kcl
"start": 113,
"type": "Literal",
"type": "Literal",
"value": 9.85
"value": {
"value": 9.85,
"suffix": "None"
}
},
"end": 117,
"operator": "-",
@ -195,7 +213,10 @@ description: Result of parsing angled_line.kcl
"start": 143,
"type": "Literal",
"type": "Literal",
"value": 15.17
"value": {
"value": 15.17,
"suffix": "None"
}
},
"end": 148,
"operator": "-",
@ -210,7 +231,10 @@ description: Result of parsing angled_line.kcl
"start": 151,
"type": "Literal",
"type": "Literal",
"value": 4.1
"value": {
"value": 4.1,
"suffix": "None"
}
},
"end": 154,
"operator": "-",
@ -273,7 +297,10 @@ description: Result of parsing angled_line.kcl
"start": 192,
"type": "Literal",
"type": "Literal",
"value": 12.35
"value": {
"value": 12.35,
"suffix": "None"
}
}
],
"end": 198,
@ -310,7 +337,10 @@ description: Result of parsing angled_line.kcl
"start": 215,
"type": "Literal",
"type": "Literal",
"value": 13.02
"value": {
"value": 13.02,
"suffix": "None"
}
},
"end": 220,
"operator": "-",
@ -324,7 +354,10 @@ description: Result of parsing angled_line.kcl
"start": 222,
"type": "Literal",
"type": "Literal",
"value": 10.03
"value": {
"value": 10.03,
"suffix": "None"
}
}
],
"end": 228,
@ -378,7 +411,10 @@ description: Result of parsing angled_line.kcl
"start": 260,
"type": "Literal",
"type": "Literal",
"value": 4.0
"value": {
"value": 4.0,
"suffix": "None"
}
},
{
"end": 264,

View File

@ -1,22 +1,36 @@
---
source: kcl/src/simulation_tests.rs
description: Program memory after executing angled_line.kcl
snapshot_kind: text
---
{
"environments": [
{
"bindings": {
"E": {
"type": "Number",
"value": 2.718281828459045,
"__meta": []
},
"HALF_TURN": {
"type": "Number",
"value": 180.0,
"__meta": []
},
"PI": {
"type": "Number",
"value": 3.141592653589793,
"__meta": []
},
"QUARTER_TURN": {
"type": "Number",
"value": 90.0,
"__meta": []
},
"TAU": {
"type": "Number",
"value": 6.283185307179586,
"__meta": []
},
"THREE_QUARTER_TURN": {
"type": "Number",
"value": 270.0,

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