use new checker
This commit is contained in:
parent
aab3fa77ad
commit
a22ced4c24
@ -137,7 +137,7 @@ class TypeChecker {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "AssignStmt": {
|
case "AssignStmt": {
|
||||||
const placeTy = this.expr(k.place, Ty.Any);
|
const placeTy = this.place(k.place, Ty.Any);
|
||||||
const exprTy = this.expr(k.expr, placeTy);
|
const exprTy = this.expr(k.expr, placeTy);
|
||||||
if (!placeTy.resolvableWith(exprTy)) {
|
if (!placeTy.resolvableWith(exprTy)) {
|
||||||
this.reporter.error(
|
this.reporter.error(
|
||||||
|
|||||||
@ -70,7 +70,7 @@ const fnTys = checker.checkFn(mainFn);
|
|||||||
// },
|
// },
|
||||||
// });
|
// });
|
||||||
|
|
||||||
const m = new middle.MiddleLowerer(syms, tys);
|
const m = new middle.MiddleLowerer(syms, checker);
|
||||||
const mainMiddleFn = m.lowerFn(mainFn);
|
const mainMiddleFn = m.lowerFn(mainFn);
|
||||||
|
|
||||||
if (Deno.args.includes("--print-mir")) {
|
if (Deno.args.includes("--print-mir")) {
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import * as ast from "./ast.ts";
|
import * as ast from "./ast.ts";
|
||||||
import { Syms, Tys } from "./front/mod.ts";
|
import { CheckedFn, Checker, Syms, Tys } from "./front/mod.ts";
|
||||||
import { Ty } from "./ty.ts";
|
import { Ty } from "./ty.ts";
|
||||||
import { BasicBlock, BinaryOp, Fn, Inst, InstKind } from "./mir.ts";
|
import { BasicBlock, BinaryOp, Fn, Inst, InstKind } from "./mir.ts";
|
||||||
|
|
||||||
@ -8,14 +8,19 @@ export class MiddleLowerer {
|
|||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private syms: Syms,
|
private syms: Syms,
|
||||||
private tys: Tys,
|
private checker: Checker,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
lowerFn(stmt: ast.FnStmt): Fn {
|
lowerFn(stmt: ast.FnStmt): Fn {
|
||||||
if (this.fns.has(stmt.id)) {
|
if (this.fns.has(stmt.id)) {
|
||||||
return this.fns.get(stmt.id)!;
|
return this.fns.get(stmt.id)!;
|
||||||
}
|
}
|
||||||
const fn = new FnLowerer(this, this.syms, this.tys, stmt).lower();
|
const fn = new FnLowerer(
|
||||||
|
this,
|
||||||
|
this.syms,
|
||||||
|
this.checker.checkFn(stmt),
|
||||||
|
stmt,
|
||||||
|
).lower();
|
||||||
this.fns.set(stmt.id, fn);
|
this.fns.set(stmt.id, fn);
|
||||||
return fn;
|
return fn;
|
||||||
}
|
}
|
||||||
@ -34,12 +39,12 @@ class FnLowerer {
|
|||||||
constructor(
|
constructor(
|
||||||
private lowerer: MiddleLowerer,
|
private lowerer: MiddleLowerer,
|
||||||
private syms: Syms,
|
private syms: Syms,
|
||||||
private tys: Tys,
|
private tys: CheckedFn,
|
||||||
private stmt: ast.FnStmt,
|
private stmt: ast.FnStmt,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
lower(): Fn {
|
lower(): Fn {
|
||||||
const ty = this.tys.fnStmt(this.stmt);
|
const ty = this.tys.ty();
|
||||||
this.lowerBlock(this.stmt.kind.body.as("Block"));
|
this.lowerBlock(this.stmt.kind.body.as("Block"));
|
||||||
this.pushInst(Ty.Void, "Return", { source: this.makeVoid() });
|
this.pushInst(Ty.Void, "Return", { source: this.makeVoid() });
|
||||||
this.bbs[0].insts.unshift(...this.allocs);
|
this.bbs[0].insts.unshift(...this.allocs);
|
||||||
@ -172,7 +177,7 @@ class FnLowerer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private lowerLetStmt(stmt: ast.NodeWithKind<"LetStmt">) {
|
private lowerLetStmt(stmt: ast.NodeWithKind<"LetStmt">) {
|
||||||
const ty = this.tys.param(stmt.kind.param.as("Param"));
|
const ty = this.tys.exprTy(stmt.kind.expr);
|
||||||
const expr = this.lowerExpr(stmt.kind.expr);
|
const expr = this.lowerExpr(stmt.kind.expr);
|
||||||
const local = new Inst(
|
const local = new Inst(
|
||||||
Ty.create("PtrMut", { ty }),
|
Ty.create("PtrMut", { ty }),
|
||||||
@ -195,7 +200,7 @@ class FnLowerer {
|
|||||||
private lowerPlace(place: ast.Node): Inst {
|
private lowerPlace(place: ast.Node): Inst {
|
||||||
// evaluate to most direct pointer
|
// evaluate to most direct pointer
|
||||||
|
|
||||||
const _ty = this.tys.place(place);
|
const _ty = this.tys.exprTy(place);
|
||||||
|
|
||||||
if (place.is("IdentExpr")) {
|
if (place.is("IdentExpr")) {
|
||||||
const sym = this.syms.get(place);
|
const sym = this.syms.get(place);
|
||||||
@ -218,9 +223,9 @@ class FnLowerer {
|
|||||||
|
|
||||||
if (place.is("IndexExpr")) {
|
if (place.is("IndexExpr")) {
|
||||||
const value = place.kind.value;
|
const value = place.kind.value;
|
||||||
const valueTy = this.tys.place(value);
|
const valueTy = this.tys.exprTy(value);
|
||||||
const arg = place.kind.arg;
|
const arg = place.kind.arg;
|
||||||
const argTy = this.tys.expr(arg);
|
const argTy = this.tys.exprTy(arg);
|
||||||
if (valueTy.is("Array") || valueTy.is("Slice")) {
|
if (valueTy.is("Array") || valueTy.is("Slice")) {
|
||||||
const valueInst = this.lowerPlace(place.kind.value);
|
const valueInst = this.lowerPlace(place.kind.value);
|
||||||
if (argTy.is("Int")) {
|
if (argTy.is("Int")) {
|
||||||
@ -257,7 +262,7 @@ class FnLowerer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private lowerExpr(expr: ast.Node): Inst {
|
private lowerExpr(expr: ast.Node): Inst {
|
||||||
const ty = this.tys.expr(expr);
|
const ty = this.tys.exprTy(expr);
|
||||||
if (expr.is("IdentExpr")) {
|
if (expr.is("IdentExpr")) {
|
||||||
const sym = this.syms.get(expr);
|
const sym = this.syms.get(expr);
|
||||||
if (sym.tag === "Fn") {
|
if (sym.tag === "Fn") {
|
||||||
@ -265,7 +270,9 @@ class FnLowerer {
|
|||||||
return this.pushInst(fn.ty, "Fn", { fn });
|
return this.pushInst(fn.ty, "Fn", { fn });
|
||||||
}
|
}
|
||||||
if (sym.tag === "FnParam") {
|
if (sym.tag === "FnParam") {
|
||||||
const ty = this.tys.expr(sym.param);
|
const ty = this.tys.ty().as("FnStmt")
|
||||||
|
.kind.ty.as("Fn")
|
||||||
|
.kind.params[sym.idx];
|
||||||
return this.pushInst(ty, "Param", { idx: sym.idx });
|
return this.pushInst(ty, "Param", { idx: sym.idx });
|
||||||
}
|
}
|
||||||
if (sym.tag === "Builtin") {
|
if (sym.tag === "Builtin") {
|
||||||
@ -290,7 +297,7 @@ class FnLowerer {
|
|||||||
return this.pushInst(ty, "Str", { value: expr.kind.value });
|
return this.pushInst(ty, "Str", { value: expr.kind.value });
|
||||||
}
|
}
|
||||||
if (expr.is("ArrayExpr")) {
|
if (expr.is("ArrayExpr")) {
|
||||||
const ty = this.tys.expr(expr);
|
const ty = this.tys.exprTy(expr);
|
||||||
const values = expr.kind.values
|
const values = expr.kind.values
|
||||||
.map((value) => this.lowerExpr(value));
|
.map((value) => this.lowerExpr(value));
|
||||||
return this.pushInst(ty, "Array", { values });
|
return this.pushInst(ty, "Array", { values });
|
||||||
@ -323,8 +330,8 @@ class FnLowerer {
|
|||||||
return this.lowerUnaryExpr(expr);
|
return this.lowerUnaryExpr(expr);
|
||||||
}
|
}
|
||||||
if (expr.is("BinaryExpr")) {
|
if (expr.is("BinaryExpr")) {
|
||||||
const leftTy = this.tys.expr(expr.kind.left);
|
const leftTy = this.tys.exprTy(expr.kind.left);
|
||||||
const rightTy = this.tys.expr(expr.kind.right);
|
const rightTy = this.tys.exprTy(expr.kind.right);
|
||||||
const binaryOp = binaryOpTests
|
const binaryOp = binaryOpTests
|
||||||
.map((test) => test(expr.kind.op, leftTy, rightTy, ty))
|
.map((test) => test(expr.kind.op, leftTy, rightTy, ty))
|
||||||
.filter((tested) => tested)
|
.filter((tested) => tested)
|
||||||
@ -342,8 +349,8 @@ class FnLowerer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private lowerUnaryExpr(expr: ast.NodeWithKind<"UnaryExpr">) {
|
private lowerUnaryExpr(expr: ast.NodeWithKind<"UnaryExpr">) {
|
||||||
const resultTy = this.tys.expr(expr);
|
const resultTy = this.tys.exprTy(expr);
|
||||||
const operandTy = this.tys.expr(expr.kind.expr);
|
const operandTy = this.tys.exprTy(expr.kind.expr);
|
||||||
if (
|
if (
|
||||||
expr.kind.op === "Neg" &&
|
expr.kind.op === "Neg" &&
|
||||||
operandTy.resolvableWith(Ty.I32) &&
|
operandTy.resolvableWith(Ty.I32) &&
|
||||||
@ -376,7 +383,7 @@ class FnLowerer {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (place.is("IndexExpr")) {
|
if (place.is("IndexExpr")) {
|
||||||
const placeTy = this.tys.expr(place);
|
const placeTy = this.tys.exprTy(place);
|
||||||
const placeInst = this.lowerPlace(place);
|
const placeInst = this.lowerPlace(place);
|
||||||
if (placeTy.is("Slice")) {
|
if (placeTy.is("Slice")) {
|
||||||
return placeInst;
|
return placeInst;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user