mirror of
https://github.com/Noratrieb/riverdelta.git
synced 2026-01-15 00:45:04 +01:00
some stuff
This commit is contained in:
parent
ef32e646d6
commit
91b183c002
11 changed files with 4320 additions and 101 deletions
74
src/error.ts
Normal file
74
src/error.ts
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
export type Span = {
|
||||
start: number;
|
||||
end: number;
|
||||
};
|
||||
|
||||
export class CompilerError extends Error {
|
||||
msg: string;
|
||||
span: Span;
|
||||
|
||||
constructor(msg: string, span: Span) {
|
||||
super(msg);
|
||||
this.msg = msg;
|
||||
this.span = span;
|
||||
}
|
||||
}
|
||||
|
||||
export function withErrorHandler(input: string, f: () => void) {
|
||||
try {
|
||||
f();
|
||||
} catch (e) {
|
||||
if (e instanceof CompilerError) {
|
||||
renderError(input, e);
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function renderError(input: string, e: CompilerError) {
|
||||
const lineSpans = lines(input);
|
||||
const line =
|
||||
e.span.start === Number.MAX_SAFE_INTEGER
|
||||
? lineSpans[lineSpans.length - 1]
|
||||
: lineSpans.find(
|
||||
(line) => line.start <= e.span.start && line.end >= e.span.start
|
||||
);
|
||||
if (!line) {
|
||||
throw Error(`Span out of bounds: ${e.span.start}..${e.span.end}`);
|
||||
}
|
||||
const lineIdx = lineSpans.indexOf(line);
|
||||
console.error(`error: ${e.message}`);
|
||||
|
||||
console.error(`${lineIdx} | ${spanToSnippet(input, line)}`);
|
||||
const startRelLine =
|
||||
e.span.start === Number.MAX_SAFE_INTEGER ? 0 : e.span.start - line.start;
|
||||
console.error(
|
||||
`${" ".repeat(String(lineIdx).length)} ${" ".repeat(startRelLine)}^`
|
||||
);
|
||||
}
|
||||
|
||||
function spanToSnippet(input: string, span: Span): string {
|
||||
if (span.start === Number.MAX_SAFE_INTEGER) {
|
||||
return "";
|
||||
}
|
||||
return input.slice(span.start, span.end);
|
||||
}
|
||||
|
||||
export function lines(input: string): Span[] {
|
||||
const lines: Span[] = [{ start: 0, end: 0 }];
|
||||
|
||||
for (let i = 0; i < input.length; i++) {
|
||||
if (input[i] === "\n") {
|
||||
lines.push({ start: i + 1, end: i + 1 });
|
||||
} else {
|
||||
lines[lines.length - 1].end++;
|
||||
}
|
||||
}
|
||||
|
||||
return lines;
|
||||
}
|
||||
|
||||
export function todo(msg: string, span: Span): never {
|
||||
throw new CompilerError(`TODO: ${msg}`, span);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue