lower let

This commit is contained in:
nora 2023-07-29 18:10:08 +02:00
parent e88d0f8782
commit 9ac5fec4bd
2 changed files with 53 additions and 17 deletions

View file

@ -11,11 +11,13 @@ import { exec } from "child_process";
const input = ` const input = `
function printInt(a: Int) = ( function printInt(a: Int) = (
0; let a = 0;
( let b = 0;
0; let c = ();
1
); a + b;
c
); );
function main() = ; function main() = ;

View file

@ -1,4 +1,13 @@
import { Ast, Expr, ExprBlock, FunctionDef, Item, Ty, TyFn, varUnreachable } from "./ast"; import {
Ast,
Expr,
ExprBlock,
FunctionDef,
Item,
Ty,
TyFn,
varUnreachable,
} from "./ast";
import * as wasm from "./wasm/defs"; import * as wasm from "./wasm/defs";
type StringifiedForMap<T> = string; type StringifiedForMap<T> = string;
@ -111,15 +120,30 @@ Expression lowering.
function lowerExpr(fcx: FuncContext, instrs: wasm.Instr[], expr: Expr) { function lowerExpr(fcx: FuncContext, instrs: wasm.Instr[], expr: Expr) {
const ty = expr.ty!; const ty = expr.ty!;
switch (expr.kind) { switch (expr.kind) {
case "empty": case "empty": {
// A ZST, do nothing. // A ZST, do nothing.
return; return;
case "let": }
// Let, that's complicated. case "let": {
todo("let"); lowerExpr(fcx, instrs, expr.rhs);
case "block": const type = wasmTypeForBody(expr.rhs.ty!);
if (type.length === 0) {
fcx.varLocations.push({ kind: "zst" });
} else if (type.length === 1) {
const local = fcx.wasm.locals.length;
fcx.wasm.locals.push(type[0]);
instrs.push({ kind: "local.set", imm: local });
fcx.varLocations.push({ kind: "local", idx: local });
}
break;
}
case "block": {
const prevVarLocationLengths = fcx.varLocations.length;
if (expr.exprs.length === 0) { if (expr.exprs.length === 0) {
// do nothing // do nothing
} else if (expr.exprs.length === 1) { } else if (expr.exprs.length === 1) {
@ -138,8 +162,11 @@ function lowerExpr(fcx: FuncContext, instrs: wasm.Instr[], expr: Expr) {
instrs.push(instr); instrs.push(instr);
} }
fcx.varLocations.length = prevVarLocationLengths;
break; break;
case "literal": }
case "literal": {
switch (expr.value.kind) { switch (expr.value.kind) {
case "str": case "str":
todo("strings"); todo("strings");
@ -147,7 +174,8 @@ function lowerExpr(fcx: FuncContext, instrs: wasm.Instr[], expr: Expr) {
instrs.push({ kind: "i64.const", imm: expr.value.value }); instrs.push({ kind: "i64.const", imm: expr.value.value });
} }
break; break;
case "ident": }
case "ident": {
const res = expr.value.res!; const res = expr.value.res!;
switch (res.kind) { switch (res.kind) {
case "local": { case "local": {
@ -175,7 +203,8 @@ function lowerExpr(fcx: FuncContext, instrs: wasm.Instr[], expr: Expr) {
} }
break; break;
case "binary": }
case "binary": {
// By evaluating the LHS first, the RHS is on top, which // By evaluating the LHS first, the RHS is on top, which
// is correct as it's popped first. Evaluating the LHS first // is correct as it's popped first. Evaluating the LHS first
// is correct for the source language too so great, no swapping. // is correct for the source language too so great, no swapping.
@ -256,7 +285,8 @@ function lowerExpr(fcx: FuncContext, instrs: wasm.Instr[], expr: Expr) {
} }
break; break;
case "unary": }
case "unary": {
lowerExpr(fcx, instrs, expr.rhs); lowerExpr(fcx, instrs, expr.rhs);
switch (expr.unaryKind) { switch (expr.unaryKind) {
case "!": case "!":
@ -273,6 +303,7 @@ function lowerExpr(fcx: FuncContext, instrs: wasm.Instr[], expr: Expr) {
todo("negation"); todo("negation");
} }
break; break;
}
case "call": case "call":
todo("call"); todo("call");
case "if": case "if":
@ -280,7 +311,10 @@ function lowerExpr(fcx: FuncContext, instrs: wasm.Instr[], expr: Expr) {
} }
} }
function lowerExprBlockBody(fcx: FuncContext, expr: ExprBlock & Expr): wasm.Instr[] { function lowerExprBlockBody(
fcx: FuncContext,
expr: ExprBlock & Expr
): wasm.Instr[] {
const innerInstrs: wasm.Instr[] = []; const innerInstrs: wasm.Instr[] = [];
const headExprs = expr.exprs.slice(0, -1); const headExprs = expr.exprs.slice(0, -1);