mirror of
https://github.com/Noratrieb/riverdelta.git
synced 2026-01-14 16:35:03 +01:00
lower let
This commit is contained in:
parent
e88d0f8782
commit
9ac5fec4bd
2 changed files with 53 additions and 17 deletions
12
src/index.ts
12
src/index.ts
|
|
@ -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() = ;
|
||||||
|
|
|
||||||
58
src/lower.ts
58
src/lower.ts
|
|
@ -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);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue