Add anonymous structs
This commit is contained in:
@@ -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()
|
||||
|
||||
Reference in New Issue
Block a user