Files
nub-lang/src/compiler/NubLang/Syntax/Templating/TemplateGenerator.cs

65 lines
2.0 KiB
C#

using NubLang.Diagnostics;
using NubLang.Syntax.Parsing.Node;
namespace NubLang.Syntax.Templating;
public class TemplateGenerator
{
private readonly SyntaxTree _syntaxTree;
private readonly TemplateTable _templateTable;
public TemplateGenerator(SyntaxTree syntaxTree, TemplateTable templateTable)
{
_syntaxTree = syntaxTree;
_templateTable = templateTable;
}
public IReadOnlyList<DefinitionSyntax> Generate()
{
var definitions = new List<DefinitionSyntax>();
foreach (var type in _syntaxTree.ReferencedTemplatedCustomTypes)
{
definitions.Add(CreateDefinition(type));
}
return definitions;
}
private DefinitionSyntax CreateDefinition(TemplatedCustomTypeSyntax type)
{
var structTemplates = _templateTable.LookupStructTemplate(type.Namespace, type.Name).ToArray();
if (structTemplates.Length > 0)
{
if (structTemplates.Length > 1)
{
throw new TemplateGeneratorException(Diagnostic.Error($"Struct template {type.Namespace}::{type.Name} has multiple definitions").Build());
}
var structTemplate = structTemplates[0];
var transformations = new Dictionary<string, TypeSyntax>();
for (var i = 0; i < structTemplate.TemplateParameters.Count; i++)
{
transformations[structTemplate.TemplateParameters[i]] = type.Arguments[i];
}
var transformer = new TypeTransformer(transformations);
var transformed = transformer.TransformStruct(structTemplate.Struct);
return transformed with { Name = type.MangledName() };
}
throw new TemplateGeneratorException(Diagnostic.Error($"Template {type.Namespace}::{type.Name} is not defined").Build());
}
}
public class TemplateGeneratorException : Exception
{
public Diagnostic Diagnostic { get; }
public TemplateGeneratorException(Diagnostic diagnostic) : base(diagnostic.Message)
{
Diagnostic = diagnostic;
}
}