diff --git a/src/lang/abstractSyntaxTree.test.ts b/src/lang/abstractSyntaxTree.test.ts index 6a18cf089..b4a44d96a 100644 --- a/src/lang/abstractSyntaxTree.test.ts +++ b/src/lang/abstractSyntaxTree.test.ts @@ -1859,3 +1859,39 @@ describe('testing nested call expressions', () => { }) }) }) + +describe('should recognise callExpresions in binaryExpressions', () => { + const code = "xLineTo(segEndX('seg02', %) + 1, %)" + it('should recognise the callExp', () => { + const tokens = lexer(code) + const { body } = abstractSyntaxTree(tokens) + const callExpArgs = (body?.[0] as any).expression?.arguments + expect(callExpArgs).toEqual([ + { + type: 'BinaryExpression', + operator: '+', + start: 8, + end: 31, + left: { + type: 'CallExpression', + start: 8, + end: 27, + callee: { type: 'Identifier', start: 8, end: 15, name: 'segEndX' }, + arguments: [ + { + type: 'Literal', + start: 16, + end: 23, + value: 'seg02', + raw: "'seg02'", + }, + { type: 'PipeSubstitution', start: 25, end: 26 }, + ], + optional: false, + }, + right: { type: 'Literal', value: 1, raw: '1', start: 30, end: 31 }, + }, + { type: 'PipeSubstitution', start: 33, end: 34 }, + ]) + }) +}) diff --git a/src/lang/abstractSyntaxTree.ts b/src/lang/abstractSyntaxTree.ts index 4a1d3c382..fa4fb8024 100644 --- a/src/lang/abstractSyntaxTree.ts +++ b/src/lang/abstractSyntaxTree.ts @@ -183,10 +183,8 @@ export function makeCallExpression( } { const currentToken = tokens[index] const braceToken = nextMeaningfulToken(tokens, index) - // const firstArgumentToken = nextMeaningfulToken(tokens, braceToken.index); const callee = makeIdentifier(tokens, index) const args = makeArguments(tokens, braceToken.index) - // const closingBraceToken = nextMeaningfulToken(tokens, args.lastIndex); const closingBraceToken = tokens[args.lastIndex] return { expression: { @@ -321,6 +319,25 @@ function makeArguments( nextBraceOrCommaToken.token.type === 'brace' && nextBraceOrCommaToken.token.value === '(' ) { + const closingBrace = findClosingBrace(tokens, nextBraceOrCommaToken.index) + const tokenAfterClosingBrace = nextMeaningfulToken(tokens, closingBrace) + if ( + tokenAfterClosingBrace.token.type === 'operator' && + tokenAfterClosingBrace.token.value !== '|>' + ) { + const { expression, lastIndex } = makeBinaryExpression( + tokens, + argumentToken.index + ) + const nextCommarOrBraceTokenIndex = nextMeaningfulToken( + tokens, + lastIndex + ).index + return makeArguments(tokens, nextCommarOrBraceTokenIndex, [ + ...previousArgs, + expression, + ]) + } const { expression, lastIndex } = makeCallExpression( tokens, argumentToken.index diff --git a/src/lang/std/sketch.ts b/src/lang/std/sketch.ts index 23f6d9eca..9051b6931 100644 --- a/src/lang/std/sketch.ts +++ b/src/lang/std/sketch.ts @@ -460,15 +460,26 @@ export const xLine: SketchLineHelper = { const newVal = createLiteral(roundOff(to[0] - from[0], 2)) const firstArg = newVal - const newLine = createCallback - ? createCallback([firstArg, firstArg]).callExp - : createCallExpression('xLine', [firstArg, createPipeSubstitution()]) - const callIndex = getLastIndex(pathToNode) - if (replaceExisting) { - pipe.body[callIndex] = newLine - } else { - pipe.body = [...pipe.body, newLine] + + if (replaceExisting && createCallback) { + const callIndex = getLastIndex(pathToNode) + const { callExp, valueUsedInTransform } = createCallback([ + firstArg, + firstArg, + ]) + pipe.body[callIndex] = callExp + return { + modifiedAst: _node, + pathToNode, + valueUsedInTransform, + } } + + const newLine = createCallExpression('xLine', [ + firstArg, + createPipeSubstitution(), + ]) + pipe.body = [...pipe.body, newLine] return { modifiedAst: _node, pathToNode } }, updateArgs: ({ node, pathToNode, to, from }) => { @@ -513,15 +524,22 @@ export const yLine: SketchLineHelper = { const getNode = getNodeFromPathCurry(_node, pathToNode) const { node: pipe } = getNode('PipeExpression') const newVal = createLiteral(roundOff(to[1] - from[1], 2)) - const newLine = createCallback - ? createCallback([newVal, newVal]).callExp - : createCallExpression('yLine', [newVal, createPipeSubstitution()]) - const callIndex = getLastIndex(pathToNode) - if (replaceExisting) { - pipe.body[callIndex] = newLine - } else { - pipe.body = [...pipe.body, newLine] + if (replaceExisting && createCallback) { + const callIndex = getLastIndex(pathToNode) + const { callExp, valueUsedInTransform } = createCallback([newVal, newVal]) + pipe.body[callIndex] = callExp + return { + modifiedAst: _node, + pathToNode, + valueUsedInTransform, + } } + + const newLine = createCallExpression('yLine', [ + newVal, + createPipeSubstitution(), + ]) + pipe.body = [...pipe.body, newLine] return { modifiedAst: _node, pathToNode } }, updateArgs: ({ node, pathToNode, to, from }) => { @@ -958,18 +976,23 @@ export const angledLineToY: SketchLineHelper = { ) const angle = createLiteral(roundOff(getAngle(from, to), 0)) const yArg = createLiteral(roundOff(to[1], 2)) - const newLine = createCallback - ? createCallback([angle, yArg]).callExp - : createCallExpression('angledLineToY', [ - createArrayExpression([angle, yArg]), - createPipeSubstitution(), - ]) - const callIndex = getLastIndex(pathToNode) - if (replaceExisting) { - pipe.body[callIndex] = newLine - } else { - pipe.body = [...pipe.body, newLine] + + if (replaceExisting && createCallback) { + const { callExp, valueUsedInTransform } = createCallback([angle, yArg]) + const callIndex = getLastIndex(pathToNode) + pipe.body[callIndex] = callExp + return { + modifiedAst: _node, + pathToNode, + valueUsedInTransform, + } } + + const newLine = createCallExpression('angledLineToY', [ + createArrayExpression([angle, yArg]), + createPipeSubstitution(), + ]) + pipe.body = [...pipe.body, newLine] return { modifiedAst: _node, pathToNode, diff --git a/src/lang/std/sketchcombos.ts b/src/lang/std/sketchcombos.ts index aedcf794a..36aecd8eb 100644 --- a/src/lang/std/sketchcombos.ts +++ b/src/lang/std/sketchcombos.ts @@ -78,6 +78,23 @@ type TransformMap = { } } +const xyLineSetLength = + ( + xOrY: 'xLine' | 'yLine', + referenceSeg = false + ): TransformInfo['createNode'] => + ({ referenceSegName, tag, forceValueUsedInTransform }) => + (args) => { + console.log('args', args) + const segRef = createSegLen(referenceSegName) + const lineVal = forceValueUsedInTransform + ? forceValueUsedInTransform + : referenceSeg + ? segRef + : args[0] + return createCallWrapper(xOrY, lineVal, tag, getArgLiteralVal(args[0])) + } + const basicAngledLineCreateNode = ( referenceSeg: 'ang' | 'len' | 'none' = 'none', @@ -397,6 +414,20 @@ const transformMap: TransformMap = { () => createCallWrapper('yLineTo', varValB, tag), }, + setAngle: { + tooltip: 'angledLineToY', + createNode: + ({ varValB, tag, forceValueUsedInTransform }) => + (args) => { + console.log(getArgLiteralVal(args[0])) + return createCallWrapper( + 'angledLineToY', + [forceValueUsedInTransform || args[0], varValB], + tag, + getArgLiteralVal(args[0]) + ) + }, + }, }, }, angledLine: { @@ -675,8 +706,40 @@ const transformMap: TransformMap = { tooltip: 'xLine', createNode: ({ referenceSegName, tag }) => - () => - createCallWrapper('xLine', createSegLen(referenceSegName), tag), + (arg) => { + const argVal = getArgLiteralVal(arg[0]) + const segLen = createSegLen(referenceSegName) as BinaryPart + const val = argVal > 0 ? segLen : createUnaryExpression(segLen) + return createCallWrapper('xLine', val, tag, argVal) + }, + }, + setHorzDistance: { + tooltip: 'xLineTo', + createNode: ({ referenceSegName, tag, forceValueUsedInTransform }) => { + return (args, referencedSegment) => { + console.log('args', args) + const valueUsedInTransform = roundOff( + getArgLiteralVal(args?.[0]) - (referencedSegment?.to?.[0] || 0), + 2 + ) + const makeBinExp = createBinaryExpression([ + createSegEnd(referenceSegName, true), + '+', + (forceValueUsedInTransform as BinaryPart) || + createLiteral(valueUsedInTransform), + ]) + return createCallWrapper( + 'xLineTo', + makeBinExp, + tag, + valueUsedInTransform + ) + } + }, + }, + setLength: { + tooltip: 'xLine', + createNode: xyLineSetLength('xLine'), }, }, }, @@ -689,6 +752,10 @@ const transformMap: TransformMap = { () => createCallWrapper('yLine', createSegLen(referenceSegName), tag), }, + setLength: { + tooltip: 'yLine', + createNode: xyLineSetLength('yLine'), + }, }, }, xLineTo: {