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 } {
|
): { value: Value; lastIndex: number } {
|
||||||
const currentToken = tokens[index]
|
const currentToken = tokens[index]
|
||||||
const { token: nextToken } = nextMeaningfulToken(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)
|
const { expression, lastIndex } = makeCallExpression(tokens, index)
|
||||||
return {
|
return {
|
||||||
value: expression,
|
value: expression,
|
||||||
@ -305,8 +306,10 @@ function makeValue(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (
|
if (
|
||||||
(currentToken.type === 'word' || currentToken.type === 'number') &&
|
(currentToken.type === 'word' ||
|
||||||
nextToken.type === 'operator'
|
currentToken.type === 'number' ||
|
||||||
|
currentToken.type === 'string') &&
|
||||||
|
nextToken?.type === 'operator'
|
||||||
) {
|
) {
|
||||||
const { expression, lastIndex } = makeBinaryExpression(tokens, index)
|
const { expression, lastIndex } = makeBinaryExpression(tokens, index)
|
||||||
return {
|
return {
|
||||||
@ -314,6 +317,23 @@ function makeValue(
|
|||||||
lastIndex,
|
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') {
|
if (currentToken.type === 'word') {
|
||||||
const identifier = makeIdentifier(tokens, index)
|
const identifier = makeIdentifier(tokens, index)
|
||||||
return {
|
return {
|
||||||
@ -328,6 +348,23 @@ function makeValue(
|
|||||||
lastIndex: index,
|
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')
|
throw new Error('Expected a previous Value if statement to match')
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -349,7 +386,6 @@ function makeVariableDeclarators(
|
|||||||
const assignmentToken = nextMeaningfulToken(tokens, index)
|
const assignmentToken = nextMeaningfulToken(tokens, index)
|
||||||
const declarationToken = previousMeaningfulToken(tokens, index)
|
const declarationToken = previousMeaningfulToken(tokens, index)
|
||||||
const contentsStartToken = nextMeaningfulToken(tokens, assignmentToken.index)
|
const contentsStartToken = nextMeaningfulToken(tokens, assignmentToken.index)
|
||||||
const nextAfterInit = nextMeaningfulToken(tokens, contentsStartToken.index)
|
|
||||||
const pipeStartIndex =
|
const pipeStartIndex =
|
||||||
assignmentToken?.token?.type === 'operator'
|
assignmentToken?.token?.type === 'operator'
|
||||||
? contentsStartToken.index
|
? contentsStartToken.index
|
||||||
@ -364,33 +400,6 @@ function makeVariableDeclarators(
|
|||||||
)
|
)
|
||||||
init = expression
|
init = expression
|
||||||
lastIndex = pipeLastIndex
|
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 (
|
} else if (
|
||||||
declarationToken.token.type === 'word' &&
|
declarationToken.token.type === 'word' &&
|
||||||
declarationToken.token.value === 'sketch'
|
declarationToken.token.value === 'sketch'
|
||||||
@ -398,29 +407,13 @@ function makeVariableDeclarators(
|
|||||||
const sketchExp = makeSketchExpression(tokens, assignmentToken.index)
|
const sketchExp = makeSketchExpression(tokens, assignmentToken.index)
|
||||||
init = sketchExp.expression
|
init = sketchExp.expression
|
||||||
lastIndex = sketchExp.lastIndex
|
lastIndex = sketchExp.lastIndex
|
||||||
} else if (nextAfterInit.token?.type === 'operator') {
|
} else {
|
||||||
const binExp = makeBinaryExpression(tokens, contentsStartToken.index)
|
const { value, lastIndex: valueLastIndex } = makeValue(
|
||||||
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(
|
|
||||||
tokens,
|
tokens,
|
||||||
contentsStartToken.index
|
contentsStartToken.index
|
||||||
)
|
)
|
||||||
init = arrayExpression.expression
|
init = value
|
||||||
lastIndex = arrayExpression.lastIndex
|
lastIndex = valueLastIndex
|
||||||
} else {
|
|
||||||
init = makeLiteral(tokens, contentsStartToken.index)
|
|
||||||
}
|
}
|
||||||
const currentDeclarator: VariableDeclarator = {
|
const currentDeclarator: VariableDeclarator = {
|
||||||
type: 'VariableDeclarator',
|
type: 'VariableDeclarator',
|
||||||
@ -594,14 +587,18 @@ function makeObjectProperties(
|
|||||||
}
|
}
|
||||||
const colonToken = nextMeaningfulToken(tokens, index)
|
const colonToken = nextMeaningfulToken(tokens, index)
|
||||||
const valueStartToken = nextMeaningfulToken(tokens, colonToken.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 = {
|
let objectProperty: ObjectProperty = {
|
||||||
type: 'ObjectProperty',
|
type: 'ObjectProperty',
|
||||||
start: propertyKeyToken.start,
|
start: propertyKeyToken.start,
|
||||||
end: value.value.end,
|
end: value.end,
|
||||||
key: makeIdentifier(tokens, index),
|
key: makeIdentifier(tokens, index),
|
||||||
value: value.value,
|
value,
|
||||||
}
|
}
|
||||||
const nextKeyToken = nextMeaningfulToken(
|
const nextKeyToken = nextMeaningfulToken(
|
||||||
tokens,
|
tokens,
|
||||||
|
@ -18,7 +18,7 @@ const newVar = myVar + 1`
|
|||||||
const { root } = exe(code)
|
const { root } = exe(code)
|
||||||
expect(root.myVar).toBe('a str')
|
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(
|
const code = fs.readFileSync(
|
||||||
'./src/lang/testExamples/variableDeclaration.cado',
|
'./src/lang/testExamples/variableDeclaration.cado',
|
||||||
'utf-8'
|
'utf-8'
|
||||||
@ -40,7 +40,7 @@ log(5, myVar)`
|
|||||||
expect(root.myVar).toBe('hello')
|
expect(root.myVar).toBe('hello')
|
||||||
expect(programMemoryOverride.log).toHaveBeenCalledWith(5, 'hello')
|
expect(programMemoryOverride.log).toHaveBeenCalledWith(5, 'hello')
|
||||||
})
|
})
|
||||||
it('fn funcN = () => {}', () => {
|
it('fn funcN = () => {} execute', () => {
|
||||||
const { root } = exe(
|
const { root } = exe(
|
||||||
[
|
[
|
||||||
'fn funcN = (a, b) => {',
|
'fn funcN = (a, b) => {',
|
||||||
|
Reference in New Issue
Block a user