mirror of
https://github.com/Noratrieb/riverdelta.git
synced 2026-01-14 16:35:03 +01:00
refactor file loading
This commit is contained in:
parent
beb0321382
commit
7eeaf548d0
9 changed files with 236 additions and 193 deletions
147
src/index.ts
147
src/index.ts
|
|
@ -1,16 +1,16 @@
|
|||
import { CompilerError, Span, withErrorPrinter } from "./error";
|
||||
import { LoadedFile, withErrorPrinter } from "./error";
|
||||
import { isValidIdent, tokenize } from "./lexer";
|
||||
import { lower as lowerToWasm } from "./lower";
|
||||
import { parse } from "./parser";
|
||||
import { ParseState, parse } from "./parser";
|
||||
import { printAst } from "./printer";
|
||||
import { resolve } from "./resolve";
|
||||
import { typeck } from "./typeck";
|
||||
import { writeModuleWatToString } from "./wasm/wat";
|
||||
import fs from "fs";
|
||||
import path from "path";
|
||||
import { exec } from "child_process";
|
||||
import { Crate, Built, Typecked, DepCrate } from "./ast";
|
||||
import { GlobalContext, CrateLoader } from "./context";
|
||||
import { Crate, Built, Typecked } from "./ast";
|
||||
import { GlobalContext, parseArgs } from "./context";
|
||||
import { loadCrate } from "./loader";
|
||||
|
||||
const INPUT = `
|
||||
extern mod std;
|
||||
|
|
@ -33,70 +33,9 @@ function linkStd() = (
|
|||
);
|
||||
`;
|
||||
|
||||
type Config = {
|
||||
input: string;
|
||||
filename: string;
|
||||
packageName: string;
|
||||
debug: Set<string>;
|
||||
noOutput: boolean;
|
||||
};
|
||||
|
||||
function parseArgs(): Config {
|
||||
let filename: string;
|
||||
let input: string;
|
||||
let packageName: string;
|
||||
let debug = new Set<string>();
|
||||
let noOutput = false;
|
||||
|
||||
if (process.argv.length > 2) {
|
||||
filename = process.argv[2];
|
||||
if (path.extname(filename) !== ".nil") {
|
||||
console.error(process.argv);
|
||||
|
||||
console.error(
|
||||
`error: filename must have \`.nil\` extension: \`${filename}\``
|
||||
);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
input = fs.readFileSync(filename, { encoding: "utf-8" });
|
||||
packageName = path.basename(filename, ".nil");
|
||||
|
||||
const debugArg = process.argv.find((arg) => arg.startsWith("--debug="));
|
||||
if (debugArg !== undefined) {
|
||||
const debugs = debugArg.slice("--debug=".length);
|
||||
debug = new Set(debugs.split(","));
|
||||
}
|
||||
|
||||
if (process.argv.some((arg) => arg === "--no-output")) {
|
||||
noOutput = true;
|
||||
}
|
||||
} else {
|
||||
filename = "<hardcoded>";
|
||||
input = INPUT;
|
||||
packageName = "test";
|
||||
debug = new Set([
|
||||
"tokens",
|
||||
"parsed",
|
||||
"resolved",
|
||||
"typecked",
|
||||
"wat",
|
||||
"wasm-validate",
|
||||
]);
|
||||
}
|
||||
|
||||
return {
|
||||
filename,
|
||||
input,
|
||||
packageName,
|
||||
debug,
|
||||
noOutput,
|
||||
};
|
||||
}
|
||||
|
||||
function main() {
|
||||
const config = parseArgs();
|
||||
const { filename, packageName, input, debug } = config;
|
||||
const opts = parseArgs(INPUT);
|
||||
const { filename, packageName, input, debug } = opts;
|
||||
|
||||
if (!isValidIdent(packageName)) {
|
||||
console.error(
|
||||
|
|
@ -105,22 +44,24 @@ function main() {
|
|||
process.exit(1);
|
||||
}
|
||||
|
||||
const gcx = new GlobalContext(loadCrate);
|
||||
const file: LoadedFile = { path: filename, content: input };
|
||||
|
||||
const gcx = new GlobalContext(opts, loadCrate);
|
||||
const mainCrate = gcx.crateId.next();
|
||||
|
||||
withErrorPrinter(
|
||||
input,
|
||||
filename,
|
||||
() => {
|
||||
const start = Date.now();
|
||||
|
||||
const tokens = tokenize(input);
|
||||
const tokens = tokenize(file);
|
||||
if (debug.has("tokens")) {
|
||||
console.log("-----TOKENS------------");
|
||||
console.log(tokens);
|
||||
}
|
||||
|
||||
const ast: Crate<Built> = parse(packageName, tokens, mainCrate);
|
||||
const parseState: ParseState = { tokens, file };
|
||||
|
||||
const ast: Crate<Built> = parse(packageName, parseState, mainCrate);
|
||||
if (debug.has("ast")) {
|
||||
console.log("-----AST---------------");
|
||||
|
||||
|
|
@ -160,7 +101,7 @@ function main() {
|
|||
console.log(moduleStringColor);
|
||||
}
|
||||
|
||||
if (!config.noOutput) {
|
||||
if (!opts.noOutput) {
|
||||
fs.writeFileSync("out.wat", moduleString);
|
||||
}
|
||||
|
||||
|
|
@ -189,62 +130,4 @@ function main() {
|
|||
);
|
||||
}
|
||||
|
||||
const loadCrate: CrateLoader = (
|
||||
gcx: GlobalContext,
|
||||
name: string,
|
||||
span: Span
|
||||
): DepCrate => {
|
||||
// We really, really want a good algorithm for finding crates.
|
||||
// But right now we just look for files in the CWD.
|
||||
|
||||
const existing = gcx.depCrates.find((crate) => crate.packageName === name);
|
||||
if (existing) {
|
||||
return existing;
|
||||
}
|
||||
|
||||
const options = [`${name}.nil`, `${name}/${name}.mod.nil`];
|
||||
|
||||
let input: string | undefined = undefined;
|
||||
let filename: string | undefined = undefined;
|
||||
options.forEach((tryName) => {
|
||||
try {
|
||||
input = fs.readFileSync(tryName, { encoding: "utf-8" });
|
||||
filename = tryName;
|
||||
} catch (e) {}
|
||||
});
|
||||
|
||||
if (input === undefined || filename === undefined) {
|
||||
throw new CompilerError(
|
||||
`failed to load ${name}, could not find ${options.join(" or ")}`,
|
||||
span
|
||||
);
|
||||
}
|
||||
|
||||
const inputString: string = input;
|
||||
|
||||
return withErrorPrinter(
|
||||
inputString,
|
||||
filename,
|
||||
(): DepCrate => {
|
||||
const crateId = gcx.crateId.next();
|
||||
|
||||
const tokens = tokenize(inputString);
|
||||
const ast = parse(name, tokens, crateId);
|
||||
const resolved = resolve(gcx, ast);
|
||||
console.log(resolved);
|
||||
|
||||
const typecked = typeck(gcx, resolved);
|
||||
|
||||
gcx.depCrates.push(typecked);
|
||||
return typecked;
|
||||
},
|
||||
() => {
|
||||
throw new CompilerError(
|
||||
`failed to load crate ${name}: crate contains errors`,
|
||||
span
|
||||
);
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
main();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue