mirror of
https://github.com/Noratrieb/riverdelta.git
synced 2026-01-14 16:35:03 +01:00
Add basic testsuite using ui_test
This commit is contained in:
parent
1551847d8c
commit
b68d775671
13 changed files with 1524 additions and 79 deletions
15
src/error.ts
15
src/error.ts
|
|
@ -11,7 +11,10 @@ export function spanMerge(a: Span, b: Span): Span {
|
|||
}
|
||||
|
||||
export const DUMMY_SPAN = { start: 0, end: 0 };
|
||||
export const EOF_SPAN = {start: Number.MAX_SAFE_INTEGER, end: Number.MAX_SAFE_INTEGER};
|
||||
export const EOF_SPAN = {
|
||||
start: Number.MAX_SAFE_INTEGER,
|
||||
end: Number.MAX_SAFE_INTEGER,
|
||||
};
|
||||
|
||||
export class CompilerError extends Error {
|
||||
msg: string;
|
||||
|
|
@ -24,16 +27,18 @@ export class CompilerError extends Error {
|
|||
}
|
||||
}
|
||||
|
||||
export function withErrorPrinter(
|
||||
export function withErrorPrinter<R>(
|
||||
input: string,
|
||||
filename: string,
|
||||
f: () => void
|
||||
): void {
|
||||
f: () => R,
|
||||
afterError: (e: CompilerError) => R
|
||||
): R {
|
||||
try {
|
||||
f();
|
||||
return f();
|
||||
} catch (e) {
|
||||
if (e instanceof CompilerError) {
|
||||
renderError(input, filename, e);
|
||||
return afterError(e);
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
|
|
|
|||
212
src/index.ts
212
src/index.ts
|
|
@ -33,13 +33,26 @@ function linkStd() = (
|
|||
);
|
||||
`;
|
||||
|
||||
function main() {
|
||||
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}\``
|
||||
);
|
||||
|
|
@ -48,12 +61,43 @@ function main() {
|
|||
|
||||
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;
|
||||
|
||||
if (!isValidIdent(packageName)) {
|
||||
console.error(
|
||||
`error: package name \`${packageName}\` is not a valid identifer`
|
||||
|
|
@ -61,62 +105,85 @@ function main() {
|
|||
process.exit(1);
|
||||
}
|
||||
|
||||
console.log(`package name: '${packageName}'`);
|
||||
withErrorPrinter(
|
||||
input,
|
||||
filename,
|
||||
() => {
|
||||
const start = Date.now();
|
||||
|
||||
withErrorPrinter(input, filename, () => {
|
||||
const start = Date.now();
|
||||
|
||||
const tokens = tokenize(input);
|
||||
console.log("-----TOKENS------------");
|
||||
console.log(tokens);
|
||||
|
||||
const ast: Crate<Built> = parse(packageName, tokens, 0);
|
||||
console.log("-----AST---------------");
|
||||
|
||||
console.dir(ast.rootItems, { depth: 50 });
|
||||
|
||||
console.log("-----AST pretty--------");
|
||||
const printed = printAst(ast);
|
||||
console.log(printed);
|
||||
|
||||
console.log("-----AST resolved------");
|
||||
const [resolved, crates] = resolve(ast, loadCrate);
|
||||
const resolvedPrinted = printAst(resolved);
|
||||
console.log(resolvedPrinted);
|
||||
|
||||
console.log("-----AST typecked------");
|
||||
const typecked: Crate<Typecked> = typeck(resolved, crates);
|
||||
const typeckPrinted = printAst(typecked);
|
||||
console.log(typeckPrinted);
|
||||
|
||||
console.log("-----wasm--------------");
|
||||
const wasmModule = lowerToWasm([typecked, ...crates]);
|
||||
const moduleStringColor = writeModuleWatToString(wasmModule, true);
|
||||
const moduleString = writeModuleWatToString(wasmModule);
|
||||
|
||||
console.log(moduleStringColor);
|
||||
|
||||
fs.writeFileSync("out.wat", moduleString);
|
||||
|
||||
console.log("--validate wasm-tools--");
|
||||
|
||||
exec("wasm-tools validate out.wat", (error, stdout, stderr) => {
|
||||
if (error && error.code === 1) {
|
||||
console.log(stderr);
|
||||
} else if (error) {
|
||||
console.error(`failed to spawn wasm-tools: ${error.message}`);
|
||||
} else {
|
||||
if (stderr) {
|
||||
console.log(stderr);
|
||||
}
|
||||
if (stdout) {
|
||||
console.log(stdout);
|
||||
}
|
||||
const tokens = tokenize(input);
|
||||
if (debug.has("tokens")) {
|
||||
console.log("-----TOKENS------------");
|
||||
console.log(tokens);
|
||||
}
|
||||
|
||||
console.log(`finished in ${Date.now() - start}ms`);
|
||||
});
|
||||
});
|
||||
const ast: Crate<Built> = parse(packageName, tokens, 0);
|
||||
if (debug.has("ast")) {
|
||||
console.log("-----AST---------------");
|
||||
|
||||
console.dir(ast.rootItems, { depth: 50 });
|
||||
|
||||
console.log("-----AST pretty--------");
|
||||
const printed = printAst(ast);
|
||||
console.log(printed);
|
||||
}
|
||||
|
||||
if (debug.has("resolved")) {
|
||||
console.log("-----AST resolved------");
|
||||
}
|
||||
const [resolved, crates] = resolve(ast, loadCrate);
|
||||
if (debug.has("resolved")) {
|
||||
const resolvedPrinted = printAst(resolved);
|
||||
console.log(resolvedPrinted);
|
||||
}
|
||||
|
||||
if (debug.has("typecked")) {
|
||||
console.log("-----AST typecked------");
|
||||
}
|
||||
const typecked: Crate<Typecked> = typeck(resolved, crates);
|
||||
if (debug.has("typecked")) {
|
||||
const typeckPrinted = printAst(typecked);
|
||||
console.log(typeckPrinted);
|
||||
}
|
||||
|
||||
if (debug.has("wat")) {
|
||||
console.log("-----wasm--------------");
|
||||
}
|
||||
const wasmModule = lowerToWasm([typecked, ...crates]);
|
||||
const moduleStringColor = writeModuleWatToString(wasmModule, true);
|
||||
const moduleString = writeModuleWatToString(wasmModule);
|
||||
|
||||
if (debug.has("wat")) {
|
||||
console.log(moduleStringColor);
|
||||
}
|
||||
|
||||
if (!config.noOutput) {
|
||||
fs.writeFileSync("out.wat", moduleString);
|
||||
}
|
||||
|
||||
if (debug.has("wasm-validate")) {
|
||||
console.log("--validate wasm-tools--");
|
||||
|
||||
exec("wasm-tools validate out.wat", (error, stdout, stderr) => {
|
||||
if (error && error.code === 1) {
|
||||
console.log(stderr);
|
||||
} else if (error) {
|
||||
console.error(`failed to spawn wasm-tools: ${error.message}`);
|
||||
} else {
|
||||
if (stderr) {
|
||||
console.log(stderr);
|
||||
}
|
||||
if (stdout) {
|
||||
console.log(stdout);
|
||||
}
|
||||
}
|
||||
|
||||
console.log(`finished in ${Date.now() - start}ms`);
|
||||
});
|
||||
}
|
||||
},
|
||||
() => process.exit(1)
|
||||
);
|
||||
}
|
||||
|
||||
function loadCrate(
|
||||
|
|
@ -134,7 +201,7 @@ function loadCrate(
|
|||
}
|
||||
|
||||
const filename = `${name}.nil`;
|
||||
let input;
|
||||
let input: string;
|
||||
try {
|
||||
input = fs.readFileSync(filename, { encoding: "utf-8" });
|
||||
} catch (e) {
|
||||
|
|
@ -144,24 +211,25 @@ function loadCrate(
|
|||
);
|
||||
}
|
||||
|
||||
try {
|
||||
const tokens = tokenize(input);
|
||||
const ast = parse(name, tokens, crateId.next());
|
||||
const [resolved, crates] = resolve(ast, loadCrate);
|
||||
console.log(resolved);
|
||||
|
||||
return withErrorPrinter(
|
||||
input,
|
||||
filename,
|
||||
() => {
|
||||
const tokens = tokenize(input);
|
||||
const ast = parse(name, tokens, crateId.next());
|
||||
const [resolved, crates] = resolve(ast, loadCrate);
|
||||
console.log(resolved);
|
||||
|
||||
const typecked = typeck(resolved, [...existingCrates, ...crates]);
|
||||
return [typecked, crates];
|
||||
} catch (e) {
|
||||
withErrorPrinter(input, filename, () => {
|
||||
throw e;
|
||||
});
|
||||
throw new CompilerError(
|
||||
`failed to load crate ${name}: crate contains errors`,
|
||||
span
|
||||
);
|
||||
}
|
||||
const typecked = typeck(resolved, [...existingCrates, ...crates]);
|
||||
return [typecked, crates];
|
||||
},
|
||||
() => {
|
||||
throw new CompilerError(
|
||||
`failed to load crate ${name}: crate contains errors`,
|
||||
span
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
main();
|
||||
|
|
|
|||
|
|
@ -101,8 +101,6 @@ function appendData(cx: Context, newData: Uint8Array): number {
|
|||
});
|
||||
return 0;
|
||||
} else {
|
||||
console.log("appending", newData);
|
||||
|
||||
const data = datas[0];
|
||||
const idx = data.init.length;
|
||||
const init = new Uint8Array(data.init.length + newData.length);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue