WIP: dev #1
@@ -448,6 +448,7 @@ public class Generator
|
|||||||
NubTypeVoid => "void" + (varName != null ? $" {varName}" : ""),
|
NubTypeVoid => "void" + (varName != null ? $" {varName}" : ""),
|
||||||
NubTypeBool => "bool" + (varName != null ? $" {varName}" : ""),
|
NubTypeBool => "bool" + (varName != null ? $" {varName}" : ""),
|
||||||
NubTypeStruct type => $"struct {NameMangler.Mangle(type.Module, type.Name, type)}" + (varName != null ? $" {varName}" : ""),
|
NubTypeStruct type => $"struct {NameMangler.Mangle(type.Module, type.Name, type)}" + (varName != null ? $" {varName}" : ""),
|
||||||
|
NubTypeAnonymousStruct type => CTypeAnonymousStruct(type, varName),
|
||||||
NubTypeEnum type => $"struct {NameMangler.Mangle(type.Module, type.Name, type)}" + (varName != null ? $" {varName}" : ""),
|
NubTypeEnum type => $"struct {NameMangler.Mangle(type.Module, type.Name, type)}" + (varName != null ? $" {varName}" : ""),
|
||||||
NubTypeEnumVariant type => CType(type.EnumType, varName),
|
NubTypeEnumVariant type => CType(type.EnumType, varName),
|
||||||
NubTypeSInt type => $"int{type.Width}_t" + (varName != null ? $" {varName}" : ""),
|
NubTypeSInt type => $"int{type.Width}_t" + (varName != null ? $" {varName}" : ""),
|
||||||
@@ -458,6 +459,11 @@ public class Generator
|
|||||||
_ => throw new ArgumentOutOfRangeException(nameof(node), node, null)
|
_ => throw new ArgumentOutOfRangeException(nameof(node), node, null)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private string CTypeAnonymousStruct(NubTypeAnonymousStruct type, string? varName)
|
||||||
|
{
|
||||||
|
return $"struct {{ {string.Join(' ', type.Fields.Select(x => $"{CType(x.Type)} {x.Name};"))} }}{(varName != null ? $" {varName}" : "")}";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class IndentedTextWriter
|
internal class IndentedTextWriter
|
||||||
|
|||||||
@@ -192,6 +192,7 @@ public class ModuleGraph
|
|||||||
{
|
{
|
||||||
NodeTypeBool => NubTypeBool.Instance,
|
NodeTypeBool => NubTypeBool.Instance,
|
||||||
NodeTypeNamed type => ResolveNamedType(type, currentModule),
|
NodeTypeNamed type => ResolveNamedType(type, currentModule),
|
||||||
|
NodeTypeAnonymousStruct type => NubTypeAnonymousStruct.Get(type.Fields.Select(x => new NubTypeAnonymousStruct.Field(x.Name.Ident, ResolveType(x.Type, currentModule))).ToList()),
|
||||||
NodeTypeFunc type => NubTypeFunc.Get(type.Parameters.Select(x => ResolveType(x, currentModule)).ToList(), ResolveType(type.ReturnType, 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)),
|
NodeTypePointer type => NubTypePointer.Get(ResolveType(type.To, currentModule)),
|
||||||
NodeTypeSInt type => NubTypeSInt.Get(type.Width),
|
NodeTypeSInt type => NubTypeSInt.Get(type.Width),
|
||||||
|
|||||||
@@ -123,7 +123,39 @@ public class NubTypeStruct : NubType
|
|||||||
public string Module { get; }
|
public string Module { get; }
|
||||||
public string Name { 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
|
public class NubTypeEnum : NubType
|
||||||
@@ -147,7 +179,7 @@ public class NubTypeEnum : NubType
|
|||||||
public string Module { get; }
|
public string Module { get; }
|
||||||
public string Name { get; }
|
public string Name { get; }
|
||||||
|
|
||||||
public override string ToString() => $"enum {Module}::{Name}";
|
public override string ToString() => $"{Module}::{Name}";
|
||||||
}
|
}
|
||||||
|
|
||||||
public class NubTypeEnumVariant : NubType
|
public class NubTypeEnumVariant : NubType
|
||||||
@@ -277,7 +309,7 @@ public class TypeEncoder
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case NubTypeStruct st:
|
case NubTypeStruct st:
|
||||||
sb.Append("T(");
|
sb.Append("TN(");
|
||||||
sb.Append(st.Module);
|
sb.Append(st.Module);
|
||||||
sb.Append(':');
|
sb.Append(':');
|
||||||
sb.Append(st.Name);
|
sb.Append(st.Name);
|
||||||
@@ -312,6 +344,17 @@ public class TypeEncoder
|
|||||||
sb.Append(')');
|
sb.Append(')');
|
||||||
break;
|
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:
|
default:
|
||||||
throw new NotSupportedException(type.GetType().Name);
|
throw new NotSupportedException(type.GetType().Name);
|
||||||
}
|
}
|
||||||
@@ -394,7 +437,34 @@ public class TypeDecoder
|
|||||||
return NubTypeFunc.Get(types.Take(types.Count - 1).ToList(), types.Last());
|
return NubTypeFunc.Get(types.Take(types.Count - 1).ToList(), types.Last());
|
||||||
}
|
}
|
||||||
|
|
||||||
private NubTypeStruct DecodeStruct()
|
private NubType DecodeStruct()
|
||||||
|
{
|
||||||
|
|
||||||
|
if (TryExpect('A'))
|
||||||
|
{
|
||||||
|
var sb = new StringBuilder();
|
||||||
|
var fields = new List<NubTypeAnonymousStruct.Field>();
|
||||||
|
|
||||||
|
Expect('(');
|
||||||
|
while (!TryExpect(')'))
|
||||||
|
{
|
||||||
|
while (!TryExpect(':'))
|
||||||
|
{
|
||||||
|
sb.Append(Consume());
|
||||||
|
}
|
||||||
|
|
||||||
|
var name = sb.ToString();
|
||||||
|
sb.Clear();
|
||||||
|
|
||||||
|
var type = DecodeType();
|
||||||
|
|
||||||
|
fields.Add(new NubTypeAnonymousStruct.Field(name, type));
|
||||||
|
}
|
||||||
|
|
||||||
|
return NubTypeAnonymousStruct.Get(fields);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TryExpect('N'))
|
||||||
{
|
{
|
||||||
var sb = new StringBuilder();
|
var sb = new StringBuilder();
|
||||||
|
|
||||||
@@ -413,6 +483,9 @@ public class TypeDecoder
|
|||||||
return NubTypeStruct.Get(module, name);
|
return NubTypeStruct.Get(module, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
throw new Exception("Expected 'A' or 'N'");
|
||||||
|
}
|
||||||
|
|
||||||
private NubType DecodeEnum()
|
private NubType DecodeEnum()
|
||||||
{
|
{
|
||||||
var sb = new StringBuilder();
|
var sb = new StringBuilder();
|
||||||
|
|||||||
@@ -457,6 +457,21 @@ public class Parser
|
|||||||
return new NodeTypeFunc(TokensFrom(startIndex), parameters, returnType);
|
return new NodeTypeFunc(TokensFrom(startIndex), parameters, returnType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (TryExpectSymbol(Symbol.OpenCurly))
|
||||||
|
{
|
||||||
|
var fields = new List<NodeTypeAnonymousStruct.Field>();
|
||||||
|
|
||||||
|
while (!TryExpectSymbol(Symbol.CloseCurly))
|
||||||
|
{
|
||||||
|
var name = ExpectIdent();
|
||||||
|
ExpectSymbol(Symbol.Colon);
|
||||||
|
var type = ParseType();
|
||||||
|
fields.Add(new NodeTypeAnonymousStruct.Field(name, type));
|
||||||
|
}
|
||||||
|
|
||||||
|
return new NodeTypeAnonymousStruct(TokensFrom(startIndex), fields);
|
||||||
|
}
|
||||||
|
|
||||||
if (TryExpectIdent(out var ident))
|
if (TryExpectIdent(out var ident))
|
||||||
{
|
{
|
||||||
switch (ident.Ident)
|
switch (ident.Ident)
|
||||||
@@ -953,6 +968,17 @@ public class NodeTypeNamed(List<Token> tokens, List<TokenIdent> sections) : Node
|
|||||||
public List<TokenIdent> Sections { get; } = sections;
|
public List<TokenIdent> Sections { get; } = sections;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class NodeTypeAnonymousStruct(List<Token> tokens, List<NodeTypeAnonymousStruct.Field> fields) : NodeType(tokens)
|
||||||
|
{
|
||||||
|
public List<Field> Fields { get; } = fields;
|
||||||
|
|
||||||
|
public class Field(TokenIdent name, NodeType type)
|
||||||
|
{
|
||||||
|
public TokenIdent Name { get; } = name;
|
||||||
|
public NodeType Type { get; } = type;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public class NodeTypePointer(List<Token> tokens, NodeType to) : NodeType(tokens)
|
public class NodeTypePointer(List<Token> tokens, NodeType to) : NodeType(tokens)
|
||||||
{
|
{
|
||||||
public NodeType To { get; } = to;
|
public NodeType To { get; } = to;
|
||||||
|
|||||||
@@ -459,6 +459,7 @@ public class TypeChecker
|
|||||||
{
|
{
|
||||||
NodeTypeBool => NubTypeBool.Instance,
|
NodeTypeBool => NubTypeBool.Instance,
|
||||||
NodeTypeNamed type => ResolveNamedType(type),
|
NodeTypeNamed type => ResolveNamedType(type),
|
||||||
|
NodeTypeAnonymousStruct type => NubTypeAnonymousStruct.Get(type.Fields.Select(x => new NubTypeAnonymousStruct.Field(x.Name.Ident, ResolveType(x.Type))).ToList()),
|
||||||
NodeTypeFunc type => NubTypeFunc.Get(type.Parameters.Select(ResolveType).ToList(), ResolveType(type.ReturnType)),
|
NodeTypeFunc type => NubTypeFunc.Get(type.Parameters.Select(ResolveType).ToList(), ResolveType(type.ReturnType)),
|
||||||
NodeTypePointer type => NubTypePointer.Get(ResolveType(type.To)),
|
NodeTypePointer type => NubTypePointer.Get(ResolveType(type.To)),
|
||||||
NodeTypeSInt type => NubTypeSInt.Get(type.Width),
|
NodeTypeSInt type => NubTypeSInt.Get(type.Width),
|
||||||
|
|||||||
@@ -1,9 +1,37 @@
|
|||||||
module math
|
module math
|
||||||
|
|
||||||
struct vec2 { x: i32 y: i32 }
|
struct vec2 {
|
||||||
struct vec3 { x: i32 y: i32 z: i32 }
|
x: i32
|
||||||
struct color { r: i32 g: i32 b: i32 a: i32 }
|
y: i32
|
||||||
struct example { a: vec2 b: vec3 c: color }
|
}
|
||||||
|
|
||||||
|
struct vec3 {
|
||||||
|
x: i32
|
||||||
|
y: i32
|
||||||
|
z: i32
|
||||||
|
}
|
||||||
|
|
||||||
|
struct color {
|
||||||
|
r: i32
|
||||||
|
g: i32
|
||||||
|
b: i32
|
||||||
|
a: i32
|
||||||
|
}
|
||||||
|
|
||||||
|
struct example {
|
||||||
|
a: {
|
||||||
|
a: i32
|
||||||
|
}
|
||||||
|
b: {
|
||||||
|
b: {
|
||||||
|
c: i32
|
||||||
|
}
|
||||||
|
c: {
|
||||||
|
d: i32
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
export enum message {
|
export enum message {
|
||||||
quit
|
quit
|
||||||
|
|||||||
Reference in New Issue
Block a user