Skip to content

Commit

Permalink
improved typeAstToType
Browse files Browse the repository at this point in the history
  • Loading branch information
ascandone committed Sep 15, 2024
1 parent 2a14096 commit 849b7aa
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 43 deletions.
2 changes: 1 addition & 1 deletion src/typecheck/analyse.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -781,7 +781,7 @@ describe("ADTs", () => {
});
});

test.todo("allows using parametric types in constructors", () => {
test("allows using parametric types in constructors", () => {
const a = new Analysis(
"Main",
`
Expand Down
100 changes: 58 additions & 42 deletions src/typecheck/analyse.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,15 @@ import {
} from "../parser";
import { bool, char, float, int, list, string } from "./core";
import { TraitImpl, defaultTraitImpls } from "./defaultImports";
import { PolyType, TVar, Type, UnifyError, instantiate, unify } from "./type";
import {
PolyType,
TVar,
Type,
UnifyError,
generalizeAsScheme,
instantiate,
unify,
} from "./type";

export function resetTraitsRegistry(
traitImpls: TraitImpl[] = defaultTraitImpls,
Expand Down Expand Up @@ -395,7 +403,7 @@ export class Analysis {

private typecheckLetDeclaration(decl: UntypedDeclaration) {
if (decl.typeHint !== undefined) {
const typeHintType = this.typeAstToType(decl.typeHint.mono);
const typeHintType = this.typeAstToType(decl.typeHint.mono, {});
this.unifyNode(decl.binding, typeHintType);
}
if (decl.extern) {
Expand Down Expand Up @@ -540,41 +548,42 @@ export class Analysis {
}
}

private typeAstToType(t: TypeAst): Type {
const helper = (t: TypeAst): Type => {
switch (t.type) {
case "named": {
const resolved = this.resolution.resolveType(t);
if (resolved === undefined) {
throw new Error("TODO handle undefined type: " + t.name);
}

// TODO actually resolve type
return {
type: "named",
args: t.args.map((arg) => helper(arg)),
moduleName: resolved.ns,
name: resolved.declaration.name,
};
private typeAstToType(t: TypeAst, boundTypes: Record<string, Type>): Type {
switch (t.type) {
case "named": {
const resolved = this.resolution.resolveType(t);
if (resolved === undefined) {
throw new Error("TODO handle undefined type: " + t.name);
}

Check warning on line 557 in src/typecheck/analyse.ts

View check run for this annotation

Codecov / codecov/patch

src/typecheck/analyse.ts#L556-L557

Added lines #L556 - L557 were not covered by tests

case "fn":
return {
type: "fn",
args: t.args.map((arg) => helper(arg)),
return: helper(t.return),
};
return {
type: "named",
args: t.args.map((arg) => this.typeAstToType(arg, boundTypes)),
moduleName: resolved.ns,
name: resolved.declaration.name,
};
}

case "var":
// TODO
return TVar.fresh().asType();
case "fn":
return {
type: "fn",
args: t.args.map((arg) => this.typeAstToType(arg, boundTypes)),
return: this.typeAstToType(t.return, boundTypes),
};

case "any":
return TVar.fresh().asType();
case "var": {
const lookup = boundTypes[t.ident];
if (lookup === undefined) {
const fresh = TVar.fresh().asType();
boundTypes[t.ident] = fresh;
return fresh;
}
return lookup;
}
};

return helper(t);
case "any":
return TVar.fresh().asType();
}
}

private getVariantType(
Expand All @@ -583,25 +592,32 @@ export class Analysis {
): PolyType {
// TODO cache and generalize

const params = declaration.params.map((p): [string, Type] => [
p.name,
TVar.fresh().asType(),
]);

const ret: Type = {
type: "named",
args: declaration.params.map(() => TVar.fresh().asType()),
moduleName: this.ns,
name: declaration.name,
moduleName: this.ns, // TODO handle imported
args: params.map((p) => p[1]),
};

let mono: Type;
if (variant.args.length === 0) {
return [{}, ret];
}

return [
{},
{
mono = ret;
} else {
mono = {
type: "fn",
args: variant.args.map((arg) => this.typeAstToType(arg)),
args: variant.args.map((arg) =>
this.typeAstToType(arg, Object.fromEntries(params)),
),
return: ret,
},
];
};
}

return [generalizeAsScheme(mono), mono];
}

// --- Public interface
Expand Down

0 comments on commit 849b7aa

Please sign in to comment.