Save mangled name in module graph
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
using System.Text;
|
using System.Diagnostics;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
namespace Compiler;
|
namespace Compiler;
|
||||||
|
|
||||||
@@ -45,7 +46,7 @@ public class Generator
|
|||||||
{
|
{
|
||||||
if (info is Module.TypeInfoStruct s)
|
if (info is Module.TypeInfoStruct s)
|
||||||
{
|
{
|
||||||
writer.WriteLine($"struct {Name.Create(module.Name, name, NubTypeStruct.Get(module.Name, name))};");
|
writer.WriteLine($"struct {NameMangler.Mangle(module.Name, name, NubTypeStruct.Get(module.Name, name))};");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -64,7 +65,7 @@ public class Generator
|
|||||||
writer.Write("__attribute__((__packed__)) ");
|
writer.Write("__attribute__((__packed__)) ");
|
||||||
}
|
}
|
||||||
|
|
||||||
writer.WriteLine(Name.Create(module.Name, name, NubTypeStruct.Get(module.Name, name)));
|
writer.WriteLine(NameMangler.Mangle(module.Name, name, NubTypeStruct.Get(module.Name, name)));
|
||||||
writer.WriteLine("{");
|
writer.WriteLine("{");
|
||||||
using (writer.Indent())
|
using (writer.Indent())
|
||||||
{
|
{
|
||||||
@@ -86,14 +87,14 @@ public class Generator
|
|||||||
{
|
{
|
||||||
if (info.Type is NubTypeFunc fn)
|
if (info.Type is NubTypeFunc fn)
|
||||||
{
|
{
|
||||||
if (!functions.Any(x => x.GetMangledName() == Name.Create(module.Name, name, info.Type)))
|
if (info.External)
|
||||||
writer.Write("extern ");
|
writer.Write("extern ");
|
||||||
|
|
||||||
writer.WriteLine($"{CType(fn.ReturnType, Name.Create(module.Name, name, info.Type))}({string.Join(", ", fn.Parameters.Select(p => CType(p)))});");
|
writer.WriteLine($"{CType(fn.ReturnType, info.MangledName)}({string.Join(", ", fn.Parameters.Select(p => CType(p)))});");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
writer.WriteLine($"{CType(info.Type, Name.Create(module.Name, name, info.Type))};");
|
writer.WriteLine($"{CType(info.Type, info.MangledName)};");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -102,12 +103,13 @@ public class Generator
|
|||||||
|
|
||||||
if (!compileLib)
|
if (!compileLib)
|
||||||
{
|
{
|
||||||
var main = functions.First(x => x.Module == "main" && x.Name.Ident == "main");
|
if (!moduleGraph.TryResolveIdentifier("main", "main", true, out var info))
|
||||||
|
throw new UnreachableException("func main::main() is not defined. This should have been caught earlier");
|
||||||
|
|
||||||
writer.WriteLine($$"""
|
writer.WriteLine($$"""
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
return {{main.GetMangledName()}}();
|
return {{info.MangledName}}();
|
||||||
}
|
}
|
||||||
""");
|
""");
|
||||||
}
|
}
|
||||||
@@ -116,8 +118,11 @@ public class Generator
|
|||||||
|
|
||||||
foreach (var function in functions)
|
foreach (var function in functions)
|
||||||
{
|
{
|
||||||
|
if (!moduleGraph.TryResolveIdentifier(function.Module, function.Name.Ident, true, out var info))
|
||||||
|
throw new UnreachableException($"Module graph does not have info about the function {function.Module}::{function.Name.Ident}. This should have been caught earlier");
|
||||||
|
|
||||||
var parameters = function.Parameters.Select(x => CType(x.Type, x.Name.Ident));
|
var parameters = function.Parameters.Select(x => CType(x.Type, x.Name.Ident));
|
||||||
writer.WriteLine($"{CType(function.ReturnType, function.GetMangledName())}({string.Join(", ", parameters)})");
|
writer.WriteLine($"{CType(function.ReturnType, info.MangledName)}({string.Join(", ", parameters)})");
|
||||||
writer.WriteLine("{");
|
writer.WriteLine("{");
|
||||||
using (writer.Indent())
|
using (writer.Indent())
|
||||||
{
|
{
|
||||||
@@ -249,7 +254,7 @@ public class Generator
|
|||||||
TypedNodeExpressionStructLiteral expression => EmitExpressionStructLiteral(expression),
|
TypedNodeExpressionStructLiteral expression => EmitExpressionStructLiteral(expression),
|
||||||
TypedNodeExpressionMemberAccess expression => EmitExpressionMemberAccess(expression),
|
TypedNodeExpressionMemberAccess expression => EmitExpressionMemberAccess(expression),
|
||||||
TypedNodeExpressionLocalIdent expression => expression.Value.Ident,
|
TypedNodeExpressionLocalIdent expression => expression.Value.Ident,
|
||||||
TypedNodeExpressionModuleIdent expression => Name.Create(expression.Module.Ident, expression.Value.Ident, expression.Type),
|
TypedNodeExpressionModuleIdent expression => EmitExpressionModuleIdent(expression),
|
||||||
TypedNodeExpressionFuncCall expression => EmitExpressionFuncCall(expression),
|
TypedNodeExpressionFuncCall expression => EmitExpressionFuncCall(expression),
|
||||||
_ => throw new ArgumentOutOfRangeException(nameof(node), node, null)
|
_ => throw new ArgumentOutOfRangeException(nameof(node), node, null)
|
||||||
};
|
};
|
||||||
@@ -304,9 +309,8 @@ public class Generator
|
|||||||
}
|
}
|
||||||
|
|
||||||
var initializerStrings = initializerValues.Select(x => $".{x.Key} = {x.Value}");
|
var initializerStrings = initializerValues.Select(x => $".{x.Key} = {x.Value}");
|
||||||
var structType = (NubTypeStruct)expression.Type;
|
|
||||||
|
|
||||||
return $"(struct {Name.Create(structType.Module, structType.Name, structType)}){{ {string.Join(", ", initializerStrings)} }}";
|
return $"({CType(expression.Type)}){{ {string.Join(", ", initializerStrings)} }}";
|
||||||
}
|
}
|
||||||
|
|
||||||
private string EmitExpressionMemberAccess(TypedNodeExpressionMemberAccess expression)
|
private string EmitExpressionMemberAccess(TypedNodeExpressionMemberAccess expression)
|
||||||
@@ -315,6 +319,14 @@ public class Generator
|
|||||||
return $"{target}.{expression.Name.Ident}";
|
return $"{target}.{expression.Name.Ident}";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private string EmitExpressionModuleIdent(TypedNodeExpressionModuleIdent expression)
|
||||||
|
{
|
||||||
|
if (!moduleGraph.TryResolveIdentifier(expression.Module.Ident, expression.Value.Ident, true, out var info))
|
||||||
|
throw new UnreachableException($"Module graph does not have info about identifier {expression.Module.Ident}::{expression.Value.Ident}. This should have been caught earlier");
|
||||||
|
|
||||||
|
return info.MangledName;
|
||||||
|
}
|
||||||
|
|
||||||
private string EmitExpressionFuncCall(TypedNodeExpressionFuncCall expression)
|
private string EmitExpressionFuncCall(TypedNodeExpressionFuncCall expression)
|
||||||
{
|
{
|
||||||
var name = EmitExpression(expression.Target);
|
var name = EmitExpression(expression.Target);
|
||||||
@@ -328,7 +340,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 {Name.Create(type.Module, type.Name, type)}" + (varName != null ? $" {varName}" : ""),
|
NubTypeStruct type => $"struct {NameMangler.Mangle(type.Module, type.Name, type)}" + (varName != null ? $" {varName}" : ""),
|
||||||
NubTypeSInt type => $"int{type.Width}_t" + (varName != null ? $" {varName}" : ""),
|
NubTypeSInt type => $"int{type.Width}_t" + (varName != null ? $" {varName}" : ""),
|
||||||
NubTypeUInt type => $"uint{type.Width}_t" + (varName != null ? $" {varName}" : ""),
|
NubTypeUInt type => $"uint{type.Width}_t" + (varName != null ? $" {varName}" : ""),
|
||||||
NubTypePointer type => CType(type.To) + (varName != null ? $" *{varName}" : "*"),
|
NubTypePointer type => CType(type.To) + (varName != null ? $" *{varName}" : "*"),
|
||||||
|
|||||||
@@ -19,6 +19,34 @@ public class ModuleGraph
|
|||||||
return modules.Values.ToList();
|
return modules.Values.ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool TryResolveIdentifier(string moduleName, string identifierName, bool searchPrivate, [NotNullWhen(true)] out Module.IdentifierInfo? info)
|
||||||
|
{
|
||||||
|
if (!TryResolveModule(moduleName, out var module))
|
||||||
|
{
|
||||||
|
info = null;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!module.TryResolveIdentifier(identifierName, searchPrivate, out info))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool TryResolveType(string moduleName, string typeName, bool searchPrivate, [NotNullWhen(true)] out Module.TypeInfo? info)
|
||||||
|
{
|
||||||
|
if (!TryResolveModule(moduleName, out var module))
|
||||||
|
{
|
||||||
|
info = null;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!module.TryResolveType(typeName, searchPrivate, out info))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
public bool TryResolveModule(string moduleName, [NotNullWhen(true)] out Module? module)
|
public bool TryResolveModule(string moduleName, [NotNullWhen(true)] out Module? module)
|
||||||
{
|
{
|
||||||
module = modules.GetValueOrDefault(moduleName);
|
module = modules.GetValueOrDefault(moduleName);
|
||||||
@@ -69,7 +97,7 @@ public class ModuleGraph
|
|||||||
|
|
||||||
foreach (var (name, identifier) in manifestModule.Identifiers)
|
foreach (var (name, identifier) in manifestModule.Identifiers)
|
||||||
{
|
{
|
||||||
module.AddIdentifier(name, new Module.IdentifierInfo(identifier.Exported, identifier.Type));
|
module.AddIdentifier(name, new Module.IdentifierInfo(identifier.Exported, identifier.Type, identifier.MangledName, true));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -110,14 +138,14 @@ public class ModuleGraph
|
|||||||
var parameters = funcDef.Parameters.Select(x => ResolveType(x.Type, module.Name)).ToList();
|
var parameters = funcDef.Parameters.Select(x => ResolveType(x.Type, module.Name)).ToList();
|
||||||
var returnType = ResolveType(funcDef.ReturnType, module.Name);
|
var returnType = ResolveType(funcDef.ReturnType, module.Name);
|
||||||
var funcType = NubTypeFunc.Get(parameters, returnType);
|
var funcType = NubTypeFunc.Get(parameters, returnType);
|
||||||
var info = new Module.IdentifierInfo(funcDef.Exported, funcType);
|
var info = new Module.IdentifierInfo(funcDef.Exported, funcType, NameMangler.Mangle(module.Name, funcDef.Name.Ident, funcType), false);
|
||||||
module.AddIdentifier(funcDef.Name.Ident, info);
|
module.AddIdentifier(funcDef.Name.Ident, info);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var globalVariable in ast.Definitions.OfType<NodeDefinitionGlobalVariable>())
|
foreach (var globalVariable in ast.Definitions.OfType<NodeDefinitionGlobalVariable>())
|
||||||
{
|
{
|
||||||
var type = ResolveType(globalVariable.Type, module.Name);
|
var type = ResolveType(globalVariable.Type, module.Name);
|
||||||
var info = new Module.IdentifierInfo(globalVariable.Exported, type);
|
var info = new Module.IdentifierInfo(globalVariable.Exported, type, NameMangler.Mangle(module.Name, globalVariable.Name.Ident, type), false);
|
||||||
module.AddIdentifier(globalVariable.Name.Ident, info);
|
module.AddIdentifier(globalVariable.Name.Ident, info);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -233,19 +261,19 @@ public class Module(string name)
|
|||||||
identifiers.Add(name, info);
|
identifiers.Add(name, info);
|
||||||
}
|
}
|
||||||
|
|
||||||
public class IdentifierInfo(bool exported, NubType type)
|
public class IdentifierInfo(bool exported, NubType type, string mangledName, bool external)
|
||||||
{
|
{
|
||||||
public bool Exported { get; } = exported;
|
public bool Exported { get; } = exported;
|
||||||
public NubType Type { get; } = type;
|
public NubType Type { get; } = type;
|
||||||
|
public string MangledName { get; } = mangledName;
|
||||||
|
public bool External { get; } = external;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public abstract class TypeInfo(bool exported)
|
public abstract class TypeInfo(bool exported)
|
||||||
{
|
{
|
||||||
public bool Exported { get; } = exported;
|
public bool Exported { get; } = exported;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public class TypeInfoStruct(bool exported, bool packed) : TypeInfo(exported)
|
public class TypeInfoStruct(bool exported, bool packed) : TypeInfo(exported)
|
||||||
{
|
{
|
||||||
private IReadOnlyList<Field>? fields;
|
private IReadOnlyList<Field>? fields;
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ public record Manifest(Dictionary<string, Manifest.Module> Modules)
|
|||||||
foreach (var module in moduleGraph.GetModules())
|
foreach (var module in moduleGraph.GetModules())
|
||||||
{
|
{
|
||||||
var types = module.GetTypes().ToDictionary(x => x.Key, x => ConvertType(x.Value));
|
var types = module.GetTypes().ToDictionary(x => x.Key, x => ConvertType(x.Value));
|
||||||
var identifiers = module.GetIdentifiers().ToDictionary(x => x.Key, x => new Module.IdentifierInfo(x.Value.Exported, x.Value.Type));
|
var identifiers = module.GetIdentifiers().ToDictionary(x => x.Key, x => new Module.IdentifierInfo(x.Value.Exported, x.Value.Type, x.Value.MangledName));
|
||||||
modules[module.Name] = new Module(types, identifiers);
|
modules[module.Name] = new Module(types, identifiers);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -90,7 +90,7 @@ public record Manifest(Dictionary<string, Manifest.Module> Modules)
|
|||||||
|
|
||||||
public record Module(Dictionary<string, Module.TypeInfo> Types, Dictionary<string, Module.IdentifierInfo> Identifiers)
|
public record Module(Dictionary<string, Module.TypeInfo> Types, Dictionary<string, Module.IdentifierInfo> Identifiers)
|
||||||
{
|
{
|
||||||
public record IdentifierInfo(bool Exported, NubType Type);
|
public record IdentifierInfo(bool Exported, NubType Type, string MangledName);
|
||||||
|
|
||||||
[JsonDerivedType(typeof(TypeInfoStruct), "struct")]
|
[JsonDerivedType(typeof(TypeInfoStruct), "struct")]
|
||||||
public abstract record TypeInfo(bool Exported);
|
public abstract record TypeInfo(bool Exported);
|
||||||
|
|||||||
@@ -150,8 +150,6 @@ public class NubTypeFunc : NubType
|
|||||||
public IReadOnlyList<NubType> Parameters { get; }
|
public IReadOnlyList<NubType> Parameters { get; }
|
||||||
public NubType ReturnType { get; }
|
public NubType ReturnType { get; }
|
||||||
|
|
||||||
public string MangledName(string name, string module) => Name.Create(name, module, this);
|
|
||||||
|
|
||||||
private NubTypeFunc(List<NubType> parameters, NubType returnType)
|
private NubTypeFunc(List<NubType> parameters, NubType returnType)
|
||||||
{
|
{
|
||||||
Parameters = parameters;
|
Parameters = parameters;
|
||||||
@@ -434,9 +432,9 @@ public static class Hashing
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Name
|
public static class NameMangler
|
||||||
{
|
{
|
||||||
public static string Create(string module, string name, NubType type)
|
public static string Mangle(string module, string name, NubType type)
|
||||||
{
|
{
|
||||||
var canonical = TypeEncoder.Encode(type);
|
var canonical = TypeEncoder.Encode(type);
|
||||||
var hash = Hashing.Fnv1a64(canonical);
|
var hash = Hashing.Fnv1a64(canonical);
|
||||||
|
|||||||
@@ -494,11 +494,6 @@ public class TypedNodeDefinitionFunc(List<Token> tokens, string module, TokenIde
|
|||||||
return NubTypeFunc.Get(Parameters.Select(x => x.Type).ToList(), ReturnType);
|
return NubTypeFunc.Get(Parameters.Select(x => x.Type).ToList(), ReturnType);
|
||||||
}
|
}
|
||||||
|
|
||||||
public string GetMangledName()
|
|
||||||
{
|
|
||||||
return Compiler.Name.Create(Module, Name.Ident, GetNubType());
|
|
||||||
}
|
|
||||||
|
|
||||||
public class Param(List<Token> tokens, TokenIdent name, NubType type) : TypedNode(tokens)
|
public class Param(List<Token> tokens, TokenIdent name, NubType type) : TypedNode(tokens)
|
||||||
{
|
{
|
||||||
public TokenIdent Name { get; } = name;
|
public TokenIdent Name { get; } = name;
|
||||||
|
|||||||
Reference in New Issue
Block a user