67 lines
2.4 KiB
C#
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;
|
|
}
|
|
} |