mirror of
https://github.com/Noratrieb/riverdelta.git
synced 2026-01-14 16:35:03 +01:00
write prInt
This commit is contained in:
parent
d9868e3111
commit
7f65dc0277
8 changed files with 155 additions and 40 deletions
|
|
@ -300,6 +300,7 @@ export const BUILTINS = [
|
|||
"Bool",
|
||||
"true",
|
||||
"false",
|
||||
"trap",
|
||||
// Intrinsics:
|
||||
"__i32_store",
|
||||
"__i64_store",
|
||||
|
|
|
|||
|
|
@ -47,16 +47,17 @@ function renderError(input: string, e: CompilerError) {
|
|||
throw Error(`Span out of bounds: ${e.span.start}..${e.span.end}`);
|
||||
}
|
||||
const lineIdx = lineSpans.indexOf(line);
|
||||
const lineNo = lineIdx + 1;
|
||||
console.error(`error: ${e.message}`);
|
||||
|
||||
console.error(`${lineIdx} | ${spanToSnippet(input, line)}`);
|
||||
console.error(`${lineNo} | ${spanToSnippet(input, line)}`);
|
||||
const startRelLine =
|
||||
e.span.start === Number.MAX_SAFE_INTEGER ? 0 : e.span.start - line.start;
|
||||
|
||||
const spanLength = min(e.span.end, line.end) - e.span.start;
|
||||
|
||||
console.error(
|
||||
`${" ".repeat(String(lineIdx).length)} ${" ".repeat(
|
||||
`${" ".repeat(String(lineNo).length)} ${" ".repeat(
|
||||
startRelLine
|
||||
)}${"^".repeat(spanLength)}`
|
||||
);
|
||||
|
|
|
|||
79
src/index.ts
79
src/index.ts
|
|
@ -9,23 +9,84 @@ import { writeModuleWatToString } from "./wasm/wat";
|
|||
import fs from "fs";
|
||||
import { exec } from "child_process";
|
||||
|
||||
const input = `
|
||||
const INPUT = `
|
||||
function main() = (
|
||||
prInt(0);
|
||||
prInt(1);
|
||||
prInt(9);
|
||||
prInt(10);
|
||||
prInt(100);
|
||||
prIntln(0);
|
||||
prIntln(1);
|
||||
prIntln(9);
|
||||
prIntln(2352353);
|
||||
prIntln(100);
|
||||
);
|
||||
|
||||
function prInt(a: Int) = (
|
||||
|
||||
function prIntln(x: Int) = (
|
||||
prInt(x);
|
||||
print("\n");
|
||||
);
|
||||
|
||||
function uwu(): (Int, Int) = (0, 0);
|
||||
function stringForDigit(x: Int): String =
|
||||
if x == 0 then "0"
|
||||
else if x == 1 then "1"
|
||||
else if x == 2 then "2"
|
||||
else if x == 3 then "3"
|
||||
else if x == 4 then "4"
|
||||
else if x == 5 then "5"
|
||||
else if x == 6 then "6"
|
||||
else if x == 7 then "7"
|
||||
else if x == 8 then "8"
|
||||
else if x == 9 then "9"
|
||||
else trap();
|
||||
|
||||
function log10(x: Int): Int = (
|
||||
let i = 0;
|
||||
loop (
|
||||
if x < 10 then break;
|
||||
i = i + 1;
|
||||
x = x / 10;
|
||||
);
|
||||
i
|
||||
);
|
||||
|
||||
function pow(base: Int, exp: Int): Int = (
|
||||
let acc = 1;
|
||||
loop (
|
||||
if exp == 0 then break;
|
||||
acc = acc * base;
|
||||
exp = exp - 1;
|
||||
);
|
||||
acc
|
||||
);
|
||||
|
||||
function prInt(x: Int) = (
|
||||
let mag = log10(x);
|
||||
|
||||
loop (
|
||||
if mag == 0 then break;
|
||||
let base = pow(10, mag);
|
||||
|
||||
let digit = x / base;
|
||||
print(stringForDigit(digit));
|
||||
|
||||
x = x % base;
|
||||
mag = mag - 1;
|
||||
);
|
||||
|
||||
print(stringForDigit(x % 10));
|
||||
);
|
||||
|
||||
function println(s: String) = (
|
||||
print(s);
|
||||
print("\n");
|
||||
);
|
||||
`;
|
||||
|
||||
function main() {
|
||||
let input: string;
|
||||
if (process.argv.length > 2) {
|
||||
input = fs.readFileSync(process.argv[2], { encoding: "utf-8" });
|
||||
} else {
|
||||
input = INPUT;
|
||||
}
|
||||
|
||||
withErrorHandler(input, () => {
|
||||
const start = Date.now();
|
||||
|
||||
|
|
|
|||
|
|
@ -203,6 +203,7 @@ type FuncContext = {
|
|||
cx: Context;
|
||||
item: Item;
|
||||
func: FunctionDef;
|
||||
wasmType: wasm.FuncType;
|
||||
wasm: wasm.Func;
|
||||
varLocations: VarLocation[];
|
||||
loopDepths: Map<LoopId, number>;
|
||||
|
|
@ -231,6 +232,7 @@ function lowerFunc(cx: Context, item: Item, func: FunctionDef) {
|
|||
cx,
|
||||
item,
|
||||
func,
|
||||
wasmType,
|
||||
wasm: wasmFunc,
|
||||
varLocations: paramLocations,
|
||||
loopDepths: new Map(),
|
||||
|
|
@ -265,7 +267,7 @@ function lowerExpr(fcx: FuncContext, instrs: wasm.Instr[], expr: Expr) {
|
|||
lowerExpr(fcx, instrs, expr.rhs);
|
||||
const types = wasmTypeForBody(expr.rhs.ty!);
|
||||
|
||||
const local = fcx.wasm.locals.length;
|
||||
const local = fcx.wasm.locals.length + fcx.wasmType.params.length;
|
||||
|
||||
fcx.wasm.locals.push(...types);
|
||||
|
||||
|
|
@ -498,6 +500,10 @@ function lowerExpr(fcx: FuncContext, instrs: wasm.Instr[], expr: Expr) {
|
|||
|
||||
if (expr.lhs.value.res!.kind === "builtin") {
|
||||
switch (expr.lhs.value.res!.name) {
|
||||
case "trap": {
|
||||
instrs.push({ kind: "unreachable" });
|
||||
break exprKind;
|
||||
}
|
||||
case "__i32_load": {
|
||||
lowerExpr(fcx, instrs, expr.args[0]);
|
||||
instrs.push({ kind: "i64.load", imm: {} });
|
||||
|
|
|
|||
|
|
@ -61,6 +61,8 @@ function typeOfBuiltinValue(name: BuiltinName, span: Span): Ty {
|
|||
return TY_BOOL;
|
||||
case "print":
|
||||
return mkTyFn([TY_STRING], TY_UNIT);
|
||||
case "trap":
|
||||
return mkTyFn([], TY_NEVER);
|
||||
case "__i32_store":
|
||||
return mkTyFn([TY_I32, TY_I32], TY_UNIT);
|
||||
case "__i64_store":
|
||||
|
|
|
|||
|
|
@ -541,11 +541,13 @@ function printImport(import_: Import, f: Formatter) {
|
|||
});
|
||||
}
|
||||
|
||||
function printFunction(func: Func, f: Formatter) {
|
||||
function printFunction(func: Func, idx: number, f: Formatter) {
|
||||
f.sexpr(() => {
|
||||
f.keyword("func");
|
||||
printId(func._name, f);
|
||||
|
||||
f.word(`(;${idx};)`, chalk.gray);
|
||||
|
||||
f.sexpr(() => {
|
||||
f.keyword("type");
|
||||
f.type(func.type);
|
||||
|
|
@ -678,9 +680,9 @@ function printModule(module: Module, f: Formatter) {
|
|||
printImport(import_, f);
|
||||
});
|
||||
|
||||
module.funcs.forEach((func) => {
|
||||
module.funcs.forEach((func, i) => {
|
||||
breakIfAny();
|
||||
printFunction(func, f);
|
||||
printFunction(func, i + module.imports.length, f);
|
||||
});
|
||||
|
||||
module.tables.forEach((table) => {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue