This commit is contained in:
nub31
2026-02-13 00:27:59 +01:00
parent 21a095f691
commit ee485e4119
6 changed files with 347 additions and 399 deletions

View File

@@ -20,13 +20,9 @@ public class Generator
private readonly ModuleGraph moduleGraph;
private readonly bool compileLib;
private readonly IndentedTextWriter writer = new();
private readonly Dictionary<NubTypeStruct, string> structTypeNames = new();
private string Emit()
{
foreach (var (i, structType) in moduleGraph.GetModules().SelectMany(x => x.GetCustomTypes().OfType<NubTypeStruct>().Index()))
structTypeNames[structType] = $"s{i}";
writer.WriteLine("""
#include <float.h>
#include <stdarg.h>
@@ -43,46 +39,61 @@ public class Generator
writer.WriteLine();
foreach (var typeName in structTypeNames)
writer.WriteLine($"struct {typeName.Value};");
writer.WriteLine();
foreach (var typeName in structTypeNames)
foreach (var module in moduleGraph.GetModules())
{
writer.Write("struct ");
if (typeName.Key.Packed)
foreach (var (name, info) in module.GetTypes())
{
writer.Write("__attribute__((__packed__)) ");
if (info is Module.TypeInfoStruct s)
{
writer.WriteLine($"struct {Name.Create(module.Name, name, NubTypeStruct.Get(module.Name, name))};");
}
}
}
writer.WriteLine(typeName.Value);
writer.WriteLine("{");
using (writer.Indent())
foreach (var module in moduleGraph.GetModules())
{
foreach (var (name, info) in module.GetTypes())
{
foreach (var field in typeName.Key.Fields)
writer.WriteLine($"{CType(field.Type, field.Name)};");
if (info is Module.TypeInfoStruct s)
{
writer.WriteLine();
writer.Write("struct ");
if (s.Packed)
{
writer.Write("__attribute__((__packed__)) ");
}
writer.WriteLine(Name.Create(module.Name, name, NubTypeStruct.Get(module.Name, name)));
writer.WriteLine("{");
using (writer.Indent())
{
foreach (var field in s.Fields)
{
writer.WriteLine($"{CType(field.Type, field.Name)};");
}
}
writer.WriteLine("};");
}
}
writer.WriteLine("};");
}
writer.WriteLine();
foreach (var module in moduleGraph.GetModules())
{
foreach (var (name, type) in module.GetIdentifierTypes())
foreach (var (name, info) in module.GetIdentifiers())
{
if (type is NubTypeFunc fn)
if (info.Type is NubTypeFunc fn)
{
if (!functions.Any(x => x.GetMangledName() == SymbolNameGen.Exported(module.Name, name, type)))
if (!functions.Any(x => x.GetMangledName() == Name.Create(module.Name, name, info.Type)))
writer.Write("extern ");
writer.WriteLine($"{CType(fn.ReturnType, SymbolNameGen.Exported(module.Name, name, type))}({string.Join(", ", fn.Parameters.Select(p => CType(p)))});");
writer.WriteLine($"{CType(fn.ReturnType, Name.Create(module.Name, name, info.Type))}({string.Join(", ", fn.Parameters.Select(p => CType(p)))});");
}
else
{
writer.WriteLine($"{CType(type, SymbolNameGen.Exported(module.Name, name, type))};");
writer.WriteLine($"{CType(info.Type, Name.Create(module.Name, name, info.Type))};");
}
}
}
@@ -238,7 +249,7 @@ public class Generator
TypedNodeExpressionStructLiteral expression => EmitExpressionStructLiteral(expression),
TypedNodeExpressionMemberAccess expression => EmitExpressionMemberAccess(expression),
TypedNodeExpressionLocalIdent expression => expression.Value.Ident,
TypedNodeExpressionModuleIdent expression => SymbolNameGen.Exported(expression.Module.Ident, expression.Value.Ident, expression.Type),
TypedNodeExpressionModuleIdent expression => Name.Create(expression.Module.Ident, expression.Value.Ident, expression.Type),
TypedNodeExpressionFuncCall expression => EmitExpressionFuncCall(expression),
_ => throw new ArgumentOutOfRangeException(nameof(node), node, null)
};
@@ -293,8 +304,9 @@ public class Generator
}
var initializerStrings = initializerValues.Select(x => $".{x.Key} = {x.Value}");
var structType = (NubTypeStruct)expression.Type;
return $"(struct {structTypeNames[(NubTypeStruct)expression.Type]}){{ {string.Join(", ", initializerStrings)} }}";
return $"(struct {Name.Create(structType.Module, structType.Name, structType)}){{ {string.Join(", ", initializerStrings)} }}";
}
private string EmitExpressionMemberAccess(TypedNodeExpressionMemberAccess expression)
@@ -316,7 +328,7 @@ public class Generator
{
NubTypeVoid => "void" + (varName != null ? $" {varName}" : ""),
NubTypeBool => "bool" + (varName != null ? $" {varName}" : ""),
NubTypeStruct type => $"struct {structTypeNames[type]}" + (varName != null ? $" {varName}" : ""),
NubTypeStruct type => $"struct {Name.Create(type.Module, type.Name, type)}" + (varName != null ? $" {varName}" : ""),
NubTypeSInt type => $"int{type.Width}_t" + (varName != null ? $" {varName}" : ""),
NubTypeUInt type => $"uint{type.Width}_t" + (varName != null ? $" {varName}" : ""),
NubTypePointer type => CType(type.To) + (varName != null ? $" *{varName}" : "*"),