This commit is contained in:
nub31
2025-07-21 16:22:05 +02:00
parent a73c9e5d94
commit b8a4f6df57
7 changed files with 5 additions and 415 deletions

View File

@@ -9,7 +9,6 @@ using NubLang.Syntax.Binding;
using NubLang.Syntax.Binding.Node;
using NubLang.Syntax.Parsing;
using NubLang.Syntax.Parsing.Node;
using NubLang.Syntax.Templating;
using NubLang.Syntax.Tokenization;
using Binder = NubLang.Syntax.Binding.Binder;
@@ -95,15 +94,6 @@ foreach (var file in options.Files)
syntaxTrees[file] = syntaxTree;
}
var templateTable = new TemplateTable(syntaxTrees.Values);
foreach (var (file, syntaxTree) in syntaxTrees)
{
var templateGenerator = new TemplateGenerator(syntaxTree, templateTable);
var definitions = templateGenerator.Generate();
syntaxTrees[file] = syntaxTree with { Definitions = syntaxTree.Definitions.Concat(definitions).ToList() };
}
var definitionTable = new DefinitionTable(syntaxTrees.Values);
var boundSyntaxTrees = new Dictionary<string, BoundSyntaxTree>();

View File

@@ -3,7 +3,7 @@ using NubLang.Syntax.Tokenization;
namespace NubLang.Syntax.Parsing.Node;
public record SyntaxTree(string Namespace, IReadOnlyList<DefinitionSyntax> Definitions, IReadOnlyList<TemplateSyntax> Templates, IReadOnlyList<TemplatedCustomTypeSyntax> ReferencedTemplatedCustomTypes, IReadOnlyList<Diagnostic> Diagnostics);
public record SyntaxTree(string Namespace, IReadOnlyList<DefinitionSyntax> Definitions, IReadOnlyList<Diagnostic> Diagnostics);
public abstract record SyntaxNode(IReadOnlyList<Token> Tokens);

View File

@@ -1,7 +0,0 @@
using NubLang.Syntax.Tokenization;
namespace NubLang.Syntax.Parsing.Node;
public abstract record TemplateSyntax(IReadOnlyList<Token> Tokens, string Namespace, IReadOnlyList<string> TemplateParameters) : SyntaxNode(Tokens);
public record StructTemplateSyntax(IReadOnlyList<Token> Tokens, string Namespace, IReadOnlyList<string> TemplateParameters, StructSyntax Struct) : TemplateSyntax(Tokens, Namespace, TemplateParameters);

View File

@@ -12,8 +12,6 @@ public sealed class Parser
private readonly IReadOnlyList<Token> _tokens;
private readonly List<Diagnostic> _diagnostics = [];
private readonly List<TemplatedCustomTypeSyntax> _referencedTemplates = [];
private List<string> _templateParameters = [];
private int _tokenIndex;
public Parser(IReadOnlyList<Token> tokens)
@@ -24,9 +22,7 @@ public sealed class Parser
public SyntaxTree Parse()
{
_referencedTemplates.Clear();
_diagnostics.Clear();
_templateParameters = [];
_tokenIndex = 0;
if (TryExpectSymbol(Symbol.Namespace))
@@ -35,33 +31,16 @@ public sealed class Parser
}
var definitions = new List<DefinitionSyntax>();
var templates = new List<TemplateSyntax>();
while (Peek().HasValue)
{
var startIndex = _tokenIndex;
try
{
if (TryExpectSymbol(Symbol.Template))
{
ExpectSymbol(Symbol.LessThan);
while (!TryExpectSymbol(Symbol.GreaterThan))
{
_templateParameters.Add(ExpectIdentifier().Value);
}
ExpectSymbol(Symbol.Struct);
var definition = ParseStruct(_tokenIndex);
templates.Add(new StructTemplateSyntax(GetTokens(startIndex), _namespace, _templateParameters, definition));
}
else
{
var definition = ParseDefinition(startIndex);
definitions.Add(definition);
}
}
catch (ParseException ex)
{
_diagnostics.Add(ex.Diagnostic);
@@ -69,7 +48,7 @@ public sealed class Parser
}
}
return new SyntaxTree(_namespace, definitions, templates, _referencedTemplates, _diagnostics);
return new SyntaxTree(_namespace, definitions, _diagnostics);
}
private DefinitionSyntax ParseDefinition(int startIndex)
@@ -657,11 +636,6 @@ public sealed class Parser
if (TryExpectIdentifier(out var name))
{
if (_templateParameters.Contains(name.Value))
{
return new TemplateTypeSyntax(GetTokens(startIndex), name.Value);
}
return name.Value switch
{
"void" => new VoidTypeSyntax(GetTokens(startIndex)),
@@ -698,9 +672,7 @@ public sealed class Parser
parameters.Add(ParseType());
}
var template = new TemplatedCustomTypeSyntax(GetTokens(startIndex), @namespace, name.Value, parameters);
_referencedTemplates.Add(template);
return template;
return new TemplatedCustomTypeSyntax(GetTokens(startIndex), @namespace, name.Value, parameters);
}
return new CustomTypeSyntax(GetTokens(startIndex), name.Value, @namespace);

View File

@@ -1,65 +0,0 @@
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;
}
}

View File

@@ -1,20 +0,0 @@
using NubLang.Syntax.Parsing.Node;
namespace NubLang.Syntax.Templating;
public class TemplateTable
{
private readonly List<TemplateSyntax> _templates;
public TemplateTable(IEnumerable<SyntaxTree> syntaxTrees)
{
_templates = syntaxTrees.SelectMany(x => x.Templates).ToList();
}
public IEnumerable<StructTemplateSyntax> LookupStructTemplate(string @namespace, string name)
{
return _templates
.OfType<StructTemplateSyntax>()
.Where(x => x.Struct.Namespace == @namespace && x.Struct.Name == @name);
}
}

View File

@@ -1,280 +0,0 @@
using NubLang.Common;
using NubLang.Syntax.Parsing.Node;
namespace NubLang.Syntax.Templating;
public class TypeTransformer
{
private readonly Dictionary<string, TypeSyntax> _transformations;
public TypeTransformer(Dictionary<string, TypeSyntax> transformations)
{
_transformations = transformations;
}
public DefinitionSyntax TransformDefinition(DefinitionSyntax definition)
{
return definition switch
{
ExternFuncSyntax node => TransformExternFunc(node),
LocalFuncSyntax node => TransformLocalFunc(node),
StructSyntax node => TransformStruct(node),
TraitImplSyntax node => TransformTraitImpl(node),
TraitSyntax node => TransformTrait(node),
_ => throw new ArgumentOutOfRangeException(nameof(definition))
};
}
public FuncSignatureSyntax TransformFuncSignature(FuncSignatureSyntax node)
{
var parameters = new List<FuncParameterSyntax>();
foreach (var parameter in node.Parameters)
{
parameters.Add(new FuncParameterSyntax(parameter.Tokens, parameter.Name, TransformType(parameter.Type)));
}
return new FuncSignatureSyntax(node.Tokens, parameters, TransformType(node.ReturnType));
}
public ExternFuncSyntax TransformExternFunc(ExternFuncSyntax node)
{
return new ExternFuncSyntax(node.Tokens, node.Namespace, node.Name, node.CallName, TransformFuncSignature(node.Signature));
}
public LocalFuncSyntax TransformLocalFunc(LocalFuncSyntax node)
{
return new LocalFuncSyntax(node.Tokens, node.Namespace, node.Name, TransformFuncSignature(node.Signature), TransformBlock(node.Body));
}
public StructSyntax TransformStruct(StructSyntax node)
{
var fields = new List<StructFieldSyntax>();
foreach (var field in node.Fields)
{
var value = Optional.Empty<ExpressionSyntax>();
if (field.Value.HasValue)
{
value = TransformExpression(field.Value.Value);
}
fields.Add(new StructFieldSyntax(field.Tokens, field.Index, field.Name, TransformType(field.Type), value));
}
return new StructSyntax(node.Tokens, node.Namespace, node.Name, fields);
}
public TraitImplSyntax TransformTraitImpl(TraitImplSyntax node)
{
var functions = new List<TraitFuncImplSyntax>();
foreach (var function in node.Functions)
{
functions.Add(new TraitFuncImplSyntax(function.Tokens, function.Name, TransformFuncSignature(function.Signature), TransformBlock(function.Body)));
}
return new TraitImplSyntax(node.Tokens, node.Namespace, TransformType(node.TraitType), TransformType(node.ForType), functions);
}
public TraitSyntax TransformTrait(TraitSyntax node)
{
var functions = new List<TraitFuncSyntax>();
foreach (var function in node.Functions)
{
functions.Add(new TraitFuncSyntax(function.Tokens, function.Name, TransformFuncSignature(function.Signature)));
}
return new TraitSyntax(node.Tokens, node.Namespace, node.Name, functions);
}
public BlockSyntax TransformBlock(BlockSyntax block)
{
var statements = new List<StatementSyntax>();
foreach (var statement in block.Statements)
{
statements.Add(TransformStatement(statement));
}
return new BlockSyntax(block.Tokens, statements);
}
public StatementSyntax TransformStatement(StatementSyntax statement)
{
return statement switch
{
AssignmentSyntax node => TransformAssignment(node),
BreakSyntax node => new BreakSyntax(node.Tokens),
ContinueSyntax node => new ContinueSyntax(node.Tokens),
IfSyntax node => TransformIf(node),
ReturnSyntax node => TransformReturn(node),
StatementExpressionSyntax node => new StatementExpressionSyntax(node.Tokens, TransformExpression(node.Expression)),
VariableDeclarationSyntax node => TransformVariableDeclaration(node),
WhileSyntax node => new WhileSyntax(node.Tokens, TransformExpression(node.Condition), TransformBlock(node.Body)),
_ => throw new ArgumentOutOfRangeException(nameof(statement))
};
}
public AssignmentSyntax TransformAssignment(AssignmentSyntax node)
{
return new AssignmentSyntax(node.Tokens, TransformExpression(node.Target), TransformExpression(node.Value));
}
public IfSyntax TransformIf(IfSyntax node)
{
var elseStatement = Optional.Empty<Variant<IfSyntax, BlockSyntax>>();
if (node.Else.HasValue)
{
elseStatement = node.Else.Value.Match<Variant<IfSyntax, BlockSyntax>>(x => TransformIf(x), x => TransformBlock(x));
}
return new IfSyntax(node.Tokens, TransformExpression(node.Condition), TransformBlock(node.Body), elseStatement);
}
public ReturnSyntax TransformReturn(ReturnSyntax node)
{
var value = Optional<ExpressionSyntax>.Empty();
if (node.Value.HasValue)
{
value = TransformExpression(node.Value.Value);
}
return new ReturnSyntax(node.Tokens, value);
}
public VariableDeclarationSyntax TransformVariableDeclaration(VariableDeclarationSyntax node)
{
var explicitType = Optional<TypeSyntax>.Empty();
if (node.ExplicitType.HasValue)
{
throw new NotImplementedException();
}
var assignment = Optional.Empty<ExpressionSyntax>();
if (node.Assignment.HasValue)
{
assignment = TransformExpression(node.Assignment.Value);
}
return new VariableDeclarationSyntax(node.Tokens, node.Name, explicitType, assignment);
}
public ExpressionSyntax TransformExpression(ExpressionSyntax expression)
{
return expression switch
{
AddressOfSyntax node => TransformAddressOf(node),
ArrayIndexAccessSyntax node => TransformArrayIndexAccess(node),
ArrayInitializerSyntax node => TransformArrayInitializer(node),
ArrowFuncParameterSyntax node => TransformArrowFuncParameter(node),
ArrowFuncSyntax node => TransformArrowFunc(node),
BinaryExpressionSyntax node => TransformBinaryExpression(node),
DereferenceSyntax node => TransformDereference(node),
FuncCallSyntax node => TransformFuncCall(node),
IdentifierSyntax node => TransformIdentifier(node),
LiteralSyntax node => TransformLiteral(node),
MemberAccessSyntax node => TransformMemberAccess(node),
StructInitializerSyntax node => TransformStructInitializer(node),
UnaryExpressionSyntax node => TransformUnaryExpression(node),
_ => throw new ArgumentOutOfRangeException(nameof(expression))
};
}
public AddressOfSyntax TransformAddressOf(AddressOfSyntax node)
{
return new AddressOfSyntax(node.Tokens, TransformExpression(node.Expression));
}
public ArrayIndexAccessSyntax TransformArrayIndexAccess(ArrayIndexAccessSyntax node)
{
return new ArrayIndexAccessSyntax(node.Tokens, TransformExpression(node.Target), TransformExpression(node.Index));
}
public ArrayInitializerSyntax TransformArrayInitializer(ArrayInitializerSyntax node)
{
return new ArrayInitializerSyntax(node.Tokens, TransformExpression(node.Capacity), TransformType(node.ElementType));
}
public ArrowFuncParameterSyntax TransformArrowFuncParameter(ArrowFuncParameterSyntax node)
{
return new ArrowFuncParameterSyntax(node.Tokens, node.Name);
}
public ArrowFuncSyntax TransformArrowFunc(ArrowFuncSyntax node)
{
var parameters = new List<ArrowFuncParameterSyntax>();
foreach (var parameter in node.Parameters)
{
parameters.Add(TransformArrowFuncParameter(parameter));
}
return new ArrowFuncSyntax(node.Tokens, parameters, TransformBlock(node.Body));
}
public BinaryExpressionSyntax TransformBinaryExpression(BinaryExpressionSyntax node)
{
return new BinaryExpressionSyntax(node.Tokens, TransformExpression(node.Left), node.Operator, TransformExpression(node.Right));
}
public DereferenceSyntax TransformDereference(DereferenceSyntax node)
{
return new DereferenceSyntax(node.Tokens, TransformExpression(node.Expression));
}
public FuncCallSyntax TransformFuncCall(FuncCallSyntax node)
{
var parameters = new List<ExpressionSyntax>();
foreach (var parameter in node.Parameters)
{
parameters.Add(TransformExpression(parameter));
}
return new FuncCallSyntax(node.Tokens, TransformExpression(node.Expression), parameters);
}
public IdentifierSyntax TransformIdentifier(IdentifierSyntax node)
{
return new IdentifierSyntax(node.Tokens, node.Namespace, node.Name);
}
public LiteralSyntax TransformLiteral(LiteralSyntax node)
{
return new LiteralSyntax(node.Tokens, node.Literal, node.Kind);
}
public MemberAccessSyntax TransformMemberAccess(MemberAccessSyntax node)
{
return new MemberAccessSyntax(node.Tokens, TransformExpression(node.Target), node.Member);
}
public StructInitializerSyntax TransformStructInitializer(StructInitializerSyntax node)
{
var initializers = new Dictionary<string, ExpressionSyntax>();
foreach (var (field, value) in node.Initializers)
{
initializers.Add(field, TransformExpression(value));
}
return new StructInitializerSyntax(node.Tokens, TransformType(node.StructType), initializers);
}
public UnaryExpressionSyntax TransformUnaryExpression(UnaryExpressionSyntax node)
{
return new UnaryExpressionSyntax(node.Tokens, node.Operator, TransformExpression(node.Operand));
}
public TypeSyntax TransformType(TypeSyntax node)
{
if (node is TemplateTypeSyntax templateType)
{
return _transformations[templateType.Name];
}
return node;
}
}