Rename kcl Value to Expr (#3360)

Rename kcl's Value to Expr

As Jon pointed out, kcl's `Value` enum is actually an expression.
"2+2" isn't a value, it's an expression, which can compute a value.
So I renamed it `Expr`.
This commit is contained in:
Adam Chalmers
2024-08-12 15:38:42 -05:00
committed by GitHub
parent d1e21d673e
commit 13986fcfd7
34 changed files with 473 additions and 475 deletions

View File

@ -26,7 +26,7 @@ import {
PathToNode,
Program,
SourceRange,
Value,
Expr,
parse,
recast,
} from 'lang/wasm'
@ -550,7 +550,7 @@ const ConstraintSymbol = ({
varNameMap[_type as LineInputsType]?.implicitConstraintDesc
const _node = useMemo(
() => getNodeFromPath<Value>(kclManager.ast, pathToNode),
() => getNodeFromPath<Expr>(kclManager.ast, pathToNode),
[kclManager.ast, pathToNode]
)
if (err(_node)) return

View File

@ -1,5 +1,5 @@
import { useEffect, useState, useRef } from 'react'
import { parse, BinaryPart, Value, ProgramMemory } from '../lang/wasm'
import { parse, BinaryPart, Expr, ProgramMemory } from '../lang/wasm'
import {
createIdentifier,
createLiteral,
@ -86,7 +86,7 @@ export function useCalc({
initialVariableName?: string
}): {
inputRef: React.RefObject<HTMLInputElement>
valueNode: Value | null
valueNode: Expr | null
calcResult: string
prevVariables: PrevVariable<unknown>[]
newVariableName: string
@ -105,7 +105,7 @@ export function useCalc({
insertIndex: 0,
bodyPath: [],
})
const [valueNode, setValueNode] = useState<Value | null>(null)
const [valueNode, setValueNode] = useState<Expr | null>(null)
const [calcResult, setCalcResult] = useState('NAN')
const [newVariableName, setNewVariableName] = useState('')
const [isNewVariableNameUnique, setIsNewVariableNameUnique] = useState(true)

View File

@ -1,7 +1,7 @@
import { Dialog, Transition } from '@headlessui/react'
import { Fragment, useState } from 'react'
import { type InstanceProps, create } from 'react-modal-promise'
import { Value } from '../lang/wasm'
import { Expr } from '../lang/wasm'
import {
AvailableVars,
addToInputHelper,
@ -13,7 +13,7 @@ import { useCalculateKclExpression } from 'lib/useCalculateKclExpression'
type ModalResolve = {
value: string
sign: number
valueNode: Value
valueNode: Expr
variableName?: string
newVariableInsertIndex: number
}

View File

@ -1,7 +1,7 @@
import { Dialog, Transition } from '@headlessui/react'
import { Fragment, useState } from 'react'
import { type InstanceProps, create } from 'react-modal-promise'
import { Value } from '../lang/wasm'
import { Expr } from '../lang/wasm'
import {
AvailableVars,
addToInputHelper,
@ -13,7 +13,7 @@ import { useCalculateKclExpression } from 'lib/useCalculateKclExpression'
type ModalResolve = {
value: string
segName: string
valueNode: Value
valueNode: Expr
variableName?: string
newVariableInsertIndex: number
sign: number

View File

@ -1,6 +1,6 @@
import { toolTips } from 'lang/langHelpers'
import { Selections } from 'lib/selections'
import { Program, Value, VariableDeclarator } from '../../lang/wasm'
import { Program, Expr, VariableDeclarator } from '../../lang/wasm'
import {
getNodePathFromSourceRange,
getNodeFromPath,
@ -29,13 +29,13 @@ export function equalAngleInfo({
getNodePathFromSourceRange(kclManager.ast, range)
)
const _nodes = paths.map((pathToNode) => {
const tmp = getNodeFromPath<Value>(kclManager.ast, pathToNode)
const tmp = getNodeFromPath<Expr>(kclManager.ast, pathToNode)
if (err(tmp)) return tmp
return tmp.node
})
const _err1 = _nodes.find(err)
if (err(_err1)) return _err1
const nodes = _nodes as Value[]
const nodes = _nodes as Expr[]
const _varDecs = paths.map((pathToNode) => {
const tmp = getNodeFromPath<VariableDeclarator>(

View File

@ -1,6 +1,6 @@
import { toolTips } from 'lang/langHelpers'
import { Selections } from 'lib/selections'
import { Program, Value, VariableDeclarator } from '../../lang/wasm'
import { Program, Expr, VariableDeclarator } from '../../lang/wasm'
import {
getNodePathFromSourceRange,
getNodeFromPath,
@ -29,13 +29,13 @@ export function setEqualLengthInfo({
getNodePathFromSourceRange(kclManager.ast, range)
)
const _nodes = paths.map((pathToNode) => {
const tmp = getNodeFromPath<Value>(kclManager.ast, pathToNode)
const tmp = getNodeFromPath<Expr>(kclManager.ast, pathToNode)
if (err(tmp)) return tmp
return tmp.node
})
const _err1 = _nodes.find(err)
if (err(_err1)) return _err1
const nodes = _nodes as Value[]
const nodes = _nodes as Expr[]
const _varDecs = paths.map((pathToNode) => {
const tmp = getNodeFromPath<VariableDeclarator>(

View File

@ -1,6 +1,6 @@
import { toolTips } from 'lang/langHelpers'
import { Selections } from 'lib/selections'
import { Program, ProgramMemory, Value } from '../../lang/wasm'
import { Program, ProgramMemory, Expr } from '../../lang/wasm'
import {
getNodePathFromSourceRange,
getNodeFromPath,
@ -27,13 +27,13 @@ export function horzVertInfo(
getNodePathFromSourceRange(kclManager.ast, range)
)
const _nodes = paths.map((pathToNode) => {
const tmp = getNodeFromPath<Value>(kclManager.ast, pathToNode)
const tmp = getNodeFromPath<Expr>(kclManager.ast, pathToNode)
if (err(tmp)) return tmp
return tmp.node
})
const _err1 = _nodes.find(err)
if (err(_err1)) return _err1
const nodes = _nodes as Value[]
const nodes = _nodes as Expr[]
const isAllTooltips = nodes.every(
(node) =>

View File

@ -1,6 +1,6 @@
import { toolTips } from 'lang/langHelpers'
import { Selections } from 'lib/selections'
import { BinaryPart, Program, Value, VariableDeclarator } from '../../lang/wasm'
import { BinaryPart, Program, Expr, VariableDeclarator } from '../../lang/wasm'
import {
getNodePathFromSourceRange,
getNodeFromPath,
@ -72,13 +72,13 @@ export function intersectInfo({
getNodePathFromSourceRange(kclManager.ast, range)
)
const _nodes = paths.map((pathToNode) => {
const tmp = getNodeFromPath<Value>(kclManager.ast, pathToNode)
const tmp = getNodeFromPath<Expr>(kclManager.ast, pathToNode)
if (err(tmp)) return tmp
return tmp.node
})
const _err1 = _nodes.find(err)
if (err(_err1)) return _err1
const nodes = _nodes as Value[]
const nodes = _nodes as Expr[]
const _varDecs = paths.map((pathToNode) => {
const tmp = getNodeFromPath<VariableDeclarator>(

View File

@ -1,6 +1,6 @@
import { toolTips } from 'lang/langHelpers'
import { Selection, Selections } from 'lib/selections'
import { PathToNode, Program, Value } from '../../lang/wasm'
import { PathToNode, Program, Expr } from '../../lang/wasm'
import {
getNodePathFromSourceRange,
getNodeFromPath,
@ -33,13 +33,13 @@ export function removeConstrainingValuesInfo({
getNodePathFromSourceRange(kclManager.ast, range)
)
const _nodes = paths.map((pathToNode) => {
const tmp = getNodeFromPath<Value>(kclManager.ast, pathToNode)
const tmp = getNodeFromPath<Expr>(kclManager.ast, pathToNode)
if (err(tmp)) return tmp
return tmp.node
})
const _err1 = _nodes.find(err)
if (err(_err1)) return _err1
const nodes = _nodes as Value[]
const nodes = _nodes as Expr[]
const updatedSelectionRanges = pathToNodes
? {

View File

@ -1,6 +1,6 @@
import { toolTips } from 'lang/langHelpers'
import { Selections } from 'lib/selections'
import { BinaryPart, Program, Value } from '../../lang/wasm'
import { BinaryPart, Program, Expr } from '../../lang/wasm'
import {
getNodePathFromSourceRange,
getNodeFromPath,
@ -49,7 +49,7 @@ export function absDistanceInfo({
getNodePathFromSourceRange(kclManager.ast, range)
)
const _nodes = paths.map((pathToNode) => {
const tmp = getNodeFromPath<Value>(
const tmp = getNodeFromPath<Expr>(
kclManager.ast,
pathToNode,
'CallExpression'
@ -59,7 +59,7 @@ export function absDistanceInfo({
})
const _err1 = _nodes.find(err)
if (err(_err1)) return _err1
const nodes = _nodes as Value[]
const nodes = _nodes as Expr[]
const isAllTooltips = nodes.every(
(node) =>

View File

@ -1,6 +1,6 @@
import { toolTips } from 'lang/langHelpers'
import { Selections } from 'lib/selections'
import { BinaryPart, Program, Value, VariableDeclarator } from '../../lang/wasm'
import { BinaryPart, Program, Expr, VariableDeclarator } from '../../lang/wasm'
import {
getNodePathFromSourceRange,
getNodeFromPath,
@ -35,13 +35,13 @@ export function angleBetweenInfo({
)
const _nodes = paths.map((pathToNode) => {
const tmp = getNodeFromPath<Value>(kclManager.ast, pathToNode)
const tmp = getNodeFromPath<Expr>(kclManager.ast, pathToNode)
if (err(tmp)) return tmp
return tmp.node
})
const _err1 = _nodes.find(err)
if (err(_err1)) return _err1
const nodes = _nodes as Value[]
const nodes = _nodes as Expr[]
const _varDecs = paths.map((pathToNode) => {
const tmp = getNodeFromPath<VariableDeclarator>(

View File

@ -1,5 +1,5 @@
import { toolTips } from 'lang/langHelpers'
import { BinaryPart, Program, Value, VariableDeclarator } from '../../lang/wasm'
import { BinaryPart, Program, Expr, VariableDeclarator } from '../../lang/wasm'
import {
getNodePathFromSourceRange,
getNodeFromPath,
@ -36,14 +36,14 @@ export function horzVertDistanceInfo({
getNodePathFromSourceRange(kclManager.ast, range)
)
const _nodes = paths.map((pathToNode) => {
const tmp = getNodeFromPath<Value>(kclManager.ast, pathToNode)
const tmp = getNodeFromPath<Expr>(kclManager.ast, pathToNode)
if (err(tmp)) return tmp
return tmp.node
})
const [hasErr, , nodesWErrs] = cleanErrs(_nodes)
if (hasErr) return nodesWErrs[0]
const nodes = _nodes as Value[]
const nodes = _nodes as Expr[]
const _varDecs = paths.map((pathToNode) => {
const tmp = getNodeFromPath<VariableDeclarator>(

View File

@ -1,6 +1,6 @@
import { toolTips } from 'lang/langHelpers'
import { Selections } from 'lib/selections'
import { BinaryPart, Program, Value } from '../../lang/wasm'
import { BinaryPart, Program, Expr } from '../../lang/wasm'
import {
getNodePathFromSourceRange,
getNodeFromPath,
@ -44,7 +44,7 @@ export function angleLengthInfo({
)
const nodes = paths.map((pathToNode) =>
getNodeFromPath<Value>(kclManager.ast, pathToNode, 'CallExpression')
getNodeFromPath<Expr>(kclManager.ast, pathToNode, 'CallExpression')
)
const _err1 = nodes.find(err)
if (err(_err1)) return _err1

View File

@ -6,7 +6,7 @@ import {
PipeExpression,
VariableDeclaration,
VariableDeclarator,
Value,
Expr,
Literal,
PipeSubstitution,
Identifier,
@ -195,10 +195,7 @@ export function findUniqueName(
return findUniqueName(searchStr, name, pad, index + 1)
}
export function mutateArrExp(
node: Value,
updateWith: ArrayExpression
): boolean {
export function mutateArrExp(node: Expr, updateWith: ArrayExpression): boolean {
if (node.type === 'ArrayExpression') {
node.elements.forEach((element, i) => {
if (isLiteralArrayOrStatic(element)) {
@ -211,7 +208,7 @@ export function mutateArrExp(
}
export function mutateObjExpProp(
node: Value,
node: Expr,
updateWith: Literal | ArrayExpression,
key: string
): boolean {
@ -254,7 +251,7 @@ export function extrudeSketch(
node: Program,
pathToNode: PathToNode,
shouldPipe = false,
distance = createLiteral(4) as Value
distance = createLiteral(4) as Expr
):
| {
modifiedAst: Program
@ -608,7 +605,7 @@ export function createVariableDeclaration(
}
export function createObjectExpression(properties: {
[key: string]: Value
[key: string]: Expr
}): ObjectExpression {
return {
type: 'ObjectExpression',

View File

@ -3,7 +3,7 @@ import {
recast,
initPromise,
PathToNode,
Value,
Expr,
Program,
CallExpression,
} from '../wasm'
@ -25,7 +25,7 @@ const runFilletTest = async (
code: string,
segmentSnippet: string,
extrudeSnippet: string,
radius = createLiteral(5) as Value,
radius = createLiteral(5) as Expr,
expectedCode: string
) => {
const astOrError = parse(code)
@ -57,7 +57,7 @@ const runFilletTest = async (
return new Error('Path to extrude node not found')
}
// const radius = createLiteral(5) as Value
// const radius = createLiteral(5) as Expr
const result = addFillet(ast, pathToSegmentNode, pathToExtrudeNode, radius)
if (err(result)) {
@ -90,7 +90,7 @@ describe('Testing addFillet', () => {
`
const segmentSnippet = `line([60.04, -55.72], %)`
const extrudeSnippet = `const extrude001 = extrude(50, sketch001)`
const radius = createLiteral(5) as Value
const radius = createLiteral(5) as Expr
const expectedCode = `const sketch001 = startSketchOn('XZ')
|> startProfileAt([2.16, 49.67], %)
|> line([101.49, 139.93], %)
@ -133,7 +133,7 @@ const extrude001 = extrude(50, sketch001)
`
const segmentSnippet = `line([60.04, -55.72], %)`
const extrudeSnippet = `const extrude001 = extrude(50, sketch001)`
const radius = createLiteral(5) as Value
const radius = createLiteral(5) as Expr
const expectedCode = `const sketch001 = startSketchOn('XZ')
|> startProfileAt([2.16, 49.67], %)
|> line([101.49, 139.93], %)
@ -176,7 +176,7 @@ const extrude001 = extrude(50, sketch001)
`
const segmentSnippet = `line([-87.24, -47.08], %, $seg03)`
const extrudeSnippet = `const extrude001 = extrude(50, sketch001)`
const radius = createLiteral(5) as Value
const radius = createLiteral(5) as Expr
const expectedCode = `const sketch001 = startSketchOn('XZ')
|> startProfileAt([2.16, 49.67], %)
|> line([101.49, 139.93], %)
@ -218,7 +218,7 @@ const extrude001 = extrude(50, sketch001)
|> fillet({ radius: 10, tags: [seg03] }, %)`
const segmentSnippet = `line([60.04, -55.72], %)`
const extrudeSnippet = `const extrude001 = extrude(50, sketch001)`
const radius = createLiteral(5) as Value
const radius = createLiteral(5) as Expr
const expectedCode = `const sketch001 = startSketchOn('XZ')
|> startProfileAt([2.16, 49.67], %)
|> line([101.49, 139.93], %)

View File

@ -4,7 +4,7 @@ import {
ObjectExpression,
PathToNode,
Program,
Value,
Expr,
VariableDeclaration,
VariableDeclarator,
} from '../wasm'
@ -35,7 +35,7 @@ export function addFillet(
node: Program,
pathToSegmentNode: PathToNode,
pathToExtrudeNode: PathToNode,
radius = createLiteral(5) as Value
radius = createLiteral(5) as Expr
// shouldPipe = false, // TODO: Implement this feature
): { modifiedAst: Program; pathToFilletNode: PathToNode } | Error {
// clone ast to make mutations safe

View File

@ -13,7 +13,7 @@ import {
SketchGroup,
SourceRange,
SyntaxType,
Value,
Expr,
VariableDeclaration,
VariableDeclarator,
} from './wasm'
@ -118,7 +118,7 @@ export function getNodeFromPathCurry(
}
function moreNodePathFromSourceRange(
node: Value | ExpressionStatement | VariableDeclaration | ReturnStatement,
node: Expr | ExpressionStatement | VariableDeclaration | ReturnStatement,
sourceRange: Selection['range'],
previousPath: PathToNode = [['body', '']]
): PathToNode {
@ -337,7 +337,7 @@ export function getNodePathFromSourceRange(
}
type KCLNode =
| Value
| Expr
| ExpressionStatement
| VariableDeclaration
| VariableDeclarator
@ -514,7 +514,7 @@ export function isNodeSafeToReplacePath(
):
| {
isSafe: boolean
value: Value
value: Expr
replacer: ReplacerFn
}
| Error {
@ -538,7 +538,7 @@ export function isNodeSafeToReplacePath(
// binaryExpression should take precedence
const [finVal, finPath] =
(binValue as Value)?.type === 'BinaryExpression'
(binValue as Expr)?.type === 'BinaryExpression'
? [binValue, outBinPath]
: [value, outPath]
@ -561,7 +561,7 @@ export function isNodeSafeToReplacePath(
return { modifiedAst: _ast, pathToReplaced }
}
const hasPipeSub = isTypeInValue(finVal as Value, 'PipeSubstitution')
const hasPipeSub = isTypeInValue(finVal as Expr, 'PipeSubstitution')
const isIdentifierCallee = path[path.length - 1][0] !== 'callee'
return {
isSafe:
@ -569,7 +569,7 @@ export function isNodeSafeToReplacePath(
isIdentifierCallee &&
acceptedNodeTypes.includes((finVal as any)?.type) &&
finPath.map(([_, type]) => type).includes('VariableDeclaration'),
value: finVal as Value,
value: finVal as Expr,
replacer: replaceNodeWithIdentifier,
}
}
@ -580,7 +580,7 @@ export function isNodeSafeToReplace(
):
| {
isSafe: boolean
value: Value
value: Expr
replacer: ReplacerFn
}
| Error {
@ -588,7 +588,7 @@ export function isNodeSafeToReplace(
return isNodeSafeToReplacePath(ast, path)
}
export function isTypeInValue(node: Value, syntaxType: SyntaxType): boolean {
export function isTypeInValue(node: Expr, syntaxType: SyntaxType): boolean {
if (node.type === syntaxType) return true
if (node.type === 'BinaryExpression') return isTypeInBinExp(node, syntaxType)
if (node.type === 'CallExpression') return isTypeInCallExp(node, syntaxType)
@ -625,7 +625,7 @@ function isTypeInArrayExp(
return node.elements.some((el) => isTypeInValue(el, syntaxType))
}
export function isValueZero(val?: Value): boolean {
export function isValueZero(val?: Expr): boolean {
return (
(val?.type === 'Literal' && Number(val.value) === 0) ||
(val?.type === 'UnaryExpression' &&

View File

@ -8,7 +8,7 @@ import {
PipeExpression,
CallExpression,
VariableDeclarator,
Value,
Expr,
Literal,
VariableDeclaration,
Identifier,
@ -72,8 +72,8 @@ export function getCoordsFromPaths(skGroup: SketchGroup, index = 0): Coords2d {
export function createFirstArg(
sketchFn: ToolTip,
val: Value | [Value, Value] | [Value, Value, Value]
): Value | Error {
val: Expr | [Expr, Expr] | [Expr, Expr, Expr]
): Expr | Error {
if (Array.isArray(val)) {
if (
[
@ -338,7 +338,7 @@ export const lineTo: SketchLineHelper = {
if (err(nodeMeta)) return nodeMeta
const { node: pipe } = nodeMeta
const newVals: [Value, Value] = [
const newVals: [Expr, Expr] = [
createLiteral(roundOff(to[0], 2)),
createLiteral(roundOff(to[1], 2)),
]
@ -1839,7 +1839,7 @@ export function getTagFromCallExpression(
return new Error(`"${callExp.callee.name}" is not a sketch line helper`)
}
function isAngleLiteral(lineArugement: Value): boolean {
function isAngleLiteral(lineArugement: Expr): boolean {
return lineArugement?.type === 'ArrayExpression'
? isLiteralArrayOrStatic(lineArugement.elements[0])
: lineArugement?.type === 'ObjectExpression'
@ -1907,8 +1907,8 @@ export function getXComponent(
function getFirstArgValuesForXYFns(callExpression: CallExpression):
| {
val: [Value, Value]
tag?: Value
val: [Expr, Expr]
tag?: Expr
}
| Error {
// used for lineTo, line
@ -1929,8 +1929,8 @@ function getFirstArgValuesForXYFns(callExpression: CallExpression):
function getFirstArgValuesForAngleFns(callExpression: CallExpression):
| {
val: [Value, Value]
tag?: Value
val: [Expr, Expr]
tag?: Expr
}
| Error {
// used for angledLine, angledLineOfXLength, angledLineToX, angledLineOfYLength, angledLineToY
@ -1957,8 +1957,8 @@ function getFirstArgValuesForAngleFns(callExpression: CallExpression):
}
function getFirstArgValuesForXYLineFns(callExpression: CallExpression): {
val: Value
tag?: Value
val: Expr
tag?: Expr
} {
// used for xLine, yLine, xLineTo, yLineTo
const firstArg = callExpression.arguments[0]
@ -1988,8 +1988,8 @@ const getAngledLineThatIntersects = (
callExp: CallExpression
):
| {
val: [Value, Value, Value]
tag?: Value
val: [Expr, Expr, Expr]
tag?: Expr
}
| Error => {
const firstArg = callExp.arguments[0]
@ -2011,8 +2011,8 @@ const getAngledLineThatIntersects = (
export function getFirstArg(callExp: CallExpression):
| {
val: Value | [Value, Value] | [Value, Value, Value]
tag?: Value
val: Expr | [Expr, Expr] | [Expr, Expr, Expr]
tag?: Expr
}
| Error {
const name = callExp?.callee?.name

View File

@ -8,7 +8,7 @@ import {
SourceRange,
Path,
PathToNode,
Value,
Expr,
} from '../wasm'
import { err } from 'lib/trap'
@ -25,7 +25,7 @@ export function getSketchSegmentFromPathToNode(
// TODO: once pathTodNode is stored on program memory as part of execution,
// we can check if the pathToNode matches the pathToNode of the sketchGroup.
// For now we fall back to the sourceRange
const nodeMeta = getNodeFromPath<Value>(ast, pathToNode)
const nodeMeta = getNodeFromPath<Expr>(ast, pathToNode)
if (err(nodeMeta)) return nodeMeta
const node = nodeMeta.node

View File

@ -1,4 +1,4 @@
import { parse, Value, recast, initPromise } from '../wasm'
import { parse, Expr, recast, initPromise } from '../wasm'
import {
getConstraintType,
getTransformInfos,
@ -69,8 +69,8 @@ function getConstraintTypeFromSourceHelper(
if (err(ast)) return ast
const args = (ast.body[0] as any).expression.arguments[0].elements as [
Value,
Value
Expr,
Expr
]
const fnName = (ast.body[0] as any).expression.callee.name as ToolTip
return getConstraintType(args, fnName)
@ -81,7 +81,7 @@ function getConstraintTypeFromSourceHelper2(
const ast = parse(code)
if (err(ast)) return ast
const arg = (ast.body[0] as any).expression.arguments[0] as Value
const arg = (ast.body[0] as any).expression.arguments[0] as Expr
const fnName = (ast.body[0] as any).expression.callee.name as ToolTip
return getConstraintType(arg, fnName)
}

View File

@ -5,7 +5,7 @@ import { cleanErrs, err } from 'lib/trap'
import {
CallExpression,
Program,
Value,
Expr,
BinaryPart,
VariableDeclarator,
PathToNode,
@ -68,8 +68,8 @@ export type ConstraintType =
function createCallWrapper(
a: ToolTip,
val: [Value, Value] | Value,
tag?: Value,
val: [Expr, Expr] | Expr,
tag?: Expr,
valueUsedInTransform?: number
): ReturnType<TransformCallback> {
const args = [createFirstArg(a, val), createPipeSubstitution()]
@ -103,8 +103,8 @@ function createCallWrapper(
*/
function createStdlibCallExpression(
tool: ToolTip,
val: Value,
tag?: Value,
val: Expr,
tag?: Expr,
valueUsedInTransform?: number
): ReturnType<TransformCallback> {
const args = [val, createPipeSubstitution()]
@ -126,10 +126,10 @@ function intersectCallWrapper({
valueUsedInTransform,
}: {
fnName: string
angleVal: Value
offsetVal: Value
intersectTag: Value
tag?: Value
angleVal: Expr
offsetVal: Expr
intersectTag: Expr
tag?: Expr
valueUsedInTransform?: number
}): ReturnType<TransformCallback> {
const firstArg: any = {
@ -137,7 +137,7 @@ function intersectCallWrapper({
offset: offsetVal,
intersectTag,
}
const args: Value[] = [
const args: Expr[] = [
createObjectExpression(firstArg),
createPipeSubstitution(),
]
@ -154,11 +154,11 @@ export type TransformInfo = {
tooltip: ToolTip
createNode: (a: {
varValues: VarValues
varValA: Value // x / angle
varValB: Value // y / length or x y for angledLineOfXlength etc
varValA: Expr // x / angle
varValB: Expr // y / length or x y for angledLineOfXlength etc
referenceSegName: string
tag?: Value
forceValueUsedInTransform?: Value
tag?: Expr
forceValueUsedInTransform?: Expr
}) => TransformCallback
}
@ -234,8 +234,8 @@ const angledLineAngleCreateNode: TransformInfo['createNode'] =
const getMinAndSegLenVals = (
referenceSegName: string,
varVal: Value
): [Value, BinaryPart] => {
varVal: Expr
): [Expr, BinaryPart] => {
const segLenVal = createSegLen(referenceSegName)
return [
createCallExpression('min', [segLenVal, varVal]),
@ -245,9 +245,9 @@ const getMinAndSegLenVals = (
const getMinAndSegAngVals = (
referenceSegName: string,
varVal: Value,
varVal: Expr,
fnName: 'legAngX' | 'legAngY' = 'legAngX'
): [Value, BinaryPart] => {
): [Expr, BinaryPart] => {
const minVal = createCallExpression('min', [
createSegLen(referenceSegName),
varVal,
@ -259,12 +259,12 @@ const getMinAndSegAngVals = (
return [minVal, legAngle]
}
const getSignedLeg = (arg: Value, legLenVal: BinaryPart) =>
const getSignedLeg = (arg: Expr, legLenVal: BinaryPart) =>
arg.type === 'Literal' && Number(arg.value) < 0
? createUnaryExpression(legLenVal)
: legLenVal
const getLegAng = (arg: Value, legAngleVal: BinaryPart) => {
const getLegAng = (arg: Expr, legAngleVal: BinaryPart) => {
const ang = (arg.type === 'Literal' && Number(arg.value)) || 0
const normalisedAngle = ((ang % 360) + 360) % 360 // between 0 and 360
const truncatedTo90 = Math.floor(normalisedAngle / 90) * 90
@ -275,14 +275,14 @@ const getLegAng = (arg: Value, legAngleVal: BinaryPart) => {
return truncatedTo90 === 0 ? legAngleVal : binExp
}
const getAngleLengthSign = (arg: Value, legAngleVal: BinaryPart) => {
const getAngleLengthSign = (arg: Expr, legAngleVal: BinaryPart) => {
const ang = (arg.type === 'Literal' && Number(arg.value)) || 0
const normalisedAngle = ((ang % 180) + 180) % 180 // between 0 and 180
return normalisedAngle > 90 ? createUnaryExpression(legAngleVal) : legAngleVal
}
function getClosesAngleDirection(
arg: Value,
arg: Expr,
refAngle: number,
angleVal: BinaryPart
) {
@ -305,7 +305,7 @@ const setHorzVertDistanceCreateNode =
getArgLiteralVal(args?.[index]) - (referencedSegment?.to?.[index] || 0),
2
)
let finalValue: Value = createBinaryExpressionWithUnary([
let finalValue: Expr = createBinaryExpressionWithUnary([
createSegEnd(referenceSegName, !index),
(forceValueUsedInTransform as BinaryPart) ||
createLiteral(valueUsedInTransform),
@ -1374,7 +1374,7 @@ export function getTransformInfo(
}
export function getConstraintType(
val: Value | [Value, Value] | [Value, Value, Value],
val: Expr | [Expr, Expr] | [Expr, Expr, Expr],
fnName: ToolTip
): LineInputsType | null {
// this function assumes that for two val sketch functions that one arg is locked down not both
@ -1416,7 +1416,7 @@ export function getTransformInfos(
getNodePathFromSourceRange(ast, range)
)
const nodes = paths.map((pathToNode) =>
getNodeFromPath<Value>(ast, pathToNode, 'CallExpression')
getNodeFromPath<Expr>(ast, pathToNode, 'CallExpression')
)
try {
@ -1449,7 +1449,7 @@ export function getRemoveConstraintsTransforms(
getNodePathFromSourceRange(ast, selectionRange.range)
)
const nodes = paths.map((pathToNode) =>
getNodeFromPath<Value>(ast, pathToNode)
getNodeFromPath<Expr>(ast, pathToNode)
)
const theTransforms = nodes.map((nodeMeta) => {
@ -1484,7 +1484,7 @@ export function transformSecondarySketchLinesTagFirst({
transformInfos: TransformInfo[]
programMemory: ProgramMemory
forceSegName?: string
forceValueUsedInTransform?: Value
forceValueUsedInTransform?: Expr
}):
| {
modifiedAst: Program
@ -1555,7 +1555,7 @@ export function transformAstSketchLines({
transformInfos: TransformInfo[]
programMemory: ProgramMemory
referenceSegName: string
forceValueUsedInTransform?: Value
forceValueUsedInTransform?: Expr
referencedSegmentRange?: Selection['range']
}):
| {
@ -1609,7 +1609,7 @@ export function transformAstSketchLines({
)
return
const nodeMeta = getNodeFromPath<Value>(ast, a.pathToNode)
const nodeMeta = getNodeFromPath<Expr>(ast, a.pathToNode)
if (err(nodeMeta)) return
if (a?.argPosition?.type === 'arrayItem') {
@ -1712,11 +1712,11 @@ export function transformAstSketchLines({
}
}
function createSegLen(referenceSegName: string): Value {
function createSegLen(referenceSegName: string): Expr {
return createCallExpression('segLen', [createIdentifier(referenceSegName)])
}
function createSegAngle(referenceSegName: string): Value {
function createSegAngle(referenceSegName: string): Expr {
return createCallExpression('segAng', [createIdentifier(referenceSegName)])
}
@ -1732,7 +1732,7 @@ function createLastSeg(isX: boolean): CallExpression {
])
}
function getArgLiteralVal(arg: Value): number {
function getArgLiteralVal(arg: Expr): number {
return arg?.type === 'Literal' ? Number(arg.value) : 0
}
@ -1776,7 +1776,7 @@ export function getConstraintLevelFromSourceRange(
}
export function isLiteralArrayOrStatic(
val: Value | [Value, Value] | [Value, Value, Value] | undefined
val: Expr | [Expr, Expr] | [Expr, Expr, Expr] | undefined
): boolean {
if (!val) return false
@ -1792,7 +1792,7 @@ export function isLiteralArrayOrStatic(
}
export function isNotLiteralArrayOrStatic(
val: Value | [Value, Value] | [Value, Value, Value]
val: Expr | [Expr, Expr] | [Expr, Expr, Expr]
): boolean {
if (Array.isArray(val)) {
const a = val[0]

View File

@ -4,7 +4,7 @@ import {
Path,
SourceRange,
Program,
Value,
Expr,
PathToNode,
CallExpression,
Literal,
@ -85,7 +85,7 @@ export type _VarValue<T> =
| ObjectPropertyInput<T>
| ArrayOrObjItemInput<T>
export type VarValue = _VarValue<Value>
export type VarValue = _VarValue<Expr>
export type RawValue = _VarValue<Literal>
export type VarValues = Array<VarValue>
@ -99,11 +99,11 @@ type SimplifiedVarValue =
| { type: 'objectProperty'; key: VarValueKeys }
export type TransformCallback = (
args: [Value, Value],
args: [Expr, Expr],
literalValues: RawValues,
referencedSegment?: Path
) => {
callExp: Value
callExp: Expr
valueUsedInTransform?: number
}

View File

@ -39,7 +39,7 @@ import { ProjectRoute } from 'wasm-lib/kcl/bindings/ProjectRoute'
import { err } from 'lib/trap'
export type { Program } from '../wasm-lib/kcl/bindings/Program'
export type { Value } from '../wasm-lib/kcl/bindings/Value'
export type { Expr } from '../wasm-lib/kcl/bindings/Expr'
export type { ObjectExpression } from '../wasm-lib/kcl/bindings/ObjectExpression'
export type { MemberExpression } from '../wasm-lib/kcl/bindings/MemberExpression'
export type { PipeExpression } from '../wasm-lib/kcl/bindings/PipeExpression'

View File

@ -7,7 +7,7 @@ import {
InterpreterFrom,
} from 'xstate'
import { Selection } from './selections'
import { Identifier, Value, VariableDeclaration } from 'lang/wasm'
import { Identifier, Expr, VariableDeclaration } from 'lang/wasm'
import { commandBarMachine } from 'machines/commandBarMachine'
type Icon = CustomIconName
@ -20,7 +20,7 @@ const INPUT_TYPES = [
'boolean',
] as const
export interface KclExpression {
valueAst: Value
valueAst: Expr
valueText: string
valueCalculated: string
}

View File

@ -5,7 +5,7 @@ import {
kclManager,
sceneEntitiesManager,
} from 'lib/singletons'
import { CallExpression, SourceRange, Value, parse, recast } from 'lang/wasm'
import { CallExpression, SourceRange, Expr, parse, recast } from 'lang/wasm'
import { ModelingMachineEvent } from 'machines/modelingMachine'
import { uuidv4 } from 'lib/utils'
import { EditorSelection, SelectionRange } from '@codemirror/state'
@ -639,7 +639,7 @@ export function updateSelections(
const newSelections = Object.entries(pathToNodeMap)
.map(([index, pathToNode]): Selection | undefined => {
const nodeMeta = getNodeFromPath<Value>(ast, pathToNode)
const nodeMeta = getNodeFromPath<Expr>(ast, pathToNode)
if (err(nodeMeta)) return undefined
const node = nodeMeta.node
return {

View File

@ -3,7 +3,7 @@ import { kclManager, engineCommandManager } from 'lib/singletons'
import { useKclContext } from 'lang/KclProvider'
import { findUniqueName } from 'lang/modifyAst'
import { PrevVariable, findAllPreviousVariables } from 'lang/queryAst'
import { ProgramMemory, Value, parse } from 'lang/wasm'
import { ProgramMemory, Expr, parse } from 'lang/wasm'
import { useEffect, useRef, useState } from 'react'
import { executeAst } from 'lang/langHelpers'
import { err, trap } from 'lib/trap'
@ -24,7 +24,7 @@ export function useCalculateKclExpression({
initialVariableName?: string
}): {
inputRef: React.RefObject<HTMLInputElement>
valueNode: Value | null
valueNode: Expr | null
calcResult: string
prevVariables: PrevVariable<unknown>[]
newVariableName: string
@ -45,7 +45,7 @@ export function useCalculateKclExpression({
insertIndex: 0,
bodyPath: [],
})
const [valueNode, setValueNode] = useState<Value | null>(null)
const [valueNode, setValueNode] = useState<Expr | null>(null)
const [calcResult, setCalcResult] = useState('NAN')
const [newVariableName, setNewVariableName] = useState('')
const [isNewVariableNameUnique, setIsNewVariableNameUnique] = useState(true)

View File

@ -1,6 +1,6 @@
extern crate alloc;
use kcl_lib::ast::types::{
BodyItem, Identifier, Literal, LiteralValue, NonCodeMeta, Program, Value, VariableDeclaration, VariableDeclarator,
BodyItem, Expr, Identifier, Literal, LiteralValue, NonCodeMeta, Program, VariableDeclaration, VariableDeclarator,
VariableKind,
};
use kcl_macros::parse;
@ -24,7 +24,7 @@ fn basic() {
name: "y".to_owned(),
digest: None,
},
init: Value::Literal(Box::new(Literal {
init: Expr::Literal(Box::new(Literal {
start: 10,
end: 11,
value: LiteralValue::IInteger(4),

View File

@ -266,7 +266,7 @@ impl Program {
/// Returns a value that includes the given character position.
/// This is a bit more recursive than `get_body_item_for_position`.
pub fn get_value_for_position(&self, pos: usize) -> Option<&Value> {
pub fn get_value_for_position(&self, pos: usize) -> Option<&Expr> {
let item = self.get_body_item_for_position(pos)?;
// Recurse over the item.
@ -389,7 +389,7 @@ impl Program {
};
// Check if we have a function expression.
if let Some(Value::FunctionExpression(ref mut function_expression)) = &mut value {
if let Some(Expr::FunctionExpression(ref mut function_expression)) = &mut value {
// Check if the params to the function expression contain the position.
for param in &mut function_expression.params {
let param_source_range: SourceRange = (&param.identifier).into();
@ -444,7 +444,7 @@ impl Program {
}
/// Replace a value with the new value, use the source range for matching the exact value.
pub fn replace_value(&mut self, source_range: SourceRange, new_value: Value) {
pub fn replace_value(&mut self, source_range: SourceRange, new_value: Expr) {
for item in &mut self.body {
match item {
BodyItem::ExpressionStatement(ref mut expression_statement) => expression_statement
@ -570,11 +570,12 @@ impl From<&BodyItem> for SourceRange {
}
}
/// An expression can be evaluated to yield a single KCL value.
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema, Bake)]
#[databake(path = kcl_lib::ast::types)]
#[ts(export)]
#[serde(tag = "type")]
pub enum Value {
pub enum Expr {
Literal(Box<Literal>),
Identifier(Box<Identifier>),
TagDeclarator(Box<TagDeclarator>),
@ -590,22 +591,22 @@ pub enum Value {
None(KclNone),
}
impl Value {
impl Expr {
pub fn compute_digest(&mut self) -> Digest {
match self {
Value::Literal(lit) => lit.compute_digest(),
Value::Identifier(id) => id.compute_digest(),
Value::TagDeclarator(tag) => tag.compute_digest(),
Value::BinaryExpression(be) => be.compute_digest(),
Value::FunctionExpression(fe) => fe.compute_digest(),
Value::CallExpression(ce) => ce.compute_digest(),
Value::PipeExpression(pe) => pe.compute_digest(),
Value::PipeSubstitution(ps) => ps.compute_digest(),
Value::ArrayExpression(ae) => ae.compute_digest(),
Value::ObjectExpression(oe) => oe.compute_digest(),
Value::MemberExpression(me) => me.compute_digest(),
Value::UnaryExpression(ue) => ue.compute_digest(),
Value::None(_) => {
Expr::Literal(lit) => lit.compute_digest(),
Expr::Identifier(id) => id.compute_digest(),
Expr::TagDeclarator(tag) => tag.compute_digest(),
Expr::BinaryExpression(be) => be.compute_digest(),
Expr::FunctionExpression(fe) => fe.compute_digest(),
Expr::CallExpression(ce) => ce.compute_digest(),
Expr::PipeExpression(pe) => pe.compute_digest(),
Expr::PipeSubstitution(ps) => ps.compute_digest(),
Expr::ArrayExpression(ae) => ae.compute_digest(),
Expr::ObjectExpression(oe) => oe.compute_digest(),
Expr::MemberExpression(me) => me.compute_digest(),
Expr::UnaryExpression(ue) => ue.compute_digest(),
Expr::None(_) => {
let mut hasher = Sha256::new();
hasher.update(b"Value::None");
hasher.finalize().into()
@ -615,19 +616,19 @@ impl Value {
fn recast(&self, options: &FormatOptions, indentation_level: usize, is_in_pipe: bool) -> String {
match &self {
Value::BinaryExpression(bin_exp) => bin_exp.recast(options),
Value::ArrayExpression(array_exp) => array_exp.recast(options, indentation_level, is_in_pipe),
Value::ObjectExpression(ref obj_exp) => obj_exp.recast(options, indentation_level, is_in_pipe),
Value::MemberExpression(mem_exp) => mem_exp.recast(),
Value::Literal(literal) => literal.recast(),
Value::FunctionExpression(func_exp) => func_exp.recast(options, indentation_level),
Value::CallExpression(call_exp) => call_exp.recast(options, indentation_level, is_in_pipe),
Value::Identifier(ident) => ident.name.to_string(),
Value::TagDeclarator(tag) => tag.recast(),
Value::PipeExpression(pipe_exp) => pipe_exp.recast(options, indentation_level),
Value::UnaryExpression(unary_exp) => unary_exp.recast(options),
Value::PipeSubstitution(_) => crate::parser::PIPE_SUBSTITUTION_OPERATOR.to_string(),
Value::None(_) => {
Expr::BinaryExpression(bin_exp) => bin_exp.recast(options),
Expr::ArrayExpression(array_exp) => array_exp.recast(options, indentation_level, is_in_pipe),
Expr::ObjectExpression(ref obj_exp) => obj_exp.recast(options, indentation_level, is_in_pipe),
Expr::MemberExpression(mem_exp) => mem_exp.recast(),
Expr::Literal(literal) => literal.recast(),
Expr::FunctionExpression(func_exp) => func_exp.recast(options, indentation_level),
Expr::CallExpression(call_exp) => call_exp.recast(options, indentation_level, is_in_pipe),
Expr::Identifier(ident) => ident.name.to_string(),
Expr::TagDeclarator(tag) => tag.recast(),
Expr::PipeExpression(pipe_exp) => pipe_exp.recast(options, indentation_level),
Expr::UnaryExpression(unary_exp) => unary_exp.recast(options),
Expr::PipeSubstitution(_) => crate::parser::PIPE_SUBSTITUTION_OPERATOR.to_string(),
Expr::None(_) => {
unimplemented!("there is no literal None, see https://github.com/KittyCAD/modeling-app/issues/1115")
}
}
@ -656,78 +657,78 @@ impl Value {
// Get the non code meta for the value.
pub fn get_non_code_meta(&self) -> Option<&NonCodeMeta> {
match self {
Value::BinaryExpression(_bin_exp) => None,
Value::ArrayExpression(_array_exp) => None,
Value::ObjectExpression(_obj_exp) => None,
Value::MemberExpression(_mem_exp) => None,
Value::Literal(_literal) => None,
Value::FunctionExpression(_func_exp) => None,
Value::CallExpression(_call_exp) => None,
Value::Identifier(_ident) => None,
Value::TagDeclarator(_tag) => None,
Value::PipeExpression(pipe_exp) => Some(&pipe_exp.non_code_meta),
Value::UnaryExpression(_unary_exp) => None,
Value::PipeSubstitution(_pipe_substitution) => None,
Value::None(_none) => None,
Expr::BinaryExpression(_bin_exp) => None,
Expr::ArrayExpression(_array_exp) => None,
Expr::ObjectExpression(_obj_exp) => None,
Expr::MemberExpression(_mem_exp) => None,
Expr::Literal(_literal) => None,
Expr::FunctionExpression(_func_exp) => None,
Expr::CallExpression(_call_exp) => None,
Expr::Identifier(_ident) => None,
Expr::TagDeclarator(_tag) => None,
Expr::PipeExpression(pipe_exp) => Some(&pipe_exp.non_code_meta),
Expr::UnaryExpression(_unary_exp) => None,
Expr::PipeSubstitution(_pipe_substitution) => None,
Expr::None(_none) => None,
}
}
pub fn replace_value(&mut self, source_range: SourceRange, new_value: Value) {
pub fn replace_value(&mut self, source_range: SourceRange, new_value: Expr) {
if source_range == self.clone().into() {
*self = new_value;
return;
}
match self {
Value::BinaryExpression(ref mut bin_exp) => bin_exp.replace_value(source_range, new_value),
Value::ArrayExpression(ref mut array_exp) => array_exp.replace_value(source_range, new_value),
Value::ObjectExpression(ref mut obj_exp) => obj_exp.replace_value(source_range, new_value),
Value::MemberExpression(_) => {}
Value::Literal(_) => {}
Value::FunctionExpression(ref mut func_exp) => func_exp.replace_value(source_range, new_value),
Value::CallExpression(ref mut call_exp) => call_exp.replace_value(source_range, new_value),
Value::Identifier(_) => {}
Value::TagDeclarator(_) => {}
Value::PipeExpression(ref mut pipe_exp) => pipe_exp.replace_value(source_range, new_value),
Value::UnaryExpression(ref mut unary_exp) => unary_exp.replace_value(source_range, new_value),
Value::PipeSubstitution(_) => {}
Value::None(_) => {}
Expr::BinaryExpression(ref mut bin_exp) => bin_exp.replace_value(source_range, new_value),
Expr::ArrayExpression(ref mut array_exp) => array_exp.replace_value(source_range, new_value),
Expr::ObjectExpression(ref mut obj_exp) => obj_exp.replace_value(source_range, new_value),
Expr::MemberExpression(_) => {}
Expr::Literal(_) => {}
Expr::FunctionExpression(ref mut func_exp) => func_exp.replace_value(source_range, new_value),
Expr::CallExpression(ref mut call_exp) => call_exp.replace_value(source_range, new_value),
Expr::Identifier(_) => {}
Expr::TagDeclarator(_) => {}
Expr::PipeExpression(ref mut pipe_exp) => pipe_exp.replace_value(source_range, new_value),
Expr::UnaryExpression(ref mut unary_exp) => unary_exp.replace_value(source_range, new_value),
Expr::PipeSubstitution(_) => {}
Expr::None(_) => {}
}
}
pub fn start(&self) -> usize {
match self {
Value::Literal(literal) => literal.start(),
Value::Identifier(identifier) => identifier.start(),
Value::TagDeclarator(tag) => tag.start(),
Value::BinaryExpression(binary_expression) => binary_expression.start(),
Value::FunctionExpression(function_expression) => function_expression.start(),
Value::CallExpression(call_expression) => call_expression.start(),
Value::PipeExpression(pipe_expression) => pipe_expression.start(),
Value::PipeSubstitution(pipe_substitution) => pipe_substitution.start(),
Value::ArrayExpression(array_expression) => array_expression.start(),
Value::ObjectExpression(object_expression) => object_expression.start(),
Value::MemberExpression(member_expression) => member_expression.start(),
Value::UnaryExpression(unary_expression) => unary_expression.start(),
Value::None(none) => none.start,
Expr::Literal(literal) => literal.start(),
Expr::Identifier(identifier) => identifier.start(),
Expr::TagDeclarator(tag) => tag.start(),
Expr::BinaryExpression(binary_expression) => binary_expression.start(),
Expr::FunctionExpression(function_expression) => function_expression.start(),
Expr::CallExpression(call_expression) => call_expression.start(),
Expr::PipeExpression(pipe_expression) => pipe_expression.start(),
Expr::PipeSubstitution(pipe_substitution) => pipe_substitution.start(),
Expr::ArrayExpression(array_expression) => array_expression.start(),
Expr::ObjectExpression(object_expression) => object_expression.start(),
Expr::MemberExpression(member_expression) => member_expression.start(),
Expr::UnaryExpression(unary_expression) => unary_expression.start(),
Expr::None(none) => none.start,
}
}
pub fn end(&self) -> usize {
match self {
Value::Literal(literal) => literal.end(),
Value::Identifier(identifier) => identifier.end(),
Value::TagDeclarator(tag) => tag.end(),
Value::BinaryExpression(binary_expression) => binary_expression.end(),
Value::FunctionExpression(function_expression) => function_expression.end(),
Value::CallExpression(call_expression) => call_expression.end(),
Value::PipeExpression(pipe_expression) => pipe_expression.end(),
Value::PipeSubstitution(pipe_substitution) => pipe_substitution.end(),
Value::ArrayExpression(array_expression) => array_expression.end(),
Value::ObjectExpression(object_expression) => object_expression.end(),
Value::MemberExpression(member_expression) => member_expression.end(),
Value::UnaryExpression(unary_expression) => unary_expression.end(),
Value::None(none) => none.end,
Expr::Literal(literal) => literal.end(),
Expr::Identifier(identifier) => identifier.end(),
Expr::TagDeclarator(tag) => tag.end(),
Expr::BinaryExpression(binary_expression) => binary_expression.end(),
Expr::FunctionExpression(function_expression) => function_expression.end(),
Expr::CallExpression(call_expression) => call_expression.end(),
Expr::PipeExpression(pipe_expression) => pipe_expression.end(),
Expr::PipeSubstitution(pipe_substitution) => pipe_substitution.end(),
Expr::ArrayExpression(array_expression) => array_expression.end(),
Expr::ObjectExpression(object_expression) => object_expression.end(),
Expr::MemberExpression(member_expression) => member_expression.end(),
Expr::UnaryExpression(unary_expression) => unary_expression.end(),
Expr::None(none) => none.end,
}
}
@ -735,82 +736,82 @@ impl Value {
/// This is really recursive so keep that in mind.
pub fn get_hover_value_for_position(&self, pos: usize, code: &str) -> Option<Hover> {
match self {
Value::BinaryExpression(binary_expression) => binary_expression.get_hover_value_for_position(pos, code),
Value::FunctionExpression(function_expression) => {
Expr::BinaryExpression(binary_expression) => binary_expression.get_hover_value_for_position(pos, code),
Expr::FunctionExpression(function_expression) => {
function_expression.get_hover_value_for_position(pos, code)
}
Value::CallExpression(call_expression) => call_expression.get_hover_value_for_position(pos, code),
Value::PipeExpression(pipe_expression) => pipe_expression.get_hover_value_for_position(pos, code),
Value::ArrayExpression(array_expression) => array_expression.get_hover_value_for_position(pos, code),
Value::ObjectExpression(object_expression) => object_expression.get_hover_value_for_position(pos, code),
Value::MemberExpression(member_expression) => member_expression.get_hover_value_for_position(pos, code),
Value::UnaryExpression(unary_expression) => unary_expression.get_hover_value_for_position(pos, code),
Expr::CallExpression(call_expression) => call_expression.get_hover_value_for_position(pos, code),
Expr::PipeExpression(pipe_expression) => pipe_expression.get_hover_value_for_position(pos, code),
Expr::ArrayExpression(array_expression) => array_expression.get_hover_value_for_position(pos, code),
Expr::ObjectExpression(object_expression) => object_expression.get_hover_value_for_position(pos, code),
Expr::MemberExpression(member_expression) => member_expression.get_hover_value_for_position(pos, code),
Expr::UnaryExpression(unary_expression) => unary_expression.get_hover_value_for_position(pos, code),
// TODO: LSP hover information for values/types. https://github.com/KittyCAD/modeling-app/issues/1126
Value::None(_) => None,
Value::Literal(_) => None,
Value::Identifier(_) => None,
Value::TagDeclarator(_) => None,
Expr::None(_) => None,
Expr::Literal(_) => None,
Expr::Identifier(_) => None,
Expr::TagDeclarator(_) => None,
// TODO: LSP hover information for symbols. https://github.com/KittyCAD/modeling-app/issues/1127
Value::PipeSubstitution(_) => None,
Expr::PipeSubstitution(_) => None,
}
}
/// Rename all identifiers that have the old name to the new given name.
fn rename_identifiers(&mut self, old_name: &str, new_name: &str) {
match self {
Value::Literal(_literal) => {}
Value::Identifier(ref mut identifier) => identifier.rename(old_name, new_name),
Value::TagDeclarator(ref mut tag) => tag.rename(old_name, new_name),
Value::BinaryExpression(ref mut binary_expression) => {
Expr::Literal(_literal) => {}
Expr::Identifier(ref mut identifier) => identifier.rename(old_name, new_name),
Expr::TagDeclarator(ref mut tag) => tag.rename(old_name, new_name),
Expr::BinaryExpression(ref mut binary_expression) => {
binary_expression.rename_identifiers(old_name, new_name)
}
Value::FunctionExpression(_function_identifier) => {}
Value::CallExpression(ref mut call_expression) => call_expression.rename_identifiers(old_name, new_name),
Value::PipeExpression(ref mut pipe_expression) => pipe_expression.rename_identifiers(old_name, new_name),
Value::PipeSubstitution(_) => {}
Value::ArrayExpression(ref mut array_expression) => array_expression.rename_identifiers(old_name, new_name),
Value::ObjectExpression(ref mut object_expression) => {
Expr::FunctionExpression(_function_identifier) => {}
Expr::CallExpression(ref mut call_expression) => call_expression.rename_identifiers(old_name, new_name),
Expr::PipeExpression(ref mut pipe_expression) => pipe_expression.rename_identifiers(old_name, new_name),
Expr::PipeSubstitution(_) => {}
Expr::ArrayExpression(ref mut array_expression) => array_expression.rename_identifiers(old_name, new_name),
Expr::ObjectExpression(ref mut object_expression) => {
object_expression.rename_identifiers(old_name, new_name)
}
Value::MemberExpression(ref mut member_expression) => {
Expr::MemberExpression(ref mut member_expression) => {
member_expression.rename_identifiers(old_name, new_name)
}
Value::UnaryExpression(ref mut unary_expression) => unary_expression.rename_identifiers(old_name, new_name),
Value::None(_) => {}
Expr::UnaryExpression(ref mut unary_expression) => unary_expression.rename_identifiers(old_name, new_name),
Expr::None(_) => {}
}
}
/// Get the constraint level for a value type.
pub fn get_constraint_level(&self) -> ConstraintLevel {
match self {
Value::Literal(literal) => literal.get_constraint_level(),
Value::Identifier(identifier) => identifier.get_constraint_level(),
Value::TagDeclarator(tag) => tag.get_constraint_level(),
Value::BinaryExpression(binary_expression) => binary_expression.get_constraint_level(),
Expr::Literal(literal) => literal.get_constraint_level(),
Expr::Identifier(identifier) => identifier.get_constraint_level(),
Expr::TagDeclarator(tag) => tag.get_constraint_level(),
Expr::BinaryExpression(binary_expression) => binary_expression.get_constraint_level(),
Value::FunctionExpression(function_identifier) => function_identifier.get_constraint_level(),
Value::CallExpression(call_expression) => call_expression.get_constraint_level(),
Value::PipeExpression(pipe_expression) => pipe_expression.get_constraint_level(),
Value::PipeSubstitution(pipe_substitution) => ConstraintLevel::Ignore {
Expr::FunctionExpression(function_identifier) => function_identifier.get_constraint_level(),
Expr::CallExpression(call_expression) => call_expression.get_constraint_level(),
Expr::PipeExpression(pipe_expression) => pipe_expression.get_constraint_level(),
Expr::PipeSubstitution(pipe_substitution) => ConstraintLevel::Ignore {
source_ranges: vec![pipe_substitution.into()],
},
Value::ArrayExpression(array_expression) => array_expression.get_constraint_level(),
Value::ObjectExpression(object_expression) => object_expression.get_constraint_level(),
Value::MemberExpression(member_expression) => member_expression.get_constraint_level(),
Value::UnaryExpression(unary_expression) => unary_expression.get_constraint_level(),
Value::None(none) => none.get_constraint_level(),
Expr::ArrayExpression(array_expression) => array_expression.get_constraint_level(),
Expr::ObjectExpression(object_expression) => object_expression.get_constraint_level(),
Expr::MemberExpression(member_expression) => member_expression.get_constraint_level(),
Expr::UnaryExpression(unary_expression) => unary_expression.get_constraint_level(),
Expr::None(none) => none.get_constraint_level(),
}
}
}
impl From<Value> for SourceRange {
fn from(value: Value) -> Self {
impl From<Expr> for SourceRange {
fn from(value: Expr) -> Self {
Self([value.start(), value.end()])
}
}
impl From<&Value> for SourceRange {
fn from(value: &Value) -> Self {
impl From<&Expr> for SourceRange {
fn from(value: &Expr) -> Self {
Self([value.start(), value.end()])
}
}
@ -864,7 +865,7 @@ impl BinaryPart {
}
}
pub fn replace_value(&mut self, source_range: SourceRange, new_value: Value) {
pub fn replace_value(&mut self, source_range: SourceRange, new_value: Expr) {
match self {
BinaryPart::Literal(_) => {}
BinaryPart::Identifier(_) => {}
@ -1224,7 +1225,7 @@ impl NonCodeMeta {
pub struct ExpressionStatement {
pub start: usize,
pub end: usize,
pub expression: Value,
pub expression: Expr,
pub digest: Option<Digest>,
}
@ -1245,7 +1246,7 @@ pub struct CallExpression {
pub start: usize,
pub end: usize,
pub callee: Identifier,
pub arguments: Vec<Value>,
pub arguments: Vec<Expr>,
pub optional: bool,
pub digest: Option<Digest>,
@ -1253,14 +1254,14 @@ pub struct CallExpression {
impl_value_meta!(CallExpression);
impl From<CallExpression> for Value {
impl From<CallExpression> for Expr {
fn from(call_expression: CallExpression) -> Self {
Value::CallExpression(Box::new(call_expression))
Expr::CallExpression(Box::new(call_expression))
}
}
impl CallExpression {
pub fn new(name: &str, arguments: Vec<Value>) -> Result<Self, KclError> {
pub fn new(name: &str, arguments: Vec<Expr>) -> Result<Self, KclError> {
Ok(Self {
start: 0,
end: 0,
@ -1284,14 +1285,14 @@ impl CallExpression {
pub fn has_substitution_arg(&self) -> bool {
self.arguments
.iter()
.any(|arg| matches!(arg, Value::PipeSubstitution(_)))
.any(|arg| matches!(arg, Expr::PipeSubstitution(_)))
}
pub fn as_source_ranges(&self) -> Vec<SourceRange> {
vec![SourceRange([self.start, self.end])]
}
pub fn replace_value(&mut self, source_range: SourceRange, new_value: Value) {
pub fn replace_value(&mut self, source_range: SourceRange, new_value: Expr) {
for arg in &mut self.arguments {
arg.replace_value(source_range, new_value.clone());
}
@ -1694,14 +1695,14 @@ impl VariableDeclaration {
})
}
pub fn replace_value(&mut self, source_range: SourceRange, new_value: Value) {
pub fn replace_value(&mut self, source_range: SourceRange, new_value: Expr) {
for declaration in &mut self.declarations {
declaration.init.replace_value(source_range, new_value.clone());
}
}
/// Returns a value that includes the given character position.
pub fn get_value_for_position(&self, pos: usize) -> Option<&Value> {
pub fn get_value_for_position(&self, pos: usize) -> Option<&Expr> {
for declaration in &self.declarations {
let source_range: SourceRange = declaration.into();
if source_range.contains(pos) {
@ -1713,7 +1714,7 @@ impl VariableDeclaration {
}
/// Returns a value that includes the given character position.
pub fn get_mut_value_for_position(&mut self, pos: usize) -> Option<&mut Value> {
pub fn get_mut_value_for_position(&mut self, pos: usize) -> Option<&mut Expr> {
for declaration in &mut self.declarations {
let source_range: SourceRange = declaration.clone().into();
if source_range.contains(pos) {
@ -1771,7 +1772,7 @@ impl VariableDeclaration {
};
let children = match &declaration.init {
Value::FunctionExpression(function_expression) => {
Expr::FunctionExpression(function_expression) => {
symbol_kind = SymbolKind::FUNCTION;
let mut children = vec![];
for param in &function_expression.params {
@ -1790,7 +1791,7 @@ impl VariableDeclaration {
}
children
}
Value::ObjectExpression(object_expression) => {
Expr::ObjectExpression(object_expression) => {
symbol_kind = SymbolKind::OBJECT;
let mut children = vec![];
for property in &object_expression.properties {
@ -1798,7 +1799,7 @@ impl VariableDeclaration {
}
children
}
Value::ArrayExpression(_) => {
Expr::ArrayExpression(_) => {
symbol_kind = SymbolKind::ARRAY;
vec![]
}
@ -1886,7 +1887,7 @@ pub struct VariableDeclarator {
/// The identifier of the variable.
pub id: Identifier,
/// The value of the variable.
pub init: Value,
pub init: Expr,
pub digest: Option<Digest>,
}
@ -1894,7 +1895,7 @@ pub struct VariableDeclarator {
impl_value_meta!(VariableDeclarator);
impl VariableDeclarator {
pub fn new(name: &str, init: Value) -> Self {
pub fn new(name: &str, init: Expr) -> Self {
Self {
start: 0,
end: 0,
@ -2217,9 +2218,9 @@ impl Default for PipeSubstitution {
}
}
impl From<PipeSubstitution> for Value {
impl From<PipeSubstitution> for Expr {
fn from(pipe_substitution: PipeSubstitution) -> Self {
Value::PipeSubstitution(Box::new(pipe_substitution))
Expr::PipeSubstitution(Box::new(pipe_substitution))
}
}
@ -2230,21 +2231,21 @@ impl From<PipeSubstitution> for Value {
pub struct ArrayExpression {
pub start: usize,
pub end: usize,
pub elements: Vec<Value>,
pub elements: Vec<Expr>,
pub digest: Option<Digest>,
}
impl_value_meta!(ArrayExpression);
impl From<ArrayExpression> for Value {
impl From<ArrayExpression> for Expr {
fn from(array_expression: ArrayExpression) -> Self {
Value::ArrayExpression(Box::new(array_expression))
Expr::ArrayExpression(Box::new(array_expression))
}
}
impl ArrayExpression {
pub fn new(elements: Vec<Value>) -> Self {
pub fn new(elements: Vec<Expr>) -> Self {
Self {
start: 0,
end: 0,
@ -2260,7 +2261,7 @@ impl ArrayExpression {
}
});
pub fn replace_value(&mut self, source_range: SourceRange, new_value: Value) {
pub fn replace_value(&mut self, source_range: SourceRange, new_value: Expr) {
for element in &mut self.elements {
element.replace_value(source_range, new_value.clone());
}
@ -2340,45 +2341,45 @@ impl ArrayExpression {
for element in &self.elements {
let result = match element {
Value::Literal(literal) => literal.into(),
Value::TagDeclarator(tag) => tag.execute(memory).await?,
Value::None(none) => none.into(),
Value::Identifier(identifier) => {
Expr::Literal(literal) => literal.into(),
Expr::TagDeclarator(tag) => tag.execute(memory).await?,
Expr::None(none) => none.into(),
Expr::Identifier(identifier) => {
let value = memory.get(&identifier.name, identifier.into())?;
value.clone()
}
Value::BinaryExpression(binary_expression) => {
Expr::BinaryExpression(binary_expression) => {
binary_expression
.get_result(memory, dynamic_state, pipe_info, ctx)
.await?
}
Value::CallExpression(call_expression) => {
Expr::CallExpression(call_expression) => {
call_expression.execute(memory, dynamic_state, pipe_info, ctx).await?
}
Value::UnaryExpression(unary_expression) => {
Expr::UnaryExpression(unary_expression) => {
unary_expression
.get_result(memory, dynamic_state, pipe_info, ctx)
.await?
}
Value::ObjectExpression(object_expression) => {
Expr::ObjectExpression(object_expression) => {
object_expression.execute(memory, dynamic_state, pipe_info, ctx).await?
}
Value::ArrayExpression(array_expression) => {
Expr::ArrayExpression(array_expression) => {
array_expression.execute(memory, dynamic_state, pipe_info, ctx).await?
}
Value::PipeExpression(pipe_expression) => {
Expr::PipeExpression(pipe_expression) => {
pipe_expression
.get_result(memory, dynamic_state, pipe_info, ctx)
.await?
}
Value::PipeSubstitution(pipe_substitution) => {
Expr::PipeSubstitution(pipe_substitution) => {
return Err(KclError::Semantic(KclErrorDetails {
message: format!("PipeSubstitution not implemented here: {:?}", pipe_substitution),
source_ranges: vec![pipe_substitution.into()],
}));
}
Value::MemberExpression(member_expression) => member_expression.get_result(memory)?,
Value::FunctionExpression(function_expression) => {
Expr::MemberExpression(member_expression) => member_expression.get_result(memory)?,
Expr::FunctionExpression(function_expression) => {
return Err(KclError::Semantic(KclErrorDetails {
message: format!("FunctionExpression not implemented here: {:?}", function_expression),
source_ranges: vec![function_expression.into()],
@ -2435,7 +2436,7 @@ impl ObjectExpression {
}
});
pub fn replace_value(&mut self, source_range: SourceRange, new_value: Value) {
pub fn replace_value(&mut self, source_range: SourceRange, new_value: Expr) {
for property in &mut self.properties {
property.value.replace_value(source_range, new_value.clone());
}
@ -2526,45 +2527,45 @@ impl ObjectExpression {
let mut object = Map::new();
for property in &self.properties {
let result = match &property.value {
Value::Literal(literal) => literal.into(),
Value::TagDeclarator(tag) => tag.execute(memory).await?,
Value::None(none) => none.into(),
Value::Identifier(identifier) => {
Expr::Literal(literal) => literal.into(),
Expr::TagDeclarator(tag) => tag.execute(memory).await?,
Expr::None(none) => none.into(),
Expr::Identifier(identifier) => {
let value = memory.get(&identifier.name, identifier.into())?;
value.clone()
}
Value::BinaryExpression(binary_expression) => {
Expr::BinaryExpression(binary_expression) => {
binary_expression
.get_result(memory, dynamic_state, pipe_info, ctx)
.await?
}
Value::CallExpression(call_expression) => {
Expr::CallExpression(call_expression) => {
call_expression.execute(memory, dynamic_state, pipe_info, ctx).await?
}
Value::UnaryExpression(unary_expression) => {
Expr::UnaryExpression(unary_expression) => {
unary_expression
.get_result(memory, dynamic_state, pipe_info, ctx)
.await?
}
Value::ObjectExpression(object_expression) => {
Expr::ObjectExpression(object_expression) => {
object_expression.execute(memory, dynamic_state, pipe_info, ctx).await?
}
Value::ArrayExpression(array_expression) => {
Expr::ArrayExpression(array_expression) => {
array_expression.execute(memory, dynamic_state, pipe_info, ctx).await?
}
Value::PipeExpression(pipe_expression) => {
Expr::PipeExpression(pipe_expression) => {
pipe_expression
.get_result(memory, dynamic_state, pipe_info, ctx)
.await?
}
Value::MemberExpression(member_expression) => member_expression.get_result(memory)?,
Value::PipeSubstitution(pipe_substitution) => {
Expr::MemberExpression(member_expression) => member_expression.get_result(memory)?,
Expr::PipeSubstitution(pipe_substitution) => {
return Err(KclError::Semantic(KclErrorDetails {
message: format!("PipeSubstitution not implemented here: {:?}", pipe_substitution),
source_ranges: vec![pipe_substitution.into()],
}));
}
Value::FunctionExpression(function_expression) => {
Expr::FunctionExpression(function_expression) => {
return Err(KclError::Semantic(KclErrorDetails {
message: format!("FunctionExpression not implemented here: {:?}", function_expression),
source_ranges: vec![function_expression.into()],
@ -2601,7 +2602,7 @@ pub struct ObjectProperty {
pub start: usize,
pub end: usize,
pub key: Identifier,
pub value: Value,
pub value: Expr,
pub digest: Option<Digest>,
}
@ -3046,7 +3047,7 @@ impl BinaryExpression {
hasher.update(slf.right.compute_digest());
});
pub fn replace_value(&mut self, source_range: SourceRange, new_value: Value) {
pub fn replace_value(&mut self, source_range: SourceRange, new_value: Expr) {
self.left.replace_value(source_range, new_value.clone());
self.right.replace_value(source_range, new_value);
}
@ -3309,7 +3310,7 @@ impl UnaryExpression {
hasher.update(slf.argument.compute_digest());
});
pub fn replace_value(&mut self, source_range: SourceRange, new_value: Value) {
pub fn replace_value(&mut self, source_range: SourceRange, new_value: Expr) {
self.argument.replace_value(source_range, new_value);
}
@ -3404,7 +3405,7 @@ pub struct PipeExpression {
pub end: usize,
// TODO: Only the first body expression can be any Value.
// The rest will be CallExpression, and the AST type should reflect this.
pub body: Vec<Value>,
pub body: Vec<Expr>,
pub non_code_meta: NonCodeMeta,
pub digest: Option<Digest>,
@ -3412,14 +3413,14 @@ pub struct PipeExpression {
impl_value_meta!(PipeExpression);
impl From<PipeExpression> for Value {
impl From<PipeExpression> for Expr {
fn from(pipe_expression: PipeExpression) -> Self {
Value::PipeExpression(Box::new(pipe_expression))
Expr::PipeExpression(Box::new(pipe_expression))
}
}
impl PipeExpression {
pub fn new(body: Vec<Value>) -> Self {
pub fn new(body: Vec<Expr>) -> Self {
Self {
start: 0,
end: 0,
@ -3437,7 +3438,7 @@ impl PipeExpression {
hasher.update(slf.non_code_meta.compute_digest());
});
pub fn replace_value(&mut self, source_range: SourceRange, new_value: Value) {
pub fn replace_value(&mut self, source_range: SourceRange, new_value: Expr) {
for value in &mut self.body {
value.replace_value(source_range, new_value.clone());
}
@ -3531,7 +3532,7 @@ impl PipeExpression {
async fn execute_pipe_body(
memory: &mut ProgramMemory,
dynamic_state: &DynamicState,
body: &[Value],
body: &[Expr],
pipe_info: &PipeInfo,
source_range: SourceRange,
ctx: &ExecutorContext,
@ -3568,17 +3569,17 @@ async fn execute_pipe_body(
// Evaluate remaining elements.
for expression in body {
let output = match expression {
Value::BinaryExpression(binary_expression) => {
Expr::BinaryExpression(binary_expression) => {
binary_expression
.get_result(memory, dynamic_state, &new_pipe_info, ctx)
.await?
}
Value::CallExpression(call_expression) => {
Expr::CallExpression(call_expression) => {
call_expression
.execute(memory, dynamic_state, &new_pipe_info, ctx)
.await?
}
Value::Identifier(identifier) => memory.get(&identifier.name, identifier.into())?.clone(),
Expr::Identifier(identifier) => memory.get(&identifier.name, identifier.into())?.clone(),
_ => {
// Return an error this should not happen.
return Err(KclError::Semantic(KclErrorDetails {
@ -3813,7 +3814,7 @@ impl FunctionExpression {
self.required_params().len()..=self.params.len()
}
pub fn replace_value(&mut self, source_range: SourceRange, new_value: Value) {
pub fn replace_value(&mut self, source_range: SourceRange, new_value: Expr) {
self.body.replace_value(source_range, new_value);
}
@ -3850,7 +3851,7 @@ impl FunctionExpression {
pub struct ReturnStatement {
pub start: usize,
pub end: usize,
pub argument: Value,
pub argument: Expr,
pub digest: Option<Digest>,
}
@ -5565,7 +5566,7 @@ const firstExtrude = startSketchOn('XY')
let BodyItem::VariableDeclaration(var_decl) = function else {
panic!("expected a variable declaration")
};
let Value::FunctionExpression(ref func_expr) = var_decl.declarations.first().unwrap().init else {
let Expr::FunctionExpression(ref func_expr) = var_decl.declarations.first().unwrap().init else {
panic!("expected a function expression")
};
let params = &func_expr.params;
@ -5589,7 +5590,7 @@ const firstExtrude = startSketchOn('XY')
let BodyItem::VariableDeclaration(var_decl) = function else {
panic!("expected a variable declaration")
};
let Value::FunctionExpression(ref func_expr) = var_decl.declarations.first().unwrap().init else {
let Expr::FunctionExpression(ref func_expr) = var_decl.declarations.first().unwrap().init else {
panic!("expected a function expression")
};
let params = &func_expr.params;
@ -5613,7 +5614,7 @@ const firstExtrude = startSketchOn('XY')
let BodyItem::VariableDeclaration(var_decl) = function else {
panic!("expected a variable declaration")
};
let Value::FunctionExpression(ref func_expr) = var_decl.declarations.first().unwrap().init else {
let Expr::FunctionExpression(ref func_expr) = var_decl.declarations.first().unwrap().init else {
panic!("expected a function expression")
};
let params = &func_expr.params;
@ -5676,7 +5677,7 @@ const firstExtrude = startSketchOn('XY')
let BodyItem::VariableDeclaration(var_decl) = function else {
panic!("expected a variable declaration")
};
let Value::FunctionExpression(ref func_expr) = var_decl.declarations.first().unwrap().init else {
let Expr::FunctionExpression(ref func_expr) = var_decl.declarations.first().unwrap().init else {
panic!("expected a function expression")
};
let params = &func_expr.params;
@ -5940,25 +5941,25 @@ const thickness = sqrt(distance * p * FOS * 6 / (sigmaAllow * width))"#;
panic!("expected a function!");
};
let Value::CallExpression(ce) = expression else {
let Expr::CallExpression(ce) = expression else {
panic!("expected a function!");
};
assert!(!ce.arguments.is_empty());
let Value::ObjectExpression(oe) = ce.arguments.first().unwrap() else {
let Expr::ObjectExpression(oe) = ce.arguments.first().unwrap() else {
panic!("expected a object!");
};
assert_eq!(oe.properties.len(), 2);
let Value::Literal(ref l) = oe.properties.first().unwrap().value else {
let Expr::Literal(ref l) = oe.properties.first().unwrap().value else {
panic!("expected a literal!");
};
assert_eq!(l.raw, "true");
let Value::Literal(ref l) = oe.properties.get(1).unwrap().value else {
let Expr::Literal(ref l) = oe.properties.get(1).unwrap().value else {
panic!("expected a literal!");
};

View File

@ -3,7 +3,7 @@ use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use serde_json::Value as JValue;
use crate::ast::types::{Literal, Value};
use crate::ast::types::{Expr, Literal};
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema, Bake)]
#[databake(path = kcl_lib::ast::types)]
@ -33,9 +33,9 @@ impl LiteralValue {
}
}
impl From<Literal> for Value {
impl From<Literal> for Expr {
fn from(literal: Literal) -> Self {
Value::Literal(Box::new(literal))
Expr::Literal(Box::new(literal))
}
}

View File

@ -11,7 +11,7 @@ use serde_json::Value as JValue;
use tower_lsp::lsp_types::{Position as LspPosition, Range as LspRange};
use crate::{
ast::types::{BodyItem, FunctionExpression, KclNone, Program, TagDeclarator, Value},
ast::types::{BodyItem, Expr, FunctionExpression, KclNone, Program, TagDeclarator},
engine::EngineManager,
errors::{KclError, KclErrorDetails},
fs::FileManager,
@ -1745,9 +1745,9 @@ impl ExecutorContext {
for statement in &program.body {
match statement {
BodyItem::ExpressionStatement(expression_statement) => {
if let Value::PipeExpression(pipe_expr) = &expression_statement.expression {
if let Expr::PipeExpression(pipe_expr) = &expression_statement.expression {
pipe_expr.get_result(memory, dynamic_state, &pipe_info, self).await?;
} else if let Value::CallExpression(call_expr) = &expression_statement.expression {
} else if let Expr::CallExpression(call_expr) = &expression_statement.expression {
call_expr.execute(memory, dynamic_state, &pipe_info, self).await?;
}
}
@ -1771,47 +1771,47 @@ impl ExecutorContext {
}
}
BodyItem::ReturnStatement(return_statement) => match &return_statement.argument {
Value::BinaryExpression(bin_expr) => {
Expr::BinaryExpression(bin_expr) => {
let result = bin_expr.get_result(memory, dynamic_state, &pipe_info, self).await?;
memory.return_ = Some(ProgramReturn::Value(result));
}
Value::UnaryExpression(unary_expr) => {
Expr::UnaryExpression(unary_expr) => {
let result = unary_expr.get_result(memory, dynamic_state, &pipe_info, self).await?;
memory.return_ = Some(ProgramReturn::Value(result));
}
Value::Identifier(identifier) => {
Expr::Identifier(identifier) => {
let value = memory.get(&identifier.name, identifier.into())?.clone();
memory.return_ = Some(ProgramReturn::Value(value));
}
Value::Literal(literal) => {
Expr::Literal(literal) => {
memory.return_ = Some(ProgramReturn::Value(literal.into()));
}
Value::TagDeclarator(tag) => {
Expr::TagDeclarator(tag) => {
memory.return_ = Some(ProgramReturn::Value(tag.into()));
}
Value::ArrayExpression(array_expr) => {
Expr::ArrayExpression(array_expr) => {
let result = array_expr.execute(memory, dynamic_state, &pipe_info, self).await?;
memory.return_ = Some(ProgramReturn::Value(result));
}
Value::ObjectExpression(obj_expr) => {
Expr::ObjectExpression(obj_expr) => {
let result = obj_expr.execute(memory, dynamic_state, &pipe_info, self).await?;
memory.return_ = Some(ProgramReturn::Value(result));
}
Value::CallExpression(call_expr) => {
Expr::CallExpression(call_expr) => {
let result = call_expr.execute(memory, dynamic_state, &pipe_info, self).await?;
memory.return_ = Some(ProgramReturn::Value(result));
}
Value::MemberExpression(member_expr) => {
Expr::MemberExpression(member_expr) => {
let result = member_expr.get_result(memory)?;
memory.return_ = Some(ProgramReturn::Value(result));
}
Value::PipeExpression(pipe_expr) => {
Expr::PipeExpression(pipe_expr) => {
let result = pipe_expr.get_result(memory, dynamic_state, &pipe_info, self).await?;
memory.return_ = Some(ProgramReturn::Value(result));
}
Value::PipeSubstitution(_) => {}
Value::FunctionExpression(_) => {}
Value::None(none) => {
Expr::PipeSubstitution(_) => {}
Expr::FunctionExpression(_) => {}
Expr::None(none) => {
memory.return_ = Some(ProgramReturn::Value(MemoryItem::from(none)));
}
},
@ -1835,7 +1835,7 @@ impl ExecutorContext {
pub async fn arg_into_mem_item<'a>(
&self,
init: &Value,
init: &Expr,
memory: &mut ProgramMemory,
dynamic_state: &DynamicState,
pipe_info: &PipeInfo,
@ -1843,19 +1843,19 @@ impl ExecutorContext {
statement_kind: StatementKind<'a>,
) -> Result<MemoryItem, KclError> {
let item = match init {
Value::None(none) => none.into(),
Value::Literal(literal) => literal.into(),
Value::TagDeclarator(tag) => tag.execute(memory).await?,
Value::Identifier(identifier) => {
Expr::None(none) => none.into(),
Expr::Literal(literal) => literal.into(),
Expr::TagDeclarator(tag) => tag.execute(memory).await?,
Expr::Identifier(identifier) => {
let value = memory.get(&identifier.name, identifier.into())?;
value.clone()
}
Value::BinaryExpression(binary_expression) => {
Expr::BinaryExpression(binary_expression) => {
binary_expression
.get_result(memory, dynamic_state, pipe_info, self)
.await?
}
Value::FunctionExpression(function_expression) => {
Expr::FunctionExpression(function_expression) => {
let mem_func = force_memory_function(
|args: Vec<MemoryItem>,
memory: ProgramMemory,
@ -1897,15 +1897,15 @@ impl ExecutorContext {
memory: Box::new(memory.clone()),
}
}
Value::CallExpression(call_expression) => {
Expr::CallExpression(call_expression) => {
call_expression.execute(memory, dynamic_state, pipe_info, self).await?
}
Value::PipeExpression(pipe_expression) => {
Expr::PipeExpression(pipe_expression) => {
pipe_expression
.get_result(memory, dynamic_state, pipe_info, self)
.await?
}
Value::PipeSubstitution(pipe_substitution) => match statement_kind {
Expr::PipeSubstitution(pipe_substitution) => match statement_kind {
StatementKind::Declaration { name } => {
let message = format!(
"you cannot declare variable {name} as %, because % can only be used in function calls"
@ -1926,16 +1926,16 @@ impl ExecutorContext {
}
},
},
Value::ArrayExpression(array_expression) => {
Expr::ArrayExpression(array_expression) => {
array_expression.execute(memory, dynamic_state, pipe_info, self).await?
}
Value::ObjectExpression(object_expression) => {
Expr::ObjectExpression(object_expression) => {
object_expression
.execute(memory, dynamic_state, pipe_info, self)
.await?
}
Value::MemberExpression(member_expression) => member_expression.get_result(memory)?,
Value::UnaryExpression(unary_expression) => {
Expr::MemberExpression(member_expression) => member_expression.get_result(memory)?,
Expr::UnaryExpression(unary_expression) => {
unary_expression
.get_result(memory, dynamic_state, pipe_info, self)
.await?

View File

@ -40,7 +40,7 @@ use tower_lsp::{
};
use crate::{
ast::types::{Value, VariableKind},
ast::types::{Expr, VariableKind},
executor::SourceRange,
lsp::{backend::Backend as _, util::IntoDiagnostic},
parser::PIPE_OPERATOR,
@ -370,7 +370,7 @@ impl Backend {
crate::walk::Node::VariableDeclarator(variable) => {
let sr: SourceRange = (&variable.id).into();
if sr.contains(source_range.start()) {
if let Value::FunctionExpression(_) = &variable.init {
if let Expr::FunctionExpression(_) = &variable.init {
let mut ti = token_index.lock().map_err(|_| anyhow::anyhow!("mutex"))?;
*ti = match self.get_semantic_token_type_index(&SemanticTokenType::FUNCTION) {
Some(index) => index,

View File

@ -10,11 +10,11 @@ use winnow::{
use crate::{
ast::types::{
ArrayExpression, BinaryExpression, BinaryOperator, BinaryPart, BodyItem, CallExpression, CommentStyle,
ArrayExpression, BinaryExpression, BinaryOperator, BinaryPart, BodyItem, CallExpression, CommentStyle, Expr,
ExpressionStatement, FnArgPrimitive, FnArgType, FunctionExpression, Identifier, Literal, LiteralIdentifier,
LiteralValue, MemberExpression, MemberObject, NonCodeMeta, NonCodeNode, NonCodeValue, ObjectExpression,
ObjectProperty, Parameter, PipeExpression, PipeSubstitution, Program, ReturnStatement, TagDeclarator,
UnaryExpression, UnaryOperator, Value, VariableDeclaration, VariableDeclarator, VariableKind,
UnaryExpression, UnaryOperator, VariableDeclaration, VariableDeclarator, VariableKind,
},
errors::{KclError, KclErrorDetails},
executor::SourceRange,
@ -136,7 +136,7 @@ fn non_code_node_no_leading_whitespace(i: TokenSlice) -> PResult<NonCodeNode> {
fn pipe_expression(i: TokenSlice) -> PResult<PipeExpression> {
let mut non_code_meta = NonCodeMeta::default();
let (head, noncode) = terminated(
(value_but_not_pipe, preceded(whitespace, opt(non_code_node))),
(expression_but_not_pipe, preceded(whitespace, opt(non_code_node))),
peek(pipe_surrounded_by_whitespace),
)
.context(expected("an expression, followed by the |> (pipe) operator"))
@ -146,9 +146,9 @@ fn pipe_expression(i: TokenSlice) -> PResult<PipeExpression> {
}
let mut values = vec![head];
let value_surrounded_by_comments = (
repeat(0.., preceded(opt(whitespace), non_code_node)), // Before the value
preceded(opt(whitespace), fn_call), // The value
repeat(0.., noncode_just_after_code), // After the value
repeat(0.., preceded(opt(whitespace), non_code_node)), // Before the expression.
preceded(opt(whitespace), fn_call), // The expression.
repeat(0.., noncode_just_after_code), // After the expression.
);
let tail: Vec<(Vec<_>, _, Vec<_>)> = repeat(
1..,
@ -183,7 +183,7 @@ fn pipe_expression(i: TokenSlice) -> PResult<PipeExpression> {
max_noncode_end = nc.end.max(max_noncode_end);
non_code_meta.insert(code_count, nc);
}
values.push(Value::CallExpression(Box::new(code)));
values.push(Expr::CallExpression(Box::new(code)));
code_count += 1;
for nc in noncode_after {
max_noncode_end = nc.end.max(max_noncode_end);
@ -318,21 +318,21 @@ fn operand(i: TokenSlice) -> PResult<BinaryPart> {
let op = possible_operands
.try_map(|part| {
let source_ranges = vec![SourceRange([part.start(), part.end()])];
let val = match part {
let expr = match part {
// TODO: these should be valid operands eventually,
// users should be able to run "let x = f() + g()"
// see https://github.com/KittyCAD/modeling-app/issues/783
Value::FunctionExpression(_)
| Value::PipeExpression(_)
| Value::PipeSubstitution(_)
| Value::ArrayExpression(_)
| Value::ObjectExpression(_) => {
Expr::FunctionExpression(_)
| Expr::PipeExpression(_)
| Expr::PipeSubstitution(_)
| Expr::ArrayExpression(_)
| Expr::ObjectExpression(_) => {
return Err(KclError::Syntax(KclErrorDetails {
source_ranges,
message: TODO_783.to_owned(),
}))
}
Value::None(_) => {
Expr::None(_) => {
return Err(KclError::Semantic(KclErrorDetails {
source_ranges,
// TODO: Better error message here.
@ -341,7 +341,7 @@ fn operand(i: TokenSlice) -> PResult<BinaryPart> {
message: "cannot use a KCL None value as an operand".to_owned(),
}));
}
Value::TagDeclarator(_) => {
Expr::TagDeclarator(_) => {
return Err(KclError::Semantic(KclErrorDetails {
source_ranges,
// TODO: Better error message here.
@ -350,14 +350,14 @@ fn operand(i: TokenSlice) -> PResult<BinaryPart> {
message: "cannot use a KCL tag declaration as an operand".to_owned(),
}));
}
Value::UnaryExpression(x) => BinaryPart::UnaryExpression(x),
Value::Literal(x) => BinaryPart::Literal(x),
Value::Identifier(x) => BinaryPart::Identifier(x),
Value::BinaryExpression(x) => BinaryPart::BinaryExpression(x),
Value::CallExpression(x) => BinaryPart::CallExpression(x),
Value::MemberExpression(x) => BinaryPart::MemberExpression(x),
Expr::UnaryExpression(x) => BinaryPart::UnaryExpression(x),
Expr::Literal(x) => BinaryPart::Literal(x),
Expr::Identifier(x) => BinaryPart::Identifier(x),
Expr::BinaryExpression(x) => BinaryPart::BinaryExpression(x),
Expr::CallExpression(x) => BinaryPart::CallExpression(x),
Expr::MemberExpression(x) => BinaryPart::MemberExpression(x),
};
Ok(val)
Ok(expr)
})
.context(expected("an operand (a value which can be used with an operator)"))
.parse_next(i)?;
@ -452,7 +452,7 @@ fn equals(i: TokenSlice) -> PResult<Token> {
fn array(i: TokenSlice) -> PResult<ArrayExpression> {
let start = open_bracket(i)?.start;
ignore_whitespace(i);
let elements = alt((integer_range, separated(0.., value, comma_sep)))
let elements = alt((integer_range, separated(0.., expression, comma_sep)))
.context(expected(
"array contents, either a numeric range (like 0..10) or a list of elements (like [1, 2, 3])",
))
@ -468,14 +468,14 @@ fn array(i: TokenSlice) -> PResult<ArrayExpression> {
}
/// Parse n..m into a vec of numbers [n, n+1, ..., m]
fn integer_range(i: TokenSlice) -> PResult<Vec<Value>> {
fn integer_range(i: TokenSlice) -> PResult<Vec<Expr>> {
let (token0, floor) = integer.parse_next(i)?;
double_period.parse_next(i)?;
let (_token1, ceiling) = integer.parse_next(i)?;
Ok((floor..=ceiling)
.map(|num| {
let num = num as i64;
Value::Literal(Box::new(Literal {
Expr::Literal(Box::new(Literal {
start: token0.start,
end: token0.end,
value: num.into(),
@ -494,16 +494,16 @@ fn object_property(i: TokenSlice) -> PResult<ObjectProperty> {
))
.parse_next(i)?;
ignore_whitespace(i);
let val = value
let expr = expression
.context(expected(
"the value which you're setting the property to, e.g. in 'height: 4', the value is 4",
))
.parse_next(i)?;
Ok(ObjectProperty {
start: key.start,
end: val.end(),
end: expr.end(),
key,
value: val,
value: expr,
digest: None,
})
}
@ -727,7 +727,7 @@ fn body_items_within_function(i: TokenSlice) -> PResult<WithinFunction> {
non_code_node.map(WithinFunction::NonCode)
},
_ =>
(expression.map(BodyItem::ExpressionStatement), opt(noncode_just_after_code)).map(WithinFunction::BodyItem),
(expression_stmt.map(BodyItem::ExpressionStatement), opt(noncode_just_after_code)).map(WithinFunction::BodyItem),
}
.context(expected("a function body items (functions are made up of variable declarations, expressions, and return statements, each of those is a possible body item"))
.parse_next(i)?;
@ -894,7 +894,7 @@ pub fn return_stmt(i: TokenSlice) -> PResult<ReturnStatement> {
))
.parse_next(i)?;
require_whitespace(i)?;
let argument = value(i)?;
let argument = expression(i)?;
Ok(ReturnStatement {
start,
end: argument.end(),
@ -903,62 +903,62 @@ pub fn return_stmt(i: TokenSlice) -> PResult<ReturnStatement> {
})
}
/// Parse a KCL value
fn value(i: TokenSlice) -> PResult<Value> {
/// Parse a KCL expression.
fn expression(i: TokenSlice) -> PResult<Expr> {
alt((
pipe_expression.map(Box::new).map(Value::PipeExpression),
value_but_not_pipe,
pipe_expression.map(Box::new).map(Expr::PipeExpression),
expression_but_not_pipe,
))
.context(expected("a KCL value"))
.parse_next(i)
}
fn value_but_not_pipe(i: TokenSlice) -> PResult<Value> {
fn expression_but_not_pipe(i: TokenSlice) -> PResult<Expr> {
alt((
binary_expression.map(Box::new).map(Value::BinaryExpression),
unary_expression.map(Box::new).map(Value::UnaryExpression),
value_allowed_in_pipe_expr,
binary_expression.map(Box::new).map(Expr::BinaryExpression),
unary_expression.map(Box::new).map(Expr::UnaryExpression),
expr_allowed_in_pipe_expr,
))
.context(expected("a KCL value"))
.parse_next(i)
}
fn unnecessarily_bracketed(i: TokenSlice) -> PResult<Value> {
fn unnecessarily_bracketed(i: TokenSlice) -> PResult<Expr> {
delimited(
terminated(open_paren, opt(whitespace)),
value,
expression,
preceded(opt(whitespace), close_paren),
)
.parse_next(i)
}
fn value_allowed_in_pipe_expr(i: TokenSlice) -> PResult<Value> {
fn expr_allowed_in_pipe_expr(i: TokenSlice) -> PResult<Expr> {
alt((
member_expression.map(Box::new).map(Value::MemberExpression),
bool_value.map(Box::new).map(Value::Literal),
tag.map(Box::new).map(Value::TagDeclarator),
literal.map(Box::new).map(Value::Literal),
fn_call.map(Box::new).map(Value::CallExpression),
identifier.map(Box::new).map(Value::Identifier),
array.map(Box::new).map(Value::ArrayExpression),
object.map(Box::new).map(Value::ObjectExpression),
pipe_sub.map(Box::new).map(Value::PipeSubstitution),
function_expression.map(Box::new).map(Value::FunctionExpression),
member_expression.map(Box::new).map(Expr::MemberExpression),
bool_value.map(Box::new).map(Expr::Literal),
tag.map(Box::new).map(Expr::TagDeclarator),
literal.map(Box::new).map(Expr::Literal),
fn_call.map(Box::new).map(Expr::CallExpression),
identifier.map(Box::new).map(Expr::Identifier),
array.map(Box::new).map(Expr::ArrayExpression),
object.map(Box::new).map(Expr::ObjectExpression),
pipe_sub.map(Box::new).map(Expr::PipeSubstitution),
function_expression.map(Box::new).map(Expr::FunctionExpression),
unnecessarily_bracketed,
))
.context(expected("a KCL value (but not a pipe expression)"))
.context(expected("a KCL expression (but not a pipe expression)"))
.parse_next(i)
}
fn possible_operands(i: TokenSlice) -> PResult<Value> {
fn possible_operands(i: TokenSlice) -> PResult<Expr> {
alt((
unary_expression.map(Box::new).map(Value::UnaryExpression),
bool_value.map(Box::new).map(Value::Literal),
member_expression.map(Box::new).map(Value::MemberExpression),
literal.map(Box::new).map(Value::Literal),
fn_call.map(Box::new).map(Value::CallExpression),
identifier.map(Box::new).map(Value::Identifier),
binary_expr_in_parens.map(Box::new).map(Value::BinaryExpression),
unary_expression.map(Box::new).map(Expr::UnaryExpression),
bool_value.map(Box::new).map(Expr::Literal),
member_expression.map(Box::new).map(Expr::MemberExpression),
literal.map(Box::new).map(Expr::Literal),
fn_call.map(Box::new).map(Expr::CallExpression),
identifier.map(Box::new).map(Expr::Identifier),
binary_expr_in_parens.map(Box::new).map(Expr::BinaryExpression),
unnecessarily_bracketed,
))
.context(expected(
@ -1007,15 +1007,15 @@ fn declaration(i: TokenSlice) -> PResult<VariableDeclaration> {
let val = if kind == VariableKind::Fn {
function_expression
.map(Box::new)
.map(Value::FunctionExpression)
.map(Expr::FunctionExpression)
.context(expected("a KCL function expression, like () => { return 1 }"))
.parse_next(i)
} else {
value
expression
.try_map(|val| {
// Function bodies can be used if and only if declaring a function.
// Check the 'if' direction:
if matches!(val, Value::FunctionExpression(_)) {
if matches!(val, Expr::FunctionExpression(_)) {
return Err(KclError::Syntax(KclErrorDetails {
source_ranges: vec![SourceRange([start, dec_end])],
message: format!("Expected a `fn` variable kind, found: `{}`", kind),
@ -1218,9 +1218,9 @@ fn bracketed_section(i: TokenSlice) -> PResult<usize> {
Ok(tokens_examined)
}
/// Parse a KCL expression.
fn expression(i: TokenSlice) -> PResult<ExpressionStatement> {
let val = value
/// Parse a KCL expression statement.
fn expression_stmt(i: TokenSlice) -> PResult<ExpressionStatement> {
let val = expression
.context(expected(
"an expression (i.e. a value, or an algorithm for calculating one), e.g. 'x + y' or '3' or 'width * 2'",
))
@ -1374,8 +1374,8 @@ fn comma_sep(i: TokenSlice) -> PResult<()> {
}
/// Arguments are passed into a function.
fn arguments(i: TokenSlice) -> PResult<Vec<Value>> {
separated(0.., value, comma_sep)
fn arguments(i: TokenSlice) -> PResult<Vec<Expr>> {
separated(0.., expression, comma_sep)
.context(expected("function arguments"))
.parse_next(i)
}
@ -1513,10 +1513,10 @@ fn fn_call(i: TokenSlice) -> PResult<CallExpression> {
};
match spec_arg.type_.as_ref() {
"TagDeclarator" => match &arg {
Value::Identifier(_) => {
Expr::Identifier(_) => {
// These are fine since we want someone to be able to map a variable to a tag declarator.
}
Value::TagDeclarator(tag) => {
Expr::TagDeclarator(tag) => {
tag.clone()
.into_valid_binding_name()
.map_err(|e| ErrMode::Cut(ContextError::from(e)))?;
@ -1532,8 +1532,8 @@ fn fn_call(i: TokenSlice) -> PResult<CallExpression> {
}
},
"TagIdentifier" => match &arg {
Value::Identifier(_) => {}
Value::MemberExpression(_) => {}
Expr::Identifier(_) => {}
Expr::MemberExpression(_) => {}
e => {
return Err(ErrMode::Cut(
KclError::Syntax(KclErrorDetails {
@ -1564,7 +1564,7 @@ mod tests {
use pretty_assertions::assert_eq;
use super::*;
use crate::ast::types::{BodyItem, Value, VariableKind};
use crate::ast::types::{BodyItem, Expr, VariableKind};
#[test]
fn parse_args() {
@ -1680,7 +1680,7 @@ const mySk1 = startSketchAt([0, 0])"#;
panic!("expected vardec");
};
let val = item.declarations.remove(0).init;
let Value::PipeExpression(pipe) = val else {
let Expr::PipeExpression(pipe) = val else {
panic!("expected pipe");
};
let mut noncode = pipe.non_code_meta;
@ -1727,7 +1727,7 @@ const mySk1 = startSketchAt([0, 0])"#;
body: vec![BodyItem::ReturnStatement(ReturnStatement {
start: 25,
end: 33,
argument: Value::Literal(Box::new(Literal {
argument: Expr::Literal(Box::new(Literal {
start: 32,
end: 33,
value: 2u32.into(),
@ -1873,7 +1873,7 @@ const mySk1 = startSketchAt([0, 0])"#;
"sqrt(distance * p * FOS * 6 / ( sigmaAllow * width ))",
] {
let tokens = crate::token::lexer(input).unwrap();
let _actual = match value.parse(&tokens) {
let _actual = match expression.parse(&tokens) {
Ok(x) => x,
Err(e) => panic!("{e:?}"),
};
@ -1919,7 +1919,7 @@ const mySk1 = startSketchAt([0, 0])"#;
Err(e) => panic!("Could not parse test {i}: {e:#?}"),
Ok(a) => a,
};
let Value::BinaryExpression(_expr) = actual.declarations.remove(0).init else {
let Expr::BinaryExpression(_expr) = actual.declarations.remove(0).init else {
panic!(
"Expected test {i} to be a binary expression but it wasn't, it was {:?}",
actual.declarations[0]
@ -2247,7 +2247,7 @@ const mySk1 = startSketchAt([0, 0])"#;
assert_eq!(actual.declarations.len(), 1);
let decl = actual.declarations.pop().unwrap();
assert_eq!(decl.id.name, "myVar");
let Value::Literal(value) = decl.init else {
let Expr::Literal(value) = decl.init else {
panic!("value should be a literal")
};
assert_eq!(value.end, test.len());
@ -2282,7 +2282,7 @@ const mySk1 = startSketchAt([0, 0])"#;
let expected = vec![BodyItem::ExpressionStatement(ExpressionStatement {
start: 0,
end: 7,
expression: Value::BinaryExpression(Box::new(expr)),
expression: Expr::BinaryExpression(Box::new(expr)),
digest: None,
})];
assert_eq!(expected, actual);
@ -2377,7 +2377,7 @@ const mySk1 = startSketchAt([0, 0])"#;
body: vec![BodyItem::ExpressionStatement(ExpressionStatement {
start: 0,
end: 4,
expression: Value::BinaryExpression(Box::new(BinaryExpression {
expression: Expr::BinaryExpression(Box::new(BinaryExpression {
start: 0,
end: 4,
left: BinaryPart::Literal(Box::new(Literal {
@ -2774,81 +2774,81 @@ e
name: "myArray".to_string(),
digest: None,
},
init: Value::ArrayExpression(Box::new(ArrayExpression {
init: Expr::ArrayExpression(Box::new(ArrayExpression {
start: 16,
end: 23,
elements: vec![
Value::Literal(Box::new(Literal {
Expr::Literal(Box::new(Literal {
start: 17,
end: 18,
value: 0u32.into(),
raw: "0".to_string(),
digest: None,
})),
Value::Literal(Box::new(Literal {
Expr::Literal(Box::new(Literal {
start: 17,
end: 18,
value: 1u32.into(),
raw: "1".to_string(),
digest: None,
})),
Value::Literal(Box::new(Literal {
Expr::Literal(Box::new(Literal {
start: 17,
end: 18,
value: 2u32.into(),
raw: "2".to_string(),
digest: None,
})),
Value::Literal(Box::new(Literal {
Expr::Literal(Box::new(Literal {
start: 17,
end: 18,
value: 3u32.into(),
raw: "3".to_string(),
digest: None,
})),
Value::Literal(Box::new(Literal {
Expr::Literal(Box::new(Literal {
start: 17,
end: 18,
value: 4u32.into(),
raw: "4".to_string(),
digest: None,
})),
Value::Literal(Box::new(Literal {
Expr::Literal(Box::new(Literal {
start: 17,
end: 18,
value: 5u32.into(),
raw: "5".to_string(),
digest: None,
})),
Value::Literal(Box::new(Literal {
Expr::Literal(Box::new(Literal {
start: 17,
end: 18,
value: 6u32.into(),
raw: "6".to_string(),
digest: None,
})),
Value::Literal(Box::new(Literal {
Expr::Literal(Box::new(Literal {
start: 17,
end: 18,
value: 7u32.into(),
raw: "7".to_string(),
digest: None,
})),
Value::Literal(Box::new(Literal {
Expr::Literal(Box::new(Literal {
start: 17,
end: 18,
value: 8u32.into(),
raw: "8".to_string(),
digest: None,
})),
Value::Literal(Box::new(Literal {
Expr::Literal(Box::new(Literal {
start: 17,
end: 18,
value: 9u32.into(),
raw: "9".to_string(),
digest: None,
})),
Value::Literal(Box::new(Literal {
Expr::Literal(Box::new(Literal {
start: 17,
end: 18,
value: 10u32.into(),

View File

@ -4,7 +4,7 @@ use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use crate::{
ast::types::{BodyItem, FunctionExpression, Program, Value},
ast::types::{BodyItem, Expr, FunctionExpression, Program},
docs::{StdLibFn, StdLibFnData},
token::lexer,
};
@ -89,7 +89,7 @@ pub fn extract_function(source: &str) -> Option<(Program, Box<FunctionExpression
let BodyItem::ExpressionStatement(expr) = src.body.last()? else {
panic!("expected expression statement");
};
let Value::FunctionExpression(function) = expr.expression.clone() else {
let Expr::FunctionExpression(function) = expr.expression.clone() else {
panic!("expected function expr");
};
Some((src, function))

View File

@ -2,8 +2,8 @@ use anyhow::Result;
use crate::{
ast::types::{
BinaryPart, BodyItem, LiteralIdentifier, MemberExpression, MemberObject, ObjectExpression, ObjectProperty,
Parameter, Program, UnaryExpression, Value, VariableDeclarator,
BinaryPart, BodyItem, Expr, LiteralIdentifier, MemberExpression, MemberObject, ObjectExpression,
ObjectProperty, Parameter, Program, UnaryExpression, VariableDeclarator,
},
walk::Node,
};
@ -108,20 +108,20 @@ where
}
}
fn walk_value<'a, WalkT>(node: &'a Value, f: &WalkT) -> Result<bool>
fn walk_value<'a, WalkT>(node: &'a Expr, f: &WalkT) -> Result<bool>
where
WalkT: Walker<'a>,
{
match node {
Value::Literal(lit) => f.walk(lit.as_ref().into()),
Value::TagDeclarator(tag) => f.walk(tag.as_ref().into()),
Expr::Literal(lit) => f.walk(lit.as_ref().into()),
Expr::TagDeclarator(tag) => f.walk(tag.as_ref().into()),
Value::Identifier(id) => {
Expr::Identifier(id) => {
// sometimes there's a bare Identifier without a Value::Identifier.
f.walk(id.as_ref().into())
}
Value::BinaryExpression(be) => {
Expr::BinaryExpression(be) => {
if !f.walk(be.as_ref().into())? {
return Ok(false);
}
@ -130,7 +130,7 @@ where
}
walk_binary_part(&be.right, f)
}
Value::FunctionExpression(fe) => {
Expr::FunctionExpression(fe) => {
if !f.walk(fe.as_ref().into())? {
return Ok(false);
}
@ -142,7 +142,7 @@ where
}
walk(&fe.body, f)
}
Value::CallExpression(ce) => {
Expr::CallExpression(ce) => {
if !f.walk(ce.as_ref().into())? {
return Ok(false);
}
@ -157,7 +157,7 @@ where
}
Ok(true)
}
Value::PipeExpression(pe) => {
Expr::PipeExpression(pe) => {
if !f.walk(pe.as_ref().into())? {
return Ok(false);
}
@ -169,8 +169,8 @@ where
}
Ok(true)
}
Value::PipeSubstitution(ps) => f.walk(ps.as_ref().into()),
Value::ArrayExpression(ae) => {
Expr::PipeSubstitution(ps) => f.walk(ps.as_ref().into()),
Expr::ArrayExpression(ae) => {
if !f.walk(ae.as_ref().into())? {
return Ok(false);
}
@ -181,10 +181,10 @@ where
}
Ok(true)
}
Value::ObjectExpression(oe) => walk_object_expression(oe, f),
Value::MemberExpression(me) => walk_member_expression(me, f),
Value::UnaryExpression(ue) => walk_unary_expression(ue, f),
Value::None(_) => Ok(true),
Expr::ObjectExpression(oe) => walk_object_expression(oe, f),
Expr::MemberExpression(me) => walk_member_expression(me, f),
Expr::UnaryExpression(ue) => walk_unary_expression(ue, f),
Expr::None(_) => Ok(true),
}
}