mirror of
https://github.com/Noratrieb/riverdelta.git
synced 2026-01-16 17:35:02 +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";
|
import { exec } from "child_process";
|
||||||
|
|
||||||
const input = `
|
const input = `
|
||||||
function main() = uwu(10);
|
function main() = (
|
||||||
|
loop (no(break););
|
||||||
|
uwu(10);
|
||||||
|
);
|
||||||
|
|
||||||
function print_a(
|
function no(a: !): String = a;
|
||||||
a: String,
|
|
||||||
): String = a;
|
|
||||||
|
|
||||||
function uwu(a: Int) = if a != 0 then (
|
function uwu(a: Int) = if a != 0 then (
|
||||||
print(print_a("uwu\n"));
|
print("uwu\n");
|
||||||
uwu(a - 1);
|
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 POINTER: wasm.ValType = USIZE;
|
||||||
|
|
||||||
const STRING_TYPES: wasm.ValType[] = [POINTER, USIZE];
|
const STRING_TYPES: wasm.ValType[] = [POINTER, USIZE];
|
||||||
const STRING_ABI: ArgRetAbi = {
|
const STRING_ABI: ArgRetAbi = STRING_TYPES;
|
||||||
kind: "aggregate",
|
|
||||||
types: STRING_TYPES,
|
|
||||||
};
|
|
||||||
|
|
||||||
const WASM_PAGE = 65536;
|
const WASM_PAGE = 65536;
|
||||||
|
|
||||||
|
|
@ -173,10 +170,7 @@ type FuncContext = {
|
||||||
|
|
||||||
type FnAbi = { params: ArgRetAbi[]; ret: ArgRetAbi };
|
type FnAbi = { params: ArgRetAbi[]; ret: ArgRetAbi };
|
||||||
|
|
||||||
type ArgRetAbi =
|
type ArgRetAbi = wasm.ValType[];
|
||||||
| { kind: "scalar"; type: wasm.ValType }
|
|
||||||
| { kind: "zst" }
|
|
||||||
| { kind: "aggregate"; types: wasm.ValType[] };
|
|
||||||
|
|
||||||
type VarLocation = { localIdx: number; types: 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;
|
const _: never = expr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ty.kind === "never") {
|
||||||
|
instrs.push({ kind: "unreachable" });
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function lowerExprBlockBody(
|
function lowerExprBlockBody(
|
||||||
|
|
@ -517,72 +516,34 @@ function loadVariable(instrs: wasm.Instr[], loc: VarLocation) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function computeAbi(ty: TyFn): FnAbi {
|
function computeAbi(ty: TyFn): FnAbi {
|
||||||
const scalar = (type: wasm.ValType): ArgRetAbi =>
|
function argRetAbi(param: Ty): ArgRetAbi {
|
||||||
({ kind: "scalar", type } as const);
|
|
||||||
const zst: ArgRetAbi = { kind: "zst" };
|
|
||||||
|
|
||||||
function paramAbi(param: Ty): ArgRetAbi {
|
|
||||||
switch (param.kind) {
|
switch (param.kind) {
|
||||||
case "string":
|
case "string":
|
||||||
return STRING_ABI;
|
return STRING_ABI;
|
||||||
case "fn":
|
case "fn":
|
||||||
todo("fn abi");
|
todo("fn abi");
|
||||||
case "int":
|
case "int":
|
||||||
return scalar("i64");
|
return ["i64"];
|
||||||
case "bool":
|
case "bool":
|
||||||
return scalar("i32");
|
return ["i32"];
|
||||||
case "list":
|
case "list":
|
||||||
todo("list abi");
|
todo("list abi");
|
||||||
case "tuple":
|
case "tuple":
|
||||||
if (param.elems.length === 0) {
|
if (param.elems.length === 0) {
|
||||||
return zst;
|
return [];
|
||||||
} else if (param.elems.length === 1) {
|
|
||||||
return paramAbi(param.elems[0]);
|
|
||||||
}
|
}
|
||||||
todo("complex tuple abi");
|
todo("complex tuple abi");
|
||||||
case "struct":
|
case "struct":
|
||||||
todo("struct ABI");
|
todo("struct ABI");
|
||||||
case "never":
|
case "never":
|
||||||
return zst;
|
return [];
|
||||||
case "var":
|
case "var":
|
||||||
varUnreachable();
|
varUnreachable();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const params = ty.params.map(paramAbi);
|
const params = ty.params.map(argRetAbi);
|
||||||
|
const ret = argRetAbi(ty.returnTy);
|
||||||
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();
|
|
||||||
}
|
|
||||||
|
|
||||||
return { params, ret };
|
return { params, ret };
|
||||||
}
|
}
|
||||||
|
|
@ -595,39 +556,14 @@ function wasmTypeForAbi(abi: FnAbi): {
|
||||||
const paramLocations: VarLocation[] = [];
|
const paramLocations: VarLocation[] = [];
|
||||||
|
|
||||||
abi.params.forEach((arg) => {
|
abi.params.forEach((arg) => {
|
||||||
switch (arg.kind) {
|
paramLocations.push({
|
||||||
case "scalar":
|
localIdx: params.length,
|
||||||
paramLocations.push({
|
types: arg,
|
||||||
localIdx: params.length,
|
});
|
||||||
types: [arg.type],
|
params.push(...arg);
|
||||||
});
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
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[] {
|
function wasmTypeForBody(ty: Ty): wasm.ValType[] {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue