This commit is contained in:
nub31
2026-02-24 20:34:27 +01:00
parent 76efc84984
commit 35867ffa28
4 changed files with 118 additions and 52 deletions

View File

@@ -8,6 +8,21 @@ namespace Compiler;
public abstract class NubType
{
public abstract override string ToString();
[Obsolete("Use IsAssignableTo instead of ==", error: true)]
public static bool operator ==(NubType? a, NubType? b) => throw new InvalidOperationException("Use IsAssignableTo");
[Obsolete("Use IsAssignableTo instead of ==", error: true)]
public static bool operator !=(NubType? a, NubType? b) => throw new InvalidOperationException("Use IsAssignableTo");
public bool IsAssignableTo(NubType target)
{
return (this, target) switch
{
(NubTypeEnumVariant variant, NubTypeEnum targetEnum) => ReferenceEquals(variant.EnumType, targetEnum),
_ => ReferenceEquals(this, target),
};
}
}
public class NubTypeVoid : NubType
@@ -135,6 +150,30 @@ public class NubTypeEnum : NubType
public override string ToString() => $"enum {Module}::{Name}";
}
public class NubTypeEnumVariant : NubType
{
private static readonly Dictionary<(NubTypeEnum EnumType, string Variant), NubTypeEnumVariant> Cache = new();
public static NubTypeEnumVariant Get(NubTypeEnum enumType, string variant)
{
if (!Cache.TryGetValue((enumType, variant), out var variantType))
Cache[(enumType, variant)] = variantType = new NubTypeEnumVariant(enumType, variant);
return variantType;
}
private NubTypeEnumVariant(NubTypeEnum enumType, string variant)
{
EnumType = enumType;
Variant = variant;
}
public NubTypeEnum EnumType { get; }
public string Variant { get; }
public override string ToString() => $"{EnumType}.{Variant}";
}
public class NubTypePointer : NubType
{
private static readonly Dictionary<NubType, NubTypePointer> Cache = new();
@@ -245,11 +284,21 @@ public class TypeEncoder
sb.Append(')');
break;
case NubTypeEnum st:
sb.Append("E(");
sb.Append(st.Module);
case NubTypeEnum e:
sb.Append("EN(");
sb.Append(e.Module);
sb.Append(':');
sb.Append(st.Name);
sb.Append(e.Name);
sb.Append(')');
break;
case NubTypeEnumVariant ev:
sb.Append("EV(");
sb.Append(ev.EnumType.Module);
sb.Append(':');
sb.Append(ev.EnumType.Name);
sb.Append(':');
sb.Append(ev.Variant);
sb.Append(')');
break;
@@ -364,23 +413,49 @@ public class TypeDecoder
return NubTypeStruct.Get(module, name);
}
private NubTypeEnum DecodeEnum()
private NubType DecodeEnum()
{
var sb = new StringBuilder();
Expect('(');
while (!TryExpect(':'))
sb.Append(Consume());
if (TryExpect('V'))
{
Expect('(');
while (!TryExpect(':'))
sb.Append(Consume());
var module = sb.ToString();
sb.Clear();
var module = sb.ToString();
sb.Clear();
while (!TryExpect(')'))
sb.Append(Consume());
while (!TryExpect(':'))
sb.Append(Consume());
var name = sb.ToString();
var name = sb.ToString();
return NubTypeEnum.Get(module, name);
while (!TryExpect(')'))
sb.Append(Consume());
var variant = sb.ToString();
return NubTypeEnumVariant.Get(NubTypeEnum.Get(module, name), variant);
}
else if (TryExpect('N'))
{
Expect('(');
while (!TryExpect(':'))
sb.Append(Consume());
var module = sb.ToString();
sb.Clear();
while (!TryExpect(')'))
sb.Append(Consume());
var name = sb.ToString();
return NubTypeEnum.Get(module, name);
}
throw new Exception($"Expected 'V' or 'N'");
}
private bool TryPeek(out char c)