This commit is contained in:
nora 2023-07-29 18:31:39 +02:00
parent 9ac5fec4bd
commit 27a4ecc46b
3 changed files with 40 additions and 17 deletions

View file

@ -10,14 +10,12 @@ import fs from "fs";
import { exec } from "child_process";
const input = `
function printInt(a: Int) = (
let a = 0;
let b = 0;
let c = ();
a + b;
c
function printInt(a: Int): Int = (
if true then (
0;
1;
);
0
);
function main() = ;

View file

@ -137,6 +137,8 @@ function lowerExpr(fcx: FuncContext, instrs: wasm.Instr[], expr: Expr) {
instrs.push({ kind: "local.set", imm: local });
fcx.varLocations.push({ kind: "local", idx: local });
} else {
todo("complex locals");
}
break;
@ -149,15 +151,10 @@ function lowerExpr(fcx: FuncContext, instrs: wasm.Instr[], expr: Expr) {
} else if (expr.exprs.length === 1) {
lowerExpr(fcx, instrs, expr.exprs[0]);
} else {
const typeIdx = internFuncType(fcx.cx, {
params: [],
returns: wasmTypeForBody(expr.ty!),
});
const instr: wasm.Instr = {
kind: "block",
instrs: lowerExprBlockBody(fcx, expr),
type: { kind: "typeidx", idx: typeIdx },
type: blockTypeForBody(fcx.cx, expr.ty!),
};
instrs.push(instr);
@ -306,8 +303,27 @@ function lowerExpr(fcx: FuncContext, instrs: wasm.Instr[], expr: Expr) {
}
case "call":
todo("call");
case "if":
todo("ifs");
case "if": {
lowerExpr(fcx, instrs, expr.cond!);
const thenInstrs: wasm.Instr[] = [];
lowerExpr(fcx, thenInstrs, expr.then);
const elseInstrs: wasm.Instr[] = [];
// If there is no else, the type is (), so an empty instr array is correct.
if (expr.else) {
lowerExpr(fcx, elseInstrs, expr.else);
}
instrs.push({
kind: "if",
then: thenInstrs,
else: elseInstrs,
type: blockTypeForBody(fcx.cx, expr.ty!),
});
break;
}
}
}
@ -467,6 +483,14 @@ function wasmTypeForBody(ty: Ty): wasm.ValType[] {
}
}
function blockTypeForBody(cx: Context, ty: Ty): wasm.Blocktype {
const typeIdx = internFuncType(cx, {
params: [],
returns: wasmTypeForBody(ty),
});
return { kind: "typeidx", idx: typeIdx };
}
function todo(msg: string): never {
throw new Error(`TODO: ${msg}`);
}

View file

@ -546,12 +546,13 @@ export function checkBody(
infcx.assign(TY_BOOL, cond.ty!, cond.span);
let ty;
let ty: Ty;
if (elsePart) {
infcx.assign(then.ty!, elsePart.ty!, elsePart.span);
ty = then.ty!;
} else {
infcx.assign(TY_UNIT, then.ty!, then.span);
ty = TY_UNIT;
}
return { ...expr, cond, then, else: elsePart, ty };