add variable declaration with binary expressions
This commit is contained in:
@ -1,25 +1,40 @@
|
|||||||
import { recast } from "./recast";
|
import { recast } from './recast'
|
||||||
import { Program } from "./abstractSyntaxTree";
|
import { Program } from './abstractSyntaxTree'
|
||||||
import { abstractSyntaxTree } from "./abstractSyntaxTree";
|
import { abstractSyntaxTree } from './abstractSyntaxTree'
|
||||||
import { lexer } from "./tokeniser";
|
import { lexer } from './tokeniser'
|
||||||
import { Token } from "./tokeniser";
|
import { Token } from './tokeniser'
|
||||||
|
|
||||||
describe("recast", () => {
|
describe('recast', () => {
|
||||||
it("recasts a simple program", () => {
|
it('recasts a simple program', () => {
|
||||||
const code = "1 + 2";
|
const code = '1 + 2'
|
||||||
const {ast, tokens } = code2ast(code);
|
const { ast } = code2ast(code)
|
||||||
const recasted = recast(ast);
|
const recasted = recast(ast)
|
||||||
expect(recasted).toBe(code);
|
expect(recasted).toBe(code)
|
||||||
});
|
})
|
||||||
});
|
it('variable declaration', () => {
|
||||||
|
const code = 'const myVar = 5'
|
||||||
|
const { ast } = code2ast(code)
|
||||||
|
const recasted = recast(ast)
|
||||||
|
expect(recasted).toBe(code)
|
||||||
|
})
|
||||||
|
it("variable declaration that's binary with string", () => {
|
||||||
|
const code = "const myVar = 5 + 'yo'"
|
||||||
|
const { ast } = code2ast(code)
|
||||||
|
const recasted = recast(ast)
|
||||||
|
expect(recasted).toBe(code)
|
||||||
|
const codeWithOtherQuotes = 'const myVar = 5 + "yo"'
|
||||||
|
const { ast: ast2 } = code2ast(codeWithOtherQuotes)
|
||||||
|
expect(recast(ast2)).toBe(codeWithOtherQuotes)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
// helpers
|
// helpers
|
||||||
|
|
||||||
function code2ast(code: string): { ast: Program; tokens: Token[]} {
|
function code2ast(code: string): { ast: Program; tokens: Token[] } {
|
||||||
const tokens = lexer(code);
|
const tokens = lexer(code)
|
||||||
const ast = abstractSyntaxTree(tokens);
|
const ast = abstractSyntaxTree(tokens)
|
||||||
return {
|
return {
|
||||||
ast,
|
ast,
|
||||||
tokens
|
tokens,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,27 +1,46 @@
|
|||||||
import { Program, BinaryExpression, BinaryPart } from "./abstractSyntaxTree";
|
import { Program, BinaryExpression, BinaryPart } from './abstractSyntaxTree'
|
||||||
|
|
||||||
export function recast(ast: Program, previousWrittenCode = ''): string {
|
export function recast(ast: Program, previousWrittenCode = ''): string {
|
||||||
return ast.body
|
return ast.body
|
||||||
.map((statement) => {
|
.map((statement) => {
|
||||||
if(statement.type === "ExpressionStatement") {
|
if (statement.type === 'ExpressionStatement') {
|
||||||
if(statement.expression.type === "BinaryExpression") {
|
if (statement.expression.type === 'BinaryExpression') {
|
||||||
return recastBinaryExpression(statement.expression);
|
return recastBinaryExpression(statement.expression)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return statement.type;
|
} else if (statement.type === 'VariableDeclaration') {
|
||||||
|
return statement.declarations
|
||||||
|
.map((declaration) => {
|
||||||
|
if (declaration.init.type === 'BinaryExpression') {
|
||||||
|
return `${statement.kind} ${
|
||||||
|
declaration.id.name
|
||||||
|
} = ${recastBinaryExpression(declaration.init)}`
|
||||||
|
} else if (declaration.init.type === 'Literal') {
|
||||||
|
return `${statement.kind} ${declaration.id.name} = ${declaration.init.value}`
|
||||||
|
}
|
||||||
|
return ''
|
||||||
|
})
|
||||||
|
.join('')
|
||||||
|
}
|
||||||
|
return statement.type
|
||||||
})
|
})
|
||||||
.join("\n");
|
.join('\n')
|
||||||
}
|
}
|
||||||
|
|
||||||
function recastBinaryExpression(expression: BinaryExpression): string {
|
function recastBinaryExpression(expression: BinaryExpression): string {
|
||||||
return `${recastBinaryPart(expression.left)} ${expression.operator} ${recastBinaryPart(expression.right)}`
|
return `${recastBinaryPart(expression.left)} ${
|
||||||
|
expression.operator
|
||||||
|
} ${recastBinaryPart(expression.right)}`
|
||||||
}
|
}
|
||||||
|
|
||||||
function recastBinaryPart(part: BinaryPart): string {
|
function recastBinaryPart(part: BinaryPart): string {
|
||||||
if(part.type === "Literal") {
|
if (part.type === 'Literal') {
|
||||||
return String(part?.value);
|
if (typeof part.value === 'string') {
|
||||||
} else if(part.type === "Identifier") {
|
const quote = part.raw.includes('"') ? '"' : "'"
|
||||||
return part.name;
|
return `${quote}${part.value}${quote}`
|
||||||
}
|
}
|
||||||
throw new Error(`Cannot recast ${part}`);
|
return String(part?.value)
|
||||||
|
} else if (part.type === 'Identifier') {
|
||||||
|
return part.name
|
||||||
|
}
|
||||||
|
throw new Error(`Cannot recast ${part}`)
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user