From 58ac38058f6759c653baec06280f6a89d80295d4 Mon Sep 17 00:00:00 2001 From: nub31 Date: Mon, 21 Jul 2025 17:16:51 +0200 Subject: [PATCH] ... --- src/compiler/NubLang/Syntax/Binding/Binder.cs | 3 +- .../Syntax/Parsing/Node/DefinitionSyntax.cs | 12 +++--- .../NubLang/Syntax/Parsing/Node/TypeSyntax.cs | 10 ++--- src/compiler/NubLang/Syntax/Parsing/Parser.cs | 41 +++++++++++-------- 4 files changed, 34 insertions(+), 32 deletions(-) diff --git a/src/compiler/NubLang/Syntax/Binding/Binder.cs b/src/compiler/NubLang/Syntax/Binding/Binder.cs index 31237b9..ae64378 100644 --- a/src/compiler/NubLang/Syntax/Binding/Binder.cs +++ b/src/compiler/NubLang/Syntax/Binding/Binder.cs @@ -603,7 +603,7 @@ public sealed class Binder { ArrayTypeSyntax type => new NubArrayType(BindType(type.BaseType)), CStringTypeSyntax => new NubCStringType(), - CustomTypeSyntax type => new NubCustomType(type.Namespace, type.Name), + CustomTypeSyntax type => new NubCustomType(type.Namespace, type.MangledName()), FuncTypeSyntax type => new NubFuncType(type.Parameters.Select(BindType).ToList(), BindType(type.ReturnType)), PointerTypeSyntax type => new NubPointerType(BindType(type.BaseType)), PrimitiveTypeSyntax type => new NubPrimitiveType(type.SyntaxKind switch @@ -622,7 +622,6 @@ public sealed class Binder _ => throw new ArgumentOutOfRangeException() }), StringTypeSyntax => new NubStringType(), - TemplatedCustomTypeSyntax type => new NubCustomType(type.Namespace, type.MangledName()), VoidTypeSyntax => new NubVoidType(), _ => throw new ArgumentOutOfRangeException(nameof(node)) }; diff --git a/src/compiler/NubLang/Syntax/Parsing/Node/DefinitionSyntax.cs b/src/compiler/NubLang/Syntax/Parsing/Node/DefinitionSyntax.cs index cf43144..13efa0d 100644 --- a/src/compiler/NubLang/Syntax/Parsing/Node/DefinitionSyntax.cs +++ b/src/compiler/NubLang/Syntax/Parsing/Node/DefinitionSyntax.cs @@ -3,24 +3,24 @@ using NubLang.Syntax.Tokenization; namespace NubLang.Syntax.Parsing.Node; -public record TemplateParameterSyntax(IReadOnlyList Tokens, string Name) : SyntaxNode(Tokens); +public record GenericParameter(IReadOnlyList Tokens, string Name) : SyntaxNode(Tokens); -public abstract record DefinitionSyntax(IReadOnlyList Tokens, string Namespace, IReadOnlyList Parameters) : SyntaxNode(Tokens); +public abstract record DefinitionSyntax(IReadOnlyList Tokens, string Namespace, IReadOnlyList Parameters) : SyntaxNode(Tokens); public record FuncParameterSyntax(IReadOnlyList Tokens, string Name, TypeSyntax Type) : SyntaxNode(Tokens); public record FuncSignatureSyntax(IReadOnlyList Tokens, IReadOnlyList Parameters, TypeSyntax ReturnType) : SyntaxNode(Tokens); -public record LocalFuncSyntax(IReadOnlyList Tokens, string Namespace, IReadOnlyList Parameters, string Name, FuncSignatureSyntax Signature, BlockSyntax Body) : DefinitionSyntax(Tokens, Namespace, Parameters); +public record LocalFuncSyntax(IReadOnlyList Tokens, string Namespace, IReadOnlyList Parameters, string Name, FuncSignatureSyntax Signature, BlockSyntax Body) : DefinitionSyntax(Tokens, Namespace, Parameters); -public record ExternFuncSyntax(IReadOnlyList Tokens, string Namespace, IReadOnlyList Parameters, string Name, string CallName, FuncSignatureSyntax Signature) : DefinitionSyntax(Tokens, Namespace, Parameters); +public record ExternFuncSyntax(IReadOnlyList Tokens, string Namespace, IReadOnlyList Parameters, string Name, string CallName, FuncSignatureSyntax Signature) : DefinitionSyntax(Tokens, Namespace, Parameters); public record StructFieldSyntax(IReadOnlyList Tokens, int Index, string Name, TypeSyntax Type, Optional Value) : SyntaxNode(Tokens); public record StructFuncSyntax(IReadOnlyList Tokens, string Name, FuncSignatureSyntax Signature, BlockSyntax Body) : SyntaxNode(Tokens); -public record StructSyntax(IReadOnlyList Tokens, string Namespace, IReadOnlyList Parameters, string Name, IReadOnlyList Fields, IReadOnlyList Funcs) : DefinitionSyntax(Tokens, Namespace, Parameters); +public record StructSyntax(IReadOnlyList Tokens, string Namespace, IReadOnlyList Parameters, string Name, IReadOnlyList Fields, IReadOnlyList Funcs) : DefinitionSyntax(Tokens, Namespace, Parameters); public record InterfaceFuncSyntax(IReadOnlyList Tokens, string Name, FuncSignatureSyntax Signature) : SyntaxNode(Tokens); -public record InterfaceSyntax(IReadOnlyList Tokens, string Namespace, IReadOnlyList Parameters, string Name, IReadOnlyList Functions) : DefinitionSyntax(Tokens, Namespace, Parameters); \ No newline at end of file +public record InterfaceSyntax(IReadOnlyList Tokens, string Namespace, IReadOnlyList Parameters, string Name, IReadOnlyList Functions) : DefinitionSyntax(Tokens, Namespace, Parameters); \ No newline at end of file diff --git a/src/compiler/NubLang/Syntax/Parsing/Node/TypeSyntax.cs b/src/compiler/NubLang/Syntax/Parsing/Node/TypeSyntax.cs index f695adb..d8f1c5f 100644 --- a/src/compiler/NubLang/Syntax/Parsing/Node/TypeSyntax.cs +++ b/src/compiler/NubLang/Syntax/Parsing/Node/TypeSyntax.cs @@ -29,9 +29,7 @@ public abstract record TypeSyntax(IReadOnlyList Tokens) : SyntaxNode(Toke StringTypeSyntax => "string", PointerTypeSyntax ptr => $"ptr_{ptr.BaseType.MangledName()}", ArrayTypeSyntax arr => $"arr_{arr.BaseType.MangledName()}", - CustomTypeSyntax custom => $"{custom.Namespace}_{custom.Name}", - TemplateTypeSyntax template => $"tmpl_{template.Name}", - TemplatedCustomTypeSyntax tmpl => $"{tmpl.Namespace}_{tmpl.Name}_{string.Join("_", tmpl.Arguments.Select(x => x.MangledName()))}", + CustomTypeSyntax custom => $"{custom.Namespace}_{custom.Name}_{string.Join("_", custom.Arguments.Select(x => x.MangledName()))}", FuncTypeSyntax func => $"func_{string.Join("_", func.Parameters.Select(x => x.MangledName()))}_to_{func.ReturnType.MangledName()}", _ => throw new NotSupportedException($"Unknown type syntax: {GetType().Name}") }; @@ -50,10 +48,8 @@ public record CStringTypeSyntax(IReadOnlyList Tokens) : TypeSyntax(Tokens public record StringTypeSyntax(IReadOnlyList Tokens) : TypeSyntax(Tokens); -public record CustomTypeSyntax(IReadOnlyList Tokens, string Name, string Namespace) : TypeSyntax(Tokens); +public record CustomTypeSyntax(IReadOnlyList Tokens, string Namespace, string Name, IReadOnlyList Arguments) : TypeSyntax(Tokens); -public record TemplatedCustomTypeSyntax(IReadOnlyList Tokens, string Namespace, string Name, IReadOnlyList Arguments) : TypeSyntax(Tokens); - -public record TemplateTypeSyntax(IReadOnlyList Tokens, string Name) : TypeSyntax(Tokens); +public record GenericTypeSyntax(IReadOnlyList Tokens, string Name) : TypeSyntax(Tokens); public record ArrayTypeSyntax(IReadOnlyList Tokens, TypeSyntax BaseType) : TypeSyntax(Tokens); \ No newline at end of file diff --git a/src/compiler/NubLang/Syntax/Parsing/Parser.cs b/src/compiler/NubLang/Syntax/Parsing/Parser.cs index 618e100..b65c47b 100644 --- a/src/compiler/NubLang/Syntax/Parsing/Parser.cs +++ b/src/compiler/NubLang/Syntax/Parsing/Parser.cs @@ -12,6 +12,7 @@ public sealed class Parser private readonly IReadOnlyList _tokens; private readonly List _diagnostics = []; + private readonly List _genericParameters = []; private int _tokenIndex; public Parser(IReadOnlyList tokens) @@ -23,6 +24,7 @@ public sealed class Parser public SyntaxTree Parse() { _diagnostics.Clear(); + _genericParameters.Clear(); _tokenIndex = 0; if (TryExpectSymbol(Symbol.Namespace)) @@ -34,13 +36,13 @@ public sealed class Parser while (Peek().HasValue) { + _genericParameters.Clear(); var startIndex = _tokenIndex; try { var keyword = ExpectSymbol(); var name = ExpectIdentifier(); - var templateParameters = new List(); if (TryExpectSymbol(Symbol.LessThan)) { @@ -57,17 +59,17 @@ public sealed class Parser .Build()); } - var parameter = new TemplateParameterSyntax(GetTokens(argumentStartIndex), identifier.Value); - templateParameters.Add(parameter); + var parameter = new GenericParameter(GetTokens(argumentStartIndex), identifier.Value); + _genericParameters.Add(parameter); } } var definition = keyword.Symbol switch { - Symbol.Extern => ParseExtern(startIndex, name, templateParameters), - Symbol.Func => ParseFunc(startIndex, name, templateParameters), - Symbol.Struct => ParseStruct(startIndex, name, templateParameters), - Symbol.Interface => ParseInterface(startIndex, name, templateParameters), + Symbol.Extern => ParseExtern(startIndex, name, _genericParameters), + Symbol.Func => ParseFunc(startIndex, name, _genericParameters), + Symbol.Struct => ParseStruct(startIndex, name, _genericParameters), + Symbol.Interface => ParseInterface(startIndex, name, _genericParameters), _ => throw new ParseException(Diagnostic .Error($"Expected 'extern', 'func', 'struct', 'trait' or 'impl' but found '{keyword.Symbol}'") .WithHelp("Valid definition keywords are 'extern', 'func', 'struct', 'trait' and 'impl'") @@ -138,7 +140,7 @@ public sealed class Parser return new FuncParameterSyntax(GetTokens(startIndex), name.Value, type); } - private DefinitionSyntax ParseExtern(int startIndex, IdentifierToken name, IReadOnlyList templateParameters) + private DefinitionSyntax ParseExtern(int startIndex, IdentifierToken name, IReadOnlyList templateParameters) { var keyword = ExpectSymbol(); return keyword.Symbol switch @@ -148,7 +150,7 @@ public sealed class Parser }; } - private ExternFuncSyntax ParseExternFunc(int startIndex, IdentifierToken name, IReadOnlyList templateParameters) + private ExternFuncSyntax ParseExternFunc(int startIndex, IdentifierToken name, IReadOnlyList templateParameters) { var callName = name.Value; @@ -162,7 +164,7 @@ public sealed class Parser return new ExternFuncSyntax(GetTokens(startIndex), _namespace, templateParameters, name.Value, callName, signature); } - private LocalFuncSyntax ParseFunc(int startIndex, IdentifierToken name, IReadOnlyList templateParameters) + private LocalFuncSyntax ParseFunc(int startIndex, IdentifierToken name, IReadOnlyList templateParameters) { var signature = ParseFuncSignature(); var body = ParseBlock(); @@ -170,7 +172,7 @@ public sealed class Parser return new LocalFuncSyntax(GetTokens(startIndex), _namespace, templateParameters, name.Value, signature, body); } - private DefinitionSyntax ParseStruct(int startIndex, IdentifierToken name, IReadOnlyList templateParameters) + private DefinitionSyntax ParseStruct(int startIndex, IdentifierToken name, IReadOnlyList templateParameters) { ExpectSymbol(Symbol.OpenBrace); @@ -186,9 +188,10 @@ public sealed class Parser if (TryExpectSymbol(Symbol.Func)) { var funcName = ExpectIdentifier().Value; - var funcSignature = ParseFuncSignature(new FuncParameterSyntax([], "this", new CustomTypeSyntax([], _namespace, name.Value))); + var thisArg = new FuncParameterSyntax([], "this", new CustomTypeSyntax([], _namespace, name.Value, templateParameters.Select(x => new GenericTypeSyntax(x.Tokens, x.Name)).ToList())); + var funcSignature = ParseFuncSignature(thisArg); var funcBody = ParseBlock(); - + funcs.Add(new StructFuncSyntax(GetTokens(memberStartIndex), funcName, funcSignature, funcBody)); } else @@ -211,7 +214,7 @@ public sealed class Parser return new StructSyntax(GetTokens(startIndex), _namespace, templateParameters, name.Value, fields, funcs); } - private InterfaceSyntax ParseInterface(int startIndex, IdentifierToken name, IReadOnlyList templateParameters) + private InterfaceSyntax ParseInterface(int startIndex, IdentifierToken name, IReadOnlyList templateParameters) { ExpectSymbol(Symbol.OpenBrace); @@ -643,6 +646,12 @@ public sealed class Parser if (TryExpectIdentifier(out var name)) { + var genericParameter = _genericParameters.FirstOrDefault(x => x.Name == name.Value); + if (genericParameter != null) + { + return new GenericTypeSyntax(GetTokens(startIndex), genericParameter.Name); + } + return name.Value switch { "void" => new VoidTypeSyntax(GetTokens(startIndex)), @@ -678,11 +687,9 @@ public sealed class Parser { parameters.Add(ParseType()); } - - return new TemplatedCustomTypeSyntax(GetTokens(startIndex), @namespace, name.Value, parameters); } - return new CustomTypeSyntax(GetTokens(startIndex), name.Value, @namespace); + return new CustomTypeSyntax(GetTokens(startIndex), name.Value, @namespace, parameters); } }