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"; import { exec } from "child_process";
const input = ` const input = `
function printInt(a: Int) = ( function printInt(a: Int): Int = (
let a = 0; if true then (
let b = 0; 0;
let c = (); 1;
);
a + b; 0
c
); );
function main() = ; function main() = ;

View file

@ -137,6 +137,8 @@ function lowerExpr(fcx: FuncContext, instrs: wasm.Instr[], expr: Expr) {
instrs.push({ kind: "local.set", imm: local }); instrs.push({ kind: "local.set", imm: local });
fcx.varLocations.push({ kind: "local", idx: local }); fcx.varLocations.push({ kind: "local", idx: local });
} else {
todo("complex locals");
} }
break; break;
@ -149,15 +151,10 @@ function lowerExpr(fcx: FuncContext, instrs: wasm.Instr[], expr: Expr) {
} else if (expr.exprs.length === 1) { } else if (expr.exprs.length === 1) {
lowerExpr(fcx, instrs, expr.exprs[0]); lowerExpr(fcx, instrs, expr.exprs[0]);
} else { } else {
const typeIdx = internFuncType(fcx.cx, {
params: [],
returns: wasmTypeForBody(expr.ty!),
});
const instr: wasm.Instr = { const instr: wasm.Instr = {
kind: "block", kind: "block",
instrs: lowerExprBlockBody(fcx, expr), instrs: lowerExprBlockBody(fcx, expr),
type: { kind: "typeidx", idx: typeIdx }, type: blockTypeForBody(fcx.cx, expr.ty!),
}; };
instrs.push(instr); instrs.push(instr);
@ -306,8 +303,27 @@ function lowerExpr(fcx: FuncContext, instrs: wasm.Instr[], expr: Expr) {
} }
case "call": case "call":
todo("call"); todo("call");
case "if": case "if": {
todo("ifs"); 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 { function todo(msg: string): never {
throw new Error(`TODO: ${msg}`); throw new Error(`TODO: ${msg}`);
} }

View file

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