From de83eb6fcdda458f0ec159e03d94fc55355b1e09 Mon Sep 17 00:00:00 2001 From: Dustin Swan Date: Thu, 26 Mar 2026 20:01:06 -0600 Subject: [PATCH] More type checking --- src/cg/01-stdlib.cg | 5 +++++ src/typechecker.ts | 17 +++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/src/cg/01-stdlib.cg b/src/cg/01-stdlib.cg index d4cd726..9e68ca6 100644 --- a/src/cg/01-stdlib.cg +++ b/src/cg/01-stdlib.cg @@ -1,3 +1,8 @@ +point : Int \ Int \ { x : Int, y : Int } = x y \ { x = x, y = y }; +getX : { x : Int, y : Int } \ Int = p \ p.x; +setX : Int \ { x : Int, y : Int } \ { x : Int, y : Int } = newX p \ p.{ x = newX }; +myPoint = point 3 "a"; + # builtins # TODO: once we get typeclasses, make these the actual types cat : a \ a \ a; diff --git a/src/typechecker.ts b/src/typechecker.ts index 9f97ff7..da00fe0 100644 --- a/src/typechecker.ts +++ b/src/typechecker.ts @@ -127,6 +127,23 @@ function infer(expr: AST, env: TypeEnv, subst: Subst): TypeAST | null { return null; } + case 'record-update': { + const recType = infer(expr.record, env, subst); + if (!recType) return null; + const resolved = applySubst(recType, subst); + if (resolved.kind !== 'type-record') return null; + + for (const [key, value] of Object.entries(expr.updates)) { + const field = resolved.fields.find(f => f.name === key); + if (field) { + const err = check(value, field.type, env, subst); + if (err) warn(err, value); + } + } + + return resolved; + } + case 'apply': { const funcType = infer(expr.func, env, subst); if (!funcType) return null;