...
This commit is contained in:
@@ -191,7 +191,7 @@ public class ModuleGraph
|
||||
return node switch
|
||||
{
|
||||
NodeTypeBool => NubTypeBool.Instance,
|
||||
NodeTypeCustom type => ResolveCustomType(type, currentModule),
|
||||
NodeTypeNamed type => ResolveNamedType(type, currentModule),
|
||||
NodeTypeFunc type => NubTypeFunc.Get(type.Parameters.Select(x => ResolveType(x, currentModule)).ToList(), ResolveType(type.ReturnType, currentModule)),
|
||||
NodeTypePointer type => NubTypePointer.Get(ResolveType(type.To, currentModule)),
|
||||
NodeTypeSInt type => NubTypeSInt.Get(type.Width),
|
||||
@@ -202,25 +202,103 @@ public class ModuleGraph
|
||||
};
|
||||
}
|
||||
|
||||
NubType ResolveCustomType(NodeTypeCustom type, string currentModule)
|
||||
NubType ResolveNamedType(NodeTypeNamed type, string currentModule)
|
||||
{
|
||||
var module = modules.GetValueOrDefault(type.Module.Ident);
|
||||
if (module == null)
|
||||
throw new CompileException(Diagnostic.Error($"Unknown module: {type.Module.Ident}").Build());
|
||||
|
||||
var includePrivate = currentModule == type.Module.Ident;
|
||||
|
||||
if (!module.TryResolveType(type.Name.Ident, includePrivate, out var customType))
|
||||
throw new CompileException(Diagnostic.Error($"Unknown custom type: {type.Module.Ident}::{type.Name.Ident}").Build());
|
||||
|
||||
return customType switch
|
||||
return type.Sections.Count switch
|
||||
{
|
||||
Module.TypeInfoStruct => NubTypeStruct.Get(type.Module.Ident, type.Name.Ident),
|
||||
Module.TypeInfoEnum => NubTypeEnum.Get(type.Module.Ident, type.Name.Ident),
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(customType))
|
||||
3 => ResolveThreePartType(type.Sections[0], type.Sections[1], type.Sections[2], currentModule),
|
||||
2 => ResolveTwoPartType(type.Sections[0], type.Sections[1], currentModule),
|
||||
1 => ResolveOnePartType(type.Sections[0], currentModule),
|
||||
_ => throw BasicError("Invalid type name")
|
||||
};
|
||||
}
|
||||
|
||||
NubType ResolveThreePartType(TokenIdent first, TokenIdent second, TokenIdent third, string currentModule)
|
||||
{
|
||||
var module = ResolveModule(first);
|
||||
if (!module.TryResolveType(second.Ident, currentModule == module.Name, out var typeInfo))
|
||||
throw BasicError($"Named type '{module.Name}::{second.Ident}' not found");
|
||||
|
||||
if (typeInfo is not Module.TypeInfoEnum enumInfo)
|
||||
throw BasicError($"'{module.Name}::{second.Ident}' is not an enum");
|
||||
|
||||
var variant = enumInfo.Variants.FirstOrDefault(v => v.Name == third.Ident);
|
||||
if (variant == null)
|
||||
throw BasicError($"Enum '{module.Name}::{second.Ident}' does not have a variant named '{third.Ident}'");
|
||||
|
||||
return NubTypeEnumVariant.Get(NubTypeEnum.Get(module.Name, second.Ident), third.Ident);
|
||||
}
|
||||
|
||||
NubType ResolveTwoPartType(TokenIdent first, TokenIdent second, string currentModule)
|
||||
{
|
||||
if (TryResolveEnumVariant(currentModule, first.Ident, second.Ident, out var variant))
|
||||
return variant;
|
||||
|
||||
var module = ResolveModule(first);
|
||||
if (!module.TryResolveType(second.Ident, currentModule == module.Name, out var typeInfo))
|
||||
throw BasicError($"Named type '{module.Name}::{second.Ident}' not found");
|
||||
|
||||
return typeInfo switch
|
||||
{
|
||||
Module.TypeInfoStruct => NubTypeStruct.Get(module.Name, second.Ident),
|
||||
Module.TypeInfoEnum => NubTypeEnum.Get(module.Name, second.Ident),
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(typeInfo))
|
||||
};
|
||||
}
|
||||
|
||||
NubType ResolveOnePartType(TokenIdent name, string currentModule)
|
||||
{
|
||||
if (!modules.TryGetValue(currentModule, out var module))
|
||||
throw BasicError($"Module '{currentModule}' not found");
|
||||
|
||||
if (!module.TryResolveType(name.Ident, true, out var typeInfo))
|
||||
throw BasicError($"Named type '{module.Name}::{name.Ident}' not found");
|
||||
|
||||
return typeInfo switch
|
||||
{
|
||||
Module.TypeInfoStruct => NubTypeStruct.Get(module.Name, name.Ident),
|
||||
Module.TypeInfoEnum => NubTypeEnum.Get(module.Name, name.Ident),
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(typeInfo))
|
||||
};
|
||||
}
|
||||
|
||||
Module ResolveModule(TokenIdent name)
|
||||
{
|
||||
if (!modules.TryGetValue(name.Ident, out var module))
|
||||
throw BasicError($"Module '{name.Ident}' not found");
|
||||
|
||||
return module;
|
||||
}
|
||||
|
||||
bool TryResolveEnumVariant(string moduleName, string enumName, string variantName, [NotNullWhen(true)] out NubType? result)
|
||||
{
|
||||
result = null;
|
||||
|
||||
if (!modules.TryGetValue(moduleName, out var module))
|
||||
return false;
|
||||
|
||||
if (!module.TryResolveType(enumName, true, out var typeInfo))
|
||||
return false;
|
||||
|
||||
if (typeInfo is not Module.TypeInfoEnum enumInfo)
|
||||
return false;
|
||||
|
||||
var variant = enumInfo.Variants.FirstOrDefault(v => v.Name == variantName);
|
||||
if (variant == null)
|
||||
return false;
|
||||
|
||||
result = NubTypeEnumVariant.Get(
|
||||
NubTypeEnum.Get(moduleName, enumName),
|
||||
variantName);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Exception BasicError(string message)
|
||||
{
|
||||
return new CompileException(Diagnostic.Error(message).Build());
|
||||
}
|
||||
|
||||
Module GetOrCreateModule(string name)
|
||||
{
|
||||
if (!modules.TryGetValue(name, out var module))
|
||||
|
||||
Reference in New Issue
Block a user