refactor makeValue and makeDeclatator to reduce code duplication

This commit is contained in:
Kurt Hutten IrevDev
2023-01-02 12:18:54 +11:00
parent dbf8a993e5
commit d2a4bb7851
3 changed files with 190 additions and 57 deletions

View File

@ -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'",
},
],
},
},
],
},
},
],
},
])
})
})

View File

@ -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,

View File

@ -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) => {',