...
This commit is contained in:
@@ -110,9 +110,9 @@ public class BoolTypeNode : SimpleTypeNode
|
|||||||
public override int GetHashCode() => HashCode.Combine(typeof(BoolTypeNode));
|
public override int GetHashCode() => HashCode.Combine(typeof(BoolTypeNode));
|
||||||
}
|
}
|
||||||
|
|
||||||
public class FuncTypeNode(IReadOnlyList<TypeNode> parameters, TypeNode returnType) : SimpleTypeNode
|
public class FuncTypeNode(List<TypeNode> parameters, TypeNode returnType) : SimpleTypeNode
|
||||||
{
|
{
|
||||||
public IReadOnlyList<TypeNode> Parameters { get; } = parameters;
|
public List<TypeNode> Parameters { get; } = parameters;
|
||||||
public TypeNode ReturnType { get; } = returnType;
|
public TypeNode ReturnType { get; } = returnType;
|
||||||
|
|
||||||
public override StorageSize StorageSize => StorageSize.U64;
|
public override StorageSize StorageSize => StorageSize.U64;
|
||||||
@@ -187,13 +187,13 @@ public class StructTypeFunc(string name, FuncTypeNode type)
|
|||||||
public FuncTypeNode Type { get; } = type;
|
public FuncTypeNode Type { get; } = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
public class StructTypeNode(string module, string name, IReadOnlyList<StructTypeField> fields, IReadOnlyList<StructTypeFunc> functions, IReadOnlyList<InterfaceTypeNode> interfaceImplementations) : ComplexTypeNode
|
public class StructTypeNode(string module, string name, List<StructTypeField> fields, List<StructTypeFunc> functions, List<InterfaceTypeNode> interfaceImplementations) : ComplexTypeNode
|
||||||
{
|
{
|
||||||
public string Module { get; } = module;
|
public string Module { get; } = module;
|
||||||
public string Name { get; } = name;
|
public string Name { get; } = name;
|
||||||
public IReadOnlyList<StructTypeField> Fields { get; set; } = fields;
|
public List<StructTypeField> Fields { get; set; } = fields;
|
||||||
public IReadOnlyList<StructTypeFunc> Functions { get; set; } = functions;
|
public List<StructTypeFunc> Functions { get; set; } = functions;
|
||||||
public IReadOnlyList<InterfaceTypeNode> InterfaceImplementations { get; set; } = interfaceImplementations;
|
public List<InterfaceTypeNode> InterfaceImplementations { get; set; } = interfaceImplementations;
|
||||||
|
|
||||||
public override string ToString() => Name;
|
public override string ToString() => Name;
|
||||||
public override bool Equals(TypeNode? other) => other is StructTypeNode structType && Name == structType.Name && Module == structType.Module;
|
public override bool Equals(TypeNode? other) => other is StructTypeNode structType && Name == structType.Name && Module == structType.Module;
|
||||||
@@ -207,11 +207,11 @@ public class InterfaceTypeFunc(string name, FuncTypeNode type, int index)
|
|||||||
public int Index { get; } = index;
|
public int Index { get; } = index;
|
||||||
}
|
}
|
||||||
|
|
||||||
public class InterfaceTypeNode(string module, string name, IReadOnlyList<InterfaceTypeFunc> functions) : ComplexTypeNode
|
public class InterfaceTypeNode(string module, string name, List<InterfaceTypeFunc> functions) : ComplexTypeNode
|
||||||
{
|
{
|
||||||
public string Module { get; } = module;
|
public string Module { get; } = module;
|
||||||
public string Name { get; } = name;
|
public string Name { get; } = name;
|
||||||
public IReadOnlyList<InterfaceTypeFunc> Functions { get; set; } = functions;
|
public List<InterfaceTypeFunc> Functions { get; set; } = functions;
|
||||||
|
|
||||||
public override string ToString() => Name;
|
public override string ToString() => Name;
|
||||||
public override bool Equals(TypeNode? other) => other is InterfaceTypeNode interfaceType && Name == interfaceType.Name && Module == interfaceType.Module;
|
public override bool Equals(TypeNode? other) => other is InterfaceTypeNode interfaceType && Name == interfaceType.Name && Module == interfaceType.Module;
|
||||||
|
|||||||
@@ -520,7 +520,26 @@ public sealed class TypeChecker
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private readonly Dictionary<(string Module, string Name), TypeNode> _typeCache = new();
|
||||||
|
private readonly HashSet<(string Module, string Name)> _resolvingTypes = [];
|
||||||
|
|
||||||
private TypeNode ResolveCustomType(CustomTypeSyntax customType)
|
private TypeNode ResolveCustomType(CustomTypeSyntax customType)
|
||||||
|
{
|
||||||
|
var key = (customType.Module, customType.Name);
|
||||||
|
|
||||||
|
if (_typeCache.TryGetValue(key, out var cachedType))
|
||||||
|
{
|
||||||
|
return cachedType;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_resolvingTypes.Add(key))
|
||||||
|
{
|
||||||
|
var placeholder = new StructTypeNode(customType.Module, customType.Name, new List<StructTypeField>(), [], []);
|
||||||
|
_typeCache[key] = placeholder;
|
||||||
|
return placeholder;
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
{
|
{
|
||||||
if (!_visibleModules.TryGetValue(customType.Module, out var module))
|
if (!_visibleModules.TryGetValue(customType.Module, out var module))
|
||||||
{
|
{
|
||||||
@@ -532,8 +551,14 @@ public sealed class TypeChecker
|
|||||||
var structType = module.StructTypes(includePrivate).FirstOrDefault(x => x.Name == customType.Name);
|
var structType = module.StructTypes(includePrivate).FirstOrDefault(x => x.Name == customType.Name);
|
||||||
if (structType != null)
|
if (structType != null)
|
||||||
{
|
{
|
||||||
|
var result = new StructTypeNode(customType.Module, structType.Name, [], [], []);
|
||||||
|
_typeCache[key] = result;
|
||||||
|
|
||||||
var fields = structType.Fields.Select(x => new StructTypeField(x.Name, ResolveType(x.Type), x.HasDefaultValue)).ToList();
|
var fields = structType.Fields.Select(x => new StructTypeField(x.Name, ResolveType(x.Type), x.HasDefaultValue)).ToList();
|
||||||
var result = new StructTypeNode(customType.Module, structType.Name, fields, [], []);
|
result.Fields.AddRange(fields);
|
||||||
|
|
||||||
|
// todo(nub31): Functions and interface implementations
|
||||||
|
|
||||||
_referencedStructTypes.Add(result);
|
_referencedStructTypes.Add(result);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -542,12 +567,21 @@ public sealed class TypeChecker
|
|||||||
if (interfaceType != null)
|
if (interfaceType != null)
|
||||||
{
|
{
|
||||||
var result = new InterfaceTypeNode(customType.Module, interfaceType.Name, []);
|
var result = new InterfaceTypeNode(customType.Module, interfaceType.Name, []);
|
||||||
|
_typeCache[key] = result;
|
||||||
|
|
||||||
|
// todo(nub31): Put func resolution code here
|
||||||
|
|
||||||
_referencedInterfaceTypes.AddRange(result);
|
_referencedInterfaceTypes.AddRange(result);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new TypeCheckerException(Diagnostic.Error($"Type {customType.Name} not found in module {customType.Module}").At(customType).Build());
|
throw new TypeCheckerException(Diagnostic.Error($"Type {customType.Name} not found in module {customType.Module}").At(customType).Build());
|
||||||
}
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_resolvingTypes.Remove(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum IdentifierKind
|
public enum IdentifierKind
|
||||||
|
|||||||
Reference in New Issue
Block a user