mirror of
https://github.com/Noratrieb/riverdelta.git
synced 2026-01-14 16:35:03 +01:00
add unreachable for unreachable things
This commit is contained in:
parent
1d9ab31baf
commit
89dbb50add
2 changed files with 26 additions and 89 deletions
11
src/index.ts
11
src/index.ts
|
|
@ -10,14 +10,15 @@ import fs from "fs";
|
|||
import { exec } from "child_process";
|
||||
|
||||
const input = `
|
||||
function main() = uwu(10);
|
||||
function main() = (
|
||||
loop (no(break););
|
||||
uwu(10);
|
||||
);
|
||||
|
||||
function print_a(
|
||||
a: String,
|
||||
): String = a;
|
||||
function no(a: !): String = a;
|
||||
|
||||
function uwu(a: Int) = if a != 0 then (
|
||||
print(print_a("uwu\n"));
|
||||
print("uwu\n");
|
||||
uwu(a - 1);
|
||||
);
|
||||
`;
|
||||
|
|
|
|||
104
src/lower.ts
104
src/lower.ts
|
|
@ -19,10 +19,7 @@ const USIZE: wasm.ValType = "i32";
|
|||
const POINTER: wasm.ValType = USIZE;
|
||||
|
||||
const STRING_TYPES: wasm.ValType[] = [POINTER, USIZE];
|
||||
const STRING_ABI: ArgRetAbi = {
|
||||
kind: "aggregate",
|
||||
types: STRING_TYPES,
|
||||
};
|
||||
const STRING_ABI: ArgRetAbi = STRING_TYPES;
|
||||
|
||||
const WASM_PAGE = 65536;
|
||||
|
||||
|
|
@ -173,10 +170,7 @@ type FuncContext = {
|
|||
|
||||
type FnAbi = { params: ArgRetAbi[]; ret: ArgRetAbi };
|
||||
|
||||
type ArgRetAbi =
|
||||
| { kind: "scalar"; type: wasm.ValType }
|
||||
| { kind: "zst" }
|
||||
| { kind: "aggregate"; types: wasm.ValType[] };
|
||||
type ArgRetAbi = wasm.ValType[];
|
||||
|
||||
type VarLocation = { localIdx: number; types: wasm.ValType[] };
|
||||
|
||||
|
|
@ -482,6 +476,11 @@ function lowerExpr(fcx: FuncContext, instrs: wasm.Instr[], expr: Expr) {
|
|||
const _: never = expr;
|
||||
}
|
||||
}
|
||||
|
||||
if (ty.kind === "never") {
|
||||
instrs.push({ kind: "unreachable" });
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
function lowerExprBlockBody(
|
||||
|
|
@ -517,72 +516,34 @@ function loadVariable(instrs: wasm.Instr[], loc: VarLocation) {
|
|||
}
|
||||
|
||||
function computeAbi(ty: TyFn): FnAbi {
|
||||
const scalar = (type: wasm.ValType): ArgRetAbi =>
|
||||
({ kind: "scalar", type } as const);
|
||||
const zst: ArgRetAbi = { kind: "zst" };
|
||||
|
||||
function paramAbi(param: Ty): ArgRetAbi {
|
||||
function argRetAbi(param: Ty): ArgRetAbi {
|
||||
switch (param.kind) {
|
||||
case "string":
|
||||
return STRING_ABI;
|
||||
case "fn":
|
||||
todo("fn abi");
|
||||
case "int":
|
||||
return scalar("i64");
|
||||
return ["i64"];
|
||||
case "bool":
|
||||
return scalar("i32");
|
||||
return ["i32"];
|
||||
case "list":
|
||||
todo("list abi");
|
||||
case "tuple":
|
||||
if (param.elems.length === 0) {
|
||||
return zst;
|
||||
} else if (param.elems.length === 1) {
|
||||
return paramAbi(param.elems[0]);
|
||||
return [];
|
||||
}
|
||||
todo("complex tuple abi");
|
||||
case "struct":
|
||||
todo("struct ABI");
|
||||
case "never":
|
||||
return zst;
|
||||
return [];
|
||||
case "var":
|
||||
varUnreachable();
|
||||
}
|
||||
}
|
||||
|
||||
const params = ty.params.map(paramAbi);
|
||||
|
||||
let ret: ArgRetAbi;
|
||||
switch (ty.returnTy.kind) {
|
||||
case "string":
|
||||
ret = STRING_ABI;
|
||||
break;
|
||||
case "fn":
|
||||
todo("fn abi");
|
||||
case "int":
|
||||
ret = scalar("i64");
|
||||
break;
|
||||
case "bool":
|
||||
ret = scalar("i32");
|
||||
break;
|
||||
case "list":
|
||||
todo("list abi");
|
||||
case "tuple":
|
||||
if (ty.returnTy.elems.length === 0) {
|
||||
ret = zst;
|
||||
break;
|
||||
} else if (ty.returnTy.elems.length === 1) {
|
||||
ret = paramAbi(ty.returnTy.elems[0]);
|
||||
break;
|
||||
}
|
||||
todo("complex tuple abi");
|
||||
case "struct":
|
||||
todo("struct ABI");
|
||||
case "never":
|
||||
ret = zst;
|
||||
break;
|
||||
case "var":
|
||||
varUnreachable();
|
||||
}
|
||||
const params = ty.params.map(argRetAbi);
|
||||
const ret = argRetAbi(ty.returnTy);
|
||||
|
||||
return { params, ret };
|
||||
}
|
||||
|
|
@ -595,39 +556,14 @@ function wasmTypeForAbi(abi: FnAbi): {
|
|||
const paramLocations: VarLocation[] = [];
|
||||
|
||||
abi.params.forEach((arg) => {
|
||||
switch (arg.kind) {
|
||||
case "scalar":
|
||||
paramLocations.push({
|
||||
localIdx: params.length,
|
||||
types: [arg.type],
|
||||
});
|
||||
params.push(arg.type);
|
||||
break;
|
||||
case "zst":
|
||||
paramLocations.push({ localIdx: /* dummy */ 0, types: [] });
|
||||
break;
|
||||
case "aggregate":
|
||||
paramLocations.push({
|
||||
localIdx: params.length,
|
||||
types: arg.types,
|
||||
});
|
||||
params.push(...arg.types);
|
||||
break;
|
||||
}
|
||||
paramLocations.push({
|
||||
localIdx: params.length,
|
||||
types: arg,
|
||||
});
|
||||
params.push(...arg);
|
||||
});
|
||||
let returns: wasm.ValType[];
|
||||
switch (abi.ret.kind) {
|
||||
case "scalar":
|
||||
returns = [abi.ret.type];
|
||||
break;
|
||||
case "zst":
|
||||
returns = [];
|
||||
break;
|
||||
case "aggregate":
|
||||
returns = abi.ret.types;
|
||||
}
|
||||
|
||||
return { type: { params, returns }, paramLocations };
|
||||
return { type: { params, returns: abi.ret }, paramLocations };
|
||||
}
|
||||
|
||||
function wasmTypeForBody(ty: Ty): wasm.ValType[] {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue