slige/compiler/ctx.ts
2025-01-22 22:40:29 +01:00

108 lines
2.6 KiB
TypeScript

import * as ast from "./ast/mod.ts";
import { Diag } from "./diagnostics.ts";
export class Ctx {
private fileIds = new Ids();
private files = new Map<Id<File>, FileInfo>();
private diags: Diag[] = [];
public fileHasChildWithIdent(file: File, childIdent: string): boolean {
return this.files.get(id(file))!
.subFiles.has(childIdent);
}
public addFile(
ident: string,
absPath: string,
relPath: string,
superFile: File | undefined,
text: string,
): File {
const file = this.fileIds.nextThenStep();
this.files.set(id(file), {
ident,
absPath,
relPath,
superFile,
subFiles: new Map(),
text,
});
if (superFile) {
this.files.get(id(superFile))!
.subFiles.set(ident, file);
}
return file;
}
public addFileAst(file: File, ast: ast.File) {
this.files.get(id(file))!.ast = ast;
}
public fileInfo(file: File): FileInfo {
this.files.get(id(file))!;
}
public reportFatal(file: File, msg: string) {
console.error(`fatal: ${msg}`);
this.reportImmediately(file, msg);
}
public enableReportImmediately = false;
public enableStacktrace = false;
private reportImmediately(file: File, msg: string) {
if (!this.enableReportImmediately) {
return;
}
if (!this.enableStacktrace) {
return;
}
class StackTracer extends Error {
constructor() {
super("StackTracer");
}
}
try {
//throw new ReportNotAnError();
} catch (error) {
if (!(error instanceof StackTracer)) {
throw error;
}
console.log(
error.stack?.replace(
"Error: StackTracer",
"Stack trace:",
) ??
error,
);
}
}
}
export type File = IdBase;
export type FileInfo = {
ident: string;
absPath: string;
relPath: string;
superFile?: File;
subFiles: Map<string, File>;
text: string;
ast?: ast.File;
};
export type IdBase = { id: number };
export type Id<IdType extends IdBase> = IdType["id"];
export const id = <IdType extends IdBase>(id: IdType): Id<IdType> => id.id;
export class Ids<IdType extends IdBase> {
private next = 0;
public nextThenStep(): IdType {
const id = this.next;
this.next += 1;
return { id } as IdType;
}
}