From f58abf685c30decf55c6aa4ebc6b0976dcdc4866 Mon Sep 17 00:00:00 2001 From: nub31 Date: Mon, 21 Jul 2025 17:51:52 +0200 Subject: [PATCH] ... --- src/compiler/NubLang.CLI/Program.cs | 2 +- src/compiler/NubLang/Syntax/Binding/Binder.cs | 14 ++--- .../NubLang/Syntax/Binding/DefinitionTable.cs | 2 +- .../Syntax/Generics/GenericInstantiator.cs | 30 +++++++++++ .../Syntax/Generics/Node/DefinitionSyntax.cs | 26 ++++++++++ .../Syntax/Generics/Node/ExpressionSyntax.cs | 52 +++++++++++++++++++ .../Syntax/Generics/Node/StatementSyntax.cs | 22 ++++++++ .../Syntax/Generics/Node/TypeSyntax.cs | 36 +++++++++++++ .../Syntax/Generics/Node/UnboundTree.cs | 10 ++++ .../Syntax/Parsing/Node/ExpressionSyntax.cs | 2 +- .../Node/{SyntaxTree.cs => ParseTree.cs} | 2 +- src/compiler/NubLang/Syntax/Parsing/Parser.cs | 4 +- 12 files changed, 189 insertions(+), 13 deletions(-) create mode 100644 src/compiler/NubLang/Syntax/Generics/GenericInstantiator.cs create mode 100644 src/compiler/NubLang/Syntax/Generics/Node/DefinitionSyntax.cs create mode 100644 src/compiler/NubLang/Syntax/Generics/Node/ExpressionSyntax.cs create mode 100644 src/compiler/NubLang/Syntax/Generics/Node/StatementSyntax.cs create mode 100644 src/compiler/NubLang/Syntax/Generics/Node/TypeSyntax.cs create mode 100644 src/compiler/NubLang/Syntax/Generics/Node/UnboundTree.cs rename src/compiler/NubLang/Syntax/Parsing/Node/{SyntaxTree.cs => ParseTree.cs} (56%) diff --git a/src/compiler/NubLang.CLI/Program.cs b/src/compiler/NubLang.CLI/Program.cs index de4b364..688c9ac 100644 --- a/src/compiler/NubLang.CLI/Program.cs +++ b/src/compiler/NubLang.CLI/Program.cs @@ -67,7 +67,7 @@ for (var i = 0; i < args.Length; i++) } var diagnostics = new List(); -var syntaxTrees = new Dictionary(); +var syntaxTrees = new Dictionary(); foreach (var file in options.Files) { diff --git a/src/compiler/NubLang/Syntax/Binding/Binder.cs b/src/compiler/NubLang/Syntax/Binding/Binder.cs index ae64378..b517537 100644 --- a/src/compiler/NubLang/Syntax/Binding/Binder.cs +++ b/src/compiler/NubLang/Syntax/Binding/Binder.cs @@ -8,7 +8,7 @@ namespace NubLang.Syntax.Binding; public sealed class Binder { - private readonly SyntaxTree _syntaxTree; + private readonly ParseTree _parseTree; private readonly DefinitionTable _definitionTable; private readonly Stack _scopes = []; @@ -16,9 +16,9 @@ public sealed class Binder private Scope Scope => _scopes.Peek(); - public Binder(SyntaxTree syntaxTree, DefinitionTable definitionTable) + public Binder(ParseTree parseTree, DefinitionTable definitionTable) { - _syntaxTree = syntaxTree; + _parseTree = parseTree; _definitionTable = definitionTable; } @@ -30,7 +30,7 @@ public sealed class Binder var diagnostics = new List(); var definitions = new List(); - foreach (var definition in _syntaxTree.Definitions) + foreach (var definition in _parseTree.Definitions) { try { @@ -42,7 +42,7 @@ public sealed class Binder } } - return new BoundSyntaxTree(_syntaxTree.Namespace, definitions, diagnostics); + return new BoundSyntaxTree(_parseTree.Namespace, definitions, diagnostics); } private BoundDefinition BindDefinition(DefinitionSyntax node) @@ -309,7 +309,7 @@ public sealed class Binder private BoundExpression BindIdentifier(IdentifierSyntax expression) { - var @namespace = expression.Namespace.Or(_syntaxTree.Namespace); + var @namespace = expression.Namespace.Or(_parseTree.Namespace); var localFuncs = _definitionTable.LookupLocalFunc(@namespace, expression.Name).ToArray(); if (localFuncs.Length > 0) { @@ -365,7 +365,7 @@ public sealed class Binder _ => throw new ArgumentOutOfRangeException() }; - return new BoundLiteral(expression.Tokens, type, expression.Literal, expression.Kind); + return new BoundLiteral(expression.Tokens, type, expression.Value, expression.Kind); } private BoundExpression BindMemberAccess(MemberAccessSyntax expression) diff --git a/src/compiler/NubLang/Syntax/Binding/DefinitionTable.cs b/src/compiler/NubLang/Syntax/Binding/DefinitionTable.cs index 7cddd36..36fa1d3 100644 --- a/src/compiler/NubLang/Syntax/Binding/DefinitionTable.cs +++ b/src/compiler/NubLang/Syntax/Binding/DefinitionTable.cs @@ -6,7 +6,7 @@ public class DefinitionTable { private readonly List _definitions; - public DefinitionTable(IEnumerable syntaxTrees) + public DefinitionTable(IEnumerable syntaxTrees) { _definitions = syntaxTrees.SelectMany(x => x.Definitions).ToList(); } diff --git a/src/compiler/NubLang/Syntax/Generics/GenericInstantiator.cs b/src/compiler/NubLang/Syntax/Generics/GenericInstantiator.cs new file mode 100644 index 0000000..257ebec --- /dev/null +++ b/src/compiler/NubLang/Syntax/Generics/GenericInstantiator.cs @@ -0,0 +1,30 @@ +using NubLang.Syntax.Generics.Node; +using NubLang.Syntax.Parsing.Node; + +namespace NubLang.Syntax.Generics; + +public class GenericInstantiator +{ + private readonly ParseTree _parseTree; + + public GenericInstantiator(ParseTree parseTree) + { + _parseTree = parseTree; + } + + public UnboundTree Visit() + { + var unboundDefinitions = new List(); + + foreach (var definition in _parseTree.Definitions) + { + switch (definition) + { + default: + throw new ArgumentOutOfRangeException(nameof(definition)); + } + } + + return new UnboundTree(_parseTree.Namespace, unboundDefinitions, _parseTree.Diagnostics); + } +} \ No newline at end of file diff --git a/src/compiler/NubLang/Syntax/Generics/Node/DefinitionSyntax.cs b/src/compiler/NubLang/Syntax/Generics/Node/DefinitionSyntax.cs new file mode 100644 index 0000000..9cfa421 --- /dev/null +++ b/src/compiler/NubLang/Syntax/Generics/Node/DefinitionSyntax.cs @@ -0,0 +1,26 @@ +using NubLang.Common; +using NubLang.Syntax.Tokenization; + +namespace NubLang.Syntax.Generics.Node; + +public record UnboundGenericParameter(IReadOnlyList Tokens, string Name) : UnboundNode(Tokens); + +public abstract record UnboundDefinition(IReadOnlyList Tokens, string Namespace, IReadOnlyList Parameters) : UnboundNode(Tokens); + +public record UnboundFuncParameter(IReadOnlyList Tokens, string Name, UnboundType Type) : UnboundNode(Tokens); + +public record UnboundFuncSignature(IReadOnlyList Tokens, IReadOnlyList Parameters, UnboundType ReturnType) : UnboundNode(Tokens); + +public record UnboundLocalFunc(IReadOnlyList Tokens, string Namespace, IReadOnlyList Parameters, string Name, UnboundFuncSignature Signature, UnboundBlock Body) : UnboundDefinition(Tokens, Namespace, Parameters); + +public record UnboundExternFunc(IReadOnlyList Tokens, string Namespace, IReadOnlyList Parameters, string Name, string CallName, UnboundFuncSignature Signature) : UnboundDefinition(Tokens, Namespace, Parameters); + +public record UnboundStructField(IReadOnlyList Tokens, int Index, string Name, UnboundType Type, Optional Value) : UnboundNode(Tokens); + +public record UnboundStructFunc(IReadOnlyList Tokens, string Name, UnboundFuncSignature Signature, UnboundBlock Body) : UnboundNode(Tokens); + +public record UnboundStruct(IReadOnlyList Tokens, string Namespace, IReadOnlyList Parameters, string Name, IReadOnlyList Fields, IReadOnlyList Funcs) : UnboundDefinition(Tokens, Namespace, Parameters); + +public record UnboundInterfaceFunc(IReadOnlyList Tokens, string Name, UnboundFuncSignature Signature) : UnboundNode(Tokens); + +public record UnboundInterface(IReadOnlyList Tokens, string Namespace, IReadOnlyList Parameters, string Name, IReadOnlyList Functions) : UnboundDefinition(Tokens, Namespace, Parameters); \ No newline at end of file diff --git a/src/compiler/NubLang/Syntax/Generics/Node/ExpressionSyntax.cs b/src/compiler/NubLang/Syntax/Generics/Node/ExpressionSyntax.cs new file mode 100644 index 0000000..3451340 --- /dev/null +++ b/src/compiler/NubLang/Syntax/Generics/Node/ExpressionSyntax.cs @@ -0,0 +1,52 @@ +using NubLang.Common; +using NubLang.Syntax.Tokenization; + +namespace NubLang.Syntax.Generics.Node; + +public enum UnboundUnaryOperator +{ + Negate, + Invert +} + +public enum UnboundBinaryOperator +{ + Equal, + NotEqual, + GreaterThan, + GreaterThanOrEqual, + LessThan, + LessThanOrEqual, + Plus, + Minus, + Multiply, + Divide +} + +public abstract record UnboundExpression(IReadOnlyList Tokens) : UnboundNode(Tokens); + +public record UnboundBinaryExpression(IReadOnlyList Tokens, UnboundExpression Left, UnboundBinaryOperator Operator, UnboundExpression Right) : UnboundExpression(Tokens); + +public record UnboundUnaryExpression(IReadOnlyList Tokens, UnboundUnaryOperator Operator, UnboundExpression Operand) : UnboundExpression(Tokens); + +public record UnboundFuncCall(IReadOnlyList Tokens, UnboundExpression Expression, IReadOnlyList Parameters) : UnboundExpression(Tokens); + +public record UnboundIdentifier(IReadOnlyList Tokens, Optional Namespace, string Name) : UnboundExpression(Tokens); + +public record UnboundArrayInitializer(IReadOnlyList Tokens, UnboundExpression Capacity, UnboundType ElementType) : UnboundExpression(Tokens); + +public record UnboundArrayIndexAccess(IReadOnlyList Tokens, UnboundExpression Target, UnboundExpression Index) : UnboundExpression(Tokens); + +public record UnboundArrowFuncParameter(IReadOnlyList Tokens, string Name) : UnboundExpression(Tokens); + +public record UnboundArrowFunc(IReadOnlyList Tokens, IReadOnlyList Parameters, UnboundBlock Body) : UnboundExpression(Tokens); + +public record UnboundAddressOf(IReadOnlyList Tokens, UnboundExpression Expression) : UnboundExpression(Tokens); + +public record UnboundLiteral(IReadOnlyList Tokens, string Value, LiteralKind Kind) : UnboundExpression(Tokens); + +public record UnboundMemberAccess(IReadOnlyList Tokens, UnboundExpression Target, string Member) : UnboundExpression(Tokens); + +public record UnboundStructInitializer(IReadOnlyList Tokens, UnboundType StructType, Dictionary Initializers) : UnboundExpression(Tokens); + +public record UnboundDereference(IReadOnlyList Tokens, UnboundExpression Expression) : UnboundExpression(Tokens); \ No newline at end of file diff --git a/src/compiler/NubLang/Syntax/Generics/Node/StatementSyntax.cs b/src/compiler/NubLang/Syntax/Generics/Node/StatementSyntax.cs new file mode 100644 index 0000000..fa90c03 --- /dev/null +++ b/src/compiler/NubLang/Syntax/Generics/Node/StatementSyntax.cs @@ -0,0 +1,22 @@ +using NubLang.Common; +using NubLang.Syntax.Tokenization; + +namespace NubLang.Syntax.Generics.Node; + +public record UnboundStatement(IReadOnlyList Tokens) : UnboundNode(Tokens); + +public record UnboundStatementExpression(IReadOnlyList Tokens, UnboundExpression Expression) : UnboundStatement(Tokens); + +public record UnboundReturn(IReadOnlyList Tokens, Optional Value) : UnboundStatement(Tokens); + +public record UnboundAssignment(IReadOnlyList Tokens, UnboundExpression Target, UnboundExpression Value) : UnboundStatement(Tokens); + +public record UnboundIf(IReadOnlyList Tokens, UnboundExpression Condition, UnboundBlock Body, Optional> Else) : UnboundStatement(Tokens); + +public record UnboundVariableDeclaration(IReadOnlyList Tokens, string Name, Optional ExplicitType, Optional Assignment) : UnboundStatement(Tokens); + +public record UnboundContinue(IReadOnlyList Tokens) : UnboundStatement(Tokens); + +public record UnboundBreak(IReadOnlyList Tokens) : UnboundStatement(Tokens); + +public record UnboundWhile(IReadOnlyList Tokens, UnboundExpression Condition, UnboundBlock Body) : UnboundStatement(Tokens); \ No newline at end of file diff --git a/src/compiler/NubLang/Syntax/Generics/Node/TypeSyntax.cs b/src/compiler/NubLang/Syntax/Generics/Node/TypeSyntax.cs new file mode 100644 index 0000000..07c0dd5 --- /dev/null +++ b/src/compiler/NubLang/Syntax/Generics/Node/TypeSyntax.cs @@ -0,0 +1,36 @@ +using NubLang.Syntax.Tokenization; + +namespace NubLang.Syntax.Generics.Node; + +public enum UnboundPrimitiveTypeKind +{ + I64, + I32, + I16, + I8, + U64, + U32, + U16, + U8, + F64, + F32, + Bool +} + +public abstract record UnboundType(IReadOnlyList Tokens) : UnboundNode(Tokens); + +public record UnboundFuncType(IReadOnlyList Tokens, IReadOnlyList Parameters, UnboundType ReturnType) : UnboundType(Tokens); + +public record UnboundPointerType(IReadOnlyList Tokens, UnboundType BaseType) : UnboundType(Tokens); + +public record UnboundVoidType(IReadOnlyList Tokens) : UnboundType(Tokens); + +public record UnboundPrimitiveType(IReadOnlyList Tokens, UnboundPrimitiveTypeKind SyntaxKind) : UnboundType(Tokens); + +public record UnboundCStringType(IReadOnlyList Tokens) : UnboundType(Tokens); + +public record UnboundStringType(IReadOnlyList Tokens) : UnboundType(Tokens); + +public record UnboundCustomType(IReadOnlyList Tokens, string Namespace, string Name, IReadOnlyList Arguments) : UnboundType(Tokens); + +public record UnboundArrayType(IReadOnlyList Tokens, UnboundType BaseType) : UnboundType(Tokens); \ No newline at end of file diff --git a/src/compiler/NubLang/Syntax/Generics/Node/UnboundTree.cs b/src/compiler/NubLang/Syntax/Generics/Node/UnboundTree.cs new file mode 100644 index 0000000..0953e8f --- /dev/null +++ b/src/compiler/NubLang/Syntax/Generics/Node/UnboundTree.cs @@ -0,0 +1,10 @@ +using NubLang.Diagnostics; +using NubLang.Syntax.Tokenization; + +namespace NubLang.Syntax.Generics.Node; + +public record UnboundTree(string Namespace, IReadOnlyList Definitions, IReadOnlyList Diagnostics); + +public abstract record UnboundNode(IReadOnlyList Tokens); + +public record UnboundBlock(IReadOnlyList Tokens, IReadOnlyList Statements) : UnboundNode(Tokens); \ 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 a6badbf..32702b2 100644 --- a/src/compiler/NubLang/Syntax/Parsing/Node/ExpressionSyntax.cs +++ b/src/compiler/NubLang/Syntax/Parsing/Node/ExpressionSyntax.cs @@ -43,7 +43,7 @@ public record ArrowFuncSyntax(IReadOnlyList Tokens, IReadOnlyList Tokens, ExpressionSyntax Expression) : ExpressionSyntax(Tokens); -public record LiteralSyntax(IReadOnlyList Tokens, string Literal, LiteralKind Kind) : ExpressionSyntax(Tokens); +public record LiteralSyntax(IReadOnlyList Tokens, string Value, LiteralKind Kind) : ExpressionSyntax(Tokens); public record MemberAccessSyntax(IReadOnlyList Tokens, ExpressionSyntax Target, string Member) : ExpressionSyntax(Tokens); diff --git a/src/compiler/NubLang/Syntax/Parsing/Node/SyntaxTree.cs b/src/compiler/NubLang/Syntax/Parsing/Node/ParseTree.cs similarity index 56% rename from src/compiler/NubLang/Syntax/Parsing/Node/SyntaxTree.cs rename to src/compiler/NubLang/Syntax/Parsing/Node/ParseTree.cs index fee54d1..2fe9f0f 100644 --- a/src/compiler/NubLang/Syntax/Parsing/Node/SyntaxTree.cs +++ b/src/compiler/NubLang/Syntax/Parsing/Node/ParseTree.cs @@ -3,7 +3,7 @@ using NubLang.Syntax.Tokenization; namespace NubLang.Syntax.Parsing.Node; -public record SyntaxTree(string Namespace, IReadOnlyList Definitions, IReadOnlyList Diagnostics); +public record ParseTree(string Namespace, IReadOnlyList Definitions, IReadOnlyList Diagnostics); public abstract record SyntaxNode(IReadOnlyList Tokens); diff --git a/src/compiler/NubLang/Syntax/Parsing/Parser.cs b/src/compiler/NubLang/Syntax/Parsing/Parser.cs index b65c47b..39eb1bd 100644 --- a/src/compiler/NubLang/Syntax/Parsing/Parser.cs +++ b/src/compiler/NubLang/Syntax/Parsing/Parser.cs @@ -21,7 +21,7 @@ public sealed class Parser _tokens = tokens; } - public SyntaxTree Parse() + public ParseTree Parse() { _diagnostics.Clear(); _genericParameters.Clear(); @@ -95,7 +95,7 @@ public sealed class Parser } } - return new SyntaxTree(_namespace, definitions, _diagnostics); + return new ParseTree(_namespace, definitions, _diagnostics); } private FuncSignatureSyntax ParseFuncSignature(FuncParameterSyntax? thisArg = null)