refactor makeValue and makeDeclatator to reduce code duplication
This commit is contained in:
		| @ -1214,4 +1214,140 @@ describe('testing pipe operator special', () => { | ||||
|       }, | ||||
|     ]) | ||||
|   }) | ||||
|   test('nested object expression ast', () => { | ||||
|     const code = `const yo = {key: { | ||||
|   key2: 'value' | ||||
| }}` | ||||
|     const tokens = lexer(code) | ||||
|     const { body } = abstractSyntaxTree(tokens) | ||||
|     expect(body).toEqual([ | ||||
|       { | ||||
|         type: 'VariableDeclaration', | ||||
|         start: 0, | ||||
|         end: 37, | ||||
|         kind: 'const', | ||||
|         declarations: [ | ||||
|           { | ||||
|             type: 'VariableDeclarator', | ||||
|             start: 6, | ||||
|             end: 37, | ||||
|             id: { | ||||
|               type: 'Identifier', | ||||
|               start: 6, | ||||
|               end: 8, | ||||
|               name: 'yo', | ||||
|             }, | ||||
|             init: { | ||||
|               type: 'ObjectExpression', | ||||
|               start: 11, | ||||
|               end: 37, | ||||
|               properties: [ | ||||
|                 { | ||||
|                   type: 'ObjectProperty', | ||||
|                   start: 12, | ||||
|                   end: 36, | ||||
|                   key: { | ||||
|                     type: 'Identifier', | ||||
|                     start: 12, | ||||
|                     end: 15, | ||||
|                     name: 'key', | ||||
|                   }, | ||||
|                   value: { | ||||
|                     type: 'ObjectExpression', | ||||
|                     start: 17, | ||||
|                     end: 36, | ||||
|                     properties: [ | ||||
|                       { | ||||
|                         type: 'ObjectProperty', | ||||
|                         start: 21, | ||||
|                         end: 34, | ||||
|                         key: { | ||||
|                           type: 'Identifier', | ||||
|                           start: 21, | ||||
|                           end: 25, | ||||
|                           name: 'key2', | ||||
|                         }, | ||||
|                         value: { | ||||
|                           type: 'Literal', | ||||
|                           start: 27, | ||||
|                           end: 34, | ||||
|                           value: 'value', | ||||
|                           raw: "'value'", | ||||
|                         }, | ||||
|                       }, | ||||
|                     ], | ||||
|                   }, | ||||
|                 }, | ||||
|               ], | ||||
|             }, | ||||
|           }, | ||||
|         ], | ||||
|       }, | ||||
|     ]) | ||||
|   }) | ||||
|   test('object expression with array ast', () => { | ||||
|     const code = `const yo = {key: [1, '2']}` | ||||
|     const tokens = lexer(code) | ||||
|     const { body } = abstractSyntaxTree(tokens) | ||||
|     expect(body).toEqual([ | ||||
|       { | ||||
|         type: 'VariableDeclaration', | ||||
|         start: 0, | ||||
|         end: 26, | ||||
|         kind: 'const', | ||||
|         declarations: [ | ||||
|           { | ||||
|             type: 'VariableDeclarator', | ||||
|             start: 6, | ||||
|             end: 26, | ||||
|             id: { | ||||
|               type: 'Identifier', | ||||
|               start: 6, | ||||
|               end: 8, | ||||
|               name: 'yo', | ||||
|             }, | ||||
|             init: { | ||||
|               type: 'ObjectExpression', | ||||
|               start: 11, | ||||
|               end: 26, | ||||
|               properties: [ | ||||
|                 { | ||||
|                   type: 'ObjectProperty', | ||||
|                   start: 12, | ||||
|                   end: 25, | ||||
|                   key: { | ||||
|                     type: 'Identifier', | ||||
|                     start: 12, | ||||
|                     end: 15, | ||||
|                     name: 'key', | ||||
|                   }, | ||||
|                   value: { | ||||
|                     type: 'ArrayExpression', | ||||
|                     start: 17, | ||||
|                     end: 25, | ||||
|                     elements: [ | ||||
|                       { | ||||
|                         type: 'Literal', | ||||
|                         start: 18, | ||||
|                         end: 19, | ||||
|                         value: 1, | ||||
|                         raw: '1', | ||||
|                       }, | ||||
|                       { | ||||
|                         type: 'Literal', | ||||
|                         start: 21, | ||||
|                         end: 24, | ||||
|                         value: '2', | ||||
|                         raw: "'2'", | ||||
|                       }, | ||||
|                     ], | ||||
|                   }, | ||||
|                 }, | ||||
|               ], | ||||
|             }, | ||||
|           }, | ||||
|         ], | ||||
|       }, | ||||
|     ]) | ||||
|   }) | ||||
| }) | ||||
|  | ||||
| @ -297,7 +297,8 @@ function makeValue( | ||||
| ): { value: Value; lastIndex: number } { | ||||
|   const currentToken = tokens[index] | ||||
|   const { token: nextToken } = nextMeaningfulToken(tokens, index) | ||||
|   if (nextToken.type === 'brace' && nextToken.value === '(') { | ||||
|   // nextToken might be empty if it's at the end of the file | ||||
|   if (nextToken?.type === 'brace' && nextToken.value === '(') { | ||||
|     const { expression, lastIndex } = makeCallExpression(tokens, index) | ||||
|     return { | ||||
|       value: expression, | ||||
| @ -305,8 +306,10 @@ function makeValue( | ||||
|     } | ||||
|   } | ||||
|   if ( | ||||
|     (currentToken.type === 'word' || currentToken.type === 'number') && | ||||
|     nextToken.type === 'operator' | ||||
|     (currentToken.type === 'word' || | ||||
|       currentToken.type === 'number' || | ||||
|       currentToken.type === 'string') && | ||||
|     nextToken?.type === 'operator' | ||||
|   ) { | ||||
|     const { expression, lastIndex } = makeBinaryExpression(tokens, index) | ||||
|     return { | ||||
| @ -314,6 +317,23 @@ function makeValue( | ||||
|       lastIndex, | ||||
|     } | ||||
|   } | ||||
|   if (currentToken.type === 'brace' && currentToken.value === '{') { | ||||
|     const objExp = makeObjectExpression(tokens, index) | ||||
|     return { | ||||
|       value: objExp.expression, | ||||
|       lastIndex: objExp.lastIndex, | ||||
|     } | ||||
|   } | ||||
|   if (currentToken.type === 'brace' && currentToken.value === '[') { | ||||
|     const arrExp = makeArrayExpression(tokens, index) | ||||
|     return { | ||||
|       value: arrExp.expression, | ||||
|       lastIndex: arrExp.lastIndex, | ||||
|     } | ||||
|   } | ||||
|   if (currentToken.type === 'word' && nextToken.type === 'period') { | ||||
|     // TODO object access | ||||
|   } | ||||
|   if (currentToken.type === 'word') { | ||||
|     const identifier = makeIdentifier(tokens, index) | ||||
|     return { | ||||
| @ -328,6 +348,23 @@ function makeValue( | ||||
|       lastIndex: index, | ||||
|     } | ||||
|   } | ||||
|   if (currentToken.type === 'brace' && currentToken.value === '(') { | ||||
|     const closingBraceIndex = findClosingBrace(tokens, index) | ||||
|     const arrowToken = nextMeaningfulToken(tokens, closingBraceIndex) | ||||
|     if ( | ||||
|       arrowToken.token.type === 'operator' && | ||||
|       arrowToken.token.value === '=>' | ||||
|     ) { | ||||
|       const { expression, lastIndex: arrowFunctionLastIndex } = | ||||
|         makeFunctionExpression(tokens, index) | ||||
|       return { | ||||
|         value: expression, | ||||
|         lastIndex: arrowFunctionLastIndex, | ||||
|       } | ||||
|     } else { | ||||
|       throw new Error('TODO - handle expression with braces') | ||||
|     } | ||||
|   } | ||||
|   throw new Error('Expected a previous Value if statement to match') | ||||
| } | ||||
|  | ||||
| @ -349,7 +386,6 @@ function makeVariableDeclarators( | ||||
|   const assignmentToken = nextMeaningfulToken(tokens, index) | ||||
|   const declarationToken = previousMeaningfulToken(tokens, index) | ||||
|   const contentsStartToken = nextMeaningfulToken(tokens, assignmentToken.index) | ||||
|   const nextAfterInit = nextMeaningfulToken(tokens, contentsStartToken.index) | ||||
|   const pipeStartIndex = | ||||
|     assignmentToken?.token?.type === 'operator' | ||||
|       ? contentsStartToken.index | ||||
| @ -364,33 +400,6 @@ function makeVariableDeclarators( | ||||
|     ) | ||||
|     init = expression | ||||
|     lastIndex = pipeLastIndex | ||||
|   } else if ( | ||||
|     contentsStartToken.token.type === 'brace' && | ||||
|     contentsStartToken.token.value === '(' | ||||
|   ) { | ||||
|     const closingBraceIndex = findClosingBrace(tokens, contentsStartToken.index) | ||||
|     const arrowToken = nextMeaningfulToken(tokens, closingBraceIndex) | ||||
|     if ( | ||||
|       arrowToken.token.type === 'operator' && | ||||
|       arrowToken.token.value === '=>' | ||||
|     ) { | ||||
|       const { expression, lastIndex: arrowFunctionLastIndex } = | ||||
|         makeFunctionExpression(tokens, contentsStartToken.index) | ||||
|       init = expression | ||||
|       lastIndex = arrowFunctionLastIndex | ||||
|     } else { | ||||
|       throw new Error('TODO - handle expression with braces') | ||||
|     } | ||||
|   } else if ( | ||||
|     contentsStartToken.token.type === 'brace' && | ||||
|     contentsStartToken.token.value === '{' | ||||
|   ) { | ||||
|     const objectExpression = makeObjectExpression( | ||||
|       tokens, | ||||
|       contentsStartToken.index | ||||
|     ) | ||||
|     init = objectExpression.expression | ||||
|     lastIndex = objectExpression.lastIndex | ||||
|   } else if ( | ||||
|     declarationToken.token.type === 'word' && | ||||
|     declarationToken.token.value === 'sketch' | ||||
| @ -398,29 +407,13 @@ function makeVariableDeclarators( | ||||
|     const sketchExp = makeSketchExpression(tokens, assignmentToken.index) | ||||
|     init = sketchExp.expression | ||||
|     lastIndex = sketchExp.lastIndex | ||||
|   } else if (nextAfterInit.token?.type === 'operator') { | ||||
|     const binExp = makeBinaryExpression(tokens, contentsStartToken.index) | ||||
|     init = binExp.expression | ||||
|     lastIndex = binExp.lastIndex | ||||
|   } else if ( | ||||
|     nextAfterInit.token?.type === 'brace' && | ||||
|     nextAfterInit.token.value === '(' | ||||
|   ) { | ||||
|     const callExInfo = makeCallExpression(tokens, contentsStartToken.index) | ||||
|     init = callExInfo.expression | ||||
|     lastIndex = callExInfo.lastIndex | ||||
|   } else if ( | ||||
|     contentsStartToken.token.type === 'brace' && | ||||
|     contentsStartToken.token.value === '[' | ||||
|   ) { | ||||
|     const arrayExpression = makeArrayExpression( | ||||
|   } else { | ||||
|     const { value, lastIndex: valueLastIndex } = makeValue( | ||||
|       tokens, | ||||
|       contentsStartToken.index | ||||
|     ) | ||||
|     init = arrayExpression.expression | ||||
|     lastIndex = arrayExpression.lastIndex | ||||
|   } else { | ||||
|     init = makeLiteral(tokens, contentsStartToken.index) | ||||
|     init = value | ||||
|     lastIndex = valueLastIndex | ||||
|   } | ||||
|   const currentDeclarator: VariableDeclarator = { | ||||
|     type: 'VariableDeclarator', | ||||
| @ -594,14 +587,18 @@ function makeObjectProperties( | ||||
|   } | ||||
|   const colonToken = nextMeaningfulToken(tokens, index) | ||||
|   const valueStartToken = nextMeaningfulToken(tokens, colonToken.index) | ||||
|   const value = makeValue(tokens, valueStartToken.index) | ||||
|   const commaOrClosingBraceToken = nextMeaningfulToken(tokens, value.lastIndex) | ||||
|  | ||||
|   const val = makeValue(tokens, valueStartToken.index) | ||||
|  | ||||
|   const value = val.value | ||||
|   const valueLastIndex = val.lastIndex | ||||
|   const commaOrClosingBraceToken = nextMeaningfulToken(tokens, valueLastIndex) | ||||
|   let objectProperty: ObjectProperty = { | ||||
|     type: 'ObjectProperty', | ||||
|     start: propertyKeyToken.start, | ||||
|     end: value.value.end, | ||||
|     end: value.end, | ||||
|     key: makeIdentifier(tokens, index), | ||||
|     value: value.value, | ||||
|     value, | ||||
|   } | ||||
|   const nextKeyToken = nextMeaningfulToken( | ||||
|     tokens, | ||||
|  | ||||
| @ -18,7 +18,7 @@ const newVar = myVar + 1` | ||||
|     const { root } = exe(code) | ||||
|     expect(root.myVar).toBe('a str') | ||||
|   }) | ||||
|   it('test assigning a var by cont concatenating two strings string', () => { | ||||
|   it('test assigning a var by cont concatenating two strings string execute', () => { | ||||
|     const code = fs.readFileSync( | ||||
|       './src/lang/testExamples/variableDeclaration.cado', | ||||
|       'utf-8' | ||||
| @ -40,7 +40,7 @@ log(5, myVar)` | ||||
|     expect(root.myVar).toBe('hello') | ||||
|     expect(programMemoryOverride.log).toHaveBeenCalledWith(5, 'hello') | ||||
|   }) | ||||
|   it('fn funcN = () => {}', () => { | ||||
|   it('fn funcN = () => {} execute', () => { | ||||
|     const { root } = exe( | ||||
|       [ | ||||
|         'fn funcN = (a, b) => {', | ||||
|  | ||||
		Reference in New Issue
	
	Block a user