...
This commit is contained in:
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user