Files
nub-lang/compiler/TypeResolver.cs
2026-02-09 15:52:14 +01:00

67 lines
2.4 KiB
C#

namespace Compiler;
public sealed class TypeResolver(string fileName)
{
private readonly Dictionary<string, NubTypeStruct> structTypes = [];
public List<NubTypeStruct> GetAllStructs() => structTypes.Values.ToList();
public NubTypeStruct? GetNamedStruct(string name) => structTypes.GetValueOrDefault(name);
public static TypeResolver Create(string fileName, Ast ast, out List<Diagnostic> diagnostics)
{
diagnostics = [];
var resolver = new TypeResolver(fileName);
foreach (var structDef in ast.Structs)
{
if (resolver.structTypes.ContainsKey(structDef.Name.Ident))
{
diagnostics.Add(Diagnostic.Error($"Duplicate struct: {structDef.Name.Ident}").At(fileName, structDef.Name).Build());
continue;
}
resolver.structTypes.Add(structDef.Name.Ident, new NubTypeStruct());
}
foreach (var structDef in ast.Structs)
{
var structType = resolver.structTypes[structDef.Name.Ident];
try
{
structType.ResolveFields(structDef.Fields.Select(f => new NubTypeStruct.Field(f.Name.Ident, resolver.Resolve(f.Type))).ToList());
}
catch (CompileException e)
{
diagnostics.Add(e.Diagnostic);
}
}
return resolver;
}
public NubType Resolve(NodeType node)
{
return node switch
{
NodeTypeBool type => new NubTypeBool(),
NodeTypeCustom type => ResolveStruct(type),
NodeTypeFunc type => new NubTypeFunc(type.Parameters.Select(Resolve).ToList(), Resolve(type.ReturnType)),
NodeTypePointer type => new NubTypePointer(Resolve(type.To)),
NodeTypeSInt type => new NubTypeSInt(type.Width),
NodeTypeUInt type => new NubTypeUInt(type.Width),
NodeTypeString type => new NubTypeString(),
NodeTypeVoid type => new NubTypeVoid(),
_ => throw new ArgumentOutOfRangeException(nameof(node))
};
}
private NubTypeStruct ResolveStruct(NodeTypeCustom type)
{
var structType = structTypes.GetValueOrDefault(type.Name.Ident);
if (structType == null)
throw new CompileException(Diagnostic.Error($"Unknown custom type: {type}").At(fileName, type).Build());
return structType;
}
}