initial recast setup

This commit is contained in:
Kurt Hutten IrevDev
2022-11-26 08:00:18 +11:00
parent ca020e14eb
commit e300cf4a76
2 changed files with 52 additions and 0 deletions

25
src/lang/recast.test.ts Normal file
View File

@ -0,0 +1,25 @@
import { recast } from "./recast";
import { Program } from "./abstractSyntaxTree";
import { abstractSyntaxTree } from "./abstractSyntaxTree";
import { lexer } from "./tokeniser";
import { Token } from "./tokeniser";
describe("recast", () => {
it("recasts a simple program", () => {
const code = "1 + 2";
const {ast, tokens } = code2ast(code);
const recasted = recast(ast);
expect(recasted).toBe(code);
});
});
// helpers
function code2ast(code: string): { ast: Program; tokens: Token[]} {
const tokens = lexer(code);
const ast = abstractSyntaxTree(tokens);
return {
ast,
tokens
}
}

27
src/lang/recast.ts Normal file
View File

@ -0,0 +1,27 @@
import { Program, BinaryExpression, BinaryPart } from "./abstractSyntaxTree";
export function recast(ast: Program, previousWrittenCode = ''): string {
return ast.body
.map((statement) => {
if(statement.type === "ExpressionStatement") {
if(statement.expression.type === "BinaryExpression") {
return recastBinaryExpression(statement.expression);
}
}
return statement.type;
})
.join("\n");
}
function recastBinaryExpression(expression: BinaryExpression): string {
return `${recastBinaryPart(expression.left)} ${expression.operator} ${recastBinaryPart(expression.right)}`
}
function recastBinaryPart(part: BinaryPart): string {
if(part.type === "Literal") {
return String(part?.value);
} else if(part.type === "Identifier") {
return part.name;
}
throw new Error(`Cannot recast ${part}`);
}