fix many things

This commit is contained in:
nora 2023-07-29 23:37:01 +02:00
parent 02bbd8ec1e
commit 7cd50ab554
7 changed files with 269 additions and 51 deletions

View file

@ -16,6 +16,7 @@ import {
Ty,
TY_BOOL,
TY_INT,
TY_NEVER,
TY_STRING,
TY_UNIT,
TyFn,
@ -78,6 +79,9 @@ function lowerAstTyBase(
),
};
}
case "never": {
return TY_NEVER;
}
}
}
@ -234,7 +238,7 @@ export function typeck(ast: Ast): Ast {
}
typecked.typeckResults = {
main: main.id,
main: { kind: "item", index: main.id },
};
return typecked;
@ -337,7 +341,10 @@ export class InferContext {
this.constrainVar(rhs.index, lhs);
return;
}
// type variable handling here
if (rhs.kind === "never") {
return;
}
switch (lhs.kind) {
case "string": {
@ -397,6 +404,8 @@ export function checkBody(
typeOfItem: (index: number) => Ty
): Expr {
const localTys = [...fnTy.params];
const loopState: { hasBreak: boolean; nestingDepth: number }[] = [];
let currentNestingDepth = 0;
const infcx = new InferContext();
@ -460,6 +469,7 @@ export function checkBody(
};
}
case "block": {
currentNestingDepth++;
const prevLocalTysLen = localTys.length;
const exprs = expr.exprs.map((expr) => this.expr(expr));
@ -468,6 +478,8 @@ export function checkBody(
localTys.length = prevLocalTysLen;
currentNestingDepth--;
return {
...expr,
exprs,
@ -544,8 +556,10 @@ export function checkBody(
}
case "if": {
const cond = this.expr(expr.cond);
currentNestingDepth++;
const then = this.expr(expr.then);
const elsePart = expr.else && this.expr(expr.else);
currentNestingDepth--;
infcx.assign(TY_BOOL, cond.ty!, cond.span);
@ -560,6 +574,42 @@ export function checkBody(
return { ...expr, cond, then, else: elsePart, ty };
}
case "loop": {
currentNestingDepth++;
loopState.push({
hasBreak: false,
nestingDepth: currentNestingDepth,
});
const body = this.expr(expr.body);
infcx.assign(TY_UNIT, body.ty!, body.span);
const hadBreak = loopState.pop();
const ty = hadBreak ? TY_UNIT : TY_NEVER;
currentNestingDepth--;
return {
...expr,
body,
ty,
};
}
case "break": {
if (loopState.length === 0) {
throw new CompilerError("break outside loop", expr.span);
}
const loopDepth = loopState[loopState.length - 1].nestingDepth;
loopState[loopState.length - 1].hasBreak = true;
const target = currentNestingDepth - loopDepth;
return {
...expr,
ty: TY_NEVER,
target,
};
}
case "structLiteral": {
const fields = expr.fields.map<[Identifier, Expr]>(([name, expr]) => [
name,