This commit is contained in:
nub31
2026-02-10 19:50:55 +01:00
parent d3e2dcede8
commit 6ae10d5f90
7 changed files with 215 additions and 64 deletions

View File

@@ -1,3 +1,5 @@
using System.Text;
namespace Compiler;
public abstract class NubType
@@ -153,6 +155,8 @@ public sealed class NubTypeFunc : NubType
public IReadOnlyList<NubType> Parameters { get; }
public NubType ReturnType { get; }
public string MangledName(string name, string module) => SymbolNameGen.Exported(name, module, this);
private NubTypeFunc(List<NubType> parameters, NubType returnType)
{
Parameters = parameters;
@@ -162,4 +166,110 @@ public sealed class NubTypeFunc : NubType
public override string ToString() => $"func({string.Join(' ', Parameters)}): {ReturnType}";
private readonly record struct Signature(IReadOnlyList<NubType> Parameters, NubType ReturnType);
}
}
static class TypeMangler
{
public static string Encode(NubType type)
{
var sb = new StringBuilder();
Encode(type, sb);
return sb.ToString();
}
private static void Encode(NubType type, StringBuilder sb)
{
switch (type)
{
case NubTypeVoid:
sb.Append('V');
break;
case NubTypeBool:
sb.Append('B');
break;
case NubTypeUInt u:
sb.Append("U(");
sb.Append(u.Width);
sb.Append(')');
break;
case NubTypeSInt s:
sb.Append("U(");
sb.Append(s.Width);
sb.Append(')');
break;
case NubTypeString:
sb.Append('S');
break;
case NubTypePointer p:
sb.Append("P(");
Encode(p.To, sb);
sb.Append(')');
break;
case NubTypeStruct st:
sb.Append($"T({st.Module}::{st.Name})").Append(st.Module).Append("::").Append(st.Name).Append(')');
break;
case NubTypeFunc fn:
sb.Append("F(");
for (int i = 0; i < fn.Parameters.Count; i++)
{
Encode(fn.Parameters[i], sb);
sb.Append(',');
}
Encode(fn.ReturnType, sb);
sb.Append(')');
break;
default:
throw new NotSupportedException(type.GetType().Name);
}
}
}
static class Hashing
{
public static ulong Fnv1a64(string text)
{
const ulong offset = 14695981039346656037UL;
const ulong prime = 1099511628211UL;
ulong hash = offset;
foreach (var c in Encoding.UTF8.GetBytes(text))
{
hash ^= c;
hash *= prime;
}
return hash;
}
}
static class SymbolNameGen
{
public static string Exported(string module, string function, NubType type)
{
var canonical = TypeMangler.Encode(type);
var hash = Hashing.Fnv1a64(canonical);
return $"nub_{Sanitize(module)}_{Sanitize(function)}_{hash:x16}";
}
private static string Sanitize(string s)
{
var sb = new StringBuilder(s.Length);
foreach (var c in s)
{
if (char.IsLetterOrDigit(c))
sb.Append(c);
else
sb.Append('_');
}
return sb.ToString();
}
}