mirror of
https://git.sfja.dk/Mikkel/slige.git
synced 2025-01-30 22:00:52 +00:00
82 lines
2.1 KiB
TypeScript
82 lines
2.1 KiB
TypeScript
import * as path from "jsr:@std/path";
|
|
import { Parser } from "./parser/parser.ts";
|
|
import * as ast from "./ast/mod.ts";
|
|
import { Ctx } from "./ctx.ts";
|
|
import { File } from "./ctx.ts";
|
|
|
|
export type Pack = {
|
|
rootMod: Mod;
|
|
};
|
|
|
|
export type Mod = null;
|
|
|
|
export interface PackEmitter {
|
|
emit(pack: Pack): void;
|
|
}
|
|
|
|
export class PackCompiler {
|
|
public constructor(
|
|
private entryFilePath: string,
|
|
private emitter: PackEmitter,
|
|
) {}
|
|
|
|
public compile() {
|
|
}
|
|
}
|
|
|
|
type _P = { file: File };
|
|
export class FileTreeCollector implements ast.Visitor<[_P]> {
|
|
private subFilePromise = Promise.resolve();
|
|
|
|
public constructor(
|
|
private ctx: Ctx,
|
|
private superFile: File | undefined,
|
|
private ident: string,
|
|
private absPath: string,
|
|
private relPath: string,
|
|
) {}
|
|
|
|
public async collect(): Promise<void> {
|
|
const text = await Deno.readTextFile(this.absPath);
|
|
const file = this.ctx.addFile(
|
|
this.ident,
|
|
this.absPath,
|
|
this.relPath,
|
|
this.superFile,
|
|
text,
|
|
);
|
|
const fileAst = new Parser(file, text).parse();
|
|
this.ctx.addFileAst(file, fileAst);
|
|
ast.visitFile(this, fileAst, { file });
|
|
await this.subFilePromise;
|
|
}
|
|
|
|
visitModFileStmt(
|
|
_stmt: ast.Stmt,
|
|
kind: ast.ModFileStmt,
|
|
{ file }: _P,
|
|
): ast.VisitRes {
|
|
const { ident, filePath: relPath } = kind;
|
|
const absPath = path.join(path.dirname(this.absPath), relPath);
|
|
this.subFilePromise = this.subFilePromise
|
|
.then(() => {
|
|
if (this.ctx.fileHasChildWithIdent(file, ident)) {
|
|
this.ctx.report({
|
|
severity: "fatal",
|
|
msg: `module '${ident}' already declared`,
|
|
file,
|
|
});
|
|
}
|
|
return new FileTreeCollector(
|
|
this.ctx,
|
|
file,
|
|
ident,
|
|
absPath,
|
|
relPath,
|
|
)
|
|
.collect();
|
|
});
|
|
return "stop";
|
|
}
|
|
}
|