diff --git a/compiler/ctx.ts b/compiler/ctx.ts index 5d0267b..001378c 100644 --- a/compiler/ctx.ts +++ b/compiler/ctx.ts @@ -1,11 +1,11 @@ import * as ast from "./ast/mod.ts"; -import { Diag } from "./diagnostics.ts"; +import { prettyPrintReport, printStackTrace, Report } from "./diagnostics.ts"; export class Ctx { private fileIds = new Ids(); private files = new Map, FileInfo>(); - private diags: Diag[] = []; + private reports: Report[] = []; public fileHasChildWithIdent(file: File, childIdent: string): boolean { return this.files.get(id(file))! @@ -40,43 +40,23 @@ export class Ctx { } public fileInfo(file: File): FileInfo { - this.files.get(id(file))!; + return this.files.get(id(file))!; } - public reportFatal(file: File, msg: string) { - console.error(`fatal: ${msg}`); - this.reportImmediately(file, msg); + public report(rep: Report) { + this.reports.push(rep); + this.reportImmediately(rep); } 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"); + private reportImmediately(rep: Report) { + if (this.enableReportImmediately) { + prettyPrintReport(this, rep); + if (this.enableStacktrace) { + printStackTrace(); } } - try { - //throw new ReportNotAnError(); - } catch (error) { - if (!(error instanceof StackTracer)) { - throw error; - } - console.log( - error.stack?.replace( - "Error: StackTracer", - "Stack trace:", - ) ?? - error, - ); - } } } diff --git a/compiler/diagnostics.ts b/compiler/diagnostics.ts index 080c030..6170397 100644 --- a/compiler/diagnostics.ts +++ b/compiler/diagnostics.ts @@ -11,7 +11,7 @@ export type Pos = { col: number; }; -export type Diag = { +export type Report = { severity: "fatal" | "error" | "warning" | "info"; origin?: string; msg: string; @@ -20,24 +20,35 @@ export type Diag = { pos?: Pos; }; -export function prettyPrintDiag(ctx: Ctx, diag: Diag) { - const { severity, msg } = diag; - const origin = diag.origin ? `${diag.origin}: ` : ""; +export function prettyPrintReport(ctx: Ctx, rep: Report) { + const { severity, msg } = rep; + const origin = rep.origin ? `${rep.origin}: ` : ""; console.error(`${origin}${severity}: ${msg}`); - if (diag.file && (diag.span || diag.pos)) { - const { absPath: path, text } = ctx.fileInfo(diag.file); - const { line, col } = diag.span?.begin ?? diag.pos!; + if (rep.file && (rep.span || rep.pos)) { + const { absPath: path } = ctx.fileInfo(rep.file); + const { line, col } = rep.span?.begin ?? rep.pos!; console.error(` at ./${path}:${line}:${col}`); - if (diag.span) { - let begin = diag.span.begin.idx; - while (begin >= 0 && text[begin - 1] != "\n") { - begin -= 1; - } - let end = diag.span.end.idx; - while (end < text.length && text[end + 1] != "\n") { - end += 1; - } - } else if (diag.pos) { - } + } +} + +export function printStackTrace() { + class StackTracer extends Error { + constructor() { + super("StackTracer"); + } + } + try { + throw new StackTracer(); + } catch (error) { + if (!(error instanceof StackTracer)) { + throw error; + } + console.log( + error.stack?.replace( + "Error: StackTracer", + "Stack trace:", + ) ?? + error, + ); } } diff --git a/compiler/main.ts b/compiler/main.ts index c0b7153..fb99755 100644 --- a/compiler/main.ts +++ b/compiler/main.ts @@ -61,6 +61,11 @@ export class FileTreeCollector implements ast.Visitor<[_P]> { 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,