mirror of
https://github.com/Noratrieb/riverdelta.git
synced 2026-01-14 16:35:03 +01:00
Implement aggregate locals
This commit is contained in:
parent
7c88a3513e
commit
1d9ab31baf
2 changed files with 35 additions and 31 deletions
|
|
@ -12,10 +12,12 @@ import { exec } from "child_process";
|
||||||
const input = `
|
const input = `
|
||||||
function main() = uwu(10);
|
function main() = uwu(10);
|
||||||
|
|
||||||
function ___print() = ;
|
function print_a(
|
||||||
|
a: String,
|
||||||
|
): String = a;
|
||||||
|
|
||||||
function uwu(a: Int) = if a != 0 then (
|
function uwu(a: Int) = if a != 0 then (
|
||||||
print("uwu\n");
|
print(print_a("uwu\n"));
|
||||||
uwu(a - 1);
|
uwu(a - 1);
|
||||||
);
|
);
|
||||||
`;
|
`;
|
||||||
|
|
|
||||||
60
src/lower.ts
60
src/lower.ts
|
|
@ -52,9 +52,9 @@ export type Context = {
|
||||||
};
|
};
|
||||||
|
|
||||||
function escapeIdentName(name: string): string {
|
function escapeIdentName(name: string): string {
|
||||||
// this allows the implementation to use an odd number of leading
|
// This allows the implementation to use 2 leading underscores
|
||||||
// underscores
|
// for any names and it will not conflict.
|
||||||
return name.replace(/_/g, "__");
|
return name.startsWith("__") ? `_${name}` : name;
|
||||||
}
|
}
|
||||||
|
|
||||||
function internFuncType(cx: Context, type: wasm.FuncType): wasm.TypeIdx {
|
function internFuncType(cx: Context, type: wasm.FuncType): wasm.TypeIdx {
|
||||||
|
|
@ -178,7 +178,7 @@ type ArgRetAbi =
|
||||||
| { kind: "zst" }
|
| { kind: "zst" }
|
||||||
| { kind: "aggregate"; types: wasm.ValType[] };
|
| { kind: "aggregate"; types: wasm.ValType[] };
|
||||||
|
|
||||||
type VarLocation = { kind: "local"; idx: number } | { kind: "zst" };
|
type VarLocation = { localIdx: number; types: wasm.ValType[] };
|
||||||
|
|
||||||
function lowerFunc(cx: Context, item: Item, func: FunctionDef) {
|
function lowerFunc(cx: Context, item: Item, func: FunctionDef) {
|
||||||
const abi = computeAbi(func.ty!);
|
const abi = computeAbi(func.ty!);
|
||||||
|
|
@ -226,19 +226,17 @@ function lowerExpr(fcx: FuncContext, instrs: wasm.Instr[], expr: Expr) {
|
||||||
}
|
}
|
||||||
case "let": {
|
case "let": {
|
||||||
lowerExpr(fcx, instrs, expr.rhs);
|
lowerExpr(fcx, instrs, expr.rhs);
|
||||||
const type = wasmTypeForBody(expr.rhs.ty!);
|
const types = 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 });
|
const local = fcx.wasm.locals.length;
|
||||||
|
|
||||||
fcx.varLocations.push({ kind: "local", idx: local });
|
fcx.wasm.locals.push(...types);
|
||||||
} else {
|
|
||||||
todo("complex locals");
|
types.forEach((_, i) => {
|
||||||
}
|
instrs.push({ kind: "local.set", imm: local + i });
|
||||||
|
});
|
||||||
|
|
||||||
|
fcx.varLocations.push({ localIdx: local, types });
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -507,17 +505,15 @@ function lowerExprBlockBody(
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadVariable(instrs: wasm.Instr[], loc: VarLocation) {
|
function loadVariable(instrs: wasm.Instr[], loc: VarLocation) {
|
||||||
switch (loc.kind) {
|
// If the type is a ZST we'll have no types and do the following:
|
||||||
case "local": {
|
// Load the ZST:
|
||||||
instrs.push({ kind: "local.get", imm: loc.idx });
|
// ...
|
||||||
break;
|
// 🪄 poof, the ZST is on the stack now.
|
||||||
}
|
// --
|
||||||
case "zst":
|
// Otherwise, load each part.
|
||||||
// Load the ZST:
|
loc.types.forEach((_, i) => {
|
||||||
// ...
|
instrs.push({ kind: "local.get", imm: loc.localIdx + i });
|
||||||
// 🪄 poof, the ZST is on the stack now.
|
});
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function computeAbi(ty: TyFn): FnAbi {
|
function computeAbi(ty: TyFn): FnAbi {
|
||||||
|
|
@ -601,14 +597,20 @@ function wasmTypeForAbi(abi: FnAbi): {
|
||||||
abi.params.forEach((arg) => {
|
abi.params.forEach((arg) => {
|
||||||
switch (arg.kind) {
|
switch (arg.kind) {
|
||||||
case "scalar":
|
case "scalar":
|
||||||
paramLocations.push({ kind: "local", idx: params.length });
|
paramLocations.push({
|
||||||
|
localIdx: params.length,
|
||||||
|
types: [arg.type],
|
||||||
|
});
|
||||||
params.push(arg.type);
|
params.push(arg.type);
|
||||||
break;
|
break;
|
||||||
case "zst":
|
case "zst":
|
||||||
paramLocations.push({ kind: "zst" });
|
paramLocations.push({ localIdx: /* dummy */ 0, types: [] });
|
||||||
break;
|
break;
|
||||||
case "aggregate":
|
case "aggregate":
|
||||||
paramLocations.push({ kind: "local", idx: params.length });
|
paramLocations.push({
|
||||||
|
localIdx: params.length,
|
||||||
|
types: arg.types,
|
||||||
|
});
|
||||||
params.push(...arg.types);
|
params.push(...arg.types);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue