66 lines
1.7 KiB
TypeScript
66 lines
1.7 KiB
TypeScript
import * as ast from "./ast.ts";
|
|
import { selectFnInstructions } from "./codegen/x86_64/isel.ts";
|
|
import { Reporter } from "./diagnostics.ts";
|
|
import * as front from "./front/mod.ts";
|
|
import * as middle from "./middle.ts";
|
|
import * as mir from "./mir.ts";
|
|
import { FnInterpreter } from "./mir_interpreter.ts";
|
|
import * as stringify from "./stringify.ts";
|
|
|
|
const reporter = new Reporter();
|
|
|
|
const filename = Deno.args[0];
|
|
const text = await Deno.readTextFile(filename);
|
|
|
|
const fileRep = reporter.ofFile({ filename, text });
|
|
|
|
const fileAst = front.parse(text, fileRep);
|
|
const syms = front.resolve(fileAst, fileRep);
|
|
|
|
let mainFn: ast.NodeWithKind<"FnStmt"> | null = null;
|
|
|
|
fileAst.visit({
|
|
visit(node) {
|
|
if (node.kind.tag === "FnStmt" && node.kind.ident === "main") {
|
|
if (mainFn) {
|
|
console.error("error: multiple 'main' functions");
|
|
Deno.exit(1);
|
|
}
|
|
|
|
ast.assertNodeWithKind(node, "FnStmt");
|
|
mainFn = node;
|
|
}
|
|
},
|
|
});
|
|
|
|
if (!mainFn) {
|
|
console.error("error: no 'main' function");
|
|
Deno.exit(1);
|
|
}
|
|
|
|
const checker = new front.Checker(syms, fileRep);
|
|
const fnTys = checker.checkFn(mainFn);
|
|
|
|
const m = new middle.MiddleLowerer(syms, checker);
|
|
const mainMiddleFn = m.lowerFn(mainFn);
|
|
|
|
if (Deno.args.includes("--print-mir")) {
|
|
for (const fn of m.allFns()) {
|
|
stringify.printWithConsoleColors(fn.pretty(stringify.consoleColors));
|
|
}
|
|
}
|
|
|
|
const result = selectFnInstructions(mainMiddleFn);
|
|
if (Deno.args.includes("--print-isel")) {
|
|
stringify.printWithConsoleColors(
|
|
stringify.x86_64FnPretty(result, stringify.consoleColors),
|
|
);
|
|
}
|
|
|
|
if (!reporter.ok()) {
|
|
reporter.printAll();
|
|
Deno.exit(1);
|
|
}
|
|
|
|
new FnInterpreter(mainMiddleFn, []).eval();
|