From eb13b94fa50d7a6132d27f1c7935a61fc5568216 Mon Sep 17 00:00:00 2001 From: nub31 Date: Sun, 6 Jul 2025 23:09:54 +0200 Subject: [PATCH] rename node -> syntax --- src/compiler/CLI/Program.cs | 1 + src/compiler/NubLang/DefinitionTable.cs | 59 +++--- .../NubLang/Diagnostics/Diagnostic.cs | 4 +- .../NubLang/Generation/QBE/QBEGenerator.cs | 40 ++-- src/compiler/NubLang/Syntax/Binding/Binder.cs | 154 ++++++++------ .../NubLang/Syntax/Node/Definition.cs | 33 +-- .../NubLang/Syntax/Node/Expression.cs | 28 +-- src/compiler/NubLang/Syntax/Node/Node.cs | 9 - src/compiler/NubLang/Syntax/Node/Statement.cs | 10 - .../NubLang/Syntax/Node/SyntaxTree.cs | 8 +- .../Syntax/Parsing/Node/DefinitionSyntax.cs | 26 +++ .../Syntax/Parsing/Node/ExpressionSyntax.cs | 50 +++++ .../Syntax/Parsing/Node/StatementSyntax.cs | 22 ++ .../NubLang/Syntax/Parsing/Node/SyntaxTree.cs | 10 + src/compiler/NubLang/Syntax/Parsing/Parser.cs | 190 +++++++++--------- 15 files changed, 373 insertions(+), 271 deletions(-) delete mode 100644 src/compiler/NubLang/Syntax/Node/Node.cs create mode 100644 src/compiler/NubLang/Syntax/Parsing/Node/DefinitionSyntax.cs create mode 100644 src/compiler/NubLang/Syntax/Parsing/Node/ExpressionSyntax.cs create mode 100644 src/compiler/NubLang/Syntax/Parsing/Node/StatementSyntax.cs create mode 100644 src/compiler/NubLang/Syntax/Parsing/Node/SyntaxTree.cs diff --git a/src/compiler/CLI/Program.cs b/src/compiler/CLI/Program.cs index 98a2359..53069f3 100644 --- a/src/compiler/CLI/Program.cs +++ b/src/compiler/CLI/Program.cs @@ -5,6 +5,7 @@ using NubLang.Diagnostics; using NubLang.Generation.QBE; using NubLang.Syntax.Node; using NubLang.Syntax.Parsing; +using NubLang.Syntax.Parsing.Node; using NubLang.Syntax.Tokenization; using Binder = NubLang.Syntax.Binding.Binder; diff --git a/src/compiler/NubLang/DefinitionTable.cs b/src/compiler/NubLang/DefinitionTable.cs index d7464e6..709015f 100644 --- a/src/compiler/NubLang/DefinitionTable.cs +++ b/src/compiler/NubLang/DefinitionTable.cs @@ -1,59 +1,60 @@ using NubLang.Syntax.Node; +using NubLang.Syntax.Parsing.Node; namespace NubLang; public sealed class DefinitionTable { - private readonly List _topLevelNodes; + private readonly List _definitions; public DefinitionTable(IEnumerable syntaxTrees) { - _topLevelNodes = syntaxTrees.SelectMany(x => x.TopLevelNodes).ToList(); + _definitions = syntaxTrees.SelectMany(x => x.Definitions).ToList(); } - public IEnumerable LookupLocalFunc(string @namespace, string name) + public IEnumerable LookupLocalFunc(string @namespace, string name) { - return _topLevelNodes - .OfType() + return _definitions + .OfType() .Where(x => x.Namespace == @namespace && x.Name == name); } - public IEnumerable LookupExternFunc(string @namespace, string name) + public IEnumerable LookupExternFunc(string @namespace, string name) { - return _topLevelNodes - .OfType() + return _definitions + .OfType() .Where(x => x.Namespace == @namespace && x.Name == name); } - public IEnumerable LookupStruct(string @namespace, string name) + public IEnumerable LookupStruct(string @namespace, string name) { - return _topLevelNodes - .OfType() + return _definitions + .OfType() .Where(x => x.Namespace == @namespace && x.Name == name); } - public IEnumerable LookupStructField(StructNode structNode, string field) + public IEnumerable LookupStructField(StructSyntax structNode, string field) { return structNode.Fields.Where(x => x.Name == field); } - public IEnumerable LookupTraitFuncImpl(NubType forType, string name) + public IEnumerable LookupTraitFuncImpl(NubType forType, string name) { - return _topLevelNodes - .OfType() + return _definitions + .OfType() .Where(x => x.ForType == forType) .SelectMany(x => x.Functions) .Where(x => x.Name == name); } - public IEnumerable LookupTrait(string @namespace, string name) + public IEnumerable LookupTrait(string @namespace, string name) { - return _topLevelNodes - .OfType() + return _definitions + .OfType() .Where(x => x.Namespace == @namespace && x.Name == name); } - public IEnumerable LookupTraitFunc(TraitNode trait, string name) + public IEnumerable LookupTraitFunc(TraitSyntax trait, string name) { return trait.Functions.Where(x => x.Name == name); } @@ -61,30 +62,30 @@ public sealed class DefinitionTable public sealed class BoundDefinitionTable { - private readonly List _topLevelNodes; + private readonly List _definitions; public BoundDefinitionTable(IEnumerable syntaxTrees) { - _topLevelNodes = syntaxTrees.SelectMany(x => x.TopLevelNodes).ToList(); + _definitions = syntaxTrees.SelectMany(x => x.Definitions).ToList(); } public BoundLocalFuncNode LookupLocalFunc(string @namespace, string name) { - return _topLevelNodes + return _definitions .OfType() .First(x => x.Namespace == @namespace && x.Name == name); } public BoundExternFuncNode LookupExternFunc(string @namespace, string name) { - return _topLevelNodes + return _definitions .OfType() .First(x => x.Namespace == @namespace && x.Name == name); } public BoundStructNode LookupStruct(string @namespace, string name) { - return _topLevelNodes + return _definitions .OfType() .First(x => x.Namespace == @namespace && x.Name == name); } @@ -96,14 +97,14 @@ public sealed class BoundDefinitionTable public IEnumerable LookupTraitImpls(NubType itemType) { - return _topLevelNodes + return _definitions .OfType() .Where(x => x.ForType == itemType); } public BoundTraitFuncImplNode LookupTraitFuncImpl(NubType forType, string name) { - return _topLevelNodes + return _definitions .OfType() .Where(x => x.ForType == forType) .SelectMany(x => x.Functions) @@ -112,7 +113,7 @@ public sealed class BoundDefinitionTable public BoundTraitNode LookupTrait(string @namespace, string name) { - return _topLevelNodes + return _definitions .OfType() .First(x => x.Namespace == @namespace && x.Name == name); } @@ -124,11 +125,11 @@ public sealed class BoundDefinitionTable public IEnumerable GetStructs() { - return _topLevelNodes.OfType(); + return _definitions.OfType(); } public IEnumerable GetTraits() { - return _topLevelNodes.OfType(); + return _definitions.OfType(); } } \ No newline at end of file diff --git a/src/compiler/NubLang/Diagnostics/Diagnostic.cs b/src/compiler/NubLang/Diagnostics/Diagnostic.cs index 2f7e6da..75370fb 100644 --- a/src/compiler/NubLang/Diagnostics/Diagnostic.cs +++ b/src/compiler/NubLang/Diagnostics/Diagnostic.cs @@ -1,5 +1,5 @@ using System.Text; -using NubLang.Syntax.Node; +using NubLang.Syntax.Parsing.Node; using NubLang.Syntax.Tokenization; namespace NubLang.Diagnostics; @@ -25,7 +25,7 @@ public class Diagnostic return this; } - public DiagnosticBuilder At(Node node) + public DiagnosticBuilder At(SyntaxNode node) { _sourceSpan = SourceSpan.Merge(node.Tokens.Select(t => t.Span)); return this; diff --git a/src/compiler/NubLang/Generation/QBE/QBEGenerator.cs b/src/compiler/NubLang/Generation/QBE/QBEGenerator.cs index e16676d..ae4ca6f 100644 --- a/src/compiler/NubLang/Generation/QBE/QBEGenerator.cs +++ b/src/compiler/NubLang/Generation/QBE/QBEGenerator.cs @@ -64,7 +64,7 @@ public static class QBEGenerator _writer.NewLine(); } - foreach (var funcDef in _syntaxTree.TopLevelNodes.OfType()) + foreach (var funcDef in _syntaxTree.Definitions.OfType()) { EmitFuncDefinition(funcDef, LocalFuncName(funcDef), funcDef.Parameters, funcDef.ReturnType, funcDef.Body, funcDef.Exported); _writer.NewLine(); @@ -766,15 +766,15 @@ public static class QBEGenerator return new Val(outputName, binaryExpression.Type, ValKind.Direct); } - private static string EmitBinaryInstructionFor(BinaryExpressionOperator op, NubType type, string left, string right) + private static string EmitBinaryInstructionFor(BoundBinaryOperator op, NubType type, string left, string right) { if (op is - BinaryExpressionOperator.Equal or - BinaryExpressionOperator.NotEqual or - BinaryExpressionOperator.GreaterThan or - BinaryExpressionOperator.GreaterThanOrEqual or - BinaryExpressionOperator.LessThan or - BinaryExpressionOperator.LessThanOrEqual) + BoundBinaryOperator.Equal or + BoundBinaryOperator.NotEqual or + BoundBinaryOperator.GreaterThan or + BoundBinaryOperator.GreaterThanOrEqual or + BoundBinaryOperator.LessThan or + BoundBinaryOperator.LessThanOrEqual) { char suffix; @@ -815,12 +815,12 @@ public static class QBEGenerator throw new NotSupportedException($"Unsupported type '{simpleType}' for binary operator '{op}'"); } - if (op is BinaryExpressionOperator.Equal) + if (op is BoundBinaryOperator.Equal) { return "ceq" + suffix; } - if (op is BinaryExpressionOperator.NotEqual) + if (op is BoundBinaryOperator.NotEqual) { return "cne" + suffix; } @@ -842,20 +842,20 @@ public static class QBEGenerator return op switch { - BinaryExpressionOperator.GreaterThan => 'c' + sign + "gt" + suffix, - BinaryExpressionOperator.GreaterThanOrEqual => 'c' + sign + "ge" + suffix, - BinaryExpressionOperator.LessThan => 'c' + sign + "lt" + suffix, - BinaryExpressionOperator.LessThanOrEqual => 'c' + sign + "le" + suffix, + BoundBinaryOperator.GreaterThan => 'c' + sign + "gt" + suffix, + BoundBinaryOperator.GreaterThanOrEqual => 'c' + sign + "ge" + suffix, + BoundBinaryOperator.LessThan => 'c' + sign + "lt" + suffix, + BoundBinaryOperator.LessThanOrEqual => 'c' + sign + "le" + suffix, _ => throw new ArgumentOutOfRangeException(nameof(op), op, null) }; } return op switch { - BinaryExpressionOperator.Plus => "add", - BinaryExpressionOperator.Minus => "sub", - BinaryExpressionOperator.Multiply => "mul", - BinaryExpressionOperator.Divide => "div", + BoundBinaryOperator.Plus => "add", + BoundBinaryOperator.Minus => "sub", + BoundBinaryOperator.Multiply => "mul", + BoundBinaryOperator.Divide => "div", _ => throw new ArgumentOutOfRangeException(nameof(op)) }; } @@ -994,7 +994,7 @@ public static class QBEGenerator switch (unaryExpression.Operator) { - case UnaryExpressionOperator.Negate: + case BoundUnaryOperator.Negate: { switch (unaryExpression.Operand.Type) { @@ -1014,7 +1014,7 @@ public static class QBEGenerator break; } - case UnaryExpressionOperator.Invert: + case BoundUnaryOperator.Invert: { switch (unaryExpression.Operand.Type) { diff --git a/src/compiler/NubLang/Syntax/Binding/Binder.cs b/src/compiler/NubLang/Syntax/Binding/Binder.cs index 053b188..5b0f9f5 100644 --- a/src/compiler/NubLang/Syntax/Binding/Binder.cs +++ b/src/compiler/NubLang/Syntax/Binding/Binder.cs @@ -1,8 +1,8 @@ using Common; using NubLang.Diagnostics; using NubLang.Syntax.Node; +using NubLang.Syntax.Parsing.Node; using NubLang.Syntax.Tokenization; -using Node_UnaryExpressionNode = NubLang.Syntax.Node.UnaryExpressionNode; namespace NubLang.Syntax.Binding; @@ -28,13 +28,13 @@ public sealed class Binder _functionReturnType = null; var diagnostics = new List(); - var topLevelNodes = new List(); + var definitions = new List(); - foreach (var topLevel in _syntaxTree.TopLevelNodes) + foreach (var definition in _syntaxTree.Definitions) { try { - topLevelNodes.Add(BindTopLevel(topLevel)); + definitions.Add(BindTopLevel(definition)); } catch (BindException e) { @@ -42,23 +42,23 @@ public sealed class Binder } } - return new BoundSyntaxTree(_syntaxTree.Namespace, topLevelNodes, diagnostics); + return new BoundSyntaxTree(_syntaxTree.Namespace, definitions, diagnostics); } - private BoundTopLevelNode BindTopLevel(TopLevelNode node) + private BoundDefinitionNode BindTopLevel(DefinitionSyntax node) { return node switch { - ExternFuncNode topLevel => BindExternFuncDefinition(topLevel), - TraitImplNode topLevel => BindTraitImplementation(topLevel), - TraitNode topLevel => BindTraitDefinition(topLevel), - LocalFuncNode topLevel => BindLocalFuncDefinition(topLevel), - StructNode topLevel => BindStruct(topLevel), + ExternFuncSyntax topLevel => BindExternFuncDefinition(topLevel), + TraitImplSyntax topLevel => BindTraitImplementation(topLevel), + TraitSyntax topLevel => BindTraitDefinition(topLevel), + LocalFuncSyntax topLevel => BindLocalFuncDefinition(topLevel), + StructSyntax topLevel => BindStruct(topLevel), _ => throw new ArgumentOutOfRangeException(nameof(node)) }; } - private BoundTraitImplNode BindTraitImplementation(TraitImplNode node) + private BoundTraitImplNode BindTraitImplementation(TraitImplSyntax node) { _variables.Clear(); var functions = new List(); @@ -79,7 +79,7 @@ public sealed class Binder return new BoundTraitImplNode(node.Tokens, node.Namespace, node.TraitType, node.ForType, functions); } - private BoundTraitNode BindTraitDefinition(TraitNode node) + private BoundTraitNode BindTraitDefinition(TraitSyntax node) { var functions = new List(); @@ -98,7 +98,7 @@ public sealed class Binder return new BoundTraitNode(node.Tokens, node.Namespace, node.Name, functions); } - private BoundStructNode BindStruct(StructNode node) + private BoundStructNode BindStruct(StructSyntax node) { var structFields = new List(); @@ -117,7 +117,7 @@ public sealed class Binder return new BoundStructNode(node.Tokens, node.Namespace, node.Name, structFields); } - private BoundExternFuncNode BindExternFuncDefinition(ExternFuncNode node) + private BoundExternFuncNode BindExternFuncDefinition(ExternFuncSyntax node) { var parameters = new List(); @@ -129,7 +129,7 @@ public sealed class Binder return new BoundExternFuncNode(node.Tokens, node.Namespace, node.Name, node.CallName, parameters, node.ReturnType); } - private BoundLocalFuncNode BindLocalFuncDefinition(LocalFuncNode node) + private BoundLocalFuncNode BindLocalFuncDefinition(LocalFuncSyntax node) { _variables.Clear(); _functionReturnType = node.ReturnType; @@ -147,7 +147,7 @@ public sealed class Binder return new BoundLocalFuncNode(node.Tokens, node.Namespace, node.Name, parameters, body, node.ReturnType, node.Exported); } - private BoundBlock BindBlock(BlockNode node) + private BoundBlock BindBlock(BlockSyntax node) { var statements = new List(); @@ -159,40 +159,40 @@ public sealed class Binder return new BoundBlock(node.Tokens, statements); } - private BoundStatementNode BindStatement(StatementNode node) + private BoundStatementNode BindStatement(StatementSyntax node) { return node switch { - AssignmentNode statement => BindAssignment(statement), - BreakNode statement => BindBreak(statement), - ContinueNode statement => BindContinue(statement), - IfNode statement => BindIf(statement), - ReturnNode statement => BindReturn(statement), - StatementExpressionNode statement => BindStatementExpression(statement), - VariableDeclarationNode statement => BindVariableDeclaration(statement), - WhileNode statement => BindWhile(statement), + AssignmentSyntax statement => BindAssignment(statement), + BreakSyntax statement => BindBreak(statement), + ContinueSyntax statement => BindContinue(statement), + IfSyntax statement => BindIf(statement), + ReturnSyntax statement => BindReturn(statement), + StatementExpressionSyntax statement => BindStatementExpression(statement), + VariableDeclarationSyntax statement => BindVariableDeclaration(statement), + WhileSyntax statement => BindWhile(statement), _ => throw new ArgumentOutOfRangeException(nameof(node)) }; } - private BoundStatementNode BindAssignment(AssignmentNode statement) + private BoundStatementNode BindAssignment(AssignmentSyntax statement) { var expression = BindExpression(statement.Target); var value = BindExpression(statement.Value, expression.Type); return new BoundAssignmentNode(statement.Tokens, expression, value); } - private BoundBreakNode BindBreak(BreakNode statement) + private BoundBreakNode BindBreak(BreakSyntax statement) { return new BoundBreakNode(statement.Tokens); } - private BoundContinueNode BindContinue(ContinueNode statement) + private BoundContinueNode BindContinue(ContinueSyntax statement) { return new BoundContinueNode(statement.Tokens); } - private BoundIfNode BindIf(IfNode statement) + private BoundIfNode BindIf(IfSyntax statement) { var elseStatement = Optional.Empty>(); @@ -208,7 +208,7 @@ public sealed class Binder return new BoundIfNode(statement.Tokens, BindExpression(statement.Condition, new NubPrimitiveType(PrimitiveTypeKind.Bool)), BindBlock(statement.Body), elseStatement); } - private BoundReturnNode BindReturn(ReturnNode statement) + private BoundReturnNode BindReturn(ReturnSyntax statement) { var value = Optional.Empty(); @@ -220,12 +220,12 @@ public sealed class Binder return new BoundReturnNode(statement.Tokens, value); } - private BoundStatementExpressionNode BindStatementExpression(StatementExpressionNode statement) + private BoundStatementExpressionNode BindStatementExpression(StatementExpressionSyntax statement) { return new BoundStatementExpressionNode(statement.Tokens, BindExpression(statement.Expression)); } - private BoundVariableDeclarationNode BindVariableDeclaration(VariableDeclarationNode statement) + private BoundVariableDeclarationNode BindVariableDeclaration(VariableDeclarationSyntax statement) { NubType? type = null; @@ -252,38 +252,38 @@ public sealed class Binder return new BoundVariableDeclarationNode(statement.Tokens, statement.Name, assignment, type); } - private BoundWhileNode BindWhile(WhileNode statement) + private BoundWhileNode BindWhile(WhileSyntax statement) { return new BoundWhileNode(statement.Tokens, BindExpression(statement.Condition, new NubPrimitiveType(PrimitiveTypeKind.Bool)), BindBlock(statement.Body)); } - private BoundExpressionNode BindExpression(ExpressionNode node, NubType? expectedType = null) + private BoundExpressionNode BindExpression(ExpressionSyntax node, NubType? expectedType = null) { return node switch { - AddressOfNode expression => BindAddressOf(expression), - AnonymousFuncNode expression => BindAnonymousFunc(expression), - ArrayIndexAccessNode expression => BindArrayIndexAccess(expression), - ArrayInitializerNode expression => BindArrayInitializer(expression), - BinaryExpressionNode expression => BindBinaryExpression(expression), - DereferenceNode expression => BindDereference(expression), - FuncCallNode expression => BindFuncCall(expression), - IdentifierNode expression => BindIdentifier(expression), - LiteralNode expression => BindLiteral(expression, expectedType), - MemberAccessNode expression => BindMemberAccess(expression), - StructInitializerNode expression => BindStructInitializer(expression), - Node_UnaryExpressionNode expression => BindUnaryExpression(expression), + AddressOfSyntax expression => BindAddressOf(expression), + AnonymousFuncSyntax expression => BindAnonymousFunc(expression), + ArrayIndexAccessSyntax expression => BindArrayIndexAccess(expression), + ArrayInitializerSyntax expression => BindArrayInitializer(expression), + BinaryExpressionSyntax expression => BindBinaryExpression(expression), + DereferenceSyntax expression => BindDereference(expression), + FuncCallSyntax expression => BindFuncCall(expression), + IdentifierSyntax expression => BindIdentifier(expression), + LiteralSyntax expression => BindLiteral(expression, expectedType), + MemberAccessSyntax expression => BindMemberAccess(expression), + StructInitializerSyntax expression => BindStructInitializer(expression), + UnaryExpressionSyntax expression => BindUnaryExpression(expression), _ => throw new ArgumentOutOfRangeException(nameof(node)) }; } - private BoundAddressOfNode BindAddressOf(AddressOfNode expression) + private BoundAddressOfNode BindAddressOf(AddressOfSyntax expression) { var inner = BindExpression(expression.Expression); return new BoundAddressOfNode(expression.Tokens, new NubPointerType(inner.Type), inner); } - private BoundAnonymousFuncNode BindAnonymousFunc(AnonymousFuncNode expression) + private BoundAnonymousFuncNode BindAnonymousFunc(AnonymousFuncSyntax expression) { var parameters = new List(); @@ -297,33 +297,33 @@ public sealed class Binder return new BoundAnonymousFuncNode(expression.Tokens, new NubFuncType(expression.ReturnType, parameters.Select(x => x.Type).ToList()), parameters, body, expression.ReturnType); } - private BoundArrayIndexAccessNode BindArrayIndexAccess(ArrayIndexAccessNode expression) + private BoundArrayIndexAccessNode BindArrayIndexAccess(ArrayIndexAccessSyntax expression) { var boundArray = BindExpression(expression.Target); var elementType = ((NubArrayType)boundArray.Type).ElementType; return new BoundArrayIndexAccessNode(expression.Tokens, elementType, boundArray, BindExpression(expression.Index, new NubPrimitiveType(PrimitiveTypeKind.U64))); } - private BoundArrayInitializerNode BindArrayInitializer(ArrayInitializerNode expression) + private BoundArrayInitializerNode BindArrayInitializer(ArrayInitializerSyntax expression) { return new BoundArrayInitializerNode(expression.Tokens, new NubArrayType(expression.ElementType), BindExpression(expression.Capacity, new NubPrimitiveType(PrimitiveTypeKind.U64)), expression.ElementType); } - private BoundBinaryExpressionNode BindBinaryExpression(BinaryExpressionNode expression) + private BoundBinaryExpressionNode BindBinaryExpression(BinaryExpressionSyntax expression) { var boundLeft = BindExpression(expression.Left); var boundRight = BindExpression(expression.Right, boundLeft.Type); - return new BoundBinaryExpressionNode(expression.Tokens, boundLeft.Type, boundLeft, expression.Operator, boundRight); + return new BoundBinaryExpressionNode(expression.Tokens, boundLeft.Type, boundLeft, BindBinaryOperator(expression.Operator), boundRight); } - private BoundDereferenceNode BindDereference(DereferenceNode expression) + private BoundDereferenceNode BindDereference(DereferenceSyntax expression) { var boundExpression = BindExpression(expression.Expression); var dereferencedType = ((NubPointerType)boundExpression.Type).BaseType; return new BoundDereferenceNode(expression.Tokens, dereferencedType, boundExpression); } - private BoundFuncCallNode BindFuncCall(FuncCallNode expression) + private BoundFuncCallNode BindFuncCall(FuncCallSyntax expression) { var boundExpression = BindExpression(expression.Expression); @@ -346,7 +346,7 @@ public sealed class Binder return new BoundFuncCallNode(expression.Tokens, funcType.ReturnType, boundExpression, parameters); } - private BoundExpressionNode BindIdentifier(IdentifierNode expression) + private BoundExpressionNode BindIdentifier(IdentifierSyntax expression) { var @namespace = expression.Namespace.Or(_syntaxTree.Namespace); var localFuncs = _definitionTable.LookupLocalFunc(@namespace, expression.Name).ToArray(); @@ -385,7 +385,7 @@ public sealed class Binder throw new BindException(Diagnostic.Error($"No identifier with then name {(expression.Namespace.HasValue ? $"{expression.Namespace.Value}::" : "")}{expression.Name} exists").Build()); } - private BoundLiteralNode BindLiteral(LiteralNode expression, NubType? expectedType = null) + private BoundLiteralNode BindLiteral(LiteralSyntax expression, NubType? expectedType = null) { var type = expectedType ?? expression.Kind switch { @@ -399,7 +399,7 @@ public sealed class Binder return new BoundLiteralNode(expression.Tokens, type, expression.Literal, expression.Kind); } - private BoundExpressionNode BindMemberAccess(MemberAccessNode expression) + private BoundExpressionNode BindMemberAccess(MemberAccessSyntax expression) { var boundExpression = BindExpression(expression.Target); @@ -472,7 +472,7 @@ public sealed class Binder throw new BindException(Diagnostic.Error($"{boundExpression.Type} does not have a member with the name {expression.Member}").Build()); } - private BoundStructInitializerNode BindStructInitializer(StructInitializerNode expression) + private BoundStructInitializerNode BindStructInitializer(StructInitializerSyntax expression) { if (expression.StructType is not NubCustomType structType) { @@ -515,7 +515,7 @@ public sealed class Binder return new BoundStructInitializerNode(expression.Tokens, structType, new NubCustomType(@struct.Namespace, @struct.Name), initializers); } - private BoundUnaryExpressionNode BindUnaryExpression(Node_UnaryExpressionNode expression) + private BoundUnaryExpressionNode BindUnaryExpression(UnaryExpressionSyntax expression) { var boundOperand = BindExpression(expression.Operand); @@ -523,7 +523,7 @@ public sealed class Binder switch (expression.Operator) { - case UnaryExpressionOperator.Negate: + case UnaryOperator.Negate: { boundOperand = BindExpression(expression.Operand, new NubPrimitiveType(PrimitiveTypeKind.I64)); @@ -534,7 +534,7 @@ public sealed class Binder break; } - case UnaryExpressionOperator.Invert: + case UnaryOperator.Invert: { boundOperand = BindExpression(expression.Operand, new NubPrimitiveType(PrimitiveTypeKind.Bool)); @@ -548,7 +548,35 @@ public sealed class Binder throw new NotImplementedException("Diagnostics not implemented"); } - return new BoundUnaryExpressionNode(expression.Tokens, type, expression.Operator, boundOperand); + return new BoundUnaryExpressionNode(expression.Tokens, type, BindBinaryOperator(expression.Operator), boundOperand); + } + + private BoundBinaryOperator BindBinaryOperator(BinaryOperator op) + { + return op switch + { + BinaryOperator.Equal => BoundBinaryOperator.Equal, + BinaryOperator.NotEqual => BoundBinaryOperator.NotEqual, + BinaryOperator.GreaterThan => BoundBinaryOperator.GreaterThan, + BinaryOperator.GreaterThanOrEqual => BoundBinaryOperator.GreaterThanOrEqual, + BinaryOperator.LessThan => BoundBinaryOperator.LessThan, + BinaryOperator.LessThanOrEqual => BoundBinaryOperator.LessThanOrEqual, + BinaryOperator.Plus => BoundBinaryOperator.Plus, + BinaryOperator.Minus => BoundBinaryOperator.Minus, + BinaryOperator.Multiply => BoundBinaryOperator.Multiply, + BinaryOperator.Divide => BoundBinaryOperator.Divide, + _ => throw new ArgumentOutOfRangeException(nameof(op), op, null) + }; + } + + private BoundUnaryOperator BindBinaryOperator(UnaryOperator op) + { + return op switch + { + UnaryOperator.Negate => BoundUnaryOperator.Negate, + UnaryOperator.Invert => BoundUnaryOperator.Invert, + _ => throw new ArgumentOutOfRangeException(nameof(op), op, null) + }; } } diff --git a/src/compiler/NubLang/Syntax/Node/Definition.cs b/src/compiler/NubLang/Syntax/Node/Definition.cs index 4b2ab24..0fa80bf 100644 --- a/src/compiler/NubLang/Syntax/Node/Definition.cs +++ b/src/compiler/NubLang/Syntax/Node/Definition.cs @@ -3,35 +3,24 @@ using NubLang.Syntax.Tokenization; namespace NubLang.Syntax.Node; -public record FuncParameterNode(IEnumerable Tokens, string Name, NubType Type) : DefinitionNode(Tokens); -public record BoundFuncParameterNode(IEnumerable Tokens, string Name, NubType Type) : DefinitionNode(Tokens); +public abstract record BoundDefinitionNode(IEnumerable Tokens, string Namespace) : BoundNode(Tokens); -public abstract record TopLevelNode(IEnumerable Tokens, string Namespace) : Node(Tokens); -public abstract record BoundTopLevelNode(IEnumerable Tokens, string Namespace) : BoundNode(Tokens); +public abstract record BoundDefinitionMemberNode(IEnumerable Tokens) : BoundNode(Tokens); -public abstract record DefinitionNode(IEnumerable Tokens) : Node(Tokens); -public abstract record BoundDefinitionNode(IEnumerable Tokens) : BoundNode(Tokens); +public record BoundFuncParameterNode(IEnumerable Tokens, string Name, NubType Type) : BoundDefinitionMemberNode(Tokens); -public record LocalFuncNode(IEnumerable Tokens, string Namespace, string Name, List Parameters, BlockNode Body, NubType ReturnType, bool Exported) : TopLevelNode(Tokens, Namespace); -public record BoundLocalFuncNode(IEnumerable Tokens, string Namespace, string Name, List Parameters, BoundBlock Body, NubType ReturnType, bool Exported) : BoundTopLevelNode(Tokens, Namespace); +public record BoundLocalFuncNode(IEnumerable Tokens, string Namespace, string Name, List Parameters, BoundBlock Body, NubType ReturnType, bool Exported) : BoundDefinitionNode(Tokens, Namespace); -public record ExternFuncNode(IEnumerable Tokens, string Namespace, string Name, string CallName, List Parameters, NubType ReturnType) : TopLevelNode(Tokens, Namespace); -public record BoundExternFuncNode(IEnumerable Tokens, string Namespace, string Name, string CallName, List Parameters, NubType ReturnType) : BoundTopLevelNode(Tokens, Namespace); +public record BoundExternFuncNode(IEnumerable Tokens, string Namespace, string Name, string CallName, List Parameters, NubType ReturnType) : BoundDefinitionNode(Tokens, Namespace); -public record StructFieldNode(IEnumerable Tokens, int Index, string Name, NubType Type, Optional Value) : DefinitionNode(Tokens); -public record StructNode(IEnumerable Tokens, string Namespace, string Name, List Fields) : TopLevelNode(Tokens, Namespace); +public record BoundStructFieldNode(IEnumerable Tokens, int Index, string Name, NubType Type, Optional Value) : BoundDefinitionMemberNode(Tokens); -public record BoundStructFieldNode(IEnumerable Tokens, int Index, string Name, NubType Type, Optional Value) : BoundDefinitionNode(Tokens); -public record BoundStructNode(IEnumerable Tokens, string Namespace, string Name, List Fields) : BoundTopLevelNode(Tokens, Namespace); +public record BoundStructNode(IEnumerable Tokens, string Namespace, string Name, List Fields) : BoundDefinitionNode(Tokens, Namespace); -public record TraitFuncNode(IEnumerable Tokens, string Name, List Parameters, NubType ReturnType) : DefinitionNode(Tokens); -public record TraitNode(IEnumerable Tokens, string Namespace, string Name, List Functions) : TopLevelNode(Tokens, Namespace); +public record BoundTraitFuncNode(IEnumerable Tokens, string Name, List Parameters, NubType ReturnType) : BoundDefinitionMemberNode(Tokens); -public record BoundTraitFuncNode(IEnumerable Tokens, string Name, List Parameters, NubType ReturnType) : BoundDefinitionNode(Tokens); -public record BoundTraitNode(IEnumerable Tokens, string Namespace, string Name, List Functions) : BoundTopLevelNode(Tokens, Namespace); +public record BoundTraitNode(IEnumerable Tokens, string Namespace, string Name, List Functions) : BoundDefinitionNode(Tokens, Namespace); -public record TraitFuncImplNode(IEnumerable Tokens, string Name, List Parameters, NubType ReturnType, BlockNode Body) : DefinitionNode(Tokens); -public record TraitImplNode(IEnumerable Tokens, string Namespace, NubType TraitType, NubType ForType, List Functions) : TopLevelNode(Tokens, Namespace); +public record BoundTraitFuncImplNode(IEnumerable Tokens, string Name, List Parameters, NubType ReturnType, BoundBlock Body) : BoundDefinitionMemberNode(Tokens); -public record BoundTraitFuncImplNode(IEnumerable Tokens, string Name, List Parameters, NubType ReturnType, BoundBlock Body) : BoundDefinitionNode(Tokens); -public record BoundTraitImplNode(IEnumerable Tokens, string Namespace, NubType TraitType, NubType ForType, List Functions) : BoundTopLevelNode(Tokens, Namespace); \ No newline at end of file +public record BoundTraitImplNode(IEnumerable Tokens, string Namespace, NubType TraitType, NubType ForType, List Functions) : BoundDefinitionNode(Tokens, Namespace); \ No newline at end of file diff --git a/src/compiler/NubLang/Syntax/Node/Expression.cs b/src/compiler/NubLang/Syntax/Node/Expression.cs index 60179bf..5c9a4c7 100644 --- a/src/compiler/NubLang/Syntax/Node/Expression.cs +++ b/src/compiler/NubLang/Syntax/Node/Expression.cs @@ -1,15 +1,14 @@ -using Common; -using NubLang.Syntax.Tokenization; +using NubLang.Syntax.Tokenization; namespace NubLang.Syntax.Node; -public enum UnaryExpressionOperator +public enum BoundUnaryOperator { Negate, Invert } -public enum BinaryExpressionOperator +public enum BoundBinaryOperator { Equal, NotEqual, @@ -23,45 +22,36 @@ public enum BinaryExpressionOperator Divide } -public abstract record ExpressionNode(IEnumerable Tokens) : Node(Tokens); public abstract record BoundExpressionNode(IEnumerable Tokens, NubType Type) : BoundNode(Tokens); -public record BinaryExpressionNode(IEnumerable Tokens, ExpressionNode Left, BinaryExpressionOperator Operator, ExpressionNode Right) : ExpressionNode(Tokens); -public record BoundBinaryExpressionNode(IEnumerable Tokens, NubType Type, BoundExpressionNode Left, BinaryExpressionOperator Operator, BoundExpressionNode Right) : BoundExpressionNode(Tokens, Type); +public record BoundBinaryExpressionNode(IEnumerable Tokens, NubType Type, BoundExpressionNode Left, BoundBinaryOperator Operator, BoundExpressionNode Right) : BoundExpressionNode(Tokens, Type); -public record UnaryExpressionNode(IEnumerable Tokens, UnaryExpressionOperator Operator, ExpressionNode Operand) : ExpressionNode(Tokens); -public record BoundUnaryExpressionNode(IEnumerable Tokens, NubType Type, UnaryExpressionOperator Operator, BoundExpressionNode Operand) : BoundExpressionNode(Tokens, Type); +public record BoundUnaryExpressionNode(IEnumerable Tokens, NubType Type, BoundUnaryOperator Operator, BoundExpressionNode Operand) : BoundExpressionNode(Tokens, Type); -public record FuncCallNode(IEnumerable Tokens, ExpressionNode Expression, List Parameters) : ExpressionNode(Tokens); public record BoundFuncCallNode(IEnumerable Tokens, NubType Type, BoundExpressionNode Expression, List Parameters) : BoundExpressionNode(Tokens, Type); -public record IdentifierNode(IEnumerable Tokens, Optional Namespace, string Name) : ExpressionNode(Tokens); public record BoundVariableIdentNode(IEnumerable Tokens, NubType Type, string Name) : BoundExpressionNode(Tokens, Type); + public record BoundLocalFuncIdentNode(IEnumerable Tokens, NubType Type, string Namespace, string Name) : BoundExpressionNode(Tokens, Type); + public record BoundExternFuncIdentNode(IEnumerable Tokens, NubType Type, string Namespace, string Name) : BoundExpressionNode(Tokens, Type); -public record ArrayInitializerNode(IEnumerable Tokens, ExpressionNode Capacity, NubType ElementType) : ExpressionNode(Tokens); public record BoundArrayInitializerNode(IEnumerable Tokens, NubType Type, BoundExpressionNode Capacity, NubType ElementType) : BoundExpressionNode(Tokens, Type); -public record ArrayIndexAccessNode(IEnumerable Tokens, ExpressionNode Target, ExpressionNode Index) : ExpressionNode(Tokens); public record BoundArrayIndexAccessNode(IEnumerable Tokens, NubType Type, BoundExpressionNode Target, BoundExpressionNode Index) : BoundExpressionNode(Tokens, Type); -public record AnonymousFuncNode(IEnumerable Tokens, List Parameters, BlockNode Body, NubType ReturnType) : ExpressionNode(Tokens); public record BoundAnonymousFuncNode(IEnumerable Tokens, NubType Type, List Parameters, BoundBlock Body, NubType ReturnType) : BoundExpressionNode(Tokens, Type); -public record AddressOfNode(IEnumerable Tokens, ExpressionNode Expression) : ExpressionNode(Tokens); public record BoundAddressOfNode(IEnumerable Tokens, NubType Type, BoundExpressionNode Expression) : BoundExpressionNode(Tokens, Type); -public record LiteralNode(IEnumerable Tokens, string Literal, LiteralKind Kind) : ExpressionNode(Tokens); public record BoundLiteralNode(IEnumerable Tokens, NubType Type, string Literal, LiteralKind Kind) : BoundExpressionNode(Tokens, Type); -public record MemberAccessNode(IEnumerable Tokens, ExpressionNode Target, string Member) : ExpressionNode(Tokens); public record BoundStructFieldAccessNode(IEnumerable Tokens, NubType Type, NubCustomType StructType, BoundExpressionNode Target, string Field) : BoundExpressionNode(Tokens, Type); + public record BoundTraitImplFuncAccessNode(IEnumerable Tokens, NubType Type, BoundExpressionNode Target, string FuncName) : BoundExpressionNode(Tokens, Type); + public record BoundTraitFuncAccessNode(IEnumerable Tokens, NubType Type, NubCustomType TraitType, BoundExpressionNode Target, string FuncName) : BoundExpressionNode(Tokens, Type); -public record StructInitializerNode(IEnumerable Tokens, NubType StructType, Dictionary Initializers) : ExpressionNode(Tokens); public record BoundStructInitializerNode(IEnumerable Tokens, NubType Type, NubCustomType StructType, Dictionary Initializers) : BoundExpressionNode(Tokens, Type); -public record DereferenceNode(IEnumerable Tokens, ExpressionNode Expression) : ExpressionNode(Tokens); public record BoundDereferenceNode(IEnumerable Tokens, NubType Type, BoundExpressionNode Expression) : BoundExpressionNode(Tokens, Type); \ No newline at end of file diff --git a/src/compiler/NubLang/Syntax/Node/Node.cs b/src/compiler/NubLang/Syntax/Node/Node.cs deleted file mode 100644 index a9207d9..0000000 --- a/src/compiler/NubLang/Syntax/Node/Node.cs +++ /dev/null @@ -1,9 +0,0 @@ -using NubLang.Syntax.Tokenization; - -namespace NubLang.Syntax.Node; - -public abstract record Node(IEnumerable Tokens); -public abstract record BoundNode(IEnumerable Tokens); - -public record BlockNode(IEnumerable Tokens, List Statements) : Node(Tokens); -public record BoundBlock(IEnumerable Tokens, List Statements) : BoundNode(Tokens); \ No newline at end of file diff --git a/src/compiler/NubLang/Syntax/Node/Statement.cs b/src/compiler/NubLang/Syntax/Node/Statement.cs index 5825b60..d72b982 100644 --- a/src/compiler/NubLang/Syntax/Node/Statement.cs +++ b/src/compiler/NubLang/Syntax/Node/Statement.cs @@ -3,30 +3,20 @@ using NubLang.Syntax.Tokenization; namespace NubLang.Syntax.Node; - -public record StatementNode(IEnumerable Tokens) : Node(Tokens); public record BoundStatementNode(IEnumerable Tokens) : BoundNode(Tokens); -public record StatementExpressionNode(IEnumerable Tokens, ExpressionNode Expression) : StatementNode(Tokens); public record BoundStatementExpressionNode(IEnumerable Tokens, BoundExpressionNode Expression) : BoundStatementNode(Tokens); -public record ReturnNode(IEnumerable Tokens, Optional Value) : StatementNode(Tokens); public record BoundReturnNode(IEnumerable Tokens, Optional Value) : BoundStatementNode(Tokens); -public record AssignmentNode(IEnumerable Tokens, ExpressionNode Target, ExpressionNode Value) : StatementNode(Tokens); public record BoundAssignmentNode(IEnumerable Tokens, BoundExpressionNode Target, BoundExpressionNode Value) : BoundStatementNode(Tokens); -public record IfNode(IEnumerable Tokens, ExpressionNode Condition, BlockNode Body, Optional> Else) : StatementNode(Tokens); public record BoundIfNode(IEnumerable Tokens, BoundExpressionNode Condition, BoundBlock Body, Optional> Else) : BoundStatementNode(Tokens); -public record VariableDeclarationNode(IEnumerable Tokens, string Name, Optional ExplicitType, Optional Assignment) : StatementNode(Tokens); public record BoundVariableDeclarationNode(IEnumerable Tokens, string Name, Optional Assignment, NubType Type) : BoundStatementNode(Tokens); -public record ContinueNode(IEnumerable Tokens) : StatementNode(Tokens); public record BoundContinueNode(IEnumerable Tokens) : BoundStatementNode(Tokens); -public record BreakNode(IEnumerable Tokens) : StatementNode(Tokens); public record BoundBreakNode(IEnumerable Tokens) : BoundStatementNode(Tokens); -public record WhileNode(IEnumerable Tokens, ExpressionNode Condition, BlockNode Body) : StatementNode(Tokens); public record BoundWhileNode(IEnumerable Tokens, BoundExpressionNode Condition, BoundBlock Body) : BoundStatementNode(Tokens); \ No newline at end of file diff --git a/src/compiler/NubLang/Syntax/Node/SyntaxTree.cs b/src/compiler/NubLang/Syntax/Node/SyntaxTree.cs index 54b4dcd..614ba8c 100644 --- a/src/compiler/NubLang/Syntax/Node/SyntaxTree.cs +++ b/src/compiler/NubLang/Syntax/Node/SyntaxTree.cs @@ -1,6 +1,10 @@ using NubLang.Diagnostics; +using NubLang.Syntax.Tokenization; namespace NubLang.Syntax.Node; -public record SyntaxTree(string Namespace, IEnumerable TopLevelNodes, IEnumerable Diagnostics); -public record BoundSyntaxTree(string Namespace, IEnumerable TopLevelNodes, IEnumerable Diagnostics); \ No newline at end of file +public record BoundSyntaxTree(string Namespace, IEnumerable Definitions, IEnumerable Diagnostics); + +public abstract record BoundNode(IEnumerable Tokens); + +public record BoundBlock(IEnumerable Tokens, List Statements) : BoundNode(Tokens); \ No newline at end of file diff --git a/src/compiler/NubLang/Syntax/Parsing/Node/DefinitionSyntax.cs b/src/compiler/NubLang/Syntax/Parsing/Node/DefinitionSyntax.cs new file mode 100644 index 0000000..5680223 --- /dev/null +++ b/src/compiler/NubLang/Syntax/Parsing/Node/DefinitionSyntax.cs @@ -0,0 +1,26 @@ +using Common; +using NubLang.Syntax.Tokenization; + +namespace NubLang.Syntax.Parsing.Node; + +public abstract record DefinitionSyntax(IEnumerable Tokens, string Namespace) : SyntaxNode(Tokens); + +public abstract record DefinitionMemberSyntax(IEnumerable Tokens) : SyntaxNode(Tokens); + +public record FuncParameterSyntax(IEnumerable Tokens, string Name, NubType Type) : DefinitionMemberSyntax(Tokens); + +public record LocalFuncSyntax(IEnumerable Tokens, string Namespace, string Name, List Parameters, BlockSyntax Body, NubType ReturnType, bool Exported) : DefinitionSyntax(Tokens, Namespace); + +public record ExternFuncSyntax(IEnumerable Tokens, string Namespace, string Name, string CallName, List Parameters, NubType ReturnType) : DefinitionSyntax(Tokens, Namespace); + +public record StructFieldSyntax(IEnumerable Tokens, int Index, string Name, NubType Type, Optional Value) : DefinitionMemberSyntax(Tokens); + +public record StructSyntax(IEnumerable Tokens, string Namespace, string Name, List Fields) : DefinitionSyntax(Tokens, Namespace); + +public record TraitFuncSyntax(IEnumerable Tokens, string Name, List Parameters, NubType ReturnType) : DefinitionMemberSyntax(Tokens); + +public record TraitSyntax(IEnumerable Tokens, string Namespace, string Name, List Functions) : DefinitionSyntax(Tokens, Namespace); + +public record TraitFuncImplSyntax(IEnumerable Tokens, string Name, List Parameters, NubType ReturnType, BlockSyntax Body) : DefinitionMemberSyntax(Tokens); + +public record TraitImplSyntax(IEnumerable Tokens, string Namespace, NubType TraitType, NubType ForType, List 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 new file mode 100644 index 0000000..1e91ea7 --- /dev/null +++ b/src/compiler/NubLang/Syntax/Parsing/Node/ExpressionSyntax.cs @@ -0,0 +1,50 @@ +using Common; +using NubLang.Syntax.Tokenization; + +namespace NubLang.Syntax.Parsing.Node; + +public enum UnaryOperator +{ + Negate, + Invert +} + +public enum BinaryOperator +{ + Equal, + NotEqual, + GreaterThan, + GreaterThanOrEqual, + LessThan, + LessThanOrEqual, + Plus, + Minus, + Multiply, + Divide +} + +public abstract record ExpressionSyntax(IEnumerable Tokens) : SyntaxNode(Tokens); + +public record BinaryExpressionSyntax(IEnumerable Tokens, ExpressionSyntax Left, BinaryOperator Operator, ExpressionSyntax Right) : ExpressionSyntax(Tokens); + +public record UnaryExpressionSyntax(IEnumerable Tokens, UnaryOperator Operator, ExpressionSyntax Operand) : ExpressionSyntax(Tokens); + +public record FuncCallSyntax(IEnumerable Tokens, ExpressionSyntax Expression, List Parameters) : ExpressionSyntax(Tokens); + +public record IdentifierSyntax(IEnumerable Tokens, Optional Namespace, string Name) : ExpressionSyntax(Tokens); + +public record ArrayInitializerSyntax(IEnumerable Tokens, ExpressionSyntax Capacity, NubType ElementType) : ExpressionSyntax(Tokens); + +public record ArrayIndexAccessSyntax(IEnumerable Tokens, ExpressionSyntax Target, ExpressionSyntax Index) : ExpressionSyntax(Tokens); + +public record AnonymousFuncSyntax(IEnumerable Tokens, List Parameters, BlockSyntax Body, NubType ReturnType) : ExpressionSyntax(Tokens); + +public record AddressOfSyntax(IEnumerable Tokens, ExpressionSyntax Expression) : ExpressionSyntax(Tokens); + +public record LiteralSyntax(IEnumerable Tokens, string Literal, LiteralKind Kind) : ExpressionSyntax(Tokens); + +public record MemberAccessSyntax(IEnumerable Tokens, ExpressionSyntax Target, string Member) : ExpressionSyntax(Tokens); + +public record StructInitializerSyntax(IEnumerable Tokens, NubType StructType, Dictionary Initializers) : ExpressionSyntax(Tokens); + +public record DereferenceSyntax(IEnumerable 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 new file mode 100644 index 0000000..08d4aec --- /dev/null +++ b/src/compiler/NubLang/Syntax/Parsing/Node/StatementSyntax.cs @@ -0,0 +1,22 @@ +using Common; +using NubLang.Syntax.Tokenization; + +namespace NubLang.Syntax.Parsing.Node; + +public record StatementSyntax(IEnumerable Tokens) : SyntaxNode(Tokens); + +public record StatementExpressionSyntax(IEnumerable Tokens, ExpressionSyntax Expression) : StatementSyntax(Tokens); + +public record ReturnSyntax(IEnumerable Tokens, Optional Value) : StatementSyntax(Tokens); + +public record AssignmentSyntax(IEnumerable Tokens, ExpressionSyntax Target, ExpressionSyntax Value) : StatementSyntax(Tokens); + +public record IfSyntax(IEnumerable Tokens, ExpressionSyntax Condition, BlockSyntax Body, Optional> Else) : StatementSyntax(Tokens); + +public record VariableDeclarationSyntax(IEnumerable Tokens, string Name, Optional ExplicitType, Optional Assignment) : StatementSyntax(Tokens); + +public record ContinueSyntax(IEnumerable Tokens) : StatementSyntax(Tokens); + +public record BreakSyntax(IEnumerable Tokens) : StatementSyntax(Tokens); + +public record WhileSyntax(IEnumerable Tokens, ExpressionSyntax Condition, BlockSyntax Body) : StatementSyntax(Tokens); \ No newline at end of file diff --git a/src/compiler/NubLang/Syntax/Parsing/Node/SyntaxTree.cs b/src/compiler/NubLang/Syntax/Parsing/Node/SyntaxTree.cs new file mode 100644 index 0000000..bcbbd9b --- /dev/null +++ b/src/compiler/NubLang/Syntax/Parsing/Node/SyntaxTree.cs @@ -0,0 +1,10 @@ +using NubLang.Diagnostics; +using NubLang.Syntax.Tokenization; + +namespace NubLang.Syntax.Parsing.Node; + +public record SyntaxTree(string Namespace, IEnumerable Definitions, IEnumerable Diagnostics); + +public abstract record SyntaxNode(IEnumerable Tokens); + +public record BlockSyntax(IEnumerable Tokens, IEnumerable Statements) : SyntaxNode(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 5ce5064..280f9ea 100644 --- a/src/compiler/NubLang/Syntax/Parsing/Parser.cs +++ b/src/compiler/NubLang/Syntax/Parsing/Parser.cs @@ -1,7 +1,7 @@ using System.Diagnostics.CodeAnalysis; using Common; using NubLang.Diagnostics; -using NubLang.Syntax.Node; +using NubLang.Syntax.Parsing.Node; using NubLang.Syntax.Tokenization; namespace NubLang.Syntax.Parsing; @@ -32,13 +32,13 @@ public sealed class Parser _namespace = ExpectIdentifier().Value; } - List topLevelNodes = []; + List definitions = []; while (Peek().HasValue) { try { - topLevelNodes.Add(ParseTopLevel()); + definitions.Add(ParseTopLevel()); } catch (ParseException ex) { @@ -47,10 +47,10 @@ public sealed class Parser } } - return new SyntaxTree(_namespace, topLevelNodes, _diagnostics); + return new SyntaxTree(_namespace, definitions, _diagnostics); } - private TopLevelNode ParseTopLevel() + private DefinitionSyntax ParseTopLevel() { var startIndex = _tokenIndex; List modifiers = []; @@ -86,10 +86,10 @@ public sealed class Parser return node; } - private TopLevelNode ParseFunc(int startIndex, List modifiers) + private DefinitionSyntax ParseFunc(int startIndex, List modifiers) { var name = ExpectIdentifier(); - List parameters = []; + List parameters = []; ExpectSymbol(Symbol.OpenParen); @@ -129,22 +129,22 @@ public sealed class Parser callName = ExpectIdentifier().Value; } - return new ExternFuncNode(GetTokensForNode(startIndex), _namespace, name.Value, callName, parameters, returnType); + return new ExternFuncSyntax(GetTokens(startIndex), _namespace, name.Value, callName, parameters, returnType); } var body = ParseBlock(); var exported = modifiers.RemoveAll(x => x.Modifier == Modifier.Export) > 0; - return new LocalFuncNode(GetTokensForNode(startIndex), _namespace, name.Value, parameters, body, returnType, exported); + return new LocalFuncSyntax(GetTokens(startIndex), _namespace, name.Value, parameters, body, returnType, exported); } - private StructNode ParseStruct(int startIndex) + private StructSyntax ParseStruct(int startIndex) { var name = ExpectIdentifier().Value; ExpectSymbol(Symbol.OpenBrace); - List variables = []; + List variables = []; var fieldIndex = 0; @@ -156,26 +156,26 @@ public sealed class Parser ExpectSymbol(Symbol.Colon); var variableType = ParseType(); - var variableValue = Optional.Empty(); + var variableValue = Optional.Empty(); if (TryExpectSymbol(Symbol.Assign)) { variableValue = ParseExpression(); } - variables.Add(new StructFieldNode(GetTokensForNode(fieldStartIndex), fieldIndex++, variableName, variableType, variableValue)); + variables.Add(new StructFieldSyntax(GetTokens(fieldStartIndex), fieldIndex++, variableName, variableType, variableValue)); } - return new StructNode(GetTokensForNode(startIndex), _namespace, name, variables); + return new StructSyntax(GetTokens(startIndex), _namespace, name, variables); } - private TraitNode ParseTrait(int startIndex) + private TraitSyntax ParseTrait(int startIndex) { var name = ExpectIdentifier().Value; ExpectSymbol(Symbol.OpenBrace); - List functions = []; + List functions = []; while (!TryExpectSymbol(Symbol.CloseBrace)) { @@ -184,7 +184,7 @@ public sealed class Parser ExpectSymbol(Symbol.Func); var funcName = ExpectIdentifier().Value; - var parameters = new List(); + var parameters = new List(); ExpectSymbol(Symbol.OpenParen); while (!TryExpectSymbol(Symbol.CloseParen)) @@ -203,19 +203,19 @@ public sealed class Parser var returnType = TryExpectSymbol(Symbol.Colon) ? ParseType() : new NubVoidType(); - functions.Add(new TraitFuncNode(GetTokensForNode(funcStartIndex), funcName, parameters, returnType)); + functions.Add(new TraitFuncSyntax(GetTokens(funcStartIndex), funcName, parameters, returnType)); } - return new TraitNode(GetTokensForNode(startIndex), _namespace, name, functions); + return new TraitSyntax(GetTokens(startIndex), _namespace, name, functions); } - private TraitImplNode ParseImplementation(int startIndex) + private TraitImplSyntax ParseImplementation(int startIndex) { var traitType = ParseType(); ExpectSymbol(Symbol.For); var forType = ParseType(); - List functions = []; + List functions = []; ExpectSymbol(Symbol.OpenBrace); while (!TryExpectSymbol(Symbol.CloseBrace)) @@ -223,7 +223,7 @@ public sealed class Parser var funcStartIndex = _tokenIndex; ExpectSymbol(Symbol.Func); var functionName = ExpectIdentifier().Value; - var parameters = new List + var parameters = new List { new([], "this", forType) }; @@ -248,23 +248,23 @@ public sealed class Parser var body = ParseBlock(); - functions.AddRange(new TraitFuncImplNode(GetTokensForNode(funcStartIndex), functionName, parameters, returnType, body)); + functions.AddRange(new TraitFuncImplSyntax(GetTokens(funcStartIndex), functionName, parameters, returnType, body)); } - return new TraitImplNode(GetTokensForNode(startIndex), _namespace, traitType, forType, functions); + return new TraitImplSyntax(GetTokens(startIndex), _namespace, traitType, forType, functions); } - private FuncParameterNode ParseFuncParameter() + private FuncParameterSyntax ParseFuncParameter() { var startIndex = _tokenIndex; var name = ExpectIdentifier(); ExpectSymbol(Symbol.Colon); var type = ParseType(); - return new FuncParameterNode(GetTokensForNode(startIndex), name.Value, type); + return new FuncParameterSyntax(GetTokens(startIndex), name.Value, type); } - private StatementNode ParseStatement() + private StatementSyntax ParseStatement() { var startIndex = _tokenIndex; if (!Peek().TryGetValue(out var token)) @@ -297,20 +297,20 @@ public sealed class Parser return ParseStatementExpression(startIndex); } - private StatementNode ParseStatementExpression(int startIndex) + private StatementSyntax ParseStatementExpression(int startIndex) { var expr = ParseExpression(); if (TryExpectSymbol(Symbol.Assign)) { var value = ParseExpression(); - return new AssignmentNode(GetTokensForNode(startIndex), expr, value); + return new AssignmentSyntax(GetTokens(startIndex), expr, value); } - return new StatementExpressionNode(GetTokensForNode(startIndex), expr); + return new StatementExpressionSyntax(GetTokens(startIndex), expr); } - private VariableDeclarationNode ParseVariableDeclaration(int startIndex) + private VariableDeclarationSyntax ParseVariableDeclaration(int startIndex) { ExpectSymbol(Symbol.Let); var name = ExpectIdentifier().Value; @@ -321,68 +321,68 @@ public sealed class Parser explicitType = ParseType(); } - var assignment = Optional.Empty(); + var assignment = Optional.Empty(); if (TryExpectSymbol(Symbol.Assign)) { assignment = ParseExpression(); } - return new VariableDeclarationNode(GetTokensForNode(startIndex), name, explicitType, assignment); + return new VariableDeclarationSyntax(GetTokens(startIndex), name, explicitType, assignment); } - private StatementNode ParseBreak(int startIndex) + private StatementSyntax ParseBreak(int startIndex) { ExpectSymbol(Symbol.Break); Next(); - return new BreakNode(GetTokensForNode(startIndex)); + return new BreakSyntax(GetTokens(startIndex)); } - private StatementNode ParseContinue(int startIndex) + private StatementSyntax ParseContinue(int startIndex) { ExpectSymbol(Symbol.Continue); - return new ContinueNode(GetTokensForNode(startIndex)); + return new ContinueSyntax(GetTokens(startIndex)); } - private ReturnNode ParseReturn(int startIndex) + private ReturnSyntax ParseReturn(int startIndex) { ExpectSymbol(Symbol.Return); - var value = Optional.Empty(); + var value = Optional.Empty(); if (_functionReturnType is not NubVoidType) { value = ParseExpression(); } - return new ReturnNode(GetTokensForNode(startIndex), value); + return new ReturnSyntax(GetTokens(startIndex), value); } - private IfNode ParseIf(int startIndex) + private IfSyntax ParseIf(int startIndex) { ExpectSymbol(Symbol.If); var condition = ParseExpression(); var body = ParseBlock(); - var elseStatement = Optional>.Empty(); + var elseStatement = Optional>.Empty(); if (TryExpectSymbol(Symbol.Else)) { var newStartIndex = _tokenIndex; elseStatement = TryExpectSymbol(Symbol.If) - ? (Variant)ParseIf(newStartIndex) - : (Variant)ParseBlock(); + ? (Variant)ParseIf(newStartIndex) + : (Variant)ParseBlock(); } - return new IfNode(GetTokensForNode(startIndex), condition, body, elseStatement); + return new IfSyntax(GetTokens(startIndex), condition, body, elseStatement); } - private WhileNode ParseWhile(int startIndex) + private WhileSyntax ParseWhile(int startIndex) { ExpectSymbol(Symbol.While); var condition = ParseExpression(); var body = ParseBlock(); - return new WhileNode(GetTokensForNode(startIndex), condition, body); + return new WhileSyntax(GetTokens(startIndex), condition, body); } - private ExpressionNode ParseExpression(int precedence = 0) + private ExpressionSyntax ParseExpression(int precedence = 0) { var startIndex = _tokenIndex; var left = ParsePrimaryExpression(); @@ -399,63 +399,63 @@ public sealed class Parser Next(); var right = ParseExpression(GetBinaryOperatorPrecedence(op.Value) + 1); - left = new BinaryExpressionNode(GetTokensForNode(startIndex), left, op.Value, right); + left = new BinaryExpressionSyntax(GetTokens(startIndex), left, op.Value, right); } return left; } - private int GetBinaryOperatorPrecedence(BinaryExpressionOperator binaryExpressionOperator) + private int GetBinaryOperatorPrecedence(BinaryOperator @operator) { - return binaryExpressionOperator switch + return @operator switch { - BinaryExpressionOperator.Multiply => 3, - BinaryExpressionOperator.Divide => 3, - BinaryExpressionOperator.Plus => 2, - BinaryExpressionOperator.Minus => 2, - BinaryExpressionOperator.GreaterThan => 1, - BinaryExpressionOperator.GreaterThanOrEqual => 1, - BinaryExpressionOperator.LessThan => 1, - BinaryExpressionOperator.LessThanOrEqual => 1, - BinaryExpressionOperator.Equal => 0, - BinaryExpressionOperator.NotEqual => 0, - _ => throw new ArgumentOutOfRangeException(nameof(binaryExpressionOperator), binaryExpressionOperator, null) + BinaryOperator.Multiply => 3, + BinaryOperator.Divide => 3, + BinaryOperator.Plus => 2, + BinaryOperator.Minus => 2, + BinaryOperator.GreaterThan => 1, + BinaryOperator.GreaterThanOrEqual => 1, + BinaryOperator.LessThan => 1, + BinaryOperator.LessThanOrEqual => 1, + BinaryOperator.Equal => 0, + BinaryOperator.NotEqual => 0, + _ => throw new ArgumentOutOfRangeException(nameof(@operator), @operator, null) }; } - private bool TryGetBinaryOperator(Symbol symbol, [NotNullWhen(true)] out BinaryExpressionOperator? binaryExpressionOperator) + private bool TryGetBinaryOperator(Symbol symbol, [NotNullWhen(true)] out BinaryOperator? binaryExpressionOperator) { switch (symbol) { case Symbol.Equal: - binaryExpressionOperator = BinaryExpressionOperator.Equal; + binaryExpressionOperator = BinaryOperator.Equal; return true; case Symbol.NotEqual: - binaryExpressionOperator = BinaryExpressionOperator.NotEqual; + binaryExpressionOperator = BinaryOperator.NotEqual; return true; case Symbol.LessThan: - binaryExpressionOperator = BinaryExpressionOperator.LessThan; + binaryExpressionOperator = BinaryOperator.LessThan; return true; case Symbol.LessThanOrEqual: - binaryExpressionOperator = BinaryExpressionOperator.LessThanOrEqual; + binaryExpressionOperator = BinaryOperator.LessThanOrEqual; return true; case Symbol.GreaterThan: - binaryExpressionOperator = BinaryExpressionOperator.GreaterThan; + binaryExpressionOperator = BinaryOperator.GreaterThan; return true; case Symbol.GreaterThanOrEqual: - binaryExpressionOperator = BinaryExpressionOperator.GreaterThanOrEqual; + binaryExpressionOperator = BinaryOperator.GreaterThanOrEqual; return true; case Symbol.Plus: - binaryExpressionOperator = BinaryExpressionOperator.Plus; + binaryExpressionOperator = BinaryOperator.Plus; return true; case Symbol.Minus: - binaryExpressionOperator = BinaryExpressionOperator.Minus; + binaryExpressionOperator = BinaryOperator.Minus; return true; case Symbol.Star: - binaryExpressionOperator = BinaryExpressionOperator.Multiply; + binaryExpressionOperator = BinaryOperator.Multiply; return true; case Symbol.ForwardSlash: - binaryExpressionOperator = BinaryExpressionOperator.Divide; + binaryExpressionOperator = BinaryOperator.Divide; return true; default: binaryExpressionOperator = null; @@ -463,17 +463,17 @@ public sealed class Parser } } - private ExpressionNode ParsePrimaryExpression() + private ExpressionSyntax ParsePrimaryExpression() { var startIndex = _tokenIndex; - ExpressionNode expr; + ExpressionSyntax expr; var token = ExpectToken(); switch (token) { case LiteralToken literal: { - expr = new LiteralNode(GetTokensForNode(startIndex), literal.Value, literal.Kind); + expr = new LiteralSyntax(GetTokens(startIndex), literal.Value, literal.Kind); break; } case IdentifierToken identifier: @@ -486,7 +486,7 @@ public sealed class Parser name = ExpectIdentifier().Value; } - expr = new IdentifierNode(GetTokensForNode(startIndex), @namespace, name); + expr = new IdentifierSyntax(GetTokens(startIndex), @namespace, name); break; } case SymbolToken symbolToken: @@ -495,7 +495,7 @@ public sealed class Parser { case Symbol.Func: { - List parameters = []; + List parameters = []; ExpectSymbol(Symbol.OpenParen); while (!TryExpectSymbol(Symbol.CloseParen)) { @@ -515,7 +515,7 @@ public sealed class Parser var body = ParseBlock(); - expr = new AnonymousFuncNode(GetTokensForNode(startIndex), parameters, body, returnType); + expr = new AnonymousFuncSyntax(GetTokens(startIndex), parameters, body, returnType); break; } case Symbol.OpenParen: @@ -528,13 +528,13 @@ public sealed class Parser case Symbol.Minus: { var expression = ParsePrimaryExpression(); - expr = new UnaryExpressionNode(GetTokensForNode(startIndex), UnaryExpressionOperator.Negate, expression); + expr = new UnaryExpressionSyntax(GetTokens(startIndex), UnaryOperator.Negate, expression); break; } case Symbol.Bang: { var expression = ParsePrimaryExpression(); - expr = new UnaryExpressionNode(GetTokensForNode(startIndex), UnaryExpressionOperator.Invert, expression); + expr = new UnaryExpressionSyntax(GetTokens(startIndex), UnaryOperator.Invert, expression); break; } case Symbol.OpenBracket: @@ -542,13 +542,13 @@ public sealed class Parser var capacity = ParseExpression(); ExpectSymbol(Symbol.CloseBracket); var type = ParseType(); - expr = new ArrayInitializerNode(GetTokensForNode(startIndex), capacity, type); + expr = new ArrayInitializerSyntax(GetTokens(startIndex), capacity, type); break; } case Symbol.Alloc: { var type = ParseType(); - Dictionary initializers = []; + Dictionary initializers = []; ExpectSymbol(Symbol.OpenBrace); while (!TryExpectSymbol(Symbol.CloseBrace)) { @@ -558,7 +558,7 @@ public sealed class Parser initializers.Add(name, value); } - expr = new StructInitializerNode(GetTokensForNode(startIndex), type, initializers); + expr = new StructInitializerSyntax(GetTokens(startIndex), type, initializers); break; } default: @@ -586,26 +586,26 @@ public sealed class Parser return ParsePostfixOperators(startIndex, expr); } - private ExpressionNode ParsePostfixOperators(int startIndex, ExpressionNode expr) + private ExpressionSyntax ParsePostfixOperators(int startIndex, ExpressionSyntax expr) { while (true) { if (TryExpectSymbol(Symbol.Ampersand)) { - expr = new AddressOfNode(GetTokensForNode(startIndex), expr); + expr = new AddressOfSyntax(GetTokens(startIndex), expr); break; } if (TryExpectSymbol(Symbol.Caret)) { - expr = new DereferenceNode(GetTokensForNode(startIndex), expr); + expr = new DereferenceSyntax(GetTokens(startIndex), expr); continue; } if (TryExpectSymbol(Symbol.Period)) { var structMember = ExpectIdentifier().Value; - expr = new MemberAccessNode(GetTokensForNode(startIndex), expr, structMember); + expr = new MemberAccessSyntax(GetTokens(startIndex), expr, structMember); continue; } @@ -613,13 +613,13 @@ public sealed class Parser { var index = ParseExpression(); ExpectSymbol(Symbol.CloseBracket); - expr = new ArrayIndexAccessNode(GetTokensForNode(startIndex), expr, index); + expr = new ArrayIndexAccessSyntax(GetTokens(startIndex), expr, index); continue; } if (TryExpectSymbol(Symbol.OpenParen)) { - var parameters = new List(); + var parameters = new List(); while (!TryExpectSymbol(Symbol.CloseParen)) { parameters.Add(ParseExpression()); @@ -633,7 +633,7 @@ public sealed class Parser } } - expr = new FuncCallNode(GetTokensForNode(startIndex), expr, parameters); + expr = new FuncCallSyntax(GetTokens(startIndex), expr, parameters); continue; } @@ -643,11 +643,11 @@ public sealed class Parser return expr; } - private BlockNode ParseBlock() + private BlockSyntax ParseBlock() { var startIndex = _tokenIndex; ExpectSymbol(Symbol.OpenBrace); - List statements = []; + List statements = []; while (Peek().HasValue && !TryExpectSymbol(Symbol.CloseBrace)) { try @@ -661,7 +661,7 @@ public sealed class Parser } } - return new BlockNode(GetTokensForNode(startIndex), statements); + return new BlockSyntax(GetTokens(startIndex), statements); } private NubType ParseType() @@ -892,7 +892,7 @@ public sealed class Parser _tokenIndex++; } - private IEnumerable GetTokensForNode(int startIndex) + private IEnumerable GetTokens(int startIndex) { return _tokens.Skip(startIndex).Take(Math.Min(_tokenIndex, _tokens.Count() - 1) - startIndex); }