...
This commit is contained in:
@@ -110,9 +110,9 @@ public class BoolTypeNode : SimpleTypeNode
|
||||
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 override StorageSize StorageSize => StorageSize.U64;
|
||||
@@ -187,13 +187,13 @@ public class StructTypeFunc(string name, FuncTypeNode 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 Name { get; } = name;
|
||||
public IReadOnlyList<StructTypeField> Fields { get; set; } = fields;
|
||||
public IReadOnlyList<StructTypeFunc> Functions { get; set; } = functions;
|
||||
public IReadOnlyList<InterfaceTypeNode> InterfaceImplementations { get; set; } = interfaceImplementations;
|
||||
public List<StructTypeField> Fields { get; set; } = fields;
|
||||
public List<StructTypeFunc> Functions { get; set; } = functions;
|
||||
public List<InterfaceTypeNode> InterfaceImplementations { get; set; } = interfaceImplementations;
|
||||
|
||||
public override string ToString() => Name;
|
||||
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 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 Name { get; } = name;
|
||||
public IReadOnlyList<InterfaceTypeFunc> Functions { get; set; } = functions;
|
||||
public List<InterfaceTypeFunc> Functions { get; set; } = functions;
|
||||
|
||||
public override string ToString() => Name;
|
||||
public override bool Equals(TypeNode? other) => other is InterfaceTypeNode interfaceType && Name == interfaceType.Name && Module == interfaceType.Module;
|
||||
|
||||
@@ -520,33 +520,67 @@ 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)
|
||||
{
|
||||
if (!_visibleModules.TryGetValue(customType.Module, out var module))
|
||||
var key = (customType.Module, customType.Name);
|
||||
|
||||
if (_typeCache.TryGetValue(key, out var cachedType))
|
||||
{
|
||||
throw new TypeCheckerException(Diagnostic.Error($"Module {customType.Module} not found").WithHelp($"import \"{customType.Module}\"").At(customType).Build());
|
||||
return cachedType;
|
||||
}
|
||||
|
||||
var includePrivate = customType.Module == _syntaxTree.Metadata.ModuleName;
|
||||
|
||||
var structType = module.StructTypes(includePrivate).FirstOrDefault(x => x.Name == customType.Name);
|
||||
if (structType != null)
|
||||
if (!_resolvingTypes.Add(key))
|
||||
{
|
||||
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, [], []);
|
||||
_referencedStructTypes.Add(result);
|
||||
return result;
|
||||
var placeholder = new StructTypeNode(customType.Module, customType.Name, new List<StructTypeField>(), [], []);
|
||||
_typeCache[key] = placeholder;
|
||||
return placeholder;
|
||||
}
|
||||
|
||||
var interfaceType = module.InterfaceTypes(includePrivate).FirstOrDefault(x => x.Name == customType.Name);
|
||||
if (interfaceType != null)
|
||||
try
|
||||
{
|
||||
var result = new InterfaceTypeNode(customType.Module, interfaceType.Name, []);
|
||||
_referencedInterfaceTypes.AddRange(result);
|
||||
return result;
|
||||
}
|
||||
if (!_visibleModules.TryGetValue(customType.Module, out var module))
|
||||
{
|
||||
throw new TypeCheckerException(Diagnostic.Error($"Module {customType.Module} not found").WithHelp($"import \"{customType.Module}\"").At(customType).Build());
|
||||
}
|
||||
|
||||
throw new TypeCheckerException(Diagnostic.Error($"Type {customType.Name} not found in module {customType.Module}").At(customType).Build());
|
||||
var includePrivate = customType.Module == _syntaxTree.Metadata.ModuleName;
|
||||
|
||||
var structType = module.StructTypes(includePrivate).FirstOrDefault(x => x.Name == customType.Name);
|
||||
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();
|
||||
result.Fields.AddRange(fields);
|
||||
|
||||
// todo(nub31): Functions and interface implementations
|
||||
|
||||
_referencedStructTypes.Add(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
var interfaceType = module.InterfaceTypes(includePrivate).FirstOrDefault(x => x.Name == customType.Name);
|
||||
if (interfaceType != null)
|
||||
{
|
||||
var result = new InterfaceTypeNode(customType.Module, interfaceType.Name, []);
|
||||
_typeCache[key] = result;
|
||||
|
||||
// todo(nub31): Put func resolution code here
|
||||
|
||||
_referencedInterfaceTypes.AddRange(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
throw new TypeCheckerException(Diagnostic.Error($"Type {customType.Name} not found in module {customType.Module}").At(customType).Build());
|
||||
}
|
||||
finally
|
||||
{
|
||||
_resolvingTypes.Remove(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user