slige/compiler/compiler.ts

184 lines
5.6 KiB
TypeScript
Raw Normal View History

import { AstCreator, Mod, Stmt } from "./ast.ts";
2024-12-15 00:07:36 +01:00
import { Checker } from "./checker.ts";
import { CompoundAssignDesugarer } from "./desugar/compound_assign.ts";
2024-12-31 03:38:38 +01:00
import { StructLiteralDesugarer } from "./desugar/struct_literal.ts";
2024-12-15 00:07:36 +01:00
import { SpecialLoopDesugarer } from "./desugar/special_loop.ts";
import { Reporter } from "./info.ts";
import { Lexer } from "./lexer.ts";
2024-12-26 01:51:05 +01:00
import { Monomorphizer } from "./mono.ts";
2024-12-26 02:38:32 +01:00
import { FnNamesMap, Lowerer } from "./lowerer.ts";
2024-12-15 00:07:36 +01:00
import { Parser } from "./parser.ts";
import { Resolver } from "./resolver.ts";
import { AstVisitor, VisitRes, visitStmts } from "./ast_visitor.ts";
import { Pos } from "./token.ts";
2024-12-31 03:38:38 +01:00
import { ArrayLiteralDesugarer } from "./desugar/array_literal.ts";
2025-01-03 01:15:05 +01:00
import { mirOpCount, printMir } from "./middle/mir.ts";
2024-12-15 00:07:36 +01:00
2025-01-02 09:14:24 +01:00
import * as path from "jsr:@std/path";
2025-01-03 01:15:05 +01:00
import { lowerAst } from "./middle/lower_ast.ts";
import { eliminateUnusedLocals } from "./middle/elim_unused_local.ts";
import {
eliminateOnlyChildsBlocks,
eliminateUnreachableBlocks,
} from "./middle/elim_blocks.ts";
2025-01-17 07:44:53 +01:00
import { checkBorrows } from "./middle/borrow_checker.ts";
import { makeMoveCopyExplicit } from "./middle/explicit_move_copy.ts";
2025-01-02 09:14:24 +01:00
2024-12-15 00:07:36 +01:00
export type CompileResult = {
program: number[];
fnNames: FnNamesMap;
};
export class Compiler {
private astCreator = new AstCreator();
2024-12-29 05:39:22 +01:00
private reporter;
2024-12-15 00:07:36 +01:00
2024-12-29 05:39:22 +01:00
public constructor(private startFilePath: string) {
this.reporter = new Reporter(this.startFilePath);
}
2024-12-15 00:07:36 +01:00
public async compile(): Promise<CompileResult> {
2025-01-02 09:14:24 +01:00
const { ast } = new ModTree(
2024-12-29 05:39:22 +01:00
this.startFilePath,
this.astCreator,
this.reporter,
).resolve();
2024-12-15 00:07:36 +01:00
2025-01-02 09:14:24 +01:00
new SpecialLoopDesugarer(this.astCreator).desugar(ast);
new ArrayLiteralDesugarer(this.astCreator).desugar(ast);
new StructLiteralDesugarer(this.astCreator).desugar(ast);
new Resolver(this.reporter).resolve(ast);
new CompoundAssignDesugarer(this.astCreator).desugar(ast);
2024-12-15 00:07:36 +01:00
2025-01-02 09:14:24 +01:00
new Checker(this.reporter).check(ast);
2024-12-15 00:07:36 +01:00
2025-01-17 07:44:53 +01:00
//const mir = lowerAst(ast);
//
//console.log("Before optimizations:");
//printMir(mir);
//const mirHistory = [mirOpCount(mir)];
//for (let i = 0; i < 1; ++i) {
// eliminateUnusedLocals(mir, this.reporter, mirHistory.length === 1);
// eliminateOnlyChildsBlocks(mir);
// eliminateUnreachableBlocks(mir);
// eliminateTransientVals(mir);
//
// const opCount = mirOpCount(mir);
// const histOccurence = mirHistory
// .filter((v) => v === opCount).length;
// if (histOccurence >= 2) {
// break;
// }
// mirHistory.push(opCount);
//}
//
//console.log("After optimizations:");
//printMir(mir);
2024-12-15 00:07:36 +01:00
if (this.reporter.errorOccured()) {
console.error("Errors occurred, stopping compilation.");
Deno.exit(1);
}
2025-01-17 07:44:53 +01:00
const mir = lowerAst(ast);
2024-12-29 05:39:22 +01:00
2025-01-17 07:44:53 +01:00
makeMoveCopyExplicit(mir);
checkBorrows(mir, this.reporter);
2024-12-26 01:51:05 +01:00
2025-01-17 07:44:53 +01:00
printMir(mir);
2024-12-15 00:07:36 +01:00
2025-01-17 07:44:53 +01:00
//const { monoFns, callMap } = new Monomorphizer(ast).monomorphize();
//
//const lastPos = await lastPosInTextFile(this.startFilePath);
//
//const lowerer = new Lowerer(monoFns, callMap, lastPos);
//const { program, fnNames } = lowerer.lower();
////lowerer.printProgram();
//
//return { program, fnNames };
return { program: [], fnNames: {} };
2024-12-15 00:07:36 +01:00
}
}
2024-12-29 05:39:22 +01:00
export class ModTree implements AstVisitor<[string]> {
constructor(
private entryFilePath: string,
private astCreator: AstCreator,
private reporter: Reporter,
) {}
public resolve(): Mod {
const entryAst = this.parseFile(this.entryFilePath);
visitStmts(entryAst, this, this.entryFilePath);
2024-12-29 05:39:22 +01:00
return { filePath: this.entryFilePath, ast: entryAst };
2024-12-29 05:39:22 +01:00
}
private parseFile(filePath: string): Stmt[] {
2024-12-29 05:39:22 +01:00
const text = Deno.readTextFileSync(filePath);
const lexer = new Lexer(text, this.reporter);
const parser = new Parser(lexer, this.astCreator, this.reporter);
const ast = parser.parse();
return ast;
}
visitModBlockStmt(stmt: Stmt, filePath: string): VisitRes {
if (stmt.kind.type !== "mod_block") {
throw new Error();
}
const { ident, stmts: ast } = stmt.kind;
2024-12-29 05:39:22 +01:00
stmt.kind = {
type: "mod",
ident,
mod: { filePath, ast },
2024-12-29 05:39:22 +01:00
};
visitStmts(ast, this, filePath);
2024-12-29 05:39:22 +01:00
return "stop";
}
visitModFileStmt(stmt: Stmt, filePath: string): VisitRes {
if (stmt.kind.type !== "mod_file") {
throw new Error();
}
const { ident, filePath: modFilePath } = stmt.kind;
const ast = this.parseFile(
2024-12-31 00:54:58 +01:00
ident === "std"
? path.join(
path.dirname(path.fromFileUrl(Deno.mainModule)),
"../std/lib.slg",
)
: path.join(path.dirname(filePath), modFilePath),
2024-12-29 05:39:22 +01:00
);
2024-12-31 00:54:58 +01:00
stmt.kind = { type: "mod", ident, mod: { filePath, ast } };
visitStmts(ast, this, filePath);
2024-12-29 05:39:22 +01:00
return "stop";
}
}
async function lastPosInTextFile(filePath: string): Promise<Pos> {
const text = await Deno.readTextFile(filePath);
let index = 0;
let line = 1;
let col = 1;
while (index < text.length) {
if (text[index] == "\n") {
line += 1;
col = 1;
} else {
col += 1;
}
index += 1;
}
return { index, line, col };
}