Add anonymous structs

This commit is contained in:
nub31
2026-02-25 21:21:28 +01:00
parent d771396bd4
commit cb4aeb9c01
6 changed files with 153 additions and 18 deletions

View File

@@ -123,7 +123,39 @@ public class NubTypeStruct : NubType
public string Module { get; }
public string Name { get; }
public override string ToString() => $"struct {Module}::{Name}";
public override string ToString() => $"{Module}::{Name}";
}
public class NubTypeAnonymousStruct : NubType
{
private static readonly Dictionary<Signature, NubTypeAnonymousStruct> Cache = new();
public static NubTypeAnonymousStruct Get(List<Field> fields)
{
var sig = new Signature(fields);
if (!Cache.TryGetValue(sig, out var func))
Cache[sig] = func = new NubTypeAnonymousStruct(fields);
return func;
}
private NubTypeAnonymousStruct(IReadOnlyList<Field> fields)
{
Fields = fields;
}
public IReadOnlyList<Field> Fields { get; }
public override string ToString() => $"{{ {string.Join(", ", Fields.Select(x => $"{x.Name}: {x.Type}"))} }}";
public class Field(string name, NubType type)
{
public string Name { get; } = name;
public NubType Type { get; } = type;
}
private record Signature(IReadOnlyList<Field> Fields);
}
public class NubTypeEnum : NubType
@@ -147,7 +179,7 @@ public class NubTypeEnum : NubType
public string Module { get; }
public string Name { get; }
public override string ToString() => $"enum {Module}::{Name}";
public override string ToString() => $"{Module}::{Name}";
}
public class NubTypeEnumVariant : NubType
@@ -277,7 +309,7 @@ public class TypeEncoder
break;
case NubTypeStruct st:
sb.Append("T(");
sb.Append("TN(");
sb.Append(st.Module);
sb.Append(':');
sb.Append(st.Name);
@@ -312,6 +344,17 @@ public class TypeEncoder
sb.Append(')');
break;
case NubTypeAnonymousStruct s:
sb.Append("TA(");
foreach (var field in s.Fields)
{
sb.Append(field.Name);
sb.Append(':');
EncodeType(sb, field.Type);
}
sb.Append(')');
break;
default:
throw new NotSupportedException(type.GetType().Name);
}
@@ -394,23 +437,53 @@ public class TypeDecoder
return NubTypeFunc.Get(types.Take(types.Count - 1).ToList(), types.Last());
}
private NubTypeStruct DecodeStruct()
private NubType DecodeStruct()
{
var sb = new StringBuilder();
Expect('(');
while (!TryExpect(':'))
sb.Append(Consume());
if (TryExpect('A'))
{
var sb = new StringBuilder();
var fields = new List<NubTypeAnonymousStruct.Field>();
var module = sb.ToString();
sb.Clear();
Expect('(');
while (!TryExpect(')'))
{
while (!TryExpect(':'))
{
sb.Append(Consume());
}
while (!TryExpect(')'))
sb.Append(Consume());
var name = sb.ToString();
sb.Clear();
var name = sb.ToString();
var type = DecodeType();
return NubTypeStruct.Get(module, name);
fields.Add(new NubTypeAnonymousStruct.Field(name, type));
}
return NubTypeAnonymousStruct.Get(fields);
}
if (TryExpect('N'))
{
var sb = new StringBuilder();
Expect('(');
while (!TryExpect(':'))
sb.Append(Consume());
var module = sb.ToString();
sb.Clear();
while (!TryExpect(')'))
sb.Append(Consume());
var name = sb.ToString();
return NubTypeStruct.Get(module, name);
}
throw new Exception("Expected 'A' or 'N'");
}
private NubType DecodeEnum()