move rt to separate file and make loader understand it

This commit is contained in:
nora 2023-08-02 20:19:14 +02:00
parent 309a286a1a
commit a1d04d264e
5 changed files with 100 additions and 61 deletions

View file

@ -13,7 +13,6 @@ import { GlobalContext, parseArgs } from "./context";
import { loadCrate } from "./loader";
const INPUT = `
extern mod a;
type A = { a: Int };
function main() = (

View file

@ -13,9 +13,22 @@ export function loadModuleFile(
moduleName: string,
span: Span
): 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
);
} else {
searchDir = relativeTo;
}
const options = [
path.join(relativeTo, `${moduleName}.nil`),
path.join(relativeTo, moduleName, `${moduleName}.mod.nil`),
path.join(searchDir, `${moduleName}.nil`),
path.join(searchDir, moduleName, `${moduleName}.mod.nil`),
];
let content: string | undefined = undefined;
@ -45,15 +58,17 @@ export const loadCrate: CrateLoader = (
// We really, really want a good algorithm for finding crates.
// But right now we just look for files in the CWD.
const existing = gcx.finalizedCrates.find((crate) => crate.packageName === name);
const existing = gcx.finalizedCrates.find(
(crate) => crate.packageName === name
);
if (existing) {
return existing;
}
const file = loadModuleFile(".", name, span);
return withErrorPrinter(
(): DepCrate => {
const file = loadModuleFile(".", name, span);
const crateId = gcx.crateId.next();
const tokens = tokenize(file);

View file

@ -33,7 +33,14 @@ import {
StructLiteralField,
} from "./ast";
import { CompilerError, LoadedFile, Span } from "./error";
import { BaseToken, Token, TokenIdent, TokenLitString } from "./lexer";
import {
BaseToken,
Token,
TokenIdent,
TokenLitString,
tokenize,
} from "./lexer";
import { loadModuleFile } from "./loader";
import { ComplexMap, ComplexSet, Ids } from "./utils";
export type ParseState = { tokens: Token[]; file: LoadedFile };
@ -46,6 +53,16 @@ export function parse(
t: State,
crateId: number
): Crate<Built> {
const [, items] = parseItems(t);
const ast: Crate<Built> = buildCrate(packageName, items, crateId, t.file);
validateAst(ast);
return ast;
}
function parseItems(t: State): [State, Item<Parsed>[]] {
const items: Item<Parsed>[] = [];
while (t.tokens.length > 0) {
@ -54,11 +71,7 @@ export function parse(
items.push(item);
}
const ast: Crate<Built> = buildCrate(packageName, items, crateId, t.file);
validateAst(ast);
return ast;
return [t, items];
}
function parseItem(t: State): [State, Item<Parsed>] {
@ -165,18 +178,32 @@ function parseItem(t: State): [State, Item<Parsed>] {
let name;
[t, name] = expectNext<TokenIdent>(t, "identifier");
[t] = expectNext(t, "(");
let contents: Item<Parsed>[] = [];
const contents: Item<Parsed>[] = [];
let popen = undefined;
[t, popen] = eat(t, "(");
if (popen) {
while (peekKind(t) !== ")") {
let item;
[t, item] = parseItem(t);
while (peekKind(t) !== ")") {
let item;
[t, item] = parseItem(t);
contents.push(item);
}
contents.push(item);
[t] = expectNext(t, ")");
} else {
if (name.span.file.path === undefined) {
throw new CompilerError(
`no known source file for statement, cannot load file relative to it`,
name.span
);
}
const file = loadModuleFile(name.span.file.path, name.ident, name.span);
const tokens = tokenize(file);
[, contents] = parseItems({ file, tokens });
}
[t] = expectNext(t, ")");
[t] = expectNext(t, ";");
const node: ModItem<Parsed> = {