From 0a315c56150f97004b556b2ec88cf69c8909cb91 Mon Sep 17 00:00:00 2001 From: Andrew Segavac Date: Wed, 20 Aug 2025 22:47:26 -0600 Subject: [PATCH] added withFunction --- packages/boringlang/src/types/type_checker.ts | 69 +++++++++++++++++-- 1 file changed, 64 insertions(+), 5 deletions(-) diff --git a/packages/boringlang/src/types/type_checker.ts b/packages/boringlang/src/types/type_checker.ts index de786ee..d7b3972 100644 --- a/packages/boringlang/src/types/type_checker.ts +++ b/packages/boringlang/src/types/type_checker.ts @@ -1,4 +1,13 @@ -import { functionToType, Module, TypeUsage } from "../parse/ast"; +import { + Function, + FunctionDeclaration, + functionToType, + Impl, + Module, + StructTypeDeclaration, + TraitTypeDeclaration, + TypeUsage, +} from "../parse/ast"; import { TypeSystem } from "./type_system"; interface EnvImpl { @@ -25,6 +34,27 @@ interface Context { environment: Record; } +function typeExists(ctx: Context, type: TypeUsage) { + if (type.typeUsage === "NamedTypeUsage") { + if ( + !ctx.environment[type.name.text] || + ctx.environment[type.name.text].namedEntity !== "NamedType" + ) { + throw Error(`${type.name.text} is not a type.`); + } + } + if (type.typeUsage === "FunctionTypeUsage") { + for (const arg of type.arguments) { + typeExists(ctx, arg); + } + typeExists(ctx, type.returnType); + } +} + +const deepCopy = (o: T) => { + return JSON.parse(JSON.stringify(o)) as T; +}; + class TypeChecker { withModule = (module: Module, typeSystem: TypeSystem) => { const ctx: Context = { @@ -94,17 +124,46 @@ class TypeChecker { // environment set up, actually recurse. for (const item of module.items) { if (item.moduleItem === "Function") { - // this.withFunction(item, typeSystem); + this.withFunction(ctx, item, typeSystem); } if (item.moduleItem === "Impl") { - // this.withImpl(item, typeSystem); + this.withImpl(ctx, item, typeSystem); } if (item.moduleItem === "StructTypeDeclaration") { - // this.withImpl(item, typeSystem); + this.withStruct(ctx, item, typeSystem); } if (item.moduleItem === "TraitTypeDeclaration") { - // this.withTrait(item, typeSystem); + this.withTrait(ctx, item, typeSystem); } } }; + + withFunction = (ctx: Context, fn: Function, typeSystem: TypeSystem) => { + this.withFunctionDeclaration(ctx, fn.declaration, typeSystem); + const fnCtx = deepCopy(ctx); + for (const arg of fn.declaration.arguments) { + fnCtx.environment[arg.name.text] = { + namedEntity: "Variable", + type: arg.type, + }; + } + // this.withBlock(fnCtx, fn.block, typeSystem); + typeSystem.compare({ + left: fn.declaration.returnType, + operation: { operation: "equals" }, + right: fn.block.type, + }); + }; + + withFunctionDeclaration = (ctx: Context, def: FunctionDeclaration, typeSystem: TypeSystem) => { + for (const arg of def.arguments) { + typeExists(ctx, arg.type); + } + typeExists(ctx, def.returnType); + }; + + withImpl = (ctx: Context, impl: Impl, typeSystem: TypeSystem) => {}; + + withStruct = (ctx: Context, struct: StructTypeDeclaration, typeSystem: TypeSystem) => {}; + withTrait = (ctx: Context, trait: TraitTypeDeclaration, typeSystem: TypeSystem) => {}; }