diff --git a/example/src/main.nub b/example/src/main.nub index 1316bb9..1ee51c6 100644 --- a/example/src/main.nub +++ b/example/src/main.nub @@ -34,9 +34,7 @@ func main(args: []cstring): i64 // } // human.print() - let x = 23 - - print_result(12, func(num) { return num == x }) + print_result(12, func(num) { return num == 12 }) return 0 } diff --git a/src/compiler/NubLang/Generation/QBE/QBEGenerator.Expression.cs b/src/compiler/NubLang/Generation/QBE/QBEGenerator.Expression.cs index e1b11e1..007e2a5 100644 --- a/src/compiler/NubLang/Generation/QBE/QBEGenerator.Expression.cs +++ b/src/compiler/NubLang/Generation/QBE/QBEGenerator.Expression.cs @@ -238,7 +238,7 @@ public partial class QBEGenerator private Val EmitVariableIdent(BoundVariableIdent variableIdent) { - return _variables.Single(v => v.Name == variableIdent.Name).Val; + return Scope.Lookup(variableIdent.Name); } private Val EmitLiteral(BoundLiteral literal) diff --git a/src/compiler/NubLang/Generation/QBE/QBEGenerator.Statement.cs b/src/compiler/NubLang/Generation/QBE/QBEGenerator.Statement.cs index dcb7ddf..1d4053b 100644 --- a/src/compiler/NubLang/Generation/QBE/QBEGenerator.Statement.cs +++ b/src/compiler/NubLang/Generation/QBE/QBEGenerator.Statement.cs @@ -47,31 +47,6 @@ public partial class QBEGenerator EmitCopyIntoOrInitialize(assignment.Value, destination.Name); } - private void EmitBlock(BoundBlock block, List? variables = null) - { - _variableScopes.Push(_variables.Count); - if (variables != null) - { - foreach (var variable in variables) - { - _variables.Push(variable); - } - } - - foreach (var statement in block.Statements.Where(_ => _codeIsReachable)) - { - EmitStatement(statement); - } - - var count = _variableScopes.Pop(); - while (_variableScopes.Count > count) - { - _variableScopes.Pop(); - } - - _codeIsReachable = true; - } - private void EmitBreak() { _writer.Indented($"jmp {_breakLabels.Peek()}"); @@ -132,7 +107,7 @@ public partial class QBEGenerator EmitStore(variableDeclaration.Assignment.Value.Type, value, name); } - _variables.Push(new Variable(variableDeclaration.Name, new Val(name, variableDeclaration.Type, ValKind.Pointer))); + Scope.Declare(variableDeclaration.Name, new Val(name, variableDeclaration.Type, ValKind.Pointer)); } private void EmitWhile(BoundWhile whileStatement) diff --git a/src/compiler/NubLang/Generation/QBE/QBEGenerator.cs b/src/compiler/NubLang/Generation/QBE/QBEGenerator.cs index f7f8162..023cc4f 100644 --- a/src/compiler/NubLang/Generation/QBE/QBEGenerator.cs +++ b/src/compiler/NubLang/Generation/QBE/QBEGenerator.cs @@ -12,14 +12,13 @@ public partial class QBEGenerator private readonly BoundDefinitionTable _definitionTable; private readonly QBEWriter _writer; - private List _cStringLiterals = []; - private List _stringLiterals = []; - private Stack _breakLabels = []; - private Stack _continueLabels = []; - private Queue<(BoundAnonymousFunc Func, string Name)> _anonymousFunctions = []; - private Dictionary _implFunctions = []; - private Stack _variables = []; - private Stack _variableScopes = []; + private readonly List _cStringLiterals = []; + private readonly List _stringLiterals = []; + private readonly Stack _breakLabels = []; + private readonly Stack _continueLabels = []; + private readonly Queue<(BoundAnonymousFunc Func, string Name)> _anonymousFunctions = []; + private readonly Dictionary _implFunctions = []; + private readonly Stack _scopes = []; private int _tmpIndex; private int _labelIndex; private int _anonymousFuncIndex; @@ -28,6 +27,8 @@ public partial class QBEGenerator private int _implFuncNameIndex; private bool _codeIsReachable = true; + private Scope Scope => _scopes.Peek(); + public QBEGenerator(BoundSyntaxTree syntaxTree, BoundDefinitionTable definitionTable, string file) { _syntaxTree = syntaxTree; @@ -37,14 +38,13 @@ public partial class QBEGenerator public string Emit() { - _cStringLiterals = []; - _stringLiterals = []; - _breakLabels = []; - _continueLabels = []; - _anonymousFunctions = []; - _implFunctions = []; - _variables = []; - _variableScopes = []; + _cStringLiterals.Clear(); + _stringLiterals.Clear(); + _breakLabels.Clear(); + _continueLabels.Clear(); + _anonymousFunctions.Clear(); + _implFunctions.Clear(); + _scopes.Clear(); _tmpIndex = 0; _labelIndex = 0; _anonymousFuncIndex = 0; @@ -347,18 +347,15 @@ public partial class QBEGenerator return "l"; } - private void EmitFuncDefinition(string name, IEnumerable parameters, NubType returnType, BoundBlock body) + private void EmitFuncDefinition(string name, IReadOnlyList parameters, NubType returnType, BoundBlock body) { - var parameterArray = parameters.ToArray(); - - _variables.Clear(); - _variableScopes.Clear(); _labelIndex = 0; _tmpIndex = 0; var builder = new StringBuilder(); builder.Append("export function "); + if (returnType is not NubVoidType) { builder.Append(FuncQBETypeName(returnType) + ' '); @@ -366,15 +363,16 @@ public partial class QBEGenerator builder.Append(name); - var parameterStrings = parameterArray.Select(x => FuncQBETypeName(x.Type) + $" %{x.Name}"); - - builder.Append($"({string.Join(", ", parameterStrings)})"); + builder.Append($"({string.Join(", ", parameters.Select(x => FuncQBETypeName(x.Type) + $" %{x.Name}"))})"); _writer.StartFunction(builder.ToString()); - var parameterVars = parameterArray.Select(parameter => new Variable(parameter.Name, new Val("%" + parameter.Name, parameter.Type, ValKind.Direct))).ToList(); + var scope = new Scope(); - EmitBlock(body, parameterVars); + foreach (var parameter in parameters) + { + scope.Declare(parameter.Name, new Val("%" + parameter.Name, parameter.Type, ValKind.Direct)); + } if (body.Statements.LastOrDefault() is not BoundReturn) { @@ -445,6 +443,20 @@ public partial class QBEGenerator _writer.WriteLine("}"); } + private void EmitBlock(BoundBlock block, Scope? scope = null) + { + _scopes.Push(scope ?? Scope.SubScope()); + + foreach (var statement in block.Statements.Where(_ => _codeIsReachable)) + { + EmitStatement(statement); + } + + _scopes.Pop(); + + _codeIsReachable = true; + } + private string EmitUnwrap(Val val) { return val.Kind switch @@ -525,29 +537,49 @@ public partial class QBEGenerator #endregion } -internal class StringLiteral(string value, string name) +public class StringLiteral(string value, string name) { public string Value { get; } = value; public string Name { get; } = name; } -internal class CStringLiteral(string value, string name) +public class CStringLiteral(string value, string name) { public string Value { get; } = value; public string Name { get; } = name; } -internal class Variable(string name, Val val) +public record Val(string Name, NubType Type, ValKind Kind, MethodCallContext? FuncCallContext = null); + +public class Scope(Scope? parent = null) { - public string Name { get; } = name; - public Val Val { get; } = val; + private readonly Dictionary _variables = []; + + public Val Lookup(string name) + { + var variable = _variables.GetValueOrDefault(name); + if (variable != null) + { + return variable; + } + + return parent?.Lookup(name) ?? throw new UnreachableException($"Variable '{name}' not found"); + } + + public void Declare(string name, Val value) + { + _variables.Add(name, value); + } + + public Scope SubScope() + { + return new Scope(this); + } } -internal record Val(string Name, NubType Type, ValKind Kind, MethodCallContext? FuncCallContext = null); +public record MethodCallContext(Val ThisArg); -internal record MethodCallContext(Val ThisArg); - -internal enum ValKind +public enum ValKind { Pointer, Direct, diff --git a/src/compiler/NubLang/Syntax/Binding/Binder.cs b/src/compiler/NubLang/Syntax/Binding/Binder.cs index 85ab7b9..031c669 100644 --- a/src/compiler/NubLang/Syntax/Binding/Binder.cs +++ b/src/compiler/NubLang/Syntax/Binding/Binder.cs @@ -586,7 +586,7 @@ public sealed class Binder return new BoundBlock(node.Tokens, statements); } - private BoundBlock BindFuncBody(BlockSyntax block, NubType returnType, IEnumerable parameters) + private BoundBlock BindFuncBody(BlockSyntax block, NubType returnType, IReadOnlyList parameters) { _funcReturnTypes.Push(returnType); diff --git a/src/compiler/NubLang/Syntax/Binding/Node/BoundDefinition.cs b/src/compiler/NubLang/Syntax/Binding/Node/BoundDefinition.cs index 5bf7f49..58c6e3c 100644 --- a/src/compiler/NubLang/Syntax/Binding/Node/BoundDefinition.cs +++ b/src/compiler/NubLang/Syntax/Binding/Node/BoundDefinition.cs @@ -3,26 +3,26 @@ using NubLang.Syntax.Tokenization; namespace NubLang.Syntax.Binding.Node; -public abstract record BoundDefinition(IEnumerable Tokens, string Namespace) : BoundNode(Tokens); +public abstract record BoundDefinition(IReadOnlyList Tokens, string Namespace) : BoundNode(Tokens); -public abstract record BoundDefinitionMember(IEnumerable Tokens) : BoundNode(Tokens); +public abstract record BoundDefinitionMember(IReadOnlyList Tokens) : BoundNode(Tokens); -public record BoundFuncParameter(IEnumerable Tokens, string Name, NubType Type) : BoundDefinitionMember(Tokens); +public record BoundFuncParameter(IReadOnlyList Tokens, string Name, NubType Type) : BoundDefinitionMember(Tokens); -public record BoundFuncSignature(IEnumerable Tokens, IEnumerable Parameters, NubType ReturnType) : BoundDefinitionMember(Tokens); +public record BoundFuncSignature(IReadOnlyList Tokens, IReadOnlyList Parameters, NubType ReturnType) : BoundDefinitionMember(Tokens); -public record BoundLocalFunc(IEnumerable Tokens, string Namespace, string Name, BoundFuncSignature Signature, BoundBlock Body) : BoundDefinition(Tokens, Namespace); +public record BoundLocalFunc(IReadOnlyList Tokens, string Namespace, string Name, BoundFuncSignature Signature, BoundBlock Body) : BoundDefinition(Tokens, Namespace); -public record BoundExternFunc(IEnumerable Tokens, string Namespace, string Name, string CallName, BoundFuncSignature Signature) : BoundDefinition(Tokens, Namespace); +public record BoundExternFunc(IReadOnlyList Tokens, string Namespace, string Name, string CallName, BoundFuncSignature Signature) : BoundDefinition(Tokens, Namespace); -public record BoundStructField(IEnumerable Tokens, int Index, string Name, NubType Type, Optional Value) : BoundDefinitionMember(Tokens); +public record BoundStructField(IReadOnlyList Tokens, int Index, string Name, NubType Type, Optional Value) : BoundDefinitionMember(Tokens); -public record BoundStruct(IEnumerable Tokens, string Namespace, string Name, List Fields) : BoundDefinition(Tokens, Namespace); +public record BoundStruct(IReadOnlyList Tokens, string Namespace, string Name, IReadOnlyList Fields) : BoundDefinition(Tokens, Namespace); -public record BoundTraitFunc(IEnumerable Tokens, string Name, BoundFuncSignature Signature) : BoundDefinitionMember(Tokens); +public record BoundTraitFunc(IReadOnlyList Tokens, string Name, BoundFuncSignature Signature) : BoundDefinitionMember(Tokens); -public record BoundTrait(IEnumerable Tokens, string Namespace, string Name, List Functions) : BoundDefinition(Tokens, Namespace); +public record BoundTrait(IReadOnlyList Tokens, string Namespace, string Name, IReadOnlyList Functions) : BoundDefinition(Tokens, Namespace); -public record BoundTraitFuncImpl(IEnumerable Tokens, string Name, BoundFuncSignature Signature, BoundBlock Body) : BoundDefinitionMember(Tokens); +public record BoundTraitFuncImpl(IReadOnlyList Tokens, string Name, BoundFuncSignature Signature, BoundBlock Body) : BoundDefinitionMember(Tokens); -public record BoundTraitImpl(IEnumerable Tokens, string Namespace, NubType TraitType, NubType ForType, List Functions) : BoundDefinition(Tokens, Namespace); \ No newline at end of file +public record BoundTraitImpl(IReadOnlyList Tokens, string Namespace, NubType TraitType, NubType ForType, IReadOnlyList Functions) : BoundDefinition(Tokens, Namespace); \ No newline at end of file diff --git a/src/compiler/NubLang/Syntax/Binding/Node/BoundExpression.cs b/src/compiler/NubLang/Syntax/Binding/Node/BoundExpression.cs index 84b41cc..cafef37 100644 --- a/src/compiler/NubLang/Syntax/Binding/Node/BoundExpression.cs +++ b/src/compiler/NubLang/Syntax/Binding/Node/BoundExpression.cs @@ -22,36 +22,36 @@ public enum BoundBinaryOperator Divide } -public abstract record BoundExpression(IEnumerable Tokens, NubType Type) : BoundNode(Tokens); +public abstract record BoundExpression(IReadOnlyList Tokens, NubType Type) : BoundNode(Tokens); -public record BoundBinaryExpression(IEnumerable Tokens, NubType Type, BoundExpression Left, BoundBinaryOperator Operator, BoundExpression Right) : BoundExpression(Tokens, Type); +public record BoundBinaryExpression(IReadOnlyList Tokens, NubType Type, BoundExpression Left, BoundBinaryOperator Operator, BoundExpression Right) : BoundExpression(Tokens, Type); -public record BoundUnaryExpression(IEnumerable Tokens, NubType Type, BoundUnaryOperator Operator, BoundExpression Operand) : BoundExpression(Tokens, Type); +public record BoundUnaryExpression(IReadOnlyList Tokens, NubType Type, BoundUnaryOperator Operator, BoundExpression Operand) : BoundExpression(Tokens, Type); -public record BoundFuncCall(IEnumerable Tokens, NubType Type, BoundExpression Expression, List Parameters) : BoundExpression(Tokens, Type); +public record BoundFuncCall(IReadOnlyList Tokens, NubType Type, BoundExpression Expression, IReadOnlyList Parameters) : BoundExpression(Tokens, Type); -public record BoundVariableIdent(IEnumerable Tokens, NubType Type, string Name) : BoundExpression(Tokens, Type); +public record BoundVariableIdent(IReadOnlyList Tokens, NubType Type, string Name) : BoundExpression(Tokens, Type); -public record BoundLocalFuncIdent(IEnumerable Tokens, NubType Type, string Namespace, string Name) : BoundExpression(Tokens, Type); +public record BoundLocalFuncIdent(IReadOnlyList Tokens, NubType Type, string Namespace, string Name) : BoundExpression(Tokens, Type); -public record BoundExternFuncIdent(IEnumerable Tokens, NubType Type, string Namespace, string Name) : BoundExpression(Tokens, Type); +public record BoundExternFuncIdent(IReadOnlyList Tokens, NubType Type, string Namespace, string Name) : BoundExpression(Tokens, Type); -public record BoundArrayInitializer(IEnumerable Tokens, NubType Type, BoundExpression Capacity, NubType ElementType) : BoundExpression(Tokens, Type); +public record BoundArrayInitializer(IReadOnlyList Tokens, NubType Type, BoundExpression Capacity, NubType ElementType) : BoundExpression(Tokens, Type); -public record BoundArrayIndexAccess(IEnumerable Tokens, NubType Type, BoundExpression Target, BoundExpression Index) : BoundExpression(Tokens, Type); +public record BoundArrayIndexAccess(IReadOnlyList Tokens, NubType Type, BoundExpression Target, BoundExpression Index) : BoundExpression(Tokens, Type); -public record BoundAnonymousFunc(IEnumerable Tokens, NubType Type, IEnumerable Parameters, NubType ReturnType, BoundBlock Body) : BoundExpression(Tokens, Type); +public record BoundAnonymousFunc(IReadOnlyList Tokens, NubType Type, IReadOnlyList Parameters, NubType ReturnType, BoundBlock Body) : BoundExpression(Tokens, Type); -public record BoundAddressOf(IEnumerable Tokens, NubType Type, BoundExpression Expression) : BoundExpression(Tokens, Type); +public record BoundAddressOf(IReadOnlyList Tokens, NubType Type, BoundExpression Expression) : BoundExpression(Tokens, Type); -public record BoundLiteral(IEnumerable Tokens, NubType Type, string Literal, LiteralKind Kind) : BoundExpression(Tokens, Type); +public record BoundLiteral(IReadOnlyList Tokens, NubType Type, string Literal, LiteralKind Kind) : BoundExpression(Tokens, Type); -public record BoundStructFieldAccess(IEnumerable Tokens, NubType Type, NubCustomType StructType, BoundExpression Target, string Field) : BoundExpression(Tokens, Type); +public record BoundStructFieldAccess(IReadOnlyList Tokens, NubType Type, NubCustomType StructType, BoundExpression Target, string Field) : BoundExpression(Tokens, Type); -public record BoundTraitImplFuncAccess(IEnumerable Tokens, NubType Type, BoundExpression Target, string FuncName) : BoundExpression(Tokens, Type); +public record BoundTraitImplFuncAccess(IReadOnlyList Tokens, NubType Type, BoundExpression Target, string FuncName) : BoundExpression(Tokens, Type); -public record BoundTraitFuncAccess(IEnumerable Tokens, NubType Type, NubCustomType TraitType, BoundExpression Target, string FuncName) : BoundExpression(Tokens, Type); +public record BoundTraitFuncAccess(IReadOnlyList Tokens, NubType Type, NubCustomType TraitType, BoundExpression Target, string FuncName) : BoundExpression(Tokens, Type); -public record BoundStructInitializer(IEnumerable Tokens, NubType Type, NubCustomType StructType, Dictionary Initializers) : BoundExpression(Tokens, Type); +public record BoundStructInitializer(IReadOnlyList Tokens, NubType Type, NubCustomType StructType, Dictionary Initializers) : BoundExpression(Tokens, Type); -public record BoundDereference(IEnumerable Tokens, NubType Type, BoundExpression Expression) : BoundExpression(Tokens, Type); \ No newline at end of file +public record BoundDereference(IReadOnlyList Tokens, NubType Type, BoundExpression Expression) : BoundExpression(Tokens, Type); \ No newline at end of file diff --git a/src/compiler/NubLang/Syntax/Binding/Node/BoundStatement.cs b/src/compiler/NubLang/Syntax/Binding/Node/BoundStatement.cs index 65ec825..cec6a4b 100644 --- a/src/compiler/NubLang/Syntax/Binding/Node/BoundStatement.cs +++ b/src/compiler/NubLang/Syntax/Binding/Node/BoundStatement.cs @@ -3,20 +3,20 @@ using NubLang.Syntax.Tokenization; namespace NubLang.Syntax.Binding.Node; -public record BoundStatement(IEnumerable Tokens) : BoundNode(Tokens); +public record BoundStatement(IReadOnlyList Tokens) : BoundNode(Tokens); -public record BoundStatementExpression(IEnumerable Tokens, BoundExpression Expression) : BoundStatement(Tokens); +public record BoundStatementExpression(IReadOnlyList Tokens, BoundExpression Expression) : BoundStatement(Tokens); -public record BoundReturn(IEnumerable Tokens, Optional Value) : BoundStatement(Tokens); +public record BoundReturn(IReadOnlyList Tokens, Optional Value) : BoundStatement(Tokens); -public record BoundAssignment(IEnumerable Tokens, BoundExpression Target, BoundExpression Value) : BoundStatement(Tokens); +public record BoundAssignment(IReadOnlyList Tokens, BoundExpression Target, BoundExpression Value) : BoundStatement(Tokens); -public record BoundIf(IEnumerable Tokens, BoundExpression Condition, BoundBlock Body, Optional> Else) : BoundStatement(Tokens); +public record BoundIf(IReadOnlyList Tokens, BoundExpression Condition, BoundBlock Body, Optional> Else) : BoundStatement(Tokens); -public record BoundVariableDeclaration(IEnumerable Tokens, string Name, Optional Assignment, NubType Type) : BoundStatement(Tokens); +public record BoundVariableDeclaration(IReadOnlyList Tokens, string Name, Optional Assignment, NubType Type) : BoundStatement(Tokens); -public record BoundContinue(IEnumerable Tokens) : BoundStatement(Tokens); +public record BoundContinue(IReadOnlyList Tokens) : BoundStatement(Tokens); -public record BoundBreak(IEnumerable Tokens) : BoundStatement(Tokens); +public record BoundBreak(IReadOnlyList Tokens) : BoundStatement(Tokens); -public record BoundWhile(IEnumerable Tokens, BoundExpression Condition, BoundBlock Body) : BoundStatement(Tokens); \ No newline at end of file +public record BoundWhile(IReadOnlyList Tokens, BoundExpression Condition, BoundBlock Body) : BoundStatement(Tokens); \ No newline at end of file diff --git a/src/compiler/NubLang/Syntax/Binding/Node/BoundSyntaxTree.cs b/src/compiler/NubLang/Syntax/Binding/Node/BoundSyntaxTree.cs index 1ceb66a..666dd33 100644 --- a/src/compiler/NubLang/Syntax/Binding/Node/BoundSyntaxTree.cs +++ b/src/compiler/NubLang/Syntax/Binding/Node/BoundSyntaxTree.cs @@ -3,8 +3,8 @@ using NubLang.Syntax.Tokenization; namespace NubLang.Syntax.Binding.Node; -public record BoundSyntaxTree(string Namespace, IEnumerable Definitions, IEnumerable Diagnostics); +public record BoundSyntaxTree(string Namespace, IReadOnlyList Definitions, IReadOnlyList Diagnostics); -public abstract record BoundNode(IEnumerable Tokens); +public abstract record BoundNode(IReadOnlyList Tokens); -public record BoundBlock(IEnumerable Tokens, List Statements) : BoundNode(Tokens); \ No newline at end of file +public record BoundBlock(IReadOnlyList Tokens, IReadOnlyList 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 index 07e0cb6..f380a4c 100644 --- a/src/compiler/NubLang/Syntax/Parsing/Node/DefinitionSyntax.cs +++ b/src/compiler/NubLang/Syntax/Parsing/Node/DefinitionSyntax.cs @@ -3,26 +3,26 @@ using NubLang.Syntax.Tokenization; namespace NubLang.Syntax.Parsing.Node; -public abstract record DefinitionSyntax(IEnumerable Tokens, string Namespace) : SyntaxNode(Tokens); +public abstract record DefinitionSyntax(IReadOnlyList Tokens, string Namespace) : SyntaxNode(Tokens); -public abstract record DefinitionMemberSyntax(IEnumerable Tokens) : SyntaxNode(Tokens); +public abstract record DefinitionMemberSyntax(IReadOnlyList Tokens) : SyntaxNode(Tokens); -public record FuncParameterSyntax(IEnumerable Tokens, string Name, NubType Type) : DefinitionMemberSyntax(Tokens); +public record FuncParameterSyntax(IReadOnlyList Tokens, string Name, NubType Type) : DefinitionMemberSyntax(Tokens); -public record FuncSignatureSyntax(IEnumerable Tokens, IEnumerable Parameters, NubType ReturnType) : DefinitionMemberSyntax(Tokens); +public record FuncSignatureSyntax(IReadOnlyList Tokens, IReadOnlyList Parameters, NubType ReturnType) : DefinitionMemberSyntax(Tokens); -public record LocalFuncSyntax(IEnumerable Tokens, string Namespace, string Name, FuncSignatureSyntax Signature, BlockSyntax Body) : DefinitionSyntax(Tokens, Namespace); +public record LocalFuncSyntax(IReadOnlyList Tokens, string Namespace, string Name, FuncSignatureSyntax Signature, BlockSyntax Body) : DefinitionSyntax(Tokens, Namespace); -public record ExternFuncSyntax(IEnumerable Tokens, string Namespace, string Name, string CallName, FuncSignatureSyntax Signature) : DefinitionSyntax(Tokens, Namespace); +public record ExternFuncSyntax(IReadOnlyList Tokens, string Namespace, string Name, string CallName, FuncSignatureSyntax Signature) : DefinitionSyntax(Tokens, Namespace); -public record StructFieldSyntax(IEnumerable Tokens, int Index, string Name, NubType Type, Optional Value) : DefinitionMemberSyntax(Tokens); +public record StructFieldSyntax(IReadOnlyList 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 StructSyntax(IReadOnlyList Tokens, string Namespace, string Name, IReadOnlyList Fields) : DefinitionSyntax(Tokens, Namespace); -public record TraitFuncSyntax(IEnumerable Tokens, string Name, FuncSignatureSyntax Signature) : DefinitionMemberSyntax(Tokens); +public record TraitFuncSyntax(IReadOnlyList Tokens, string Name, FuncSignatureSyntax Signature) : DefinitionMemberSyntax(Tokens); -public record TraitSyntax(IEnumerable Tokens, string Namespace, string Name, List Functions) : DefinitionSyntax(Tokens, Namespace); +public record TraitSyntax(IReadOnlyList Tokens, string Namespace, string Name, IReadOnlyList Functions) : DefinitionSyntax(Tokens, Namespace); -public record TraitFuncImplSyntax(IEnumerable Tokens, string Name, FuncSignatureSyntax Signature, BlockSyntax Body) : DefinitionMemberSyntax(Tokens); +public record TraitFuncImplSyntax(IReadOnlyList Tokens, string Name, FuncSignatureSyntax Signature, 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 +public record TraitImplSyntax(IReadOnlyList Tokens, string Namespace, NubType TraitType, NubType ForType, IReadOnlyList Functions) : DefinitionSyntax(Tokens, Namespace); \ No newline at end of file diff --git a/src/compiler/NubLang/Syntax/Parsing/Node/ExpressionSyntax.cs b/src/compiler/NubLang/Syntax/Parsing/Node/ExpressionSyntax.cs index 1bf3ef0..94ea7da 100644 --- a/src/compiler/NubLang/Syntax/Parsing/Node/ExpressionSyntax.cs +++ b/src/compiler/NubLang/Syntax/Parsing/Node/ExpressionSyntax.cs @@ -23,30 +23,30 @@ public enum BinaryOperator Divide } -public abstract record ExpressionSyntax(IEnumerable Tokens) : SyntaxNode(Tokens); +public abstract record ExpressionSyntax(IReadOnlyList Tokens) : SyntaxNode(Tokens); -public record BinaryExpressionSyntax(IEnumerable Tokens, ExpressionSyntax Left, BinaryOperator Operator, ExpressionSyntax Right) : ExpressionSyntax(Tokens); +public record BinaryExpressionSyntax(IReadOnlyList Tokens, ExpressionSyntax Left, BinaryOperator Operator, ExpressionSyntax Right) : ExpressionSyntax(Tokens); -public record UnaryExpressionSyntax(IEnumerable Tokens, UnaryOperator Operator, ExpressionSyntax Operand) : ExpressionSyntax(Tokens); +public record UnaryExpressionSyntax(IReadOnlyList Tokens, UnaryOperator Operator, ExpressionSyntax Operand) : ExpressionSyntax(Tokens); -public record FuncCallSyntax(IEnumerable Tokens, ExpressionSyntax Expression, List Parameters) : ExpressionSyntax(Tokens); +public record FuncCallSyntax(IReadOnlyList Tokens, ExpressionSyntax Expression, IReadOnlyList Parameters) : ExpressionSyntax(Tokens); -public record IdentifierSyntax(IEnumerable Tokens, Optional Namespace, string Name) : ExpressionSyntax(Tokens); +public record IdentifierSyntax(IReadOnlyList Tokens, Optional Namespace, string Name) : ExpressionSyntax(Tokens); -public record ArrayInitializerSyntax(IEnumerable Tokens, ExpressionSyntax Capacity, NubType ElementType) : ExpressionSyntax(Tokens); +public record ArrayInitializerSyntax(IReadOnlyList Tokens, ExpressionSyntax Capacity, NubType ElementType) : ExpressionSyntax(Tokens); -public record ArrayIndexAccessSyntax(IEnumerable Tokens, ExpressionSyntax Target, ExpressionSyntax Index) : ExpressionSyntax(Tokens); +public record ArrayIndexAccessSyntax(IReadOnlyList Tokens, ExpressionSyntax Target, ExpressionSyntax Index) : ExpressionSyntax(Tokens); -public record AnonymousFuncParameterSyntax(IEnumerable Tokens, string Name) : ExpressionSyntax(Tokens); +public record AnonymousFuncParameterSyntax(IReadOnlyList Tokens, string Name) : ExpressionSyntax(Tokens); -public record AnonymousFuncSyntax(IEnumerable Tokens, List Parameters, BlockSyntax Body) : ExpressionSyntax(Tokens); +public record AnonymousFuncSyntax(IReadOnlyList Tokens, IReadOnlyList Parameters, BlockSyntax Body) : ExpressionSyntax(Tokens); -public record AddressOfSyntax(IEnumerable Tokens, ExpressionSyntax Expression) : ExpressionSyntax(Tokens); +public record AddressOfSyntax(IReadOnlyList Tokens, ExpressionSyntax Expression) : ExpressionSyntax(Tokens); -public record LiteralSyntax(IEnumerable Tokens, string Literal, LiteralKind Kind) : ExpressionSyntax(Tokens); +public record LiteralSyntax(IReadOnlyList Tokens, string Literal, LiteralKind Kind) : ExpressionSyntax(Tokens); -public record MemberAccessSyntax(IEnumerable Tokens, ExpressionSyntax Target, string Member) : ExpressionSyntax(Tokens); +public record MemberAccessSyntax(IReadOnlyList Tokens, ExpressionSyntax Target, string Member) : ExpressionSyntax(Tokens); -public record StructInitializerSyntax(IEnumerable Tokens, NubType StructType, Dictionary Initializers) : ExpressionSyntax(Tokens); +public record StructInitializerSyntax(IReadOnlyList Tokens, NubType StructType, Dictionary Initializers) : ExpressionSyntax(Tokens); -public record DereferenceSyntax(IEnumerable Tokens, ExpressionSyntax Expression) : ExpressionSyntax(Tokens); \ No newline at end of file +public record DereferenceSyntax(IReadOnlyList Tokens, ExpressionSyntax Expression) : ExpressionSyntax(Tokens); \ No newline at end of file diff --git a/src/compiler/NubLang/Syntax/Parsing/Node/StatementSyntax.cs b/src/compiler/NubLang/Syntax/Parsing/Node/StatementSyntax.cs index 7e15cb1..7a1ec02 100644 --- a/src/compiler/NubLang/Syntax/Parsing/Node/StatementSyntax.cs +++ b/src/compiler/NubLang/Syntax/Parsing/Node/StatementSyntax.cs @@ -3,20 +3,20 @@ using NubLang.Syntax.Tokenization; namespace NubLang.Syntax.Parsing.Node; -public record StatementSyntax(IEnumerable Tokens) : SyntaxNode(Tokens); +public record StatementSyntax(IReadOnlyList Tokens) : SyntaxNode(Tokens); -public record StatementExpressionSyntax(IEnumerable Tokens, ExpressionSyntax Expression) : StatementSyntax(Tokens); +public record StatementExpressionSyntax(IReadOnlyList Tokens, ExpressionSyntax Expression) : StatementSyntax(Tokens); -public record ReturnSyntax(IEnumerable Tokens, Optional Value) : StatementSyntax(Tokens); +public record ReturnSyntax(IReadOnlyList Tokens, Optional Value) : StatementSyntax(Tokens); -public record AssignmentSyntax(IEnumerable Tokens, ExpressionSyntax Target, ExpressionSyntax Value) : StatementSyntax(Tokens); +public record AssignmentSyntax(IReadOnlyList Tokens, ExpressionSyntax Target, ExpressionSyntax Value) : StatementSyntax(Tokens); -public record IfSyntax(IEnumerable Tokens, ExpressionSyntax Condition, BlockSyntax Body, Optional> Else) : StatementSyntax(Tokens); +public record IfSyntax(IReadOnlyList Tokens, ExpressionSyntax Condition, BlockSyntax Body, Optional> Else) : StatementSyntax(Tokens); -public record VariableDeclarationSyntax(IEnumerable Tokens, string Name, Optional ExplicitType, Optional Assignment) : StatementSyntax(Tokens); +public record VariableDeclarationSyntax(IReadOnlyList Tokens, string Name, Optional ExplicitType, Optional Assignment) : StatementSyntax(Tokens); -public record ContinueSyntax(IEnumerable Tokens) : StatementSyntax(Tokens); +public record ContinueSyntax(IReadOnlyList Tokens) : StatementSyntax(Tokens); -public record BreakSyntax(IEnumerable Tokens) : StatementSyntax(Tokens); +public record BreakSyntax(IReadOnlyList Tokens) : StatementSyntax(Tokens); -public record WhileSyntax(IEnumerable Tokens, ExpressionSyntax Condition, BlockSyntax Body) : StatementSyntax(Tokens); \ No newline at end of file +public record WhileSyntax(IReadOnlyList 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 index bcbbd9b..fee54d1 100644 --- a/src/compiler/NubLang/Syntax/Parsing/Node/SyntaxTree.cs +++ b/src/compiler/NubLang/Syntax/Parsing/Node/SyntaxTree.cs @@ -3,8 +3,8 @@ using NubLang.Syntax.Tokenization; namespace NubLang.Syntax.Parsing.Node; -public record SyntaxTree(string Namespace, IEnumerable Definitions, IEnumerable Diagnostics); +public record SyntaxTree(string Namespace, IReadOnlyList Definitions, IReadOnlyList Diagnostics); -public abstract record SyntaxNode(IEnumerable Tokens); +public abstract record SyntaxNode(IReadOnlyList Tokens); -public record BlockSyntax(IEnumerable Tokens, IEnumerable Statements) : SyntaxNode(Tokens); \ No newline at end of file +public record BlockSyntax(IReadOnlyList Tokens, IReadOnlyList 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 33caa09..738bbc1 100644 --- a/src/compiler/NubLang/Syntax/Parsing/Parser.cs +++ b/src/compiler/NubLang/Syntax/Parsing/Parser.cs @@ -9,12 +9,12 @@ namespace NubLang.Syntax.Parsing; public sealed class Parser { private string _namespace; - private readonly IEnumerable _tokens; + private readonly IReadOnlyList _tokens; private readonly List _diagnostics = []; private int _tokenIndex; - public Parser(IEnumerable tokens) + public Parser(IReadOnlyList tokens) { _namespace = "default"; _tokens = tokens; @@ -815,9 +815,9 @@ public sealed class Parser _tokenIndex++; } - private IEnumerable GetTokens(int startIndex) + private List GetTokens(int startIndex) { - return _tokens.Skip(startIndex).Take(Math.Min(_tokenIndex, _tokens.Count() - 1) - startIndex); + return _tokens.Skip(startIndex).Take(Math.Min(_tokenIndex, _tokens.Count() - 1) - startIndex).ToList(); } } diff --git a/src/compiler/NubLang/Syntax/Tokenization/Tokenizer.cs b/src/compiler/NubLang/Syntax/Tokenization/Tokenizer.cs index f8fb7f6..ed60ec5 100644 --- a/src/compiler/NubLang/Syntax/Tokenization/Tokenizer.cs +++ b/src/compiler/NubLang/Syntax/Tokenization/Tokenizer.cs @@ -66,7 +66,7 @@ public sealed class Tokenizer _sourceText = sourceText; } - public IEnumerable Tokenize(out IEnumerable diagnostics) + public IReadOnlyList Tokenize(out IReadOnlyList diagnostics) { _index = 0;