From 0aa0911b0fdf49578fb58003be3d52e3c60d55c4 Mon Sep 17 00:00:00 2001 From: nub31 Date: Wed, 9 Jul 2025 20:29:10 +0200 Subject: [PATCH] Type syntax when parsing --- src/compiler/NubLang/NubType.cs | 24 ++------ .../Syntax/Parsing/Node/DefinitionSyntax.cs | 8 +-- .../Syntax/Parsing/Node/ExpressionSyntax.cs | 4 +- .../Syntax/Parsing/Node/StatementSyntax.cs | 2 +- .../NubLang/Syntax/Parsing/Node/TypeSyntax.cs | 23 ++++++++ src/compiler/NubLang/Syntax/Parsing/Parser.cs | 56 ++++++++++--------- 6 files changed, 65 insertions(+), 52 deletions(-) create mode 100644 src/compiler/NubLang/Syntax/Parsing/Node/TypeSyntax.cs diff --git a/src/compiler/NubLang/NubType.cs b/src/compiler/NubLang/NubType.cs index 7a48e8a..becd22e 100644 --- a/src/compiler/NubLang/NubType.cs +++ b/src/compiler/NubLang/NubType.cs @@ -96,8 +96,8 @@ public abstract class NubSimpleType : NubType public class NubFuncType(NubType returnType, List parameters) : NubSimpleType { - public NubType ReturnType { get; } = returnType; public List Parameters { get; } = parameters; + public NubType ReturnType { get; } = returnType; public override StorageSize StorageSize => StorageSize.U64; @@ -225,11 +225,10 @@ public class NubStringType : NubComplexType public override int GetHashCode() => HashCode.Combine(typeof(NubStringType)); } -public class NubCustomType(string @namespace, string name, IReadOnlyList parameters) : NubComplexType +public class NubCustomType(string @namespace, string name) : NubComplexType { public string Namespace { get; } = @namespace; public string Name { get; } = name; - public IReadOnlyList Parameters { get; } = parameters; public CustomTypeKind Kind(BoundDefinitionTable definitionTable) { @@ -289,22 +288,9 @@ public class NubCustomType(string @namespace, string name, IReadOnlyList $"{Namespace}::{Name}{(Parameters.Any() ? $"<{string.Join(",", Parameters)}>" : "")}"; - public override bool Equals(NubType? other) => other is NubCustomType custom && Namespace == custom.Namespace && Name == custom.Name && Parameters.SequenceEqual(custom.Parameters); - - public override int GetHashCode() - { - var hash = new HashCode(); - hash.Add(typeof(NubFuncType)); - hash.Add(Namespace); - hash.Add(Name); - foreach (var param in Parameters) - { - hash.Add(param); - } - - return hash.ToHashCode(); - } + public override string ToString() => $"{Namespace}::{Name}"; + public override bool Equals(NubType? other) => other is NubCustomType custom && Namespace == custom.Namespace && Name == custom.Name; + public override int GetHashCode() => HashCode.Combine(typeof(NubCustomType), Namespace, Name); } public enum CustomTypeKind diff --git a/src/compiler/NubLang/Syntax/Parsing/Node/DefinitionSyntax.cs b/src/compiler/NubLang/Syntax/Parsing/Node/DefinitionSyntax.cs index f380a4c..b36d337 100644 --- a/src/compiler/NubLang/Syntax/Parsing/Node/DefinitionSyntax.cs +++ b/src/compiler/NubLang/Syntax/Parsing/Node/DefinitionSyntax.cs @@ -7,15 +7,15 @@ public abstract record DefinitionSyntax(IReadOnlyList Tokens, string Name public abstract record DefinitionMemberSyntax(IReadOnlyList Tokens) : SyntaxNode(Tokens); -public record FuncParameterSyntax(IReadOnlyList Tokens, string Name, NubType Type) : DefinitionMemberSyntax(Tokens); +public record FuncParameterSyntax(IReadOnlyList Tokens, string Name, TypeSyntax Type) : DefinitionMemberSyntax(Tokens); -public record FuncSignatureSyntax(IReadOnlyList Tokens, IReadOnlyList Parameters, NubType ReturnType) : DefinitionMemberSyntax(Tokens); +public record FuncSignatureSyntax(IReadOnlyList Tokens, IReadOnlyList Parameters, TypeSyntax ReturnType) : DefinitionMemberSyntax(Tokens); public record LocalFuncSyntax(IReadOnlyList Tokens, string Namespace, string Name, FuncSignatureSyntax Signature, BlockSyntax Body) : DefinitionSyntax(Tokens, Namespace); public record ExternFuncSyntax(IReadOnlyList Tokens, string Namespace, string Name, string CallName, FuncSignatureSyntax Signature) : DefinitionSyntax(Tokens, Namespace); -public record StructFieldSyntax(IReadOnlyList Tokens, int Index, string Name, NubType Type, Optional Value) : DefinitionMemberSyntax(Tokens); +public record StructFieldSyntax(IReadOnlyList Tokens, int Index, string Name, TypeSyntax Type, Optional Value) : DefinitionMemberSyntax(Tokens); public record StructSyntax(IReadOnlyList Tokens, string Namespace, string Name, IReadOnlyList Fields) : DefinitionSyntax(Tokens, Namespace); @@ -25,4 +25,4 @@ public record TraitSyntax(IReadOnlyList Tokens, string Namespace, string public record TraitFuncImplSyntax(IReadOnlyList Tokens, string Name, FuncSignatureSyntax Signature, BlockSyntax Body) : DefinitionMemberSyntax(Tokens); -public record TraitImplSyntax(IReadOnlyList Tokens, string Namespace, NubType TraitType, NubType ForType, IReadOnlyList Functions) : DefinitionSyntax(Tokens, Namespace); \ No newline at end of file +public record TraitImplSyntax(IReadOnlyList Tokens, string Namespace, TypeSyntax TraitType, TypeSyntax ForType, IReadOnlyList Functions) : DefinitionSyntax(Tokens, Namespace); \ No newline at end of file diff --git a/src/compiler/NubLang/Syntax/Parsing/Node/ExpressionSyntax.cs b/src/compiler/NubLang/Syntax/Parsing/Node/ExpressionSyntax.cs index 3a7a2bd..a6badbf 100644 --- a/src/compiler/NubLang/Syntax/Parsing/Node/ExpressionSyntax.cs +++ b/src/compiler/NubLang/Syntax/Parsing/Node/ExpressionSyntax.cs @@ -33,7 +33,7 @@ public record FuncCallSyntax(IReadOnlyList Tokens, ExpressionSyntax Expre public record IdentifierSyntax(IReadOnlyList Tokens, Optional Namespace, string Name) : ExpressionSyntax(Tokens); -public record ArrayInitializerSyntax(IReadOnlyList Tokens, ExpressionSyntax Capacity, NubType ElementType) : ExpressionSyntax(Tokens); +public record ArrayInitializerSyntax(IReadOnlyList Tokens, ExpressionSyntax Capacity, TypeSyntax ElementType) : ExpressionSyntax(Tokens); public record ArrayIndexAccessSyntax(IReadOnlyList Tokens, ExpressionSyntax Target, ExpressionSyntax Index) : ExpressionSyntax(Tokens); @@ -47,6 +47,6 @@ public record LiteralSyntax(IReadOnlyList Tokens, string Literal, Literal public record MemberAccessSyntax(IReadOnlyList Tokens, ExpressionSyntax Target, string Member) : ExpressionSyntax(Tokens); -public record StructInitializerSyntax(IReadOnlyList Tokens, NubType StructType, Dictionary Initializers) : ExpressionSyntax(Tokens); +public record StructInitializerSyntax(IReadOnlyList Tokens, TypeSyntax StructType, Dictionary Initializers) : ExpressionSyntax(Tokens); public record DereferenceSyntax(IReadOnlyList Tokens, ExpressionSyntax Expression) : ExpressionSyntax(Tokens); \ No newline at end of file diff --git a/src/compiler/NubLang/Syntax/Parsing/Node/StatementSyntax.cs b/src/compiler/NubLang/Syntax/Parsing/Node/StatementSyntax.cs index 7a1ec02..73fcb3e 100644 --- a/src/compiler/NubLang/Syntax/Parsing/Node/StatementSyntax.cs +++ b/src/compiler/NubLang/Syntax/Parsing/Node/StatementSyntax.cs @@ -13,7 +13,7 @@ public record AssignmentSyntax(IReadOnlyList Tokens, ExpressionSyntax Tar public record IfSyntax(IReadOnlyList Tokens, ExpressionSyntax Condition, BlockSyntax Body, Optional> Else) : StatementSyntax(Tokens); -public record VariableDeclarationSyntax(IReadOnlyList Tokens, string Name, Optional ExplicitType, Optional Assignment) : StatementSyntax(Tokens); +public record VariableDeclarationSyntax(IReadOnlyList Tokens, string Name, Optional ExplicitType, Optional Assignment) : StatementSyntax(Tokens); public record ContinueSyntax(IReadOnlyList Tokens) : StatementSyntax(Tokens); diff --git a/src/compiler/NubLang/Syntax/Parsing/Node/TypeSyntax.cs b/src/compiler/NubLang/Syntax/Parsing/Node/TypeSyntax.cs new file mode 100644 index 0000000..f59b8bf --- /dev/null +++ b/src/compiler/NubLang/Syntax/Parsing/Node/TypeSyntax.cs @@ -0,0 +1,23 @@ +using NubLang.Syntax.Tokenization; + +namespace NubLang.Syntax.Parsing.Node; + +public abstract record TypeSyntax(IReadOnlyList Tokens) : SyntaxNode(Tokens); + +public record FuncTypeSyntax(IReadOnlyList Tokens, IReadOnlyList Parameters, TypeSyntax ReturnType) : TypeSyntax(Tokens); + +public record PointerTypeSyntax(IReadOnlyList Tokens, TypeSyntax BaseType) : TypeSyntax(Tokens); + +public record VoidTypeSyntax(IReadOnlyList Tokens) : TypeSyntax(Tokens); + +public record PrimitiveTypeSyntax(IReadOnlyList Tokens, PrimitiveTypeKind Kind) : TypeSyntax(Tokens); + +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 TemplateTypeSyntax(IReadOnlyList Tokens, string Name, string Namespace, IReadOnlyList Arguments) : 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 3f12dbe..dcbd1fb 100644 --- a/src/compiler/NubLang/Syntax/Parsing/Parser.cs +++ b/src/compiler/NubLang/Syntax/Parsing/Parser.cs @@ -117,7 +117,7 @@ public sealed class Parser } } - var returnType = TryExpectSymbol(Symbol.Colon) ? ParseType() : new NubVoidType(); + var returnType = TryExpectSymbol(Symbol.Colon) ? ParseType() : new VoidTypeSyntax([Peek().GetValue()]); return new FuncSignatureSyntax(GetTokens(startIndex), parameters, returnType); } @@ -295,7 +295,7 @@ public sealed class Parser ExpectSymbol(Symbol.Let); var name = ExpectIdentifier().Value; - var explicitType = Optional.Empty(); + var explicitType = Optional.Empty(); if (TryExpectSymbol(Symbol.Colon)) { explicitType = ParseType(); @@ -649,30 +649,32 @@ public sealed class Parser return new BlockSyntax(GetTokens(startIndex), statements); } - private NubType ParseType() + private TypeSyntax ParseType() { + var startIndex = _tokenIndex; + if (TryExpectIdentifier(out var name)) { return name.Value switch { - "void" => new NubVoidType(), - "string" => new NubStringType(), - "cstring" => new NubCStringType(), - "i64" => new NubPrimitiveType(PrimitiveTypeKind.I64), - "i32" => new NubPrimitiveType(PrimitiveTypeKind.I32), - "i16" => new NubPrimitiveType(PrimitiveTypeKind.I16), - "i8" => new NubPrimitiveType(PrimitiveTypeKind.I8), - "u64" => new NubPrimitiveType(PrimitiveTypeKind.U64), - "u32" => new NubPrimitiveType(PrimitiveTypeKind.U32), - "u16" => new NubPrimitiveType(PrimitiveTypeKind.U16), - "u8" => new NubPrimitiveType(PrimitiveTypeKind.U8), - "f64" => new NubPrimitiveType(PrimitiveTypeKind.F64), - "f32" => new NubPrimitiveType(PrimitiveTypeKind.F32), - "bool" => new NubPrimitiveType(PrimitiveTypeKind.Bool), + "void" => new VoidTypeSyntax(GetTokens(startIndex)), + "string" => new StringTypeSyntax(GetTokens(startIndex)), + "cstring" => new CStringTypeSyntax(GetTokens(startIndex)), + "i64" => new PrimitiveTypeSyntax(GetTokens(startIndex), PrimitiveTypeKind.I64), + "i32" => new PrimitiveTypeSyntax(GetTokens(startIndex), PrimitiveTypeKind.I32), + "i16" => new PrimitiveTypeSyntax(GetTokens(startIndex), PrimitiveTypeKind.I16), + "i8" => new PrimitiveTypeSyntax(GetTokens(startIndex), PrimitiveTypeKind.I8), + "u64" => new PrimitiveTypeSyntax(GetTokens(startIndex), PrimitiveTypeKind.U64), + "u32" => new PrimitiveTypeSyntax(GetTokens(startIndex), PrimitiveTypeKind.U32), + "u16" => new PrimitiveTypeSyntax(GetTokens(startIndex), PrimitiveTypeKind.U16), + "u8" => new PrimitiveTypeSyntax(GetTokens(startIndex), PrimitiveTypeKind.U8), + "f64" => new PrimitiveTypeSyntax(GetTokens(startIndex), PrimitiveTypeKind.F64), + "f32" => new PrimitiveTypeSyntax(GetTokens(startIndex), PrimitiveTypeKind.F32), + "bool" => new PrimitiveTypeSyntax(GetTokens(startIndex), PrimitiveTypeKind.Bool), _ => ParseCustomType() }; - NubCustomType ParseCustomType() + TypeSyntax ParseCustomType() { var @namespace = _namespace; if (TryExpectSymbol(Symbol.DoubleColon)) @@ -680,7 +682,7 @@ public sealed class Parser @namespace = ExpectIdentifier().Value; } - var parameters = new List(); + var parameters = new List(); if (TryExpectSymbol(Symbol.LessThan)) { @@ -688,22 +690,24 @@ public sealed class Parser { parameters.Add(ParseType()); } + + return new TemplateTypeSyntax(GetTokens(startIndex), @namespace, name.Value, parameters); } - return new NubCustomType(@namespace, name.Value, parameters); + return new CustomTypeSyntax(GetTokens(startIndex), @namespace, name.Value); } } if (TryExpectSymbol(Symbol.Caret)) { var baseType = ParseType(); - return new NubPointerType(baseType); + return new PointerTypeSyntax(GetTokens(startIndex), baseType); } if (TryExpectSymbol(Symbol.Func)) { ExpectSymbol(Symbol.OpenParen); - List parameters = []; + List parameters = []; while (!TryExpectSymbol(Symbol.CloseParen)) { var parameter = ParseType(); @@ -718,16 +722,16 @@ public sealed class Parser } } - var returnType = TryExpectSymbol(Symbol.Colon) ? ParseType() : new NubVoidType(); + var returnType = TryExpectSymbol(Symbol.Colon) ? ParseType() : new VoidTypeSyntax(GetTokens(startIndex)); - return new NubFuncType(returnType, parameters); + return new FuncTypeSyntax(GetTokens(startIndex), parameters, returnType); } if (TryExpectSymbol(Symbol.OpenBracket)) { ExpectSymbol(Symbol.CloseBracket); var baseType = ParseType(); - return new NubArrayType(baseType); + return new ArrayTypeSyntax(GetTokens(startIndex), baseType); } if (!Peek().TryGetValue(out var peekToken)) @@ -735,7 +739,7 @@ public sealed class Parser throw new ParseException(Diagnostic .Error("Unexpected end of file while parsing type") .WithHelp("Expected a type name") - .At(_tokens.Last()) + .At(_tokens[^1]) .Build()); }