From 853f57102c35a7bfa506e88f1296be6b08572137 Mon Sep 17 00:00:00 2001 From: nub31 Date: Tue, 12 Aug 2025 21:05:12 +0200 Subject: [PATCH] Fix infinite recursion --- .../NubLang/TypeChecking/Node/TypeNode.cs | 10 ++++----- .../NubLang/TypeChecking/TypeChecker.cs | 22 +++++++++++++++++-- 2 files changed, 25 insertions(+), 7 deletions(-) diff --git a/src/compiler/NubLang/TypeChecking/Node/TypeNode.cs b/src/compiler/NubLang/TypeChecking/Node/TypeNode.cs index 511a872..fa77541 100644 --- a/src/compiler/NubLang/TypeChecking/Node/TypeNode.cs +++ b/src/compiler/NubLang/TypeChecking/Node/TypeNode.cs @@ -177,19 +177,19 @@ public class StringTypeNode : ComplexTypeNode public class StructTypeNode(string name, IReadOnlyList fields, IReadOnlyList functions, IReadOnlyList interfaceImplementations) : ComplexTypeNode { public string Name { get; } = name; - public IReadOnlyList Fields { get; } = fields; - public IReadOnlyList Functions { get; } = functions; - public IReadOnlyList InterfaceImplementations { get; } = interfaceImplementations; + public IReadOnlyList Fields { get; set; } = fields; + public IReadOnlyList Functions { get; set; } = functions; + public IReadOnlyList InterfaceImplementations { get; set; } = interfaceImplementations; public override string ToString() => Name; public override bool Equals(TypeNode? other) => other is StructTypeNode custom && Name == custom.Name; public override int GetHashCode() => HashCode.Combine(typeof(StructTypeNode), Name); } -public class InterfaceTypeNode(string name, IReadOnlyList funcs) : ComplexTypeNode +public class InterfaceTypeNode(string name, IReadOnlyList functions) : ComplexTypeNode { public string Name { get; } = name; - public IReadOnlyList Funcs { get; } = funcs; + public IReadOnlyList Functions { get; set; } = functions; public override string ToString() => Name; public override bool Equals(TypeNode? other) => other is InterfaceTypeNode custom && Name == custom.Name; diff --git a/src/compiler/NubLang/TypeChecking/TypeChecker.cs b/src/compiler/NubLang/TypeChecking/TypeChecker.cs index e29b612..2fdf35e 100644 --- a/src/compiler/NubLang/TypeChecking/TypeChecker.cs +++ b/src/compiler/NubLang/TypeChecking/TypeChecker.cs @@ -646,8 +646,15 @@ public sealed class TypeChecker }; } + private readonly Dictionary _typeCache = new(); + private TypeNode CheckCustomType(CustomTypeSyntax type) { + if (_typeCache.TryGetValue(type.Name, out var cachedType)) + { + return cachedType; + } + var structs = _definitionTable.LookupStruct(type.Name).ToArray(); if (structs.Length > 0) { @@ -658,6 +665,9 @@ public sealed class TypeChecker var @struct = structs[0]; + var result = new StructTypeNode(type.Name, [], [], []); + _typeCache.Add(type.Name, result); + var fields = @struct.Fields.Select(x => CheckType(x.Type)).ToList(); var funcs = @struct.Functions @@ -677,7 +687,10 @@ public sealed class TypeChecker interfaceImplementations.Add(interfaceType); } - return new StructTypeNode(type.Name, fields, funcs, interfaceImplementations); + result.Fields = fields; + result.Functions = funcs; + result.InterfaceImplementations = interfaceImplementations; + return result; } var interfaces = _definitionTable.LookupInterface(type.Name).ToArray(); @@ -689,11 +702,16 @@ public sealed class TypeChecker } var @interface = interfaces[0]; + + var result = new InterfaceTypeNode(type.Name, []); + _typeCache.Add(type.Name, result); + var functions = @interface.Functions .Select(x => new FuncTypeNode(x.Signature.Parameters.Select(y => CheckType(y.Type)).ToList(), CheckType(x.Signature.ReturnType))) .ToList(); - return new InterfaceTypeNode(type.Name, functions); + result.Functions = functions; + return result; } throw new TypeCheckerException(Diagnostic.Error($"Type {type.Name} is not defined").Build());