mirror of
https://github.com/Noratrieb/riverdelta.git
synced 2026-01-15 00:45:04 +01:00
error recovery!
This commit is contained in:
parent
c0c08488ba
commit
ef04f21100
18 changed files with 799 additions and 366 deletions
|
|
@ -1,27 +1,41 @@
|
|||
import { DepCrate } from "./ast";
|
||||
import { CrateId, DepCrate } from "./ast";
|
||||
import { CrateLoader, GlobalContext } from "./context";
|
||||
import { CompilerError, LoadedFile, Span, withErrorPrinter } from "./error";
|
||||
import { CompilerError, ErrorEmitted, LoadedFile, Span } from "./error";
|
||||
import fs from "fs";
|
||||
import path from "path";
|
||||
import { tokenize } from "./lexer";
|
||||
import { ParseState, parse } from "./parser";
|
||||
import { resolve } from "./resolve";
|
||||
import { typeck } from "./typeck";
|
||||
import { ComplexMap } from "./utils";
|
||||
|
||||
export type LoadResult<T> =
|
||||
| {
|
||||
ok: true;
|
||||
value: T;
|
||||
}
|
||||
| {
|
||||
ok: false;
|
||||
err: CompilerError;
|
||||
};
|
||||
|
||||
export function loadModuleFile(
|
||||
relativeTo: string,
|
||||
moduleName: string,
|
||||
span: Span,
|
||||
): LoadedFile {
|
||||
): LoadResult<LoadedFile> {
|
||||
let searchDir: string;
|
||||
if (relativeTo.endsWith(".mod.nil")) {
|
||||
// x/uwu.mod.nil searches in x/
|
||||
searchDir = path.dirname(relativeTo);
|
||||
} else if (relativeTo.endsWith(".nil")) {
|
||||
throw new CompilerError(
|
||||
`.nil files cannot have submodules. use .mod.nil in a subdirectory`,
|
||||
span,
|
||||
);
|
||||
return {
|
||||
ok: false,
|
||||
err: new CompilerError(
|
||||
`.nil files cannot have submodules. use .mod.nil in a subdirectory`,
|
||||
span,
|
||||
),
|
||||
};
|
||||
} else {
|
||||
searchDir = relativeTo;
|
||||
}
|
||||
|
|
@ -41,13 +55,34 @@ export function loadModuleFile(
|
|||
});
|
||||
|
||||
if (content === undefined || filePath === undefined) {
|
||||
throw new CompilerError(
|
||||
`failed to load ${moduleName}, could not find ${options.join(" or ")}`,
|
||||
span,
|
||||
);
|
||||
return {
|
||||
ok: false,
|
||||
err: new CompilerError(
|
||||
`failed to load ${moduleName}, could not find ${options.join(" or ")}`,
|
||||
span,
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
return { content, path: filePath };
|
||||
return { ok: true, value: { content, path: filePath } };
|
||||
}
|
||||
|
||||
function dummyErrorCrate(
|
||||
id: CrateId,
|
||||
packageName: string,
|
||||
emitted: ErrorEmitted,
|
||||
): DepCrate {
|
||||
return {
|
||||
id,
|
||||
packageName,
|
||||
rootItems: [],
|
||||
itemsById: new ComplexMap(),
|
||||
rootFile: { content: "<dummy>" },
|
||||
fatalError: emitted,
|
||||
typeckResults: {
|
||||
main: undefined,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export const loadCrate: CrateLoader = (
|
||||
|
|
@ -65,27 +100,27 @@ export const loadCrate: CrateLoader = (
|
|||
return existing;
|
||||
}
|
||||
|
||||
return withErrorPrinter(
|
||||
(): DepCrate => {
|
||||
const file = loadModuleFile(".", name, span);
|
||||
const crateId = gcx.crateId.next();
|
||||
|
||||
const crateId = gcx.crateId.next();
|
||||
const file = loadModuleFile(".", name, span);
|
||||
if (!file.ok) {
|
||||
return dummyErrorCrate(crateId, name, gcx.error.emit(file.err));
|
||||
}
|
||||
|
||||
const tokens = tokenize(file);
|
||||
const parseState: ParseState = { tokens, file };
|
||||
const ast = parse(name, parseState, crateId);
|
||||
const resolved = resolve(gcx, ast);
|
||||
const tokens = tokenize(gcx.error, file.value);
|
||||
if (!tokens.ok) {
|
||||
return dummyErrorCrate(crateId, name, tokens.err);
|
||||
}
|
||||
const parseState: ParseState = {
|
||||
tokens: tokens.tokens,
|
||||
file: file.value,
|
||||
gcx,
|
||||
};
|
||||
const ast = parse(name, parseState, crateId);
|
||||
const resolved = resolve(gcx, ast);
|
||||
|
||||
const typecked = typeck(gcx, resolved);
|
||||
const typecked = typeck(gcx, resolved);
|
||||
|
||||
gcx.finalizedCrates.push(typecked);
|
||||
return typecked;
|
||||
},
|
||||
() => {
|
||||
throw new CompilerError(
|
||||
`failed to load crate ${name}: crate contains errors`,
|
||||
span,
|
||||
);
|
||||
},
|
||||
);
|
||||
gcx.finalizedCrates.push(typecked);
|
||||
return typecked;
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue