From 23126b91e9715097acb1236012c7066cacd31390 Mon Sep 17 00:00:00 2001 From: nub31 Date: Sun, 22 Jun 2025 18:18:42 +0200 Subject: [PATCH] ... --- src/CLI/Program.cs | 62 +++++----- src/Generation/QBE/QBEGenerator.cs | 116 +++++++++--------- src/Syntax/Diagnostics/ConsoleColors.cs | 2 +- src/Syntax/Diagnostics/Diagnostic.cs | 2 +- src/Syntax/Diagnostics/DiagnosticsResult.cs | 20 --- .../Parsing/Definitions/DefinitionNode.cs | 2 +- .../Parsing/Definitions/FuncDefinitionNode.cs | 4 +- .../Definitions/StructDefinitionNode.cs | 2 +- .../Parsing/Expressions/AddressOfNode.cs | 2 +- .../Parsing/Expressions/AnonymousFuncNode.cs | 2 +- .../Expressions/ArrayIndexAccessNode.cs | 2 +- .../Expressions/ArrayInitializerNode.cs | 2 +- .../Expressions/BinaryExpressionNode.cs | 2 +- .../Parsing/Expressions/DereferenceNode.cs | 2 +- .../Parsing/Expressions/ExpressionNode.cs | 4 +- .../Expressions/FixedArrayInitializerNode.cs | 2 +- .../Parsing/Expressions/FuncCallNode.cs | 2 +- .../Parsing/Expressions/IdentifierNode.cs | 2 +- src/Syntax/Parsing/Expressions/LiteralNode.cs | 2 +- .../Parsing/Expressions/MemberAccessNode.cs | 2 +- .../Expressions/StructInitializerNode.cs | 2 +- .../Expressions/UnaryExpressionNode.cs | 2 +- src/Syntax/Parsing/Node.cs | 4 +- src/Syntax/Parsing/Parser.cs | 27 ++-- .../Statements/ArrayIndexAssignmentNode.cs | 2 +- src/Syntax/Parsing/Statements/BlockNode.cs | 2 +- src/Syntax/Parsing/Statements/BreakNode.cs | 2 +- src/Syntax/Parsing/Statements/ContinueNode.cs | 2 +- .../Statements/DereferenceAssignmentNode.cs | 2 +- src/Syntax/Parsing/Statements/IfNode.cs | 2 +- .../Statements/MemberAssignmentNode.cs | 2 +- src/Syntax/Parsing/Statements/ReturnNode.cs | 2 +- .../Statements/StatementExpressionNode.cs | 2 +- .../Parsing/Statements/StatementNode.cs | 2 +- .../Statements/VariableAssignmentNode.cs | 2 +- .../Statements/VariableDeclarationNode.cs | 2 +- src/Syntax/Parsing/Statements/WhileNode.cs | 2 +- src/Syntax/Tokenization/Tokenizer.cs | 14 ++- src/Syntax/Typing/TypeChecker.cs | 6 +- 39 files changed, 154 insertions(+), 163 deletions(-) delete mode 100644 src/Syntax/Diagnostics/DiagnosticsResult.cs diff --git a/src/CLI/Program.cs b/src/CLI/Program.cs index 411c24c..25ad51b 100644 --- a/src/CLI/Program.cs +++ b/src/CLI/Program.cs @@ -3,6 +3,7 @@ using System.Reflection; using CLI; using Generation.QBE; using Syntax; +using Syntax.Diagnostics; using Syntax.Parsing; using Syntax.Tokenization; using Syntax.Typing; @@ -23,7 +24,7 @@ if (Directory.Exists(BIN_INT_DIR)) Directory.CreateDirectory(BIN_DIR); Directory.CreateDirectory(BIN_INT_DIR); -var error = false; +var diagnostics = new List(); var compilationUnits = new List(); var sourceTexts = new Dictionary(); @@ -34,41 +35,44 @@ foreach (var file in args) Console.Error.WriteLine($"File '{file}' does not exist"); return 1; } - - var content = File.ReadAllText(file); - - var sourceText = new SourceText(file, content); - - var tokenizeResult = Tokenizer.Tokenize(sourceText); - tokenizeResult.PrintAllDiagnostics(); - error = error || tokenizeResult.HasErrors; - - var parseResult = Parser.ParseFile(tokenizeResult.Value); - parseResult.PrintAllDiagnostics(); - error = error || parseResult.HasErrors; - - if (parseResult.Value != null) - { - compilationUnits.Add(parseResult.Value); - sourceTexts[parseResult.Value] = sourceText; - } } -if (error) +foreach (var file in args) { - return 1; + var content = File.ReadAllText(file); + var sourceText = new SourceText(file, content); + + var tokenizeResult = Tokenizer.Tokenize(sourceText, out var tokenizerDiagnostics); + diagnostics.AddRange(tokenizerDiagnostics); + + var compilationUnit = Parser.ParseFile(tokenizeResult, out var parseDiagnostics); + diagnostics.AddRange(parseDiagnostics); + + if (compilationUnit != null) + { + compilationUnits.Add(compilationUnit); + sourceTexts[compilationUnit] = sourceText; + } + else + { + throw new Exception(); + } } var definitionTable = new DefinitionTable(compilationUnits); foreach (var compilationUnit in compilationUnits) { - var typeCheckResult = TypeChecker.Check(compilationUnit, definitionTable); - typeCheckResult.PrintAllDiagnostics(); - error = error || typeCheckResult.HasErrors; + TypeChecker.Check(compilationUnit, definitionTable, out var typeCheckerDiagnostics); + diagnostics.AddRange(typeCheckerDiagnostics); } -if (error) +foreach (var diagnostic in diagnostics) +{ + Console.Error.WriteLine(diagnostic.FormatANSI()); +} + +if (diagnostics.Any(diagnostic => diagnostic.Severity == DiagnosticSeverity.Error)) { return 1; } @@ -83,11 +87,11 @@ foreach (var compilationUnit in compilationUnits) var outputDirectory = Path.GetDirectoryName(outputPath); Debug.Assert(!string.IsNullOrWhiteSpace(outputDirectory)); Directory.CreateDirectory(outputDirectory); - + var ssa = QBEGenerator.Emit(compilationUnit, definitionTable); - var ssaPath = Path.ChangeExtension(outputPath, "ssa"); + var ssaPath = Path.ChangeExtension(outputPath, "ssa"); File.WriteAllText(ssaPath, ssa); - + var asm = await QBE.Invoke(ssa); if (asm == null) { @@ -143,4 +147,4 @@ foreach (var resourceName in runtimeResources) } var linkSuccess = await GCC.Link(objectFiles, Path.Combine(BIN_DIR, "out")); -return linkSuccess ? 0 : 1; +return linkSuccess ? 0 : 1; \ No newline at end of file diff --git a/src/Generation/QBE/QBEGenerator.cs b/src/Generation/QBE/QBEGenerator.cs index 87c75ad..54bc836 100644 --- a/src/Generation/QBE/QBEGenerator.cs +++ b/src/Generation/QBE/QBEGenerator.cs @@ -426,7 +426,7 @@ public static class QBEGenerator } } - parameterVars.Add(new Variable(parameter.Name, new Ident(parameterName, parameter.Type))); + parameterVars.Add(new Variable(parameter.Name, new Val(parameterName, parameter.Type))); } EmitBlock(body, parameterVars); @@ -659,14 +659,14 @@ public static class QBEGenerator { var tmp = VarName(); _builder.AppendLine($" {tmp} =l alloc8 {SizeOf(variableDeclaration.Type)}"); - _variables.Push(new Variable(variableDeclaration.Name, new Ident(tmp, variableDeclaration.Type))); + _variables.Push(new Variable(variableDeclaration.Name, new Val(tmp, variableDeclaration.Type))); } private static void EmitVariableAssignment(VariableAssignmentNode variableAssignment) { var value = EmitUnwrap(EmitExpression(variableAssignment.Value)); var variable = _variables.Single(x => x.Name == variableAssignment.Identifier.Name); - EmitCopy(variableAssignment.Value.Type, value, variable.Ident.Name); + EmitCopy(variableAssignment.Value.Type, value, variable.Val.Name); } private static void EmitWhile(WhileNode whileStatement) @@ -690,7 +690,7 @@ public static class QBEGenerator _breakLabels.Pop(); } - private static Ident EmitExpression(ExpressionNode expression) + private static Val EmitExpression(ExpressionNode expression) { return expression switch { @@ -711,11 +711,11 @@ public static class QBEGenerator }; } - private static Ident EmitAnonymousFunc(AnonymousFuncNode anonymousFunc) + private static Val EmitAnonymousFunc(AnonymousFuncNode anonymousFunc) { var name = $"$anon_func{++_anonymousFuncIndex}"; _anonymousFunctions.Enqueue((anonymousFunc, name)); - return new Ident(name, anonymousFunc.Type, IdentKind.Func); + return new Val(name, anonymousFunc.Type, ValKind.Func); } private static string EmitArrayIndexPointer(ArrayIndexAccessNode arrayIndexAccess) @@ -738,12 +738,12 @@ public static class QBEGenerator return pointer; } - private static Ident EmitArrayIndexAccess(ArrayIndexAccessNode arrayIndexAccess) + private static Val EmitArrayIndexAccess(ArrayIndexAccessNode arrayIndexAccess) { var pointer = EmitArrayIndexPointer(arrayIndexAccess); var outputName = VarName(); _builder.AppendLine($" {outputName} {QBEAssign(arrayIndexAccess.Type)} {QBELoad(arrayIndexAccess.Type)} {pointer}"); - return new Ident(outputName, arrayIndexAccess.Type); + return new Val(outputName, arrayIndexAccess.Type); } private static void EmitArrayBoundsCheck(string array, string index) @@ -770,7 +770,7 @@ public static class QBEGenerator _builder.AppendLine(notOobLabel); } - private static Ident EmitArrayInitializer(ArrayInitializerNode arrayInitializer) + private static Val EmitArrayInitializer(ArrayInitializerNode arrayInitializer) { var capacity = EmitUnwrap(EmitExpression(arrayInitializer.Capacity)); var elementSize = SizeOf(arrayInitializer.ElementType); @@ -788,24 +788,24 @@ public static class QBEGenerator _builder.AppendLine($" {dataPointer} =l add {arrayPointer}, 8"); _builder.AppendLine($" call $nub_memset(l {dataPointer}, w 0, l {capacityInBytes})"); - return new Ident(arrayPointer, arrayInitializer.Type); + return new Val(arrayPointer, arrayInitializer.Type); } - private static Ident EmitDereference(DereferenceNode dereference) + private static Val EmitDereference(DereferenceNode dereference) { var result = EmitUnwrap(EmitExpression(dereference.Expression)); var outputName = VarName(); _builder.AppendLine($" {outputName} {QBEAssign(dereference.Type)} {QBELoad(dereference.Type)} {result}"); - return new Ident(outputName, dereference.Type); + return new Val(outputName, dereference.Type); } - private static Ident EmitAddressOf(AddressOfNode addressOf) + private static Val EmitAddressOf(AddressOfNode addressOf) { switch (addressOf.Expression) { case ArrayIndexAccessNode arrayIndexAccess: var pointer = EmitArrayIndexPointer(arrayIndexAccess); - return new Ident(pointer, addressOf.Type); + return new Val(pointer, addressOf.Type); case DereferenceNode dereference: return EmitExpression(dereference.Expression); case IdentifierNode identifier: @@ -814,21 +814,21 @@ public static class QBEGenerator throw new NotSupportedException("There is nothing to address in another namespace"); } - return _variables.Single(x => x.Name == identifier.Name).Ident; + return _variables.Single(x => x.Name == identifier.Name).Val; case MemberAccessNode memberAccess: var ptr = EmitMemberAccessPointer(memberAccess); - return new Ident(ptr, addressOf.Type); + return new Val(ptr, addressOf.Type); default: throw new ArgumentOutOfRangeException(); } } - private static Ident EmitBinaryExpression(BinaryExpressionNode binaryExpression) + private static Val EmitBinaryExpression(BinaryExpressionNode binaryExpression) { var left = EmitUnwrap(EmitExpression(binaryExpression.Left)); var right = EmitUnwrap(EmitExpression(binaryExpression.Right)); var outputName = VarName(); - var output = new Ident(outputName, binaryExpression.Type); + var output = new Val(outputName, binaryExpression.Type); switch (binaryExpression.Operator) { @@ -1037,31 +1037,31 @@ public static class QBEGenerator throw new NotSupportedException($"Binary operator {binaryExpression.Operator} for types {binaryExpression.Left.Type} and {binaryExpression.Right.Type} not supported"); } - private static Ident EmitIdentifier(IdentifierNode identifier) + private static Val EmitIdentifier(IdentifierNode identifier) { if (_definitionTable.LookupFunc(identifier.Namespace.Or(_compilationUnit.Namespace), identifier.Name).TryGetValue(out var func)) { - return new Ident(FuncName(func), identifier.Type, IdentKind.Func); + return new Val(FuncName(func), identifier.Type, ValKind.Func); } if (!identifier.Namespace.HasValue) { - return _variables.Single(v => v.Name == identifier.Name).Ident; + return _variables.Single(v => v.Name == identifier.Name).Val; } throw new UnreachableException(); } - private static Ident EmitLiteral(LiteralNode literal) + private static Val EmitLiteral(LiteralNode literal) { if (literal.Type.IsInteger) { switch (literal.Kind) { case LiteralKind.Integer: - return new Ident(literal.Literal, literal.Type, IdentKind.Literal); + return new Val(literal.Literal, literal.Type, ValKind.Literal); case LiteralKind.Float: - return new Ident(literal.Literal.Split(".").First(), literal.Type, IdentKind.Literal); + return new Val(literal.Literal.Split(".").First(), literal.Type, ValKind.Literal); default: throw new ArgumentOutOfRangeException(); } @@ -1071,14 +1071,14 @@ public static class QBEGenerator { var value = double.Parse(literal.Literal, CultureInfo.InvariantCulture); var bits = BitConverter.DoubleToInt64Bits(value); - return new Ident(bits.ToString(), literal.Type, IdentKind.Literal); + return new Val(bits.ToString(), literal.Type, ValKind.Literal); } if (literal.Type.IsFloat32) { var value = float.Parse(literal.Literal, CultureInfo.InvariantCulture); var bits = BitConverter.SingleToInt32Bits(value); - return new Ident(bits.ToString(), literal.Type, IdentKind.Literal); + return new Val(bits.ToString(), literal.Type, ValKind.Literal); } switch (literal.Kind) @@ -1086,15 +1086,15 @@ public static class QBEGenerator case LiteralKind.String: var cStringLiteral = new CStringLiteral(literal.Literal, CStringName()); _cStringLiterals.Add(cStringLiteral); - return new Ident(cStringLiteral.Name, literal.Type, IdentKind.Literal); + return new Val(cStringLiteral.Name, literal.Type, ValKind.Literal); case LiteralKind.Bool: - return new Ident(bool.Parse(literal.Literal) ? "1" : "0", literal.Type, IdentKind.Literal); + return new Val(bool.Parse(literal.Literal) ? "1" : "0", literal.Type, ValKind.Literal); default: throw new ArgumentOutOfRangeException(); } } - private static Ident EmitStructInitializer(StructInitializerNode structInitializer) + private static Val EmitStructInitializer(StructInitializerNode structInitializer) { var structDefinition = _definitionTable.LookupStruct(structInitializer.StructType.Namespace, structInitializer.StructType.Name).GetValue(); @@ -1126,10 +1126,10 @@ public static class QBEGenerator } } - return new Ident(output, structInitializer.StructType); + return new Val(output, structInitializer.StructType); } - private static Ident EmitUnaryExpression(UnaryExpressionNode unaryExpression) + private static Val EmitUnaryExpression(UnaryExpressionNode unaryExpression) { var operand = EmitUnwrap(EmitExpression(unaryExpression.Operand)); var outputName = VarName(); @@ -1142,16 +1142,16 @@ public static class QBEGenerator { case NubPrimitiveType { Kind: PrimitiveTypeKind.I64 }: _builder.AppendLine($" {outputName} =l neg {operand}"); - return new Ident(outputName, unaryExpression.Type); + return new Val(outputName, unaryExpression.Type); case NubPrimitiveType { Kind: PrimitiveTypeKind.I32 or PrimitiveTypeKind.I16 or PrimitiveTypeKind.I8 }: _builder.AppendLine($" {outputName} =w neg {operand}"); - return new Ident(outputName, unaryExpression.Type); + return new Val(outputName, unaryExpression.Type); case NubPrimitiveType { Kind: PrimitiveTypeKind.F64 }: _builder.AppendLine($" {outputName} =d neg {operand}"); - return new Ident(outputName, unaryExpression.Type); + return new Val(outputName, unaryExpression.Type); case NubPrimitiveType { Kind: PrimitiveTypeKind.F32 }: _builder.AppendLine($" {outputName} =s neg {operand}"); - return new Ident(outputName, unaryExpression.Type); + return new Val(outputName, unaryExpression.Type); } break; @@ -1162,7 +1162,7 @@ public static class QBEGenerator { case NubPrimitiveType { Kind: PrimitiveTypeKind.Bool }: _builder.AppendLine($" {outputName} =w xor {operand}, 1"); - return new Ident(outputName, unaryExpression.Type); + return new Val(outputName, unaryExpression.Type); } break; @@ -1206,16 +1206,16 @@ public static class QBEGenerator } } - private static Ident EmitMemberAccess(MemberAccessNode memberAccess) + private static Val EmitMemberAccess(MemberAccessNode memberAccess) { var pointer = EmitMemberAccessPointer(memberAccess); var output = VarName(); _builder.AppendLine($" {output} {QBEAssign(memberAccess.Type)} {QBELoad(memberAccess.Type)} {pointer}"); - return new Ident(output, memberAccess.Type); + return new Val(output, memberAccess.Type); } - private static Ident EmitFixedArrayInitializer(FixedArrayInitializerNode fixedArrayInitializer) + private static Val EmitFixedArrayInitializer(FixedArrayInitializerNode fixedArrayInitializer) { var totalSize = SizeOf(fixedArrayInitializer.Type); var outputName = VarName(); @@ -1229,10 +1229,10 @@ public static class QBEGenerator var dataSize = totalSize - 8; _builder.AppendLine($" call $nub_memset(l {dataPtr}, w 0, l {dataSize})"); - return new Ident(outputName, fixedArrayInitializer.Type); + return new Val(outputName, fixedArrayInitializer.Type); } - private static Ident EmitFuncCall(FuncCallNode funcCall) + private static Val EmitFuncCall(FuncCallNode funcCall) { var funcType = (NubFuncType)funcCall.Expression.Type; @@ -1277,12 +1277,12 @@ public static class QBEGenerator { var outputName = VarName(); _builder.AppendLine($" {outputName} {QBEAssign(funcCall.Type)} call {funcPointer}({string.Join(", ", parameterStrings)})"); - return new Ident(outputName, funcCall.Type); + return new Val(outputName, funcCall.Type); } else { _builder.AppendLine($" call {funcPointer}({string.Join(", ", parameterStrings)})"); - return new Ident(string.Empty, funcCall.Type); + return new Val(string.Empty, funcCall.Type); } } @@ -1298,27 +1298,27 @@ public static class QBEGenerator } } - private static string EmitUnwrap(Ident ident) + private static string EmitUnwrap(Val val) { - if (ident.Type.IsVoid) + if (val.Type.IsVoid) { throw new InvalidOperationException("Cannot unwrap temporary of void type"); } - switch (ident.Kind) + switch (val.Kind) { - case IdentKind.Func: - case IdentKind.Literal: - return ident.Name; - case IdentKind.Variable: - if (IsPointerType(ident.Type)) + case ValKind.Func: + case ValKind.Literal: + return val.Name; + case ValKind.Variable: + if (IsPointerType(val.Type)) { - return ident.Name; + return val.Name; } else { var result = VarName(); - _builder.AppendLine($" {result} {QBEAssign(ident.Type)} {QBELoad(ident.Type)} {ident.Name}"); + _builder.AppendLine($" {result} {QBEAssign(val.Type)} {QBELoad(val.Type)} {val.Name}"); return result; } default: @@ -1333,17 +1333,17 @@ internal class CStringLiteral(string value, string name) public string Name { get; } = name; } -internal class Variable(string name, Ident ident) +internal class Variable(string name, Val val) { public string Name { get; } = name; - public Ident Ident { get; } = ident; + public Val Val { get; } = val; } -internal class Ident(string name, NubType type, IdentKind kind = IdentKind.Variable) +internal class Val(string name, NubType type, ValKind kind = ValKind.Variable) { public string Name { get; } = name; public NubType Type { get; } = type; - public IdentKind Kind { get; } = kind; + public ValKind Kind { get; } = kind; public override string ToString() { @@ -1351,7 +1351,7 @@ internal class Ident(string name, NubType type, IdentKind kind = IdentKind.Varia } } -internal enum IdentKind +internal enum ValKind { Func, Variable, diff --git a/src/Syntax/Diagnostics/ConsoleColors.cs b/src/Syntax/Diagnostics/ConsoleColors.cs index 4275a60..887a2fa 100644 --- a/src/Syntax/Diagnostics/ConsoleColors.cs +++ b/src/Syntax/Diagnostics/ConsoleColors.cs @@ -130,7 +130,7 @@ public static class ConsoleColors public static string ColorizeSource(string source) { var sourceText = new SourceText(string.Empty, source); - var tokens = Tokenizer.Tokenize(sourceText).Value; + var tokens = Tokenizer.Tokenize(sourceText, out _); var result = new StringBuilder(); var lastCharIndex = 0; diff --git a/src/Syntax/Diagnostics/Diagnostic.cs b/src/Syntax/Diagnostics/Diagnostic.cs index 6f0e06f..fd94dad 100644 --- a/src/Syntax/Diagnostics/Diagnostic.cs +++ b/src/Syntax/Diagnostics/Diagnostic.cs @@ -63,7 +63,7 @@ public class Diagnostic Help = help; } - public string Format() + public string FormatANSI() { var sb = new StringBuilder(); diff --git a/src/Syntax/Diagnostics/DiagnosticsResult.cs b/src/Syntax/Diagnostics/DiagnosticsResult.cs deleted file mode 100644 index 70e7bde..0000000 --- a/src/Syntax/Diagnostics/DiagnosticsResult.cs +++ /dev/null @@ -1,20 +0,0 @@ -namespace Syntax.Diagnostics; - -public class DiagnosticsResult(List diagnostics) -{ - public bool HasErrors => diagnostics.Any(d => d.Severity == DiagnosticSeverity.Error); - - public void PrintAllDiagnostics() - { - foreach (var diagnostic in diagnostics) - { - Console.Error.WriteLine(diagnostic.Format()); - Console.Error.WriteLine(); - } - } -} - -public class DiagnosticsResult(List diagnostics, TResult value) : DiagnosticsResult(diagnostics) -{ - public TResult Value { get; } = value; -} \ No newline at end of file diff --git a/src/Syntax/Parsing/Definitions/DefinitionNode.cs b/src/Syntax/Parsing/Definitions/DefinitionNode.cs index dbdeb20..3e856f9 100644 --- a/src/Syntax/Parsing/Definitions/DefinitionNode.cs +++ b/src/Syntax/Parsing/Definitions/DefinitionNode.cs @@ -3,7 +3,7 @@ using Syntax.Tokenization; namespace Syntax.Parsing.Definitions; -public abstract class DefinitionNode(IReadOnlyList tokens, Optional documentation, string @namespace) : Node(tokens) +public abstract class DefinitionNode(IEnumerable tokens, Optional documentation, string @namespace) : Node(tokens) { public Optional Documentation { get; } = documentation; public string Namespace { get; set; } = @namespace; diff --git a/src/Syntax/Parsing/Definitions/FuncDefinitionNode.cs b/src/Syntax/Parsing/Definitions/FuncDefinitionNode.cs index d8a0c6b..7e04296 100644 --- a/src/Syntax/Parsing/Definitions/FuncDefinitionNode.cs +++ b/src/Syntax/Parsing/Definitions/FuncDefinitionNode.cs @@ -22,7 +22,7 @@ public interface IFuncSignature public string ToString() => $"{Name}({string.Join(", ", Parameters.Select(p => p.ToString()))}){": " + ReturnType}"; } -public class LocalFuncDefinitionNode(IReadOnlyList tokens, Optional documentation, string @namespace, string name, List parameters, BlockNode body, NubType returnType, bool exported) : DefinitionNode(tokens, documentation, @namespace), IFuncSignature +public class LocalFuncDefinitionNode(IEnumerable tokens, Optional documentation, string @namespace, string name, List parameters, BlockNode body, NubType returnType, bool exported) : DefinitionNode(tokens, documentation, @namespace), IFuncSignature { public string Name { get; } = name; public List Parameters { get; } = parameters; @@ -33,7 +33,7 @@ public class LocalFuncDefinitionNode(IReadOnlyList tokens, Optional $"{Name}({string.Join(", ", Parameters.Select(p => p.ToString()))}){": " + ReturnType}"; } -public class ExternFuncDefinitionNode(IReadOnlyList tokens, Optional documentation, string @namespace, string name, string callName, List parameters, NubType returnType) : DefinitionNode(tokens, documentation, @namespace), IFuncSignature +public class ExternFuncDefinitionNode(IEnumerable tokens, Optional documentation, string @namespace, string name, string callName, List parameters, NubType returnType) : DefinitionNode(tokens, documentation, @namespace), IFuncSignature { public string Name { get; } = name; public string CallName { get; } = callName; diff --git a/src/Syntax/Parsing/Definitions/StructDefinitionNode.cs b/src/Syntax/Parsing/Definitions/StructDefinitionNode.cs index eca4386..98604f9 100644 --- a/src/Syntax/Parsing/Definitions/StructDefinitionNode.cs +++ b/src/Syntax/Parsing/Definitions/StructDefinitionNode.cs @@ -12,7 +12,7 @@ public class StructField(string name, NubType type, Optional val public Optional Value { get; } = value; } -public class StructDefinitionNode(IReadOnlyList tokens, Optional documentation, string @namespace, string name, List fields) : DefinitionNode(tokens, documentation, @namespace) +public class StructDefinitionNode(IEnumerable tokens, Optional documentation, string @namespace, string name, List fields) : DefinitionNode(tokens, documentation, @namespace) { public string Name { get; } = name; public List Fields { get; } = fields; diff --git a/src/Syntax/Parsing/Expressions/AddressOfNode.cs b/src/Syntax/Parsing/Expressions/AddressOfNode.cs index 096da0f..8807061 100644 --- a/src/Syntax/Parsing/Expressions/AddressOfNode.cs +++ b/src/Syntax/Parsing/Expressions/AddressOfNode.cs @@ -2,7 +2,7 @@ using Syntax.Tokenization; namespace Syntax.Parsing.Expressions; -public class AddressOfNode(IReadOnlyList tokens, LValueNode expression) : ExpressionNode(tokens) +public class AddressOfNode(IEnumerable tokens, LValueNode expression) : ExpressionNode(tokens) { public LValueNode Expression { get; } = expression; } \ No newline at end of file diff --git a/src/Syntax/Parsing/Expressions/AnonymousFuncNode.cs b/src/Syntax/Parsing/Expressions/AnonymousFuncNode.cs index fbce82d..f53798f 100644 --- a/src/Syntax/Parsing/Expressions/AnonymousFuncNode.cs +++ b/src/Syntax/Parsing/Expressions/AnonymousFuncNode.cs @@ -5,7 +5,7 @@ using Syntax.Typing; namespace Syntax.Parsing.Expressions; -public class AnonymousFuncNode(IReadOnlyList tokens, List parameters, BlockNode body, NubType returnType) : ExpressionNode(tokens) +public class AnonymousFuncNode(IEnumerable tokens, List parameters, BlockNode body, NubType returnType) : ExpressionNode(tokens) { public List Parameters { get; } = parameters; public BlockNode Body { get; } = body; diff --git a/src/Syntax/Parsing/Expressions/ArrayIndexAccessNode.cs b/src/Syntax/Parsing/Expressions/ArrayIndexAccessNode.cs index d408a21..5795e9e 100644 --- a/src/Syntax/Parsing/Expressions/ArrayIndexAccessNode.cs +++ b/src/Syntax/Parsing/Expressions/ArrayIndexAccessNode.cs @@ -2,7 +2,7 @@ using Syntax.Tokenization; namespace Syntax.Parsing.Expressions; -public class ArrayIndexAccessNode(IReadOnlyList tokens, ExpressionNode array, ExpressionNode index) : LValueNode(tokens) +public class ArrayIndexAccessNode(IEnumerable tokens, ExpressionNode array, ExpressionNode index) : LValueNode(tokens) { public ExpressionNode Array { get; } = array; public ExpressionNode Index { get; } = index; diff --git a/src/Syntax/Parsing/Expressions/ArrayInitializerNode.cs b/src/Syntax/Parsing/Expressions/ArrayInitializerNode.cs index 7cd9cd2..ce1b00f 100644 --- a/src/Syntax/Parsing/Expressions/ArrayInitializerNode.cs +++ b/src/Syntax/Parsing/Expressions/ArrayInitializerNode.cs @@ -3,7 +3,7 @@ using Syntax.Typing; namespace Syntax.Parsing.Expressions; -public class ArrayInitializerNode(IReadOnlyList tokens, ExpressionNode capacity, NubType elementType) : ExpressionNode(tokens) +public class ArrayInitializerNode(IEnumerable tokens, ExpressionNode capacity, NubType elementType) : ExpressionNode(tokens) { public ExpressionNode Capacity { get; } = capacity; public NubType ElementType { get; } = elementType; diff --git a/src/Syntax/Parsing/Expressions/BinaryExpressionNode.cs b/src/Syntax/Parsing/Expressions/BinaryExpressionNode.cs index 64d0a7f..b33b8b3 100644 --- a/src/Syntax/Parsing/Expressions/BinaryExpressionNode.cs +++ b/src/Syntax/Parsing/Expressions/BinaryExpressionNode.cs @@ -2,7 +2,7 @@ namespace Syntax.Parsing.Expressions; -public class BinaryExpressionNode(IReadOnlyList tokens, ExpressionNode left, BinaryExpressionOperator @operator, ExpressionNode right) : ExpressionNode(tokens) +public class BinaryExpressionNode(IEnumerable tokens, ExpressionNode left, BinaryExpressionOperator @operator, ExpressionNode right) : ExpressionNode(tokens) { public ExpressionNode Left { get; } = left; public BinaryExpressionOperator Operator { get; } = @operator; diff --git a/src/Syntax/Parsing/Expressions/DereferenceNode.cs b/src/Syntax/Parsing/Expressions/DereferenceNode.cs index e66175a..0108106 100644 --- a/src/Syntax/Parsing/Expressions/DereferenceNode.cs +++ b/src/Syntax/Parsing/Expressions/DereferenceNode.cs @@ -2,7 +2,7 @@ using Syntax.Tokenization; namespace Syntax.Parsing.Expressions; -public class DereferenceNode(IReadOnlyList tokens, ExpressionNode expression) : LValueNode(tokens) +public class DereferenceNode(IEnumerable tokens, ExpressionNode expression) : LValueNode(tokens) { public ExpressionNode Expression { get; } = expression; } \ No newline at end of file diff --git a/src/Syntax/Parsing/Expressions/ExpressionNode.cs b/src/Syntax/Parsing/Expressions/ExpressionNode.cs index 1760a9c..4b5290b 100644 --- a/src/Syntax/Parsing/Expressions/ExpressionNode.cs +++ b/src/Syntax/Parsing/Expressions/ExpressionNode.cs @@ -3,7 +3,7 @@ using Syntax.Typing; namespace Syntax.Parsing.Expressions; -public abstract class ExpressionNode(IReadOnlyList tokens) : Node(tokens) +public abstract class ExpressionNode(IEnumerable tokens) : Node(tokens) { private NubType? _type; public NubType Type @@ -13,4 +13,4 @@ public abstract class ExpressionNode(IReadOnlyList tokens) : Node(tokens) } } -public abstract class LValueNode(IReadOnlyList tokens) : ExpressionNode(tokens); +public abstract class LValueNode(IEnumerable tokens) : ExpressionNode(tokens); diff --git a/src/Syntax/Parsing/Expressions/FixedArrayInitializerNode.cs b/src/Syntax/Parsing/Expressions/FixedArrayInitializerNode.cs index 479182d..525b6bd 100644 --- a/src/Syntax/Parsing/Expressions/FixedArrayInitializerNode.cs +++ b/src/Syntax/Parsing/Expressions/FixedArrayInitializerNode.cs @@ -3,7 +3,7 @@ using Syntax.Typing; namespace Syntax.Parsing.Expressions; -public class FixedArrayInitializerNode(IReadOnlyList tokens, NubType elementType, int capacity) : ExpressionNode(tokens) +public class FixedArrayInitializerNode(IEnumerable tokens, NubType elementType, int capacity) : ExpressionNode(tokens) { public NubType ElementType { get; } = elementType; public int Capacity { get; } = capacity; diff --git a/src/Syntax/Parsing/Expressions/FuncCallNode.cs b/src/Syntax/Parsing/Expressions/FuncCallNode.cs index 1da4ced..b5f083d 100644 --- a/src/Syntax/Parsing/Expressions/FuncCallNode.cs +++ b/src/Syntax/Parsing/Expressions/FuncCallNode.cs @@ -2,7 +2,7 @@ namespace Syntax.Parsing.Expressions; -public class FuncCallNode(IReadOnlyList tokens, ExpressionNode expression, List parameters) : ExpressionNode(tokens) +public class FuncCallNode(IEnumerable tokens, ExpressionNode expression, List parameters) : ExpressionNode(tokens) { public ExpressionNode Expression = expression; public List Parameters { get; } = parameters; diff --git a/src/Syntax/Parsing/Expressions/IdentifierNode.cs b/src/Syntax/Parsing/Expressions/IdentifierNode.cs index 9aac442..5870ae6 100644 --- a/src/Syntax/Parsing/Expressions/IdentifierNode.cs +++ b/src/Syntax/Parsing/Expressions/IdentifierNode.cs @@ -3,7 +3,7 @@ using Syntax.Tokenization; namespace Syntax.Parsing.Expressions; -public class IdentifierNode(IReadOnlyList tokens, Optional @namespace, string name) : LValueNode(tokens) +public class IdentifierNode(IEnumerable tokens, Optional @namespace, string name) : LValueNode(tokens) { public Optional Namespace { get; } = @namespace; public string Name { get; } = name; diff --git a/src/Syntax/Parsing/Expressions/LiteralNode.cs b/src/Syntax/Parsing/Expressions/LiteralNode.cs index cf0d382..b2fcd46 100644 --- a/src/Syntax/Parsing/Expressions/LiteralNode.cs +++ b/src/Syntax/Parsing/Expressions/LiteralNode.cs @@ -2,7 +2,7 @@ namespace Syntax.Parsing.Expressions; -public class LiteralNode(IReadOnlyList tokens, string literal, LiteralKind kind) : ExpressionNode(tokens) +public class LiteralNode(IEnumerable tokens, string literal, LiteralKind kind) : ExpressionNode(tokens) { public string Literal { get; } = literal; public LiteralKind Kind { get; } = kind; diff --git a/src/Syntax/Parsing/Expressions/MemberAccessNode.cs b/src/Syntax/Parsing/Expressions/MemberAccessNode.cs index 6988b36..dbd09c3 100644 --- a/src/Syntax/Parsing/Expressions/MemberAccessNode.cs +++ b/src/Syntax/Parsing/Expressions/MemberAccessNode.cs @@ -2,7 +2,7 @@ namespace Syntax.Parsing.Expressions; -public class MemberAccessNode(IReadOnlyList tokens, ExpressionNode expression, string member) : LValueNode(tokens) +public class MemberAccessNode(IEnumerable tokens, ExpressionNode expression, string member) : LValueNode(tokens) { public ExpressionNode Expression { get; } = expression; public string Member { get; } = member; diff --git a/src/Syntax/Parsing/Expressions/StructInitializerNode.cs b/src/Syntax/Parsing/Expressions/StructInitializerNode.cs index d398e40..66ecf56 100644 --- a/src/Syntax/Parsing/Expressions/StructInitializerNode.cs +++ b/src/Syntax/Parsing/Expressions/StructInitializerNode.cs @@ -3,7 +3,7 @@ using Syntax.Typing; namespace Syntax.Parsing.Expressions; -public class StructInitializerNode(IReadOnlyList tokens, NubStructType structType, Dictionary initializers) : ExpressionNode(tokens) +public class StructInitializerNode(IEnumerable tokens, NubStructType structType, Dictionary initializers) : ExpressionNode(tokens) { public NubStructType StructType { get; } = structType; public Dictionary Initializers { get; } = initializers; diff --git a/src/Syntax/Parsing/Expressions/UnaryExpressionNode.cs b/src/Syntax/Parsing/Expressions/UnaryExpressionNode.cs index 77e9969..b7e238b 100644 --- a/src/Syntax/Parsing/Expressions/UnaryExpressionNode.cs +++ b/src/Syntax/Parsing/Expressions/UnaryExpressionNode.cs @@ -2,7 +2,7 @@ using Syntax.Tokenization; namespace Syntax.Parsing.Expressions; -public class UnaryExpressionNode(IReadOnlyList tokens, UnaryExpressionOperator @operator, ExpressionNode operand) : ExpressionNode(tokens) +public class UnaryExpressionNode(IEnumerable tokens, UnaryExpressionOperator @operator, ExpressionNode operand) : ExpressionNode(tokens) { public UnaryExpressionOperator Operator { get; } = @operator; public ExpressionNode Operand { get; } = operand; diff --git a/src/Syntax/Parsing/Node.cs b/src/Syntax/Parsing/Node.cs index 86ef4e2..f2fcddc 100644 --- a/src/Syntax/Parsing/Node.cs +++ b/src/Syntax/Parsing/Node.cs @@ -2,7 +2,7 @@ namespace Syntax.Parsing; -public abstract class Node(IReadOnlyList tokens) +public abstract class Node(IEnumerable tokens) { - public IReadOnlyList Tokens { get; set; } = tokens; + public IEnumerable Tokens { get; set; } = tokens; } \ No newline at end of file diff --git a/src/Syntax/Parsing/Parser.cs b/src/Syntax/Parsing/Parser.cs index 3c1403a..81b920e 100644 --- a/src/Syntax/Parsing/Parser.cs +++ b/src/Syntax/Parsing/Parser.cs @@ -14,10 +14,10 @@ public static class Parser { private static string _namespace = null!; private static List _diagnostics = []; - private static List _tokens = []; + private static IEnumerable _tokens = []; private static int _index; - public static DiagnosticsResult ParseFile(List tokens) + public static CompilationUnit? ParseFile(IEnumerable tokens, out IEnumerable diagnostics) { _tokens = tokens; _namespace = null!; @@ -33,7 +33,8 @@ public static class Parser catch (ParseException ex) { _diagnostics.Add(ex.Diagnostic); - return new DiagnosticsResult(_diagnostics, null); + diagnostics = _diagnostics; + return null; } try @@ -46,7 +47,8 @@ public static class Parser definitions.Add(definition); } - return new DiagnosticsResult(_diagnostics, new CompilationUnit(_namespace, definitions)); + diagnostics = _diagnostics; + return new CompilationUnit(_namespace, definitions); } catch (ParseException ex) { @@ -54,7 +56,8 @@ public static class Parser RecoverToNextDefinition(); } - return new DiagnosticsResult(_diagnostics, null); + diagnostics = _diagnostics; + return null; } private static DefinitionNode ParseDefinition() @@ -63,7 +66,7 @@ public static class Parser List modifiers = []; List documentationParts = []; - while (_index < _tokens.Count && _tokens[_index] is DocumentationToken commentToken) + while (_index < _tokens.Count() && _tokens.ElementAt(_index) is DocumentationToken commentToken) { documentationParts.Add(commentToken.Documentation); _index++; @@ -898,14 +901,14 @@ public static class Parser private static Optional Peek(int offset = 0) { var peekIndex = _index + offset; - while (peekIndex < _tokens.Count && _tokens[peekIndex] is DocumentationToken) + while (peekIndex < _tokens.Count() && _tokens.ElementAt(peekIndex) is DocumentationToken) { peekIndex++; } - if (peekIndex < _tokens.Count) + if (peekIndex < _tokens.Count()) { - return _tokens[peekIndex]; + return _tokens.ElementAt(peekIndex); } return Optional.Empty(); @@ -913,7 +916,7 @@ public static class Parser private static void Next() { - while (_index < _tokens.Count && _tokens[_index] is DocumentationToken) + while (_index < _tokens.Count() && _tokens.ElementAt(_index) is DocumentationToken) { _index++; } @@ -921,9 +924,9 @@ public static class Parser _index++; } - private static IReadOnlyList GetTokensForNode(int startIndex) + private static IEnumerable GetTokensForNode(int startIndex) { - return _tokens[startIndex..Math.Min(_index, _tokens.Count - 1)]; + return _tokens.Skip(startIndex).Take(Math.Min(_index, _tokens.Count() - 1) - startIndex); } } diff --git a/src/Syntax/Parsing/Statements/ArrayIndexAssignmentNode.cs b/src/Syntax/Parsing/Statements/ArrayIndexAssignmentNode.cs index cd730f4..20cc7a6 100644 --- a/src/Syntax/Parsing/Statements/ArrayIndexAssignmentNode.cs +++ b/src/Syntax/Parsing/Statements/ArrayIndexAssignmentNode.cs @@ -3,7 +3,7 @@ using Syntax.Tokenization; namespace Syntax.Parsing.Statements; -public class ArrayIndexAssignmentNode(IReadOnlyList tokens, ArrayIndexAccessNode arrayIndexAccess, ExpressionNode value) : StatementNode(tokens) +public class ArrayIndexAssignmentNode(IEnumerable tokens, ArrayIndexAccessNode arrayIndexAccess, ExpressionNode value) : StatementNode(tokens) { public ArrayIndexAccessNode ArrayIndexAccess { get; } = arrayIndexAccess; public ExpressionNode Value { get; } = value; diff --git a/src/Syntax/Parsing/Statements/BlockNode.cs b/src/Syntax/Parsing/Statements/BlockNode.cs index b540443..4440292 100644 --- a/src/Syntax/Parsing/Statements/BlockNode.cs +++ b/src/Syntax/Parsing/Statements/BlockNode.cs @@ -2,7 +2,7 @@ namespace Syntax.Parsing.Statements; -public class BlockNode(IReadOnlyList tokens, List statements) : Node(tokens) +public class BlockNode(IEnumerable tokens, List statements) : Node(tokens) { public List Statements { get; } = statements; } \ No newline at end of file diff --git a/src/Syntax/Parsing/Statements/BreakNode.cs b/src/Syntax/Parsing/Statements/BreakNode.cs index 90c2583..ef29724 100644 --- a/src/Syntax/Parsing/Statements/BreakNode.cs +++ b/src/Syntax/Parsing/Statements/BreakNode.cs @@ -2,4 +2,4 @@ using Syntax.Tokenization; namespace Syntax.Parsing.Statements; -public class BreakNode(IReadOnlyList tokens) : StatementNode(tokens); \ No newline at end of file +public class BreakNode(IEnumerable tokens) : StatementNode(tokens); \ No newline at end of file diff --git a/src/Syntax/Parsing/Statements/ContinueNode.cs b/src/Syntax/Parsing/Statements/ContinueNode.cs index 686de7b..70a1761 100644 --- a/src/Syntax/Parsing/Statements/ContinueNode.cs +++ b/src/Syntax/Parsing/Statements/ContinueNode.cs @@ -2,4 +2,4 @@ using Syntax.Tokenization; namespace Syntax.Parsing.Statements; -public class ContinueNode(IReadOnlyList tokens) : StatementNode(tokens); \ No newline at end of file +public class ContinueNode(IEnumerable tokens) : StatementNode(tokens); \ No newline at end of file diff --git a/src/Syntax/Parsing/Statements/DereferenceAssignmentNode.cs b/src/Syntax/Parsing/Statements/DereferenceAssignmentNode.cs index 70e0ace..00118b6 100644 --- a/src/Syntax/Parsing/Statements/DereferenceAssignmentNode.cs +++ b/src/Syntax/Parsing/Statements/DereferenceAssignmentNode.cs @@ -3,7 +3,7 @@ using Syntax.Tokenization; namespace Syntax.Parsing.Statements; -public class DereferenceAssignmentNode(IReadOnlyList tokens, DereferenceNode dereference, ExpressionNode value) : StatementNode(tokens) +public class DereferenceAssignmentNode(IEnumerable tokens, DereferenceNode dereference, ExpressionNode value) : StatementNode(tokens) { public DereferenceNode Dereference { get; } = dereference; public ExpressionNode Value { get; } = value; diff --git a/src/Syntax/Parsing/Statements/IfNode.cs b/src/Syntax/Parsing/Statements/IfNode.cs index 5a598ef..d8b5708 100644 --- a/src/Syntax/Parsing/Statements/IfNode.cs +++ b/src/Syntax/Parsing/Statements/IfNode.cs @@ -4,7 +4,7 @@ using Syntax.Tokenization; namespace Syntax.Parsing.Statements; -public class IfNode(IReadOnlyList tokens, ExpressionNode condition, BlockNode body, Optional> @else) : StatementNode(tokens) +public class IfNode(IEnumerable tokens, ExpressionNode condition, BlockNode body, Optional> @else) : StatementNode(tokens) { public ExpressionNode Condition { get; } = condition; public BlockNode Body { get; } = body; diff --git a/src/Syntax/Parsing/Statements/MemberAssignmentNode.cs b/src/Syntax/Parsing/Statements/MemberAssignmentNode.cs index a288bf4..1e0d37b 100644 --- a/src/Syntax/Parsing/Statements/MemberAssignmentNode.cs +++ b/src/Syntax/Parsing/Statements/MemberAssignmentNode.cs @@ -3,7 +3,7 @@ using Syntax.Tokenization; namespace Syntax.Parsing.Statements; -public class MemberAssignmentNode(IReadOnlyList tokens, MemberAccessNode expression, ExpressionNode value) : StatementNode(tokens) +public class MemberAssignmentNode(IEnumerable tokens, MemberAccessNode expression, ExpressionNode value) : StatementNode(tokens) { public MemberAccessNode MemberAccess { get; } = expression; public ExpressionNode Value { get; } = value; diff --git a/src/Syntax/Parsing/Statements/ReturnNode.cs b/src/Syntax/Parsing/Statements/ReturnNode.cs index 3b89a00..cd30338 100644 --- a/src/Syntax/Parsing/Statements/ReturnNode.cs +++ b/src/Syntax/Parsing/Statements/ReturnNode.cs @@ -4,7 +4,7 @@ using Syntax.Tokenization; namespace Syntax.Parsing.Statements; -public class ReturnNode(IReadOnlyList tokens, Optional value) : StatementNode(tokens) +public class ReturnNode(IEnumerable tokens, Optional value) : StatementNode(tokens) { public Optional Value { get; } = value; } \ No newline at end of file diff --git a/src/Syntax/Parsing/Statements/StatementExpressionNode.cs b/src/Syntax/Parsing/Statements/StatementExpressionNode.cs index 5dbde34..3da4203 100644 --- a/src/Syntax/Parsing/Statements/StatementExpressionNode.cs +++ b/src/Syntax/Parsing/Statements/StatementExpressionNode.cs @@ -3,7 +3,7 @@ using Syntax.Tokenization; namespace Syntax.Parsing.Statements; -public class StatementExpressionNode(IReadOnlyList tokens, ExpressionNode expression) : StatementNode(tokens) +public class StatementExpressionNode(IEnumerable tokens, ExpressionNode expression) : StatementNode(tokens) { public ExpressionNode Expression { get; } = expression; } \ No newline at end of file diff --git a/src/Syntax/Parsing/Statements/StatementNode.cs b/src/Syntax/Parsing/Statements/StatementNode.cs index d50eb16..305a1b7 100644 --- a/src/Syntax/Parsing/Statements/StatementNode.cs +++ b/src/Syntax/Parsing/Statements/StatementNode.cs @@ -2,4 +2,4 @@ namespace Syntax.Parsing.Statements; -public abstract class StatementNode(IReadOnlyList tokens) : Node(tokens); \ No newline at end of file +public abstract class StatementNode(IEnumerable tokens) : Node(tokens); \ No newline at end of file diff --git a/src/Syntax/Parsing/Statements/VariableAssignmentNode.cs b/src/Syntax/Parsing/Statements/VariableAssignmentNode.cs index 51abb63..3e032cc 100644 --- a/src/Syntax/Parsing/Statements/VariableAssignmentNode.cs +++ b/src/Syntax/Parsing/Statements/VariableAssignmentNode.cs @@ -3,7 +3,7 @@ using Syntax.Tokenization; namespace Syntax.Parsing.Statements; -public class VariableAssignmentNode(IReadOnlyList tokens, IdentifierNode identifier, ExpressionNode value) : StatementNode(tokens) +public class VariableAssignmentNode(IEnumerable tokens, IdentifierNode identifier, ExpressionNode value) : StatementNode(tokens) { public IdentifierNode Identifier { get; } = identifier; public ExpressionNode Value { get; } = value; diff --git a/src/Syntax/Parsing/Statements/VariableDeclarationNode.cs b/src/Syntax/Parsing/Statements/VariableDeclarationNode.cs index 64fc58d..788164d 100644 --- a/src/Syntax/Parsing/Statements/VariableDeclarationNode.cs +++ b/src/Syntax/Parsing/Statements/VariableDeclarationNode.cs @@ -3,7 +3,7 @@ using Syntax.Typing; namespace Syntax.Parsing.Statements; -public class VariableDeclarationNode(IReadOnlyList tokens, string name, NubType type) : StatementNode(tokens) +public class VariableDeclarationNode(IEnumerable tokens, string name, NubType type) : StatementNode(tokens) { public string Name { get; } = name; public NubType Type { get; } = type; diff --git a/src/Syntax/Parsing/Statements/WhileNode.cs b/src/Syntax/Parsing/Statements/WhileNode.cs index 24af7fd..625c51b 100644 --- a/src/Syntax/Parsing/Statements/WhileNode.cs +++ b/src/Syntax/Parsing/Statements/WhileNode.cs @@ -3,7 +3,7 @@ using Syntax.Tokenization; namespace Syntax.Parsing.Statements; -public class WhileNode(IReadOnlyList tokens, ExpressionNode condition, BlockNode body) : StatementNode(tokens) +public class WhileNode(IEnumerable tokens, ExpressionNode condition, BlockNode body) : StatementNode(tokens) { public ExpressionNode Condition { get; } = condition; public BlockNode Body { get; } = body; diff --git a/src/Syntax/Tokenization/Tokenizer.cs b/src/Syntax/Tokenization/Tokenizer.cs index c8db68e..5a3784d 100644 --- a/src/Syntax/Tokenization/Tokenizer.cs +++ b/src/Syntax/Tokenization/Tokenizer.cs @@ -62,19 +62,21 @@ public static class Tokenizer private static SourceText _sourceText; private static int _index; - - public static DiagnosticsResult> Tokenize(SourceText sourceText) + + public static IEnumerable Tokenize(SourceText sourceText, out IEnumerable diagnostics) { _sourceText = sourceText; _index = 0; - + List tokens = []; while (ParseToken().TryGetValue(out var token)) { tokens.Add(token); } - return new DiagnosticsResult>([], tokens); + // TODO: Implement diagnostics + diagnostics = []; + return tokens; } private static void ConsumeWhitespace() @@ -99,7 +101,7 @@ public static class Tokenizer { Next(); Next(); - + if (Peek().TryGetValue(out var thirdChar) && thirdChar == '/') { Next(); @@ -109,6 +111,7 @@ public static class Tokenizer buffer += character; Next(); } + Next(); return new DocumentationToken(CreateSpan(startIndex), buffer); } @@ -117,6 +120,7 @@ public static class Tokenizer { Next(); } + Next(); return ParseToken(); } diff --git a/src/Syntax/Typing/TypeChecker.cs b/src/Syntax/Typing/TypeChecker.cs index a05264d..d400a31 100644 --- a/src/Syntax/Typing/TypeChecker.cs +++ b/src/Syntax/Typing/TypeChecker.cs @@ -18,7 +18,7 @@ public static class TypeChecker private static NubType? _currentFunctionReturnType; private static Queue _anonymousFunctions = []; - public static DiagnosticsResult Check(CompilationUnit compilationUnit, DefinitionTable definitionTable) + public static void Check(CompilationUnit compilationUnit, DefinitionTable definitionTable, out IEnumerable diagnostics) { _compilationUnit = compilationUnit; _definitionTable = definitionTable; @@ -43,8 +43,8 @@ public static class TypeChecker CheckFuncDef(func.Parameters, func.Body, func.ReturnType); } - - return new DiagnosticsResult(_diagnostics); + + diagnostics = _diagnostics; } private static void CheckStructDef(StructDefinitionNode structDef)