use reporter
Some checks failed
Check / Explore-Gitea-Actions (push) Failing after 8s

This commit is contained in:
sfja 2026-03-16 22:01:54 +01:00
parent d908ff30e0
commit 4d7998eb9f
6 changed files with 95 additions and 52 deletions

View File

@ -1,6 +1,71 @@
export class Reporter {
report() {}
private reports: Report[] = [];
private errorOccured = false;
report(report: Report) {
if (report.severity === "error") {
this.errorOccured = true;
}
this.reports.push(report);
}
ok(): boolean {
return !this.errorOccured;
}
printAll() {
for (const report of this.reports) {
printReport(report);
}
}
abort(): never {
this.printAll();
console.error("fatal: a fatal error occured");
Deno.exit(1);
}
ofFile(file: FileInfo): FileReporter {
return new FileReporter(this, file);
}
}
export class FileReporter {
constructor(
private reporter: Reporter,
private file: FileInfo,
) {}
error(loc: Loc, message: string) {
this.reporter.report({
severity: "error",
file: this.file,
loc,
message,
});
}
info(loc: Loc, message: string) {
this.reporter.report({
severity: "info",
file: this.file,
loc,
message,
});
}
abort(): never {
this.reporter.abort();
}
}
export type Report = {
severity: Severity;
file: FileInfo;
loc: Loc;
message: string;
};
export type Severity = "error" | "info";
export type Loc = {
idx: number;
@ -13,14 +78,9 @@ export type FileInfo = {
text: string;
};
export function printDiagnostics(
filename: string,
loc: Loc,
severity: "error" | "info",
message: string,
text?: string,
) {
const line = loc.line;
function printReport(report: Report) {
const { severity, file: { filename, text }, message, loc } = report;
const { line, col } = loc;
const severityColor = ({
"error": "red",
@ -49,12 +109,12 @@ export function printDiagnostics(
`${" ".repeat(lineNumberText.length)}%c|\n` +
`${lineNumberText}|%c${lineText}\n` +
`${" ".repeat(lineNumberText.length)}%c|` +
`%c${"~".repeat(lineText.length)}\n` +
`${" ".repeat(col - 1)}%c^\n` +
`${" ".repeat(lineNumberText.length)}%c|%c`,
"color: cyan;",
"color: lightwhite;",
"color: cyan;",
`color: ${severityColor};`,
`color: ${severityColor}; font-weight: bold;`,
"color: cyan;",
"",
);

View File

@ -1,5 +1,5 @@
import * as ast from "../ast.ts";
import { Loc, printDiagnostics } from "../diagnostics.ts";
import { FileReporter, Loc } from "../diagnostics.ts";
import { Ty } from "../ty.ts";
import { builtins } from "./builtins.ts";
import { ResolveMap } from "./resolve.ts";
@ -14,10 +14,8 @@ export class Checker {
private nodeTys = new Map<number, Ty>();
constructor(
private filename: string,
private text: string,
private file: ast.Node,
private resols: ResolveMap,
private reporter: FileReporter,
) {}
check(node: ast.Node): Ty {
@ -338,27 +336,15 @@ export class Checker {
}
private error(loc: Loc, message: string) {
printDiagnostics(
this.filename,
loc,
"error",
message,
this.text,
);
this.reporter.error(loc, message);
}
private info(loc: Loc, message: string) {
printDiagnostics(
this.filename,
loc,
"info",
message,
this.text,
);
this.reporter.info(loc, message);
}
private fail(): never {
Deno.exit(1);
this.reporter.abort();
}
}

View File

@ -1,11 +1,11 @@
import * as ast from "../ast.ts";
import { Loc, printDiagnostics } from "../diagnostics.ts";
import { FileReporter, Loc } from "../diagnostics.ts";
export function parse(
filename: string,
text: string,
reporter: FileReporter,
): ast.Node {
return new Parser(filename, text).parseFile();
return new Parser(text, reporter).parseFile();
}
export class Parser {
@ -15,8 +15,8 @@ export class Parser {
private prevTok: Tok | null = null;
constructor(
private filename: string,
private text: string,
private reporter: FileReporter,
) {
this.toks = tokenize(text);
}
@ -334,9 +334,8 @@ export class Parser {
}
private error(message: string, loc: Loc): never {
printDiagnostics(this.filename, loc, "error", message, this.text);
throw new Error();
Deno.exit(1);
this.reporter.error(loc, message);
this.reporter.abort();
}
private eat(type: string): boolean {

View File

@ -1,5 +1,5 @@
import * as ast from "../ast.ts";
import { printDiagnostics } from "../diagnostics.ts";
import { FileReporter } from "../diagnostics.ts";
import { builtins } from "./builtins.ts";
export class ResolveMap {
@ -33,9 +33,8 @@ export type Sym =
};
export function resolve(
filename: string,
text: string,
file: ast.Node,
reporter: FileReporter,
): ResolveMap {
let syms = ResolverSyms.root();
const resols = new Map<number, Sym>();
@ -81,14 +80,8 @@ export function resolve(
if (k.tag === "IdentExpr") {
const sym = syms.resolveExpr(k.ident);
if (sym === null) {
printDiagnostics(
filename,
node.loc,
"error",
`undefined symbol '${k.ident}'`,
text,
);
Deno.exit(1);
reporter.error(node.loc, `undefined symbol '${k.ident}'`);
reporter.abort();
}
resols.set(node.id, sym);
}

View File

@ -1,14 +1,19 @@
import * as ast from "./ast.ts";
import { Reporter } from "./diagnostics.ts";
import * as front from "./front/mod.ts";
import * as middle from "./middle.ts";
import { FnInterpreter } from "./mir_interpreter.ts";
const reporter = new Reporter();
const filename = Deno.args[0];
const text = await Deno.readTextFile(filename);
const fileAst = front.parse(filename, text);
const resols = front.resolve(filename, text, fileAst);
const checker = new front.Checker(filename, text, fileAst, resols);
const fileRep = reporter.ofFile({ filename, text });
const fileAst = front.parse(text, fileRep);
const resols = front.resolve(fileAst, fileRep);
const checker = new front.Checker(resols, fileRep);
let mainFn: ast.NodeWithKind<"FnStmt"> | null = null;

View File

@ -1,7 +1,7 @@
fn main()
{
let array: [int; 3] = [1, 2, 3];
let array: [int; 3] = [1, 2, false];
// let a = 4;
// let b = a;