mirror of
https://github.com/Noratrieb/riverdelta.git
synced 2026-01-15 17:05:03 +01:00
fix many things
This commit is contained in:
parent
02bbd8ec1e
commit
7cd50ab554
7 changed files with 269 additions and 51 deletions
|
|
@ -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,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue