diff --git a/src/compiler/NubLang.CLI/Options.cs b/src/compiler/NubLang.CLI/Options.cs index 2ff86cb..d3efdd7 100644 --- a/src/compiler/NubLang.CLI/Options.cs +++ b/src/compiler/NubLang.CLI/Options.cs @@ -1,3 +1,5 @@ +using NubLang.Code; + namespace NubLang.CLI; public class Options @@ -5,5 +7,5 @@ public class Options public string? CustomRuntime { get; set; } public string? OutputPath { get; set; } public bool Link { get; set; } = true; - public List Files { get; } = []; + public List Files { get; } = []; } \ No newline at end of file diff --git a/src/compiler/NubLang.CLI/Program.cs b/src/compiler/NubLang.CLI/Program.cs index de4b364..8baec03 100644 --- a/src/compiler/NubLang.CLI/Program.cs +++ b/src/compiler/NubLang.CLI/Program.cs @@ -1,6 +1,6 @@ using System.Reflection; using NubLang.CLI; -using NubLang; +using NubLang.Code; using NubLang.Common; using NubLang.Diagnostics; using NubLang.Generation; @@ -62,16 +62,16 @@ for (var i = 0; i < args.Length; i++) } else { - options.Files.Add(arg); + options.Files.Add(new SourceFile(arg)); } } var diagnostics = new List(); -var syntaxTrees = new Dictionary(); +var syntaxTrees = new List(); foreach (var file in options.Files) { - if (!File.Exists(file)) + if (!File.Exists(file.Path)) { Console.Error.WriteLine($"File '{file}' does not exist"); return 1; @@ -80,30 +80,27 @@ foreach (var file in options.Files) foreach (var file in options.Files) { - var content = File.ReadAllText(file); - var sourceText = new SourceText(file, content); - - var tokenizer = new Tokenizer(sourceText); + var tokenizer = new Tokenizer(file.GetText()); var tokenizeResult = tokenizer.Tokenize(out var tokenizerDiagnostics); diagnostics.AddRange(tokenizerDiagnostics); var parser = new Parser(tokenizeResult); - var syntaxTree = parser.Parse(); - diagnostics.AddRange(syntaxTree.Diagnostics); + var syntaxTree = parser.Parse(out var parserDiagnostics); + diagnostics.AddRange(parserDiagnostics); - syntaxTrees[file] = syntaxTree; + syntaxTrees.Add(syntaxTree); } -var definitionTable = new DefinitionTable(syntaxTrees.Values); +var definitionTable = new DefinitionTable(syntaxTrees); -var boundSyntaxTrees = new Dictionary(); +var boundSyntaxTrees = new List(); -foreach (var (file, syntaxTree) in syntaxTrees) +foreach (var syntaxTree in syntaxTrees) { var binder = new Binder(syntaxTree, definitionTable); var boundSyntaxTree = binder.Bind(); diagnostics.AddRange(boundSyntaxTree.Diagnostics); - boundSyntaxTrees[file] = boundSyntaxTree; + boundSyntaxTrees.Add(boundSyntaxTree); } foreach (var diagnostic in diagnostics) @@ -116,15 +113,15 @@ if (diagnostics.Any(diagnostic => diagnostic.Severity == DiagnosticSeverity.Erro return 1; } -var boundDefinitionTable = new BoundDefinitionTable(boundSyntaxTrees.Values); +var boundDefinitionTable = new BoundDefinitionTable(boundSyntaxTrees); var objectFiles = new List(); -foreach (var file in options.Files) +foreach (var syntaxTree in boundSyntaxTrees) { - var outFileName = $"{HexString.CreateUnique(8)}_{Path.GetFileNameWithoutExtension(file)}"; + var outFileName = HexString.CreateUnique(8); - var generator = new QBEGenerator(boundSyntaxTrees[file], boundDefinitionTable, file); + var generator = new QBEGenerator(syntaxTree, boundDefinitionTable); var ssa = generator.Emit(); File.WriteAllText(Path.Join(INT_DEBUG_DIR, $"{outFileName}.ssa"), ssa); diff --git a/src/compiler/NubLang/Code/SourceFile.cs b/src/compiler/NubLang/Code/SourceFile.cs new file mode 100644 index 0000000..0b39ce5 --- /dev/null +++ b/src/compiler/NubLang/Code/SourceFile.cs @@ -0,0 +1,29 @@ +namespace NubLang.Code; + +public class SourceFile +{ + private string? _content; + + public SourceFile(string path) + { + Path = path ?? throw new ArgumentNullException(nameof(path)); + } + + public string Path { get; } + + public string GetText() => _content ??= File.ReadAllText(Path); + public override string ToString() => Path; + + public override bool Equals(object? obj) + { + return obj is SourceFile other && other.Path == Path; + } + + public override int GetHashCode() + { + return HashCode.Combine(typeof(SourceFile), Path); + } + + public static bool operator ==(SourceFile? left, SourceFile? right) => Equals(left, right); + public static bool operator !=(SourceFile? left, SourceFile? right) => !Equals(left, right); +} \ No newline at end of file diff --git a/src/compiler/NubLang/Code/SourceLocation.cs b/src/compiler/NubLang/Code/SourceLocation.cs new file mode 100644 index 0000000..6574b4f --- /dev/null +++ b/src/compiler/NubLang/Code/SourceLocation.cs @@ -0,0 +1,53 @@ +namespace NubLang.Code; + +public readonly struct SourceLocation : IEquatable +{ + public static SourceLocation Zero => new(0, 0); + + public SourceLocation(int line, int column) + { + Line = line; + Column = column; + } + + public int Line { get; } + public int Column { get; } + + public override string ToString() + { + return $"{Line}:{Column}"; + } + + public int CompareTo(SourceLocation other) + { + var lineComparison = Line.CompareTo(other.Line); + if (lineComparison == 0) + { + return Column.CompareTo(other.Column); + } + + return lineComparison; + } + + public override bool Equals(object? obj) + { + return obj is SourceLocation other && Equals(other); + } + + public bool Equals(SourceLocation other) + { + return Line == other.Line && Column == other.Column; + } + + public override int GetHashCode() + { + return HashCode.Combine(typeof(SourceLocation), Line, Column); + } + + public static bool operator ==(SourceLocation left, SourceLocation right) => Equals(left, right); + public static bool operator !=(SourceLocation left, SourceLocation right) => !Equals(left, right); + public static bool operator <(SourceLocation left, SourceLocation right) => left.Line < right.Line || (left.Line == right.Line && left.Column < right.Column); + public static bool operator >(SourceLocation left, SourceLocation right) => left.Line > right.Line || (left.Line == right.Line && left.Column > right.Column); + public static bool operator <=(SourceLocation left, SourceLocation right) => left.Line <= right.Line || (left.Line == right.Line && left.Column <= right.Column); + public static bool operator >=(SourceLocation left, SourceLocation right) => left.Line >= right.Line || (left.Line == right.Line && left.Column >= right.Column); +} \ No newline at end of file diff --git a/src/compiler/NubLang/Code/SourceSpan.cs b/src/compiler/NubLang/Code/SourceSpan.cs new file mode 100644 index 0000000..3e7a89b --- /dev/null +++ b/src/compiler/NubLang/Code/SourceSpan.cs @@ -0,0 +1,57 @@ +namespace NubLang.Code; + +public readonly struct SourceSpan : IEquatable +{ + public static SourceSpan Zero => new(SourceLocation.Zero, SourceLocation.Zero); + + public static SourceSpan Merge(params IEnumerable spans) + { + var spanArray = spans as SourceSpan[] ?? spans.ToArray(); + + if (spanArray.Length == 0) + { + return Zero; + } + + var minStart = spanArray.Min(s => s.Start); + var maxEnd = spanArray.Max(s => s.End); + + return new SourceSpan(minStart, maxEnd); + } + + public SourceSpan(SourceLocation start, SourceLocation end) + { + if (start > end) + { + throw new ArgumentException("Start location cannot be after end location"); + } + + Start = start; + End = end; + } + + public SourceLocation Start { get; } + public SourceLocation End { get; } + + public override string ToString() + { + if (Start == End) + { + return $"{Start}"; + } + + if (Start.Line == End.Line) + { + return Start.Column == End.Column ? $"{Start}" : $"{Start.Line}:{Start.Column}-{End.Column}"; + } + + return $"{Start}-{End}"; + } + + public bool Equals(SourceSpan other) => Start == other.Start && End == other.End; + public override bool Equals(object? obj) => obj is SourceSpan other && Equals(other); + public override int GetHashCode() => HashCode.Combine(typeof(SourceSpan), Start, End); + + public static bool operator ==(SourceSpan left, SourceSpan right) => Equals(left, right); + public static bool operator !=(SourceSpan left, SourceSpan right) => !Equals(left, right); +} \ No newline at end of file diff --git a/src/compiler/NubLang/Diagnostics/ConsoleColors.cs b/src/compiler/NubLang/Diagnostics/ConsoleColors.cs index 086a46f..1a6f7a3 100644 --- a/src/compiler/NubLang/Diagnostics/ConsoleColors.cs +++ b/src/compiler/NubLang/Diagnostics/ConsoleColors.cs @@ -1,6 +1,3 @@ -using System.Text; -using NubLang.Syntax.Tokenization; - namespace NubLang.Diagnostics; public static class ConsoleColors @@ -56,118 +53,4 @@ public static class ConsoleColors { return IsColorSupported() ? $"{color}{text}{Reset}" : text; } - - private static string GetTokenColor(Token token) - { - switch (token) - { - case IdentifierToken: - return White; - case LiteralToken literal: - return literal.Kind switch - { - LiteralKind.String => Green, - LiteralKind.Integer or LiteralKind.Float => BrightBlue, - LiteralKind.Bool => Blue, - _ => White - }; - case SymbolToken symbol: - switch (symbol.Symbol) - { - case Symbol.If: - case Symbol.Else: - case Symbol.While: - case Symbol.Break: - case Symbol.Continue: - case Symbol.Return: - return Magenta; - case Symbol.Func: - case Symbol.Struct: - case Symbol.Namespace: - case Symbol.Let: - case Symbol.Alloc: - return Blue; - case Symbol.Assign: - case Symbol.Bang: - case Symbol.Equal: - case Symbol.NotEqual: - case Symbol.LessThan: - case Symbol.LessThanOrEqual: - case Symbol.GreaterThan: - case Symbol.GreaterThanOrEqual: - case Symbol.Plus: - case Symbol.Minus: - case Symbol.Star: - case Symbol.ForwardSlash: - case Symbol.Caret: - case Symbol.Ampersand: - return White; - case Symbol.Colon: - case Symbol.Comma: - case Symbol.Period: - case Symbol.DoubleColon: - return Faint; - case Symbol.OpenParen: - case Symbol.CloseParen: - case Symbol.OpenBrace: - case Symbol.CloseBrace: - case Symbol.OpenBracket: - case Symbol.CloseBracket: - return Yellow; - default: - return White; - } - default: - return White; - } - } - - public static string ColorizeSource(string source) - { - var sourceText = new SourceText(string.Empty, source); - var tokenizer = new Tokenizer(sourceText); - var tokens = tokenizer.Tokenize(out _); - var result = new StringBuilder(); - var lastCharIndex = 0; - - foreach (var token in tokens) - { - var tokenStartIndex = GetCharacterIndex(sourceText, token.Span.Start); - var tokenEndIndex = GetCharacterIndex(sourceText, token.Span.End); - - if (tokenStartIndex > lastCharIndex) - { - var between = sourceText.Content.Substring(lastCharIndex, tokenStartIndex - lastCharIndex); - result.Append(between); - } - - var tokenText = sourceText.Content.Substring(tokenStartIndex, tokenEndIndex - tokenStartIndex); - - result.Append(Colorize(tokenText, GetTokenColor(token))); - lastCharIndex = tokenEndIndex; - } - - if (lastCharIndex < sourceText.Content.Length) - { - var remaining = sourceText.Content[lastCharIndex..]; - result.Append(Colorize(remaining, Faint)); - } - - return result.ToString(); - } - - private static int GetCharacterIndex(SourceText sourceText, SourceLocation location) - { - var lines = sourceText.Content.Split('\n'); - var index = 0; - - for (var i = 0; i < location.Line - 1 && i < lines.Length; i++) - { - index += lines[i].Length + 1; - } - - index += location.Column - 1; - - return Math.Min(index, sourceText.Content.Length); - } } \ No newline at end of file diff --git a/src/compiler/NubLang/Diagnostics/Diagnostic.cs b/src/compiler/NubLang/Diagnostics/Diagnostic.cs index 75370fb..096101d 100644 --- a/src/compiler/NubLang/Diagnostics/Diagnostic.cs +++ b/src/compiler/NubLang/Diagnostics/Diagnostic.cs @@ -1,6 +1,4 @@ using System.Text; -using NubLang.Syntax.Parsing.Node; -using NubLang.Syntax.Tokenization; namespace NubLang.Diagnostics; @@ -11,7 +9,6 @@ public class Diagnostic private readonly DiagnosticSeverity _severity; private readonly string _message; private string? _help; - private SourceSpan? _sourceSpan; public DiagnosticBuilder(DiagnosticSeverity severity, string message) { @@ -19,31 +16,13 @@ public class Diagnostic _message = message; } - public DiagnosticBuilder At(Token token) - { - _sourceSpan = token.Span; - return this; - } - - public DiagnosticBuilder At(SyntaxNode node) - { - _sourceSpan = SourceSpan.Merge(node.Tokens.Select(t => t.Span)); - return this; - } - - public DiagnosticBuilder At(SourceSpan span) - { - _sourceSpan = span; - return this; - } - public DiagnosticBuilder WithHelp(string help) { _help = help; return this; } - public Diagnostic Build() => new(_severity, _message, _sourceSpan, _help); + public Diagnostic Build() => new(_severity, _message, _help); } public static DiagnosticBuilder Error(string message) => new(DiagnosticSeverity.Error, message); @@ -52,14 +31,12 @@ public class Diagnostic public DiagnosticSeverity Severity { get; } public string Message { get; } - public SourceSpan? Span { get; } public string? Help { get; } - private Diagnostic(DiagnosticSeverity severity, string message, SourceSpan? span, string? help) + private Diagnostic(DiagnosticSeverity severity, string message, string? help) { Severity = severity; Message = message; - Span = span; Help = help; } @@ -70,21 +47,9 @@ public class Diagnostic var severityText = GetSeverityText(Severity); sb.Append(severityText); - if (Span.HasValue) - { - var locationText = $" at {Span.Value.Text.Path}:{Span}"; - sb.Append(ConsoleColors.Colorize(locationText, ConsoleColors.Faint)); - } - sb.Append(": "); sb.Append(ConsoleColors.Colorize(Message, ConsoleColors.BrightWhite)); - if (Span.HasValue) - { - sb.AppendLine(); - AppendSourceContext(sb, Span.Value, Severity); - } - if (!string.IsNullOrEmpty(Help)) { sb.AppendLine(); @@ -104,107 +69,6 @@ public class Diagnostic _ => throw new ArgumentOutOfRangeException(nameof(severity), severity, "Unknown diagnostic severity") }; } - - private static void AppendSourceContext(StringBuilder sb, SourceSpan span, DiagnosticSeverity severity) - { - var lines = span.Text.Content.Split('\n'); - var startLine = span.Start.Line; - var endLine = span.End.Line; - - const int contextLines = 3; - - var lineNumWidth = Math.Min(endLine + contextLines, lines.Length).ToString().Length; - - var contextStart = Math.Max(1, startLine - contextLines); - var contextEnd = Math.Min(lines.Length, endLine + contextLines); - - var contextWidth = 0; - for (var i = contextStart; i <= contextEnd; i++) - { - if (lines[i - 1].Length > contextWidth) - { - contextWidth = lines[i - 1].Length; - } - } - - sb.AppendLine(ConsoleColors.Colorize('╭' + new string('─', lineNumWidth + 2) + '┬' + new string('─', contextWidth + 2) + '╮', ConsoleColors.Faint)); - - for (var lineNum = contextStart; lineNum < startLine; lineNum++) - { - AppendContextLine(sb, lineNum, lines[lineNum - 1], lineNumWidth, contextWidth); - } - - for (var lineNum = startLine; lineNum <= endLine; lineNum++) - { - AppendContextLine(sb, lineNum, lines[lineNum - 1], lineNumWidth, contextWidth); - AppendErrorIndicators(sb, span, lineNum, lines[lineNum - 1], lineNumWidth, contextWidth, severity); - } - - for (var lineNum = endLine + 1; lineNum <= contextEnd; lineNum++) - { - AppendContextLine(sb, lineNum, lines[lineNum - 1], lineNumWidth, contextWidth); - } - - sb.Append(ConsoleColors.Colorize('╰' + new string('─', lineNumWidth + 2) + '┴' + new string('─', contextWidth + 2) + '╯', ConsoleColors.Faint)); - } - - private static void AppendContextLine(StringBuilder sb, int lineNum, string line, int lineNumWidth, int contextWidth) - { - sb.Append(ConsoleColors.Colorize('│' + " ", ConsoleColors.Faint)); - var lineNumStr = lineNum.ToString().PadLeft(lineNumWidth); - sb.Append(ConsoleColors.Colorize(lineNumStr, ConsoleColors.Faint)); - sb.Append(ConsoleColors.Colorize(" │ ", ConsoleColors.Faint)); - sb.Append(ConsoleColors.ColorizeSource(line.PadRight(contextWidth))); - sb.Append(ConsoleColors.Colorize(" " + '│', ConsoleColors.Faint)); - sb.AppendLine(); - } - - private static void AppendErrorIndicators(StringBuilder sb, SourceSpan span, int lineNum, string line, int lineNumWidth, int contextWidth, DiagnosticSeverity severity) - { - var color = severity switch - { - DiagnosticSeverity.Info => ConsoleColors.Blue, - DiagnosticSeverity.Warning => ConsoleColors.Yellow, - DiagnosticSeverity.Error => ConsoleColors.Red, - _ => throw new ArgumentOutOfRangeException(nameof(severity), severity, null) - }; - - sb.Append(ConsoleColors.Colorize('│' + " ", ConsoleColors.Faint)); - sb.Append(new string(' ', lineNumWidth)); - sb.Append(ConsoleColors.Colorize(" │ ", ConsoleColors.Faint)); - var indicators = GetIndicatorsForLine(span, lineNum, line); - sb.Append(ConsoleColors.Colorize(indicators.PadRight(contextWidth), color)); - sb.Append(ConsoleColors.Colorize(" " + '│', ConsoleColors.Faint)); - sb.AppendLine(); - } - - private static string GetIndicatorsForLine(SourceSpan span, int lineNum, string line) - { - const char indicator = '^'; - - if (lineNum == span.Start.Line && lineNum == span.End.Line) - { - var startCol = Math.Max(0, span.Start.Column - 1); - var endCol = Math.Min(line.Length, span.End.Column - 1); - var length = Math.Max(1, endCol - startCol); - - return new string(' ', startCol) + new string(indicator, length); - } - - if (lineNum == span.Start.Line) - { - var startCol = Math.Max(0, span.Start.Column - 1); - return new string(' ', startCol) + new string(indicator, Math.Max(0, line.Length - startCol)); - } - - if (lineNum == span.End.Line) - { - var endCol = Math.Min(line.Length, span.End.Column - 1); - return new string(indicator, Math.Max(0, endCol)); - } - - return new string(indicator, line.Length); - } } public enum DiagnosticSeverity diff --git a/src/compiler/NubLang/Generation/QBE/QBEGenerator.Expression.cs b/src/compiler/NubLang/Generation/QBE/QBEGenerator.Expression.cs index 754cd07..e26fd6c 100644 --- a/src/compiler/NubLang/Generation/QBE/QBEGenerator.Expression.cs +++ b/src/compiler/NubLang/Generation/QBE/QBEGenerator.Expression.cs @@ -10,8 +10,6 @@ public partial class QBEGenerator { private Val EmitExpression(BoundExpression expression) { - _writer.WriteDebugLocation(expression); - return expression switch { BoundArrayInitializer arrayInitializer => EmitArrayInitializer(arrayInitializer), @@ -27,8 +25,7 @@ public partial class QBEGenerator BoundLiteral literal => EmitLiteral(literal), BoundUnaryExpression unaryExpression => EmitUnaryExpression(unaryExpression), BoundStructFieldAccess structFieldAccess => EmitStructFieldAccess(structFieldAccess), - BoundTraitFuncAccess traitFuncAccess => EmitTraitFuncAccess(traitFuncAccess), - BoundTraitImplFuncAccess traitImplFuncAccess => EmitTraitImplFuncAccess(traitImplFuncAccess), + BoundInterfaceFuncAccess traitFuncAccess => EmitTraitFuncAccess(traitFuncAccess), BoundArrayIndexAccess arrayIndex => EmitArrayIndexAccess(arrayIndex), _ => throw new ArgumentOutOfRangeException(nameof(expression)) }; @@ -418,22 +415,11 @@ public partial class QBEGenerator return new Val(output, structFieldAccess.Type, ValKind.Pointer); } - private Val EmitTraitFuncAccess(BoundTraitFuncAccess traitFuncAccess) + private Val EmitTraitFuncAccess(BoundInterfaceFuncAccess interfaceFuncAccess) { throw new NotImplementedException(); } - private Val EmitTraitImplFuncAccess(BoundTraitImplFuncAccess traitImplFuncAccess) - { - var target = EmitExpression(traitImplFuncAccess.Target); - - var funcImpl = _definitionTable.LookupTraitFuncImpl(traitImplFuncAccess.Target.Type, traitImplFuncAccess.FuncName); - - var name = ImplFuncName(); - _implFunctions.TryAdd(funcImpl, name); - return new Val(name, traitImplFuncAccess.Type, ValKind.Direct, new MethodCallContext(target)); - } - private Val EmitFuncCall(BoundFuncCall funcCall) { var expression = EmitExpression(funcCall.Expression); @@ -441,12 +427,6 @@ public partial class QBEGenerator var parameterStrings = new List(); - if (expression.FuncCallContext != null) - { - var thisArg = EmitUnwrap(expression.FuncCallContext.ThisArg); - parameterStrings.Add($"{FuncQBETypeName(expression.FuncCallContext.ThisArg.Type)} {thisArg}"); - } - foreach (var parameter in funcCall.Parameters) { var copy = EmitCreateCopyOrInitialize(parameter); diff --git a/src/compiler/NubLang/Generation/QBE/QBEGenerator.Statement.cs b/src/compiler/NubLang/Generation/QBE/QBEGenerator.Statement.cs index 1d4053b..2b8853a 100644 --- a/src/compiler/NubLang/Generation/QBE/QBEGenerator.Statement.cs +++ b/src/compiler/NubLang/Generation/QBE/QBEGenerator.Statement.cs @@ -7,8 +7,6 @@ public partial class QBEGenerator { private void EmitStatement(BoundStatement statement) { - _writer.WriteDebugLocation(statement); - switch (statement) { case BoundAssignment assignment: diff --git a/src/compiler/NubLang/Generation/QBE/QBEGenerator.cs b/src/compiler/NubLang/Generation/QBE/QBEGenerator.cs index d2da756..b53dd19 100644 --- a/src/compiler/NubLang/Generation/QBE/QBEGenerator.cs +++ b/src/compiler/NubLang/Generation/QBE/QBEGenerator.cs @@ -18,23 +18,21 @@ public partial class QBEGenerator private readonly Stack _breakLabels = []; private readonly Stack _continueLabels = []; private readonly Queue<(BoundArrowFunc Func, string Name)> _arrowFunctions = []; - private readonly Dictionary _implFunctions = []; private readonly Stack _scopes = []; private int _tmpIndex; private int _labelIndex; private int _arrowFuncIndex; private int _cStringLiteralIndex; private int _stringLiteralIndex; - private int _implFuncNameIndex; private bool _codeIsReachable = true; private Scope Scope => _scopes.Peek(); - public QBEGenerator(BoundSyntaxTree syntaxTree, BoundDefinitionTable definitionTable, string file) + public QBEGenerator(BoundSyntaxTree syntaxTree, BoundDefinitionTable definitionTable) { _syntaxTree = syntaxTree; _definitionTable = definitionTable; - _writer = new QBEWriter(file); + _writer = new QBEWriter(); } public string Emit() @@ -44,14 +42,12 @@ public partial class QBEGenerator _breakLabels.Clear(); _continueLabels.Clear(); _arrowFunctions.Clear(); - _implFunctions.Clear(); _scopes.Clear(); _tmpIndex = 0; _labelIndex = 0; _arrowFuncIndex = 0; _cStringLiteralIndex = 0; _stringLiteralIndex = 0; - _implFuncNameIndex = 0; _codeIsReachable = true; foreach (var structDef in _definitionTable.GetStructs()) @@ -78,12 +74,6 @@ public partial class QBEGenerator _writer.NewLine(); } - foreach (var (impl, name) in _implFunctions) - { - EmitFuncDefinition(name, impl.Signature.Parameters, impl.Signature.ReturnType, impl.Body); - _writer.NewLine(); - } - foreach (var cStringLiteral in _cStringLiterals) { _writer.WriteLine($"data {cStringLiteral.Name} = {{ b \"{cStringLiteral.Value}\", b 0 }}"); @@ -207,19 +197,16 @@ public partial class QBEGenerator { case BoundArrayInitializer arrayInitializer: { - _writer.WriteDebugLocation(arrayInitializer); EmitStore(source.Type, EmitUnwrap(EmitArrayInitializer(arrayInitializer)), destinationPointer); return true; } case BoundStructInitializer structInitializer: { - _writer.WriteDebugLocation(structInitializer); EmitStructInitializer(structInitializer, destinationPointer); return true; } case BoundLiteral { Kind: LiteralKind.String } literal: { - _writer.WriteDebugLocation(literal); EmitStore(source.Type, EmitUnwrap(EmitLiteral(literal)), destinationPointer); return true; } @@ -521,11 +508,6 @@ public partial class QBEGenerator return $"${funcDef.CallName}"; } - private string ImplFuncName() - { - return $"$impl{++_implFuncNameIndex}"; - } - private string CustomTypeName(NubCustomType customType) { return CustomTypeName(customType.Namespace, customType.Name); @@ -551,7 +533,7 @@ public class CStringLiteral(string value, string name) public string Name { get; } = name; } -public record Val(string Name, NubType Type, ValKind Kind, MethodCallContext? FuncCallContext = null); +public record Val(string Name, NubType Type, ValKind Kind); public class Scope(Scope? parent = null) { @@ -579,8 +561,6 @@ public class Scope(Scope? parent = null) } } -public record MethodCallContext(Val ThisArg); - public enum ValKind { Pointer, diff --git a/src/compiler/NubLang/Generation/QBE/QBEWriter.cs b/src/compiler/NubLang/Generation/QBE/QBEWriter.cs index 08e1a59..023eb56 100644 --- a/src/compiler/NubLang/Generation/QBE/QBEWriter.cs +++ b/src/compiler/NubLang/Generation/QBE/QBEWriter.cs @@ -1,22 +1,13 @@ using System.Text; -using NubLang.Syntax.Binding.Node; namespace NubLang.Generation.QBE; internal class QBEWriter { private readonly StringBuilder _builder = new(); - private int _currentLine = -1; - - public QBEWriter(string debugFile) - { - _builder.AppendLine($"dbgfile \"{debugFile}\""); - _builder.AppendLine(); - } public void StartFunction(string signature) { - _currentLine = -1; _builder.Append(signature); _builder.AppendLine(" {"); _builder.AppendLine("@start"); @@ -27,26 +18,6 @@ internal class QBEWriter _builder.AppendLine("}"); } - private void WriteDebugLocation(SourceSpan span) - { - var line = span.Start.Line; - - if (_currentLine != line) - { - _builder.AppendLine($" dbgloc {line}"); - _currentLine = line; - } - } - - public void WriteDebugLocation(BoundNode node) - { - var firstToken = node.Tokens.FirstOrDefault(); - if (firstToken != null) - { - // WriteDebugLocation(firstToken.Span); - } - } - public void Indented(string value) { _builder.Append('\t'); diff --git a/src/compiler/NubLang/Source.cs b/src/compiler/NubLang/Source.cs deleted file mode 100644 index 3f941fe..0000000 --- a/src/compiler/NubLang/Source.cs +++ /dev/null @@ -1,274 +0,0 @@ -using System.Diagnostics.CodeAnalysis; - -namespace NubLang; - -/// -/// Represents a location in source code with line and column information. -/// Lines and columns are 1-based to match typical editor conventions. -/// -public readonly struct SourceLocation : IEquatable, IComparable -{ - public SourceLocation(int line, int column) - { - if (line < 1) - { - throw new ArgumentOutOfRangeException(nameof(line), "Line must be >= 1"); - } - - if (column < 1) - { - throw new ArgumentOutOfRangeException(nameof(column), "Column must be >= 1"); - } - - Line = line; - Column = column; - } - - public int Line { get; } - public int Column { get; } - - public int CompareTo(SourceLocation other) - { - var lineComparison = Line.CompareTo(other.Line); - if (lineComparison == 0) - { - return Column.CompareTo(other.Column); - } - - return lineComparison; - } - - public override string ToString() - { - return $"{Line}:{Column}"; - } - - public bool Equals(SourceLocation other) - { - return Line == other.Line && Column == other.Column; - } - - public override bool Equals([NotNullWhen(true)] object? obj) - { - return obj is SourceLocation other && Equals(other); - } - - public override int GetHashCode() - { - return HashCode.Combine(Line, Column); - } - - public static bool operator ==(SourceLocation left, SourceLocation right) => left.Equals(right); - public static bool operator !=(SourceLocation left, SourceLocation right) => !left.Equals(right); - public static bool operator <(SourceLocation left, SourceLocation right) => left.CompareTo(right) < 0; - public static bool operator >(SourceLocation left, SourceLocation right) => left.CompareTo(right) > 0; - public static bool operator <=(SourceLocation left, SourceLocation right) => left.CompareTo(right) <= 0; - public static bool operator >=(SourceLocation left, SourceLocation right) => left.CompareTo(right) >= 0; -} - -/// -/// Represents source text with a name (typically filename) and content. -/// Equality is based on both name and content for better semantics. -/// -public struct SourceText : IEquatable -{ - private int _lines = -1; - - public SourceText(string path, string content) - { - Path = path ?? throw new ArgumentNullException(nameof(path)); - Content = content ?? throw new ArgumentNullException(nameof(content)); - } - - public string Path { get; } - public string Content { get; } - - public int LineCount() - { - if (_lines == -1) - { - _lines = Content.Split('\n').Length + 1; - } - - return _lines; - } - - /// - /// Gets a specific line from the source text (1-based). - /// - public string GetLine(int lineNumber) - { - if (lineNumber < 1) - { - throw new ArgumentOutOfRangeException(nameof(lineNumber)); - } - - var lines = Content.Split('\n'); - return lineNumber <= lines.Length ? lines[lineNumber - 1] : string.Empty; - } - - public bool Equals(SourceText other) - { - return Path == other.Path && Content == other.Content; - } - - public override bool Equals([NotNullWhen(true)] object? obj) - { - return obj is SourceText other && Equals(other); - } - - public override int GetHashCode() - { - return HashCode.Combine(Path, Content); - } - - public override string ToString() - { - return Path; - } - - public static bool operator ==(SourceText left, SourceText right) => left.Equals(right); - public static bool operator !=(SourceText left, SourceText right) => !left.Equals(right); -} - -/// -/// Represents a span of source code from a start to end location within a source text. -/// -public readonly struct SourceSpan : IEquatable -{ - public SourceSpan(SourceText text, SourceLocation start, SourceLocation end) - { - if (start > end) - { - throw new ArgumentException("Start location cannot be after end location"); - } - - if (end.Line > text.LineCount() || end.Line == text.LineCount() && end.Column > text.GetLine(text.LineCount()).Length + 1) - { - throw new ArgumentException("End location cannot be after text end location"); - } - - Text = text; - Start = start; - End = end; - } - - public SourceText Text { get; } - public SourceLocation Start { get; } - public SourceLocation End { get; } - - /// - /// Gets whether this span represents a single point (start == end). - /// - public bool IsEmpty => Start == End; - - /// - /// Gets whether this span is contained within a single line. - /// - public bool IsSingleLine => Start.Line == End.Line; - - /// - /// Gets the text content covered by this span. - /// - public string GetText() - { - if (IsEmpty) - { - return string.Empty; - } - - var lines = Text.Content.Split('\n'); - - if (IsSingleLine) - { - var line = lines[Start.Line - 1]; - var startCol = Math.Min(Start.Column - 1, line.Length); - var endCol = Math.Min(End.Column - 1, line.Length); - return line.Substring(startCol, Math.Max(0, endCol - startCol)); - } - - var result = new List(); - for (var i = Start.Line - 1; i < Math.Min(End.Line, lines.Length); i++) - { - var line = lines[i]; - if (i == Start.Line - 1) - { - result.Add(line[Math.Min(Start.Column - 1, line.Length)..]); - } - else if (i == End.Line - 1) - { - result.Add(line[..Math.Min(End.Column - 1, line.Length)]); - } - else - { - result.Add(line); - } - } - - return string.Join("\n", result); - } - - /// - /// Merges multiple source spans from the same file into a single span. - /// The result spans from the earliest start to the latest end. - /// - public static SourceSpan Merge(IEnumerable spans) - { - var spanArray = spans.ToArray(); - if (spanArray.Length == 0) - { - throw new ArgumentException("Cannot merge empty collection of spans", nameof(spans)); - } - - var firstText = spanArray[0].Text; - if (spanArray.Any(s => !s.Text.Equals(firstText))) - { - throw new ArgumentException("All spans must be from the same source text", nameof(spans)); - } - - var minStart = spanArray.Min(s => s.Start); - var maxEnd = spanArray.Max(s => s.End); - - return new SourceSpan(firstText, minStart, maxEnd); - } - - public override string ToString() - { - if (IsEmpty) - { - return $"{Start}"; - } - - if (IsSingleLine) - { - return Start.Column == End.Column ? $"{Start}" : $"{Start.Line}:{Start.Column}-{End.Column}"; - } - - return $"{Start}-{End}"; - } - - public bool Equals(SourceSpan other) - { - return Text.Equals(other.Text) && Start.Equals(other.Start) && End.Equals(other.End); - } - - public override bool Equals([NotNullWhen(true)] object? obj) - { - return obj is SourceSpan other && Equals(other); - } - - public override int GetHashCode() - { - return HashCode.Combine(Text, Start, End); - } - - public static bool operator ==(SourceSpan left, SourceSpan right) - { - return left.Equals(right); - } - - public static bool operator !=(SourceSpan left, SourceSpan right) - { - return !left.Equals(right); - } -} \ No newline at end of file diff --git a/src/compiler/NubLang/Syntax/Binding/Binder.cs b/src/compiler/NubLang/Syntax/Binding/Binder.cs index 14379c5..50243fe 100644 --- a/src/compiler/NubLang/Syntax/Binding/Binder.cs +++ b/src/compiler/NubLang/Syntax/Binding/Binder.cs @@ -63,10 +63,10 @@ public sealed class Binder foreach (var function in node.Functions) { - functions.Add(new BoundTraitFunc(node.Tokens, function.Name, BindFuncSignature(function.Signature))); + functions.Add(new BoundTraitFunc(function.Name, BindFuncSignature(function.Signature))); } - return new BoundTrait(node.Tokens, node.Namespace, node.Name, functions); + return new BoundTrait(node.Namespace, node.Name, functions); } private BoundStruct BindStruct(StructSyntax node) @@ -82,15 +82,15 @@ public sealed class Binder value = BindExpression(field.Value.Value, BindType(field.Type)); } - structFields.Add(new BoundStructField(field.Tokens, field.Index, field.Name, BindType(field.Type), value)); + structFields.Add(new BoundStructField(field.Index, field.Name, BindType(field.Type), value)); } - return new BoundStruct(node.Tokens, node.Namespace, node.Name, structFields); + return new BoundStruct(node.Namespace, node.Name, structFields); } private BoundExternFunc BindExternFuncDefinition(ExternFuncSyntax node) { - return new BoundExternFunc(node.Tokens, node.Namespace, node.Name, node.CallName, BindFuncSignature(node.Signature)); + return new BoundExternFunc(node.Namespace, node.Name, node.CallName, BindFuncSignature(node.Signature)); } private BoundLocalFunc BindLocalFuncDefinition(LocalFuncSyntax node) @@ -98,7 +98,7 @@ public sealed class Binder var signature = BindFuncSignature(node.Signature); var body = BindFuncBody(node.Body, signature.ReturnType, signature.Parameters); - return new BoundLocalFunc(node.Tokens, node.Namespace, node.Name, signature, body); + return new BoundLocalFunc(node.Namespace, node.Name, signature, body); } private BoundStatement BindStatement(StatementSyntax node) @@ -106,8 +106,8 @@ public sealed class Binder return node switch { AssignmentSyntax statement => BindAssignment(statement), - BreakSyntax statement => BindBreak(statement), - ContinueSyntax statement => BindContinue(statement), + BreakSyntax => new BoundBreak(), + ContinueSyntax => new BoundContinue(), IfSyntax statement => BindIf(statement), ReturnSyntax statement => BindReturn(statement), StatementExpressionSyntax statement => BindStatementExpression(statement), @@ -121,17 +121,7 @@ public sealed class Binder { var expression = BindExpression(statement.Target); var value = BindExpression(statement.Value, expression.Type); - return new BoundAssignment(statement.Tokens, expression, value); - } - - private BoundBreak BindBreak(BreakSyntax statement) - { - return new BoundBreak(statement.Tokens); - } - - private BoundContinue BindContinue(ContinueSyntax statement) - { - return new BoundContinue(statement.Tokens); + return new BoundAssignment(expression, value); } private BoundIf BindIf(IfSyntax statement) @@ -147,7 +137,7 @@ public sealed class Binder ); } - return new BoundIf(statement.Tokens, BindExpression(statement.Condition, new NubPrimitiveType(PrimitiveTypeKind.Bool)), BindBlock(statement.Body), elseStatement); + return new BoundIf(BindExpression(statement.Condition, new NubPrimitiveType(PrimitiveTypeKind.Bool)), BindBlock(statement.Body), elseStatement); } private BoundReturn BindReturn(ReturnSyntax statement) @@ -159,12 +149,12 @@ public sealed class Binder value = BindExpression(statement.Value.Value, _funcReturnTypes.Peek()); } - return new BoundReturn(statement.Tokens, value); + return new BoundReturn(value); } private BoundStatementExpression BindStatementExpression(StatementExpressionSyntax statement) { - return new BoundStatementExpression(statement.Tokens, BindExpression(statement.Expression)); + return new BoundStatementExpression(BindExpression(statement.Expression)); } private BoundVariableDeclaration BindVariableDeclaration(VariableDeclarationSyntax statement) @@ -191,12 +181,12 @@ public sealed class Binder Scope.Declare(new Variable(statement.Name, type)); - return new BoundVariableDeclaration(statement.Tokens, statement.Name, assignment, type); + return new BoundVariableDeclaration(statement.Name, assignment, type); } private BoundWhile BindWhile(WhileSyntax statement) { - return new BoundWhile(statement.Tokens, BindExpression(statement.Condition, new NubPrimitiveType(PrimitiveTypeKind.Bool)), BindBlock(statement.Body)); + return new BoundWhile(BindExpression(statement.Condition, new NubPrimitiveType(PrimitiveTypeKind.Bool)), BindBlock(statement.Body)); } private BoundExpression BindExpression(ExpressionSyntax node, NubType? expectedType = null) @@ -222,19 +212,19 @@ public sealed class Binder private BoundAddressOf BindAddressOf(AddressOfSyntax expression) { var inner = BindExpression(expression.Expression); - return new BoundAddressOf(expression.Tokens, new NubPointerType(inner.Type), inner); + return new BoundAddressOf(new NubPointerType(inner.Type), inner); } private BoundArrowFunc BindArrowFunc(ArrowFuncSyntax expression, NubType? expectedType = null) { if (expectedType == null) { - throw new BindException(Diagnostic.Error("Cannot infer argument types for arrow function").At(expression).Build()); + throw new BindException(Diagnostic.Error("Cannot infer argument types for arrow function").Build()); } if (expectedType is not NubFuncType funcType) { - throw new BindException(Diagnostic.Error($"Expected {expectedType}, but got arrow function").At(expression).Build()); + throw new BindException(Diagnostic.Error($"Expected {expectedType}, but got arrow function").Build()); } var parameters = new List(); @@ -248,40 +238,40 @@ public sealed class Binder var expectedParameterType = funcType.Parameters[i]; var parameter = expression.Parameters[i]; - parameters.Add(new BoundFuncParameter(parameter.Tokens, parameter.Name, expectedParameterType)); + parameters.Add(new BoundFuncParameter(parameter.Name, expectedParameterType)); } var body = BindFuncBody(expression.Body, funcType.ReturnType, parameters); - return new BoundArrowFunc(expression.Tokens, new NubFuncType(parameters.Select(x => x.Type).ToList(), funcType.ReturnType), parameters, funcType.ReturnType, body); + return new BoundArrowFunc(new NubFuncType(parameters.Select(x => x.Type).ToList(), funcType.ReturnType), parameters, funcType.ReturnType, body); } private BoundArrayIndexAccess BindArrayIndexAccess(ArrayIndexAccessSyntax expression) { var boundArray = BindExpression(expression.Target); var elementType = ((NubArrayType)boundArray.Type).ElementType; - return new BoundArrayIndexAccess(expression.Tokens, elementType, boundArray, BindExpression(expression.Index, new NubPrimitiveType(PrimitiveTypeKind.U64))); + return new BoundArrayIndexAccess(elementType, boundArray, BindExpression(expression.Index, new NubPrimitiveType(PrimitiveTypeKind.U64))); } private BoundArrayInitializer BindArrayInitializer(ArrayInitializerSyntax expression) { var capacity = BindExpression(expression.Capacity, new NubPrimitiveType(PrimitiveTypeKind.U64)); var type = new NubArrayType(BindType(expression.ElementType)); - return new BoundArrayInitializer(expression.Tokens, type, capacity, BindType(expression.ElementType)); + return new BoundArrayInitializer(type, capacity, BindType(expression.ElementType)); } private BoundBinaryExpression BindBinaryExpression(BinaryExpressionSyntax expression) { var boundLeft = BindExpression(expression.Left); var boundRight = BindExpression(expression.Right, boundLeft.Type); - return new BoundBinaryExpression(expression.Tokens, boundLeft.Type, boundLeft, BindBinaryOperator(expression.Operator), boundRight); + return new BoundBinaryExpression(boundLeft.Type, boundLeft, BindBinaryOperator(expression.Operator), boundRight); } private BoundDereference BindDereference(DereferenceSyntax expression) { var boundExpression = BindExpression(expression.Expression); var dereferencedType = ((NubPointerType)boundExpression.Type).BaseType; - return new BoundDereference(expression.Tokens, dereferencedType, boundExpression); + return new BoundDereference(dereferencedType, boundExpression); } private BoundFuncCall BindFuncCall(FuncCallSyntax expression) @@ -304,7 +294,7 @@ public sealed class Binder parameters.Add(BindExpression(parameter, expectedType)); } - return new BoundFuncCall(expression.Tokens, funcType.ReturnType, boundExpression, parameters); + return new BoundFuncCall(funcType.ReturnType, boundExpression, parameters); } private BoundExpression BindIdentifier(IdentifierSyntax expression) @@ -323,7 +313,7 @@ public sealed class Binder var returnType = BindType(localFunc.Signature.ReturnType); var parameterTypes = localFunc.Signature.Parameters.Select(p => BindType(p.Type)).ToList(); var type = new NubFuncType(parameterTypes, returnType); - return new BoundLocalFuncIdent(expression.Tokens, type, @namespace, expression.Name); + return new BoundLocalFuncIdent(type, @namespace, expression.Name); } var externFuncs = _definitionTable.LookupExternFunc(@namespace, expression.Name).ToArray(); @@ -339,7 +329,7 @@ public sealed class Binder var returnType = BindType(externFunc.Signature.ReturnType); var parameterTypes = externFunc.Signature.Parameters.Select(p => BindType(p.Type)).ToList(); var type = new NubFuncType(parameterTypes, returnType); - return new BoundExternFuncIdent(expression.Tokens, type, @namespace, expression.Name); + return new BoundExternFuncIdent(type, @namespace, expression.Name); } if (!expression.Namespace.HasValue) @@ -347,7 +337,7 @@ public sealed class Binder var variable = Scope.Lookup(expression.Name); if (variable != null) { - return new BoundVariableIdent(expression.Tokens, variable.Type, variable.Name); + return new BoundVariableIdent(variable.Type, variable.Name); } } @@ -365,7 +355,7 @@ public sealed class Binder _ => throw new ArgumentOutOfRangeException() }; - return new BoundLiteral(expression.Tokens, type, expression.Value, expression.Kind); + return new BoundLiteral(type, expression.Value, expression.Kind); } private BoundExpression BindMemberAccess(MemberAccessSyntax expression) @@ -385,7 +375,7 @@ public sealed class Binder // var returnType = BindType(impl.Signature.ReturnType); // var parameterTypes = impl.Signature.Parameters.Select(p => BindType(p.Type)).ToList(); // var type = new NubFuncType(parameterTypes, returnType); - // return new BoundTraitImplFuncAccess(expression.Tokens, type, boundExpression, expression.Member); + // return new BoundTraitImplFuncAccess(type, boundExpression, expression.Member); // } if (boundExpression.Type is NubCustomType customType) @@ -413,7 +403,7 @@ public sealed class Binder var returnType = BindType(traitFunc.Signature.ReturnType); var parameterTypes = traitFunc.Signature.Parameters.Select(p => BindType(p.Type)).ToList(); var type = new NubFuncType(parameterTypes, returnType); - return new BoundTraitFuncAccess(expression.Tokens, type, customType, boundExpression, expression.Member); + return new BoundInterfaceFuncAccess(type, customType, boundExpression, expression.Member); } } @@ -437,7 +427,7 @@ public sealed class Binder var field = fields[0]; - return new BoundStructFieldAccess(expression.Tokens, BindType(field.Type), customType, boundExpression, expression.Member); + return new BoundStructFieldAccess(BindType(field.Type), customType, boundExpression, expression.Member); } } } @@ -487,7 +477,7 @@ public sealed class Binder initializers[field] = BindExpression(initializer, BindType(fields[0].Type)); } - return new BoundStructInitializer(expression.Tokens, structType, initializers); + return new BoundStructInitializer(structType, initializers); } private BoundUnaryExpression BindUnaryExpression(UnaryExpressionSyntax expression) @@ -523,7 +513,7 @@ public sealed class Binder throw new NotImplementedException("Diagnostics not implemented"); } - return new BoundUnaryExpression(expression.Tokens, type, BindBinaryOperator(expression.Operator), boundOperand); + return new BoundUnaryExpression(type, BindBinaryOperator(expression.Operator), boundOperand); } private BoundFuncSignature BindFuncSignature(FuncSignatureSyntax node) @@ -532,10 +522,10 @@ public sealed class Binder foreach (var parameter in node.Parameters) { - parameters.Add(new BoundFuncParameter(parameter.Tokens, parameter.Name, BindType(parameter.Type))); + parameters.Add(new BoundFuncParameter(parameter.Name, BindType(parameter.Type))); } - return new BoundFuncSignature(node.Tokens, parameters, BindType(node.ReturnType)); + return new BoundFuncSignature(parameters, BindType(node.ReturnType)); } private BoundBinaryOperator BindBinaryOperator(BinaryOperator op) @@ -579,7 +569,7 @@ public sealed class Binder _scopes.Pop(); - return new BoundBlock(node.Tokens, statements); + return new BoundBlock(statements); } private BoundBlock BindFuncBody(BlockSyntax block, NubType returnType, IReadOnlyList parameters) diff --git a/src/compiler/NubLang/Syntax/Binding/Node/BoundDefinition.cs b/src/compiler/NubLang/Syntax/Binding/Node/BoundDefinition.cs index 47805d3..b980cb7 100644 --- a/src/compiler/NubLang/Syntax/Binding/Node/BoundDefinition.cs +++ b/src/compiler/NubLang/Syntax/Binding/Node/BoundDefinition.cs @@ -1,26 +1,25 @@ using NubLang.Common; -using NubLang.Syntax.Tokenization; namespace NubLang.Syntax.Binding.Node; -public abstract record BoundDefinition(IReadOnlyList Tokens, string Namespace) : BoundNode(Tokens); +public abstract record BoundDefinition(string Namespace) : BoundNode; -public record BoundFuncParameter(IReadOnlyList Tokens, string Name, NubType Type) : BoundNode(Tokens); +public record BoundFuncParameter(string Name, NubType Type) : BoundNode; -public record BoundFuncSignature(IReadOnlyList Tokens, IReadOnlyList Parameters, NubType ReturnType) : BoundNode(Tokens); +public record BoundFuncSignature(IReadOnlyList Parameters, NubType ReturnType) : BoundNode; -public record BoundLocalFunc(IReadOnlyList Tokens, string Namespace, string Name, BoundFuncSignature Signature, BoundBlock Body) : BoundDefinition(Tokens, Namespace); +public record BoundLocalFunc(string Namespace, string Name, BoundFuncSignature Signature, BoundBlock Body) : BoundDefinition(Namespace); -public record BoundExternFunc(IReadOnlyList Tokens, string Namespace, string Name, string CallName, BoundFuncSignature Signature) : BoundDefinition(Tokens, Namespace); +public record BoundExternFunc(string Namespace, string Name, string CallName, BoundFuncSignature Signature) : BoundDefinition(Namespace); -public record BoundStructField(IReadOnlyList Tokens, int Index, string Name, NubType Type, Optional Value) : BoundNode(Tokens); +public record BoundStructField(int Index, string Name, NubType Type, Optional Value) : BoundNode; -public record BoundStruct(IReadOnlyList Tokens, string Namespace, string Name, IReadOnlyList Fields) : BoundDefinition(Tokens, Namespace); +public record BoundStruct(string Namespace, string Name, IReadOnlyList Fields) : BoundDefinition(Namespace); -public record BoundTraitFunc(IReadOnlyList Tokens, string Name, BoundFuncSignature Signature) : BoundNode(Tokens); +public record BoundTraitFunc(string Name, BoundFuncSignature Signature) : BoundNode; -public record BoundTrait(IReadOnlyList Tokens, string Namespace, string Name, IReadOnlyList Functions) : BoundDefinition(Tokens, Namespace); +public record BoundTrait(string Namespace, string Name, IReadOnlyList Functions) : BoundDefinition(Namespace); -public record BoundTraitFuncImpl(IReadOnlyList Tokens, string Name, BoundFuncSignature Signature, BoundBlock Body) : BoundNode(Tokens); +public record BoundTraitFuncImpl(string Name, BoundFuncSignature Signature, BoundBlock Body) : BoundNode; -public record BoundTraitImpl(IReadOnlyList Tokens, string Namespace, NubType TraitType, NubType ForType, IReadOnlyList Functions) : BoundDefinition(Tokens, Namespace); \ No newline at end of file +public record BoundTraitImpl(string Namespace, NubType TraitType, NubType ForType, IReadOnlyList Functions) : BoundDefinition(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 70f4da0..c01f1a8 100644 --- a/src/compiler/NubLang/Syntax/Binding/Node/BoundExpression.cs +++ b/src/compiler/NubLang/Syntax/Binding/Node/BoundExpression.cs @@ -22,36 +22,34 @@ public enum BoundBinaryOperator Divide } -public abstract record BoundExpression(IReadOnlyList Tokens, NubType Type) : BoundNode(Tokens); +public abstract record BoundExpression(NubType Type) : BoundNode; -public record BoundBinaryExpression(IReadOnlyList Tokens, NubType Type, BoundExpression Left, BoundBinaryOperator Operator, BoundExpression Right) : BoundExpression(Tokens, Type); +public record BoundBinaryExpression(NubType Type, BoundExpression Left, BoundBinaryOperator Operator, BoundExpression Right) : BoundExpression(Type); -public record BoundUnaryExpression(IReadOnlyList Tokens, NubType Type, BoundUnaryOperator Operator, BoundExpression Operand) : BoundExpression(Tokens, Type); +public record BoundUnaryExpression(NubType Type, BoundUnaryOperator Operator, BoundExpression Operand) : BoundExpression(Type); -public record BoundFuncCall(IReadOnlyList Tokens, NubType Type, BoundExpression Expression, IReadOnlyList Parameters) : BoundExpression(Tokens, Type); +public record BoundFuncCall(NubType Type, BoundExpression Expression, IReadOnlyList Parameters) : BoundExpression(Type); -public record BoundVariableIdent(IReadOnlyList Tokens, NubType Type, string Name) : BoundExpression(Tokens, Type); +public record BoundVariableIdent(NubType Type, string Name) : BoundExpression(Type); -public record BoundLocalFuncIdent(IReadOnlyList Tokens, NubType Type, string Namespace, string Name) : BoundExpression(Tokens, Type); +public record BoundLocalFuncIdent(NubType Type, string Namespace, string Name) : BoundExpression(Type); -public record BoundExternFuncIdent(IReadOnlyList Tokens, NubType Type, string Namespace, string Name) : BoundExpression(Tokens, Type); +public record BoundExternFuncIdent(NubType Type, string Namespace, string Name) : BoundExpression(Type); -public record BoundArrayInitializer(IReadOnlyList Tokens, NubType Type, BoundExpression Capacity, NubType ElementType) : BoundExpression(Tokens, Type); +public record BoundArrayInitializer(NubType Type, BoundExpression Capacity, NubType ElementType) : BoundExpression(Type); -public record BoundArrayIndexAccess(IReadOnlyList Tokens, NubType Type, BoundExpression Target, BoundExpression Index) : BoundExpression(Tokens, Type); +public record BoundArrayIndexAccess(NubType Type, BoundExpression Target, BoundExpression Index) : BoundExpression(Type); -public record BoundArrowFunc(IReadOnlyList Tokens, NubType Type, IReadOnlyList Parameters, NubType ReturnType, BoundBlock Body) : BoundExpression(Tokens, Type); +public record BoundArrowFunc(NubType Type, IReadOnlyList Parameters, NubType ReturnType, BoundBlock Body) : BoundExpression(Type); -public record BoundAddressOf(IReadOnlyList Tokens, NubType Type, BoundExpression Expression) : BoundExpression(Tokens, Type); +public record BoundAddressOf(NubType Type, BoundExpression Expression) : BoundExpression(Type); -public record BoundLiteral(IReadOnlyList Tokens, NubType Type, string Literal, LiteralKind Kind) : BoundExpression(Tokens, Type); +public record BoundLiteral(NubType Type, string Literal, LiteralKind Kind) : BoundExpression(Type); -public record BoundStructFieldAccess(IReadOnlyList Tokens, NubType Type, NubCustomType StructType, BoundExpression Target, string Field) : BoundExpression(Tokens, Type); +public record BoundStructFieldAccess(NubType Type, NubCustomType StructType, BoundExpression Target, string Field) : BoundExpression(Type); -public record BoundTraitImplFuncAccess(IReadOnlyList Tokens, NubType Type, BoundExpression Target, string FuncName) : BoundExpression(Tokens, Type); +public record BoundInterfaceFuncAccess(NubType Type, NubCustomType InterfaceType, BoundExpression Target, string FuncName) : BoundExpression(Type); -public record BoundTraitFuncAccess(IReadOnlyList Tokens, NubType Type, NubCustomType TraitType, BoundExpression Target, string FuncName) : BoundExpression(Tokens, Type); +public record BoundStructInitializer(NubCustomType StructType, Dictionary Initializers) : BoundExpression(StructType); -public record BoundStructInitializer(IReadOnlyList Tokens, NubCustomType StructType, Dictionary Initializers) : BoundExpression(Tokens, StructType); - -public record BoundDereference(IReadOnlyList Tokens, NubType Type, BoundExpression Expression) : BoundExpression(Tokens, Type); \ No newline at end of file +public record BoundDereference(NubType Type, BoundExpression Expression) : BoundExpression(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 cec6a4b..4d1474b 100644 --- a/src/compiler/NubLang/Syntax/Binding/Node/BoundStatement.cs +++ b/src/compiler/NubLang/Syntax/Binding/Node/BoundStatement.cs @@ -1,22 +1,21 @@ using NubLang.Common; -using NubLang.Syntax.Tokenization; namespace NubLang.Syntax.Binding.Node; -public record BoundStatement(IReadOnlyList Tokens) : BoundNode(Tokens); +public record BoundStatement : BoundNode; -public record BoundStatementExpression(IReadOnlyList Tokens, BoundExpression Expression) : BoundStatement(Tokens); +public record BoundStatementExpression(BoundExpression Expression) : BoundStatement; -public record BoundReturn(IReadOnlyList Tokens, Optional Value) : BoundStatement(Tokens); +public record BoundReturn(Optional Value) : BoundStatement; -public record BoundAssignment(IReadOnlyList Tokens, BoundExpression Target, BoundExpression Value) : BoundStatement(Tokens); +public record BoundAssignment(BoundExpression Target, BoundExpression Value) : BoundStatement; -public record BoundIf(IReadOnlyList Tokens, BoundExpression Condition, BoundBlock Body, Optional> Else) : BoundStatement(Tokens); +public record BoundIf(BoundExpression Condition, BoundBlock Body, Optional> Else) : BoundStatement; -public record BoundVariableDeclaration(IReadOnlyList Tokens, string Name, Optional Assignment, NubType Type) : BoundStatement(Tokens); +public record BoundVariableDeclaration(string Name, Optional Assignment, NubType Type) : BoundStatement; -public record BoundContinue(IReadOnlyList Tokens) : BoundStatement(Tokens); +public record BoundContinue : BoundStatement; -public record BoundBreak(IReadOnlyList Tokens) : BoundStatement(Tokens); +public record BoundBreak : BoundStatement; -public record BoundWhile(IReadOnlyList Tokens, BoundExpression Condition, BoundBlock Body) : BoundStatement(Tokens); \ No newline at end of file +public record BoundWhile(BoundExpression Condition, BoundBlock Body) : BoundStatement; \ 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 666dd33..b3c3067 100644 --- a/src/compiler/NubLang/Syntax/Binding/Node/BoundSyntaxTree.cs +++ b/src/compiler/NubLang/Syntax/Binding/Node/BoundSyntaxTree.cs @@ -1,10 +1,9 @@ using NubLang.Diagnostics; -using NubLang.Syntax.Tokenization; namespace NubLang.Syntax.Binding.Node; public record BoundSyntaxTree(string Namespace, IReadOnlyList Definitions, IReadOnlyList Diagnostics); -public abstract record BoundNode(IReadOnlyList Tokens); +public abstract record BoundNode; -public record BoundBlock(IReadOnlyList Tokens, IReadOnlyList Statements) : BoundNode(Tokens); \ No newline at end of file +public record BoundBlock(IReadOnlyList Statements) : BoundNode; \ 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 0c5aad1..1f607a1 100644 --- a/src/compiler/NubLang/Syntax/Parsing/Node/DefinitionSyntax.cs +++ b/src/compiler/NubLang/Syntax/Parsing/Node/DefinitionSyntax.cs @@ -1,11 +1,10 @@ using NubLang.Common; -using NubLang.Syntax.Tokenization; namespace NubLang.Syntax.Parsing.Node; -public abstract record DefinitionSyntax(IReadOnlyList Tokens, string Namespace) : SyntaxNode(Tokens); +public abstract record DefinitionSyntax(string Namespace) : SyntaxNode; -public record FuncParameterSyntax(IReadOnlyList Tokens, string Name, TypeSyntax Type) : SyntaxNode(Tokens) +public record FuncParameterSyntax(string Name, TypeSyntax Type) : SyntaxNode { public override IEnumerable GetChildren() { @@ -13,7 +12,7 @@ public record FuncParameterSyntax(IReadOnlyList Tokens, string Name, Type } } -public record FuncSignatureSyntax(IReadOnlyList Tokens, IReadOnlyList Parameters, TypeSyntax ReturnType) : SyntaxNode(Tokens) +public record FuncSignatureSyntax(IReadOnlyList Parameters, TypeSyntax ReturnType) : SyntaxNode { public override IEnumerable GetChildren() { @@ -26,7 +25,7 @@ public record FuncSignatureSyntax(IReadOnlyList Tokens, IReadOnlyList Tokens, string Namespace, string Name, FuncSignatureSyntax Signature, BlockSyntax Body) : DefinitionSyntax(Tokens, Namespace) +public record LocalFuncSyntax(string Namespace, string Name, FuncSignatureSyntax Signature, BlockSyntax Body) : DefinitionSyntax(Namespace) { public override IEnumerable GetChildren() { @@ -35,7 +34,7 @@ public record LocalFuncSyntax(IReadOnlyList Tokens, string Namespace, str } } -public record ExternFuncSyntax(IReadOnlyList Tokens, string Namespace, string Name, string CallName, FuncSignatureSyntax Signature) : DefinitionSyntax(Tokens, Namespace) +public record ExternFuncSyntax(string Namespace, string Name, string CallName, FuncSignatureSyntax Signature) : DefinitionSyntax(Namespace) { public override IEnumerable GetChildren() { @@ -43,7 +42,7 @@ public record ExternFuncSyntax(IReadOnlyList Tokens, string Namespace, st } } -public record StructFieldSyntax(IReadOnlyList Tokens, int Index, string Name, TypeSyntax Type, Optional Value) : SyntaxNode(Tokens) +public record StructFieldSyntax(int Index, string Name, TypeSyntax Type, Optional Value) : SyntaxNode { public override IEnumerable GetChildren() { @@ -55,7 +54,7 @@ public record StructFieldSyntax(IReadOnlyList Tokens, int Index, string N } } -public record StructFuncSyntax(IReadOnlyList Tokens, string Name, FuncSignatureSyntax Signature, BlockSyntax Body) : SyntaxNode(Tokens) +public record StructFuncSyntax(string Name, FuncSignatureSyntax Signature, BlockSyntax Body) : SyntaxNode { public override IEnumerable GetChildren() { @@ -64,7 +63,7 @@ public record StructFuncSyntax(IReadOnlyList Tokens, string Name, FuncSig } } -public record StructSyntax(IReadOnlyList Tokens, string Namespace, string Name, IReadOnlyList Fields, IReadOnlyList Functions) : DefinitionSyntax(Tokens, Namespace) +public record StructSyntax(string Namespace, string Name, IReadOnlyList Fields, IReadOnlyList Functions) : DefinitionSyntax(Namespace) { public override IEnumerable GetChildren() { @@ -80,7 +79,7 @@ public record StructSyntax(IReadOnlyList Tokens, string Namespace, string } } -public record InterfaceFuncSyntax(IReadOnlyList Tokens, string Name, FuncSignatureSyntax Signature) : SyntaxNode(Tokens) +public record InterfaceFuncSyntax(string Name, FuncSignatureSyntax Signature) : SyntaxNode { public override IEnumerable GetChildren() { @@ -88,7 +87,7 @@ public record InterfaceFuncSyntax(IReadOnlyList Tokens, string Name, Func } } -public record InterfaceSyntax(IReadOnlyList Tokens, string Namespace, string Name, IReadOnlyList Functions) : DefinitionSyntax(Tokens, Namespace) +public record InterfaceSyntax(string Namespace, string Name, IReadOnlyList Functions) : DefinitionSyntax(Namespace) { public override IEnumerable GetChildren() { diff --git a/src/compiler/NubLang/Syntax/Parsing/Node/ExpressionSyntax.cs b/src/compiler/NubLang/Syntax/Parsing/Node/ExpressionSyntax.cs index 44983f1..d95e616 100644 --- a/src/compiler/NubLang/Syntax/Parsing/Node/ExpressionSyntax.cs +++ b/src/compiler/NubLang/Syntax/Parsing/Node/ExpressionSyntax.cs @@ -23,9 +23,9 @@ public enum BinaryOperator Divide } -public abstract record ExpressionSyntax(IReadOnlyList Tokens) : SyntaxNode(Tokens); +public abstract record ExpressionSyntax : SyntaxNode; -public record BinaryExpressionSyntax(IReadOnlyList Tokens, ExpressionSyntax Left, BinaryOperator Operator, ExpressionSyntax Right) : ExpressionSyntax(Tokens) +public record BinaryExpressionSyntax(ExpressionSyntax Left, BinaryOperator Operator, ExpressionSyntax Right) : ExpressionSyntax { public override IEnumerable GetChildren() { @@ -34,7 +34,7 @@ public record BinaryExpressionSyntax(IReadOnlyList Tokens, ExpressionSynt } } -public record UnaryExpressionSyntax(IReadOnlyList Tokens, UnaryOperator Operator, ExpressionSyntax Operand) : ExpressionSyntax(Tokens) +public record UnaryExpressionSyntax(UnaryOperator Operator, ExpressionSyntax Operand) : ExpressionSyntax { public override IEnumerable GetChildren() { @@ -42,7 +42,7 @@ public record UnaryExpressionSyntax(IReadOnlyList Tokens, UnaryOperator O } } -public record FuncCallSyntax(IReadOnlyList Tokens, ExpressionSyntax Expression, IReadOnlyList Parameters) : ExpressionSyntax(Tokens) +public record FuncCallSyntax(ExpressionSyntax Expression, IReadOnlyList Parameters) : ExpressionSyntax { public override IEnumerable GetChildren() { @@ -54,12 +54,12 @@ public record FuncCallSyntax(IReadOnlyList Tokens, ExpressionSyntax Expre } } -public record IdentifierSyntax(IReadOnlyList Tokens, Optional Namespace, string Name) : ExpressionSyntax(Tokens) +public record IdentifierSyntax(Optional Namespace, string Name) : ExpressionSyntax { public override IEnumerable GetChildren() => []; } -public record ArrayInitializerSyntax(IReadOnlyList Tokens, ExpressionSyntax Capacity, TypeSyntax ElementType) : ExpressionSyntax(Tokens) +public record ArrayInitializerSyntax(ExpressionSyntax Capacity, TypeSyntax ElementType) : ExpressionSyntax { public override IEnumerable GetChildren() { @@ -68,7 +68,7 @@ public record ArrayInitializerSyntax(IReadOnlyList Tokens, ExpressionSynt } } -public record ArrayIndexAccessSyntax(IReadOnlyList Tokens, ExpressionSyntax Target, ExpressionSyntax Index) : ExpressionSyntax(Tokens) +public record ArrayIndexAccessSyntax(ExpressionSyntax Target, ExpressionSyntax Index) : ExpressionSyntax { public override IEnumerable GetChildren() { @@ -77,12 +77,12 @@ public record ArrayIndexAccessSyntax(IReadOnlyList Tokens, ExpressionSynt } } -public record ArrowFuncParameterSyntax(IReadOnlyList Tokens, string Name) : ExpressionSyntax(Tokens) +public record ArrowFuncParameterSyntax(string Name) : ExpressionSyntax { public override IEnumerable GetChildren() => []; } -public record ArrowFuncSyntax(IReadOnlyList Tokens, IReadOnlyList Parameters, BlockSyntax Body) : ExpressionSyntax(Tokens) +public record ArrowFuncSyntax(IReadOnlyList Parameters, BlockSyntax Body) : ExpressionSyntax { public override IEnumerable GetChildren() { @@ -95,7 +95,7 @@ public record ArrowFuncSyntax(IReadOnlyList Tokens, IReadOnlyList Tokens, ExpressionSyntax Expression) : ExpressionSyntax(Tokens) +public record AddressOfSyntax(ExpressionSyntax Expression) : ExpressionSyntax { public override IEnumerable GetChildren() { @@ -103,12 +103,12 @@ public record AddressOfSyntax(IReadOnlyList Tokens, ExpressionSyntax Expr } } -public record LiteralSyntax(IReadOnlyList Tokens, string Value, LiteralKind Kind) : ExpressionSyntax(Tokens) +public record LiteralSyntax(string Value, LiteralKind Kind) : ExpressionSyntax { public override IEnumerable GetChildren() => []; } -public record MemberAccessSyntax(IReadOnlyList Tokens, ExpressionSyntax Target, string Member) : ExpressionSyntax(Tokens) +public record MemberAccessSyntax(ExpressionSyntax Target, string Member) : ExpressionSyntax { public override IEnumerable GetChildren() { @@ -116,7 +116,7 @@ public record MemberAccessSyntax(IReadOnlyList Tokens, ExpressionSyntax T } } -public record StructInitializerSyntax(IReadOnlyList Tokens, TypeSyntax StructType, Dictionary Initializers) : ExpressionSyntax(Tokens) +public record StructInitializerSyntax(TypeSyntax StructType, Dictionary Initializers) : ExpressionSyntax { public override IEnumerable GetChildren() { @@ -128,7 +128,7 @@ public record StructInitializerSyntax(IReadOnlyList Tokens, TypeSyntax St } } -public record DereferenceSyntax(IReadOnlyList Tokens, ExpressionSyntax Expression) : ExpressionSyntax(Tokens) +public record DereferenceSyntax(ExpressionSyntax Expression) : ExpressionSyntax { public override IEnumerable GetChildren() { diff --git a/src/compiler/NubLang/Syntax/Parsing/Node/StatementSyntax.cs b/src/compiler/NubLang/Syntax/Parsing/Node/StatementSyntax.cs index e4a90dd..61c23e3 100644 --- a/src/compiler/NubLang/Syntax/Parsing/Node/StatementSyntax.cs +++ b/src/compiler/NubLang/Syntax/Parsing/Node/StatementSyntax.cs @@ -1,11 +1,10 @@ using NubLang.Common; -using NubLang.Syntax.Tokenization; namespace NubLang.Syntax.Parsing.Node; -public abstract record StatementSyntax(IReadOnlyList Tokens) : SyntaxNode(Tokens); +public abstract record StatementSyntax : SyntaxNode; -public record StatementExpressionSyntax(IReadOnlyList Tokens, ExpressionSyntax Expression) : StatementSyntax(Tokens) +public record StatementExpressionSyntax(ExpressionSyntax Expression) : StatementSyntax { public override IEnumerable GetChildren() { @@ -13,7 +12,7 @@ public record StatementExpressionSyntax(IReadOnlyList Tokens, ExpressionS } } -public record ReturnSyntax(IReadOnlyList Tokens, Optional Value) : StatementSyntax(Tokens) +public record ReturnSyntax(Optional Value) : StatementSyntax { public override IEnumerable GetChildren() { @@ -24,7 +23,7 @@ public record ReturnSyntax(IReadOnlyList Tokens, Optional Tokens, ExpressionSyntax Target, ExpressionSyntax Value) : StatementSyntax(Tokens) +public record AssignmentSyntax(ExpressionSyntax Target, ExpressionSyntax Value) : StatementSyntax { public override IEnumerable GetChildren() { @@ -33,7 +32,7 @@ public record AssignmentSyntax(IReadOnlyList Tokens, ExpressionSyntax Tar } } -public record IfSyntax(IReadOnlyList Tokens, ExpressionSyntax Condition, BlockSyntax Body, Optional> Else) : StatementSyntax(Tokens) +public record IfSyntax(ExpressionSyntax Condition, BlockSyntax Body, Optional> Else) : StatementSyntax { public override IEnumerable GetChildren() { @@ -53,7 +52,7 @@ public record IfSyntax(IReadOnlyList Tokens, ExpressionSyntax Condition, } } -public record VariableDeclarationSyntax(IReadOnlyList Tokens, string Name, Optional ExplicitType, Optional Assignment) : StatementSyntax(Tokens) +public record VariableDeclarationSyntax(string Name, Optional ExplicitType, Optional Assignment) : StatementSyntax { public override IEnumerable GetChildren() { @@ -69,17 +68,17 @@ public record VariableDeclarationSyntax(IReadOnlyList Tokens, string Name } } -public record ContinueSyntax(IReadOnlyList Tokens) : StatementSyntax(Tokens) +public record ContinueSyntax : StatementSyntax { public override IEnumerable GetChildren() => []; } -public record BreakSyntax(IReadOnlyList Tokens) : StatementSyntax(Tokens) +public record BreakSyntax : StatementSyntax { public override IEnumerable GetChildren() => []; } -public record WhileSyntax(IReadOnlyList Tokens, ExpressionSyntax Condition, BlockSyntax Body) : StatementSyntax(Tokens) +public record WhileSyntax(ExpressionSyntax Condition, BlockSyntax Body) : StatementSyntax { public override IEnumerable GetChildren() => []; } \ No newline at end of file diff --git a/src/compiler/NubLang/Syntax/Parsing/Node/SyntaxNode.cs b/src/compiler/NubLang/Syntax/Parsing/Node/SyntaxNode.cs index 4867206..0ae50bd 100644 --- a/src/compiler/NubLang/Syntax/Parsing/Node/SyntaxNode.cs +++ b/src/compiler/NubLang/Syntax/Parsing/Node/SyntaxNode.cs @@ -1,9 +1,6 @@ -using NubLang.Diagnostics; -using NubLang.Syntax.Tokenization; - namespace NubLang.Syntax.Parsing.Node; -public abstract record SyntaxNode(IReadOnlyList Tokens) +public abstract record SyntaxNode { public abstract IEnumerable GetChildren(); @@ -21,7 +18,7 @@ public abstract record SyntaxNode(IReadOnlyList Tokens) } } -public record SyntaxTree(IReadOnlyList Tokens, string Namespace, IReadOnlyList Definitions, IReadOnlyList Diagnostics) : SyntaxNode(Tokens) +public record SyntaxTree(string Namespace, IReadOnlyList Definitions) : SyntaxNode { public override IEnumerable GetChildren() { @@ -32,7 +29,7 @@ public record SyntaxTree(IReadOnlyList Tokens, string Namespace, IReadOnl } } -public record BlockSyntax(IReadOnlyList Tokens, IReadOnlyList Statements) : SyntaxNode(Tokens) +public record BlockSyntax(IReadOnlyList Statements) : SyntaxNode { public override IEnumerable GetChildren() { diff --git a/src/compiler/NubLang/Syntax/Parsing/Node/TypeSyntax.cs b/src/compiler/NubLang/Syntax/Parsing/Node/TypeSyntax.cs index 3d0c9f2..26a29f5 100644 --- a/src/compiler/NubLang/Syntax/Parsing/Node/TypeSyntax.cs +++ b/src/compiler/NubLang/Syntax/Parsing/Node/TypeSyntax.cs @@ -1,5 +1,3 @@ -using NubLang.Syntax.Tokenization; - namespace NubLang.Syntax.Parsing.Node; public enum PrimitiveTypeSyntaxKind @@ -17,7 +15,7 @@ public enum PrimitiveTypeSyntaxKind Bool } -public abstract record TypeSyntax(IReadOnlyList Tokens) : SyntaxNode(Tokens) +public abstract record TypeSyntax : SyntaxNode { public string MangledName() { @@ -36,7 +34,7 @@ public abstract record TypeSyntax(IReadOnlyList Tokens) : SyntaxNode(Toke } } -public record FuncTypeSyntax(IReadOnlyList Tokens, IReadOnlyList Parameters, TypeSyntax ReturnType) : TypeSyntax(Tokens) +public record FuncTypeSyntax(IReadOnlyList Parameters, TypeSyntax ReturnType) : TypeSyntax { public override IEnumerable GetChildren() { @@ -49,7 +47,7 @@ public record FuncTypeSyntax(IReadOnlyList Tokens, IReadOnlyList Tokens, TypeSyntax BaseType) : TypeSyntax(Tokens) +public record PointerTypeSyntax(TypeSyntax BaseType) : TypeSyntax { public override IEnumerable GetChildren() { @@ -57,32 +55,32 @@ public record PointerTypeSyntax(IReadOnlyList Tokens, TypeSyntax BaseType } } -public record VoidTypeSyntax(IReadOnlyList Tokens) : TypeSyntax(Tokens) +public record VoidTypeSyntax : TypeSyntax { public override IEnumerable GetChildren() => []; } -public record PrimitiveTypeSyntax(IReadOnlyList Tokens, PrimitiveTypeSyntaxKind SyntaxKind) : TypeSyntax(Tokens) +public record PrimitiveTypeSyntax(PrimitiveTypeSyntaxKind SyntaxKind) : TypeSyntax { public override IEnumerable GetChildren() => []; } -public record CStringTypeSyntax(IReadOnlyList Tokens) : TypeSyntax(Tokens) +public record CStringTypeSyntax : TypeSyntax { public override IEnumerable GetChildren() => []; } -public record StringTypeSyntax(IReadOnlyList Tokens) : TypeSyntax(Tokens) +public record StringTypeSyntax : TypeSyntax { public override IEnumerable GetChildren() => []; } -public record CustomTypeSyntax(IReadOnlyList Tokens, string Namespace, string Name) : TypeSyntax(Tokens) +public record CustomTypeSyntax(string Namespace, string Name) : TypeSyntax { public override IEnumerable GetChildren() => []; } -public record ArrayTypeSyntax(IReadOnlyList Tokens, TypeSyntax BaseType) : TypeSyntax(Tokens) +public record ArrayTypeSyntax(TypeSyntax BaseType) : TypeSyntax { public override IEnumerable GetChildren() { diff --git a/src/compiler/NubLang/Syntax/Parsing/Parser.cs b/src/compiler/NubLang/Syntax/Parsing/Parser.cs index bca9931..40f0763 100644 --- a/src/compiler/NubLang/Syntax/Parsing/Parser.cs +++ b/src/compiler/NubLang/Syntax/Parsing/Parser.cs @@ -11,7 +11,7 @@ public sealed class Parser private string _namespace; private readonly IReadOnlyList _tokens; - private readonly List _diagnostics = []; + private List _diagnostics = []; private int _tokenIndex; public Parser(IReadOnlyList tokens) @@ -20,9 +20,9 @@ public sealed class Parser _tokens = tokens; } - public SyntaxTree Parse() + public SyntaxTree Parse(out IReadOnlyList diagnostics) { - _diagnostics.Clear(); + _diagnostics = []; _tokenIndex = 0; if (TryExpectSymbol(Symbol.Namespace)) @@ -34,22 +34,19 @@ public sealed class Parser while (Peek().HasValue) { - var startIndex = _tokenIndex; - try { var keyword = ExpectSymbol(); var definition = keyword.Symbol switch { - Symbol.Extern => ParseExtern(startIndex), - Symbol.Func => ParseFunc(startIndex), - Symbol.Struct => ParseStruct(startIndex), - Symbol.Interface => ParseInterface(startIndex), + Symbol.Extern => ParseExtern(), + Symbol.Func => ParseFunc(), + Symbol.Struct => ParseStruct(), + Symbol.Interface => ParseInterface(), _ => throw new ParseException(Diagnostic - .Error($"Expected 'extern', 'func', 'struct', 'trait' or 'impl' but found '{keyword.Symbol}'") - .WithHelp("Valid definition keywords are 'extern', 'func', 'struct', 'trait' and 'impl'") - .At(keyword) + .Error($"Expected 'extern', 'func', 'struct' or 'interface' but found '{keyword.Symbol}'") + .WithHelp("Valid definition keywords are 'extern', 'func', 'struct' and 'interface'") .Build()) }; @@ -71,13 +68,12 @@ public sealed class Parser } } - return new SyntaxTree(_tokens, _namespace, definitions, _diagnostics); + diagnostics = _diagnostics; + return new SyntaxTree(_namespace, definitions); } private FuncSignatureSyntax ParseFuncSignature(FuncParameterSyntax? thisArg = null) { - var startIndex = _tokenIndex; - List parameters = []; if (thisArg != null) @@ -96,38 +92,36 @@ public sealed class Parser _diagnostics.Add(Diagnostic .Warning("Missing comma between function parameters") .WithHelp("Add a ',' to separate parameters") - .At(token) .Build()); } } - var returnType = TryExpectSymbol(Symbol.Colon) ? ParseType() : new VoidTypeSyntax([GetTokens(startIndex).Last()]); + var returnType = TryExpectSymbol(Symbol.Colon) ? ParseType() : new VoidTypeSyntax(); - return new FuncSignatureSyntax(GetTokens(startIndex), parameters, returnType); + return new FuncSignatureSyntax(parameters, returnType); } private FuncParameterSyntax ParseFuncParameter() { - var startIndex = _tokenIndex; var name = ExpectIdentifier(); ExpectSymbol(Symbol.Colon); var type = ParseType(); - return new FuncParameterSyntax(GetTokens(startIndex), name.Value, type); + return new FuncParameterSyntax(name.Value, type); } - private DefinitionSyntax ParseExtern(int startIndex) + private DefinitionSyntax ParseExtern() { var keyword = ExpectSymbol(); return keyword.Symbol switch { - Symbol.Func => ParseExternFunc(startIndex), - _ => throw new ParseException(Diagnostic.Error($"Unexpected symbol {keyword.Symbol} after extern declaration").At(keyword).Build()) + Symbol.Func => ParseExternFunc(), + _ => throw new ParseException(Diagnostic.Error($"Unexpected symbol {keyword.Symbol} after extern declaration").Build()) }; } - private ExternFuncSyntax ParseExternFunc(int startIndex) + private ExternFuncSyntax ParseExternFunc() { var name = ExpectIdentifier(); @@ -140,19 +134,19 @@ public sealed class Parser var signature = ParseFuncSignature(); - return new ExternFuncSyntax(GetTokens(startIndex), _namespace, name.Value, callName, signature); + return new ExternFuncSyntax(_namespace, name.Value, callName, signature); } - private LocalFuncSyntax ParseFunc(int startIndex) + private LocalFuncSyntax ParseFunc() { var name = ExpectIdentifier(); var signature = ParseFuncSignature(); var body = ParseBlock(); - return new LocalFuncSyntax(GetTokens(startIndex), _namespace, name.Value, signature, body); + return new LocalFuncSyntax(_namespace, name.Value, signature, body); } - private DefinitionSyntax ParseStruct(int startIndex) + private DefinitionSyntax ParseStruct() { var name = ExpectIdentifier(); @@ -165,16 +159,14 @@ public sealed class Parser while (!TryExpectSymbol(Symbol.CloseBrace)) { - var memberStartIndex = _tokenIndex; - if (TryExpectSymbol(Symbol.Func)) { var funcName = ExpectIdentifier().Value; - var thisArg = new FuncParameterSyntax([], "this", new CustomTypeSyntax([], _namespace, name.Value)); + var thisArg = new FuncParameterSyntax("this", new CustomTypeSyntax(_namespace, name.Value)); var funcSignature = ParseFuncSignature(thisArg); var funcBody = ParseBlock(); - funcs.Add(new StructFuncSyntax(GetTokens(memberStartIndex), funcName, funcSignature, funcBody)); + funcs.Add(new StructFuncSyntax(funcName, funcSignature, funcBody)); } else { @@ -189,14 +181,14 @@ public sealed class Parser fieldValue = ParseExpression(); } - fields.Add(new StructFieldSyntax(GetTokens(memberStartIndex), fieldIndex++, fieldName, fieldType, fieldValue)); + fields.Add(new StructFieldSyntax(fieldIndex++, fieldName, fieldType, fieldValue)); } } - return new StructSyntax(GetTokens(startIndex), _namespace, name.Value, fields, funcs); + return new StructSyntax(_namespace, name.Value, fields, funcs); } - private InterfaceSyntax ParseInterface(int startIndex) + private InterfaceSyntax ParseInterface() { var name = ExpectIdentifier(); @@ -206,27 +198,23 @@ public sealed class Parser while (!TryExpectSymbol(Symbol.CloseBrace)) { - var funcStartIndex = _tokenIndex; - ExpectSymbol(Symbol.Func); var funcName = ExpectIdentifier().Value; var signature = ParseFuncSignature(); - functions.Add(new InterfaceFuncSyntax(GetTokens(funcStartIndex), funcName, signature)); + functions.Add(new InterfaceFuncSyntax(funcName, signature)); } - return new InterfaceSyntax(GetTokens(startIndex), _namespace, name.Value, functions); + return new InterfaceSyntax(_namespace, name.Value, functions); } private StatementSyntax ParseStatement() { - var startIndex = _tokenIndex; if (!Peek().TryGetValue(out var token)) { throw new ParseException(Diagnostic .Error("Unexpected end of file while parsing statement") - .At(_tokens[^1]) .Build()); } @@ -235,37 +223,37 @@ public sealed class Parser switch (symbol.Symbol) { case Symbol.Return: - return ParseReturn(startIndex); + return ParseReturn(); case Symbol.If: - return ParseIf(startIndex); + return ParseIf(); case Symbol.While: - return ParseWhile(startIndex); + return ParseWhile(); case Symbol.Let: - return ParseVariableDeclaration(startIndex); + return ParseVariableDeclaration(); case Symbol.Break: - return ParseBreak(startIndex); + return ParseBreak(); case Symbol.Continue: - return ParseContinue(startIndex); + return ParseContinue(); } } - return ParseStatementExpression(startIndex); + return ParseStatementExpression(); } - private StatementSyntax ParseStatementExpression(int startIndex) + private StatementSyntax ParseStatementExpression() { var expr = ParseExpression(); if (TryExpectSymbol(Symbol.Assign)) { var value = ParseExpression(); - return new AssignmentSyntax(GetTokens(startIndex), expr, value); + return new AssignmentSyntax(expr, value); } - return new StatementExpressionSyntax(GetTokens(startIndex), expr); + return new StatementExpressionSyntax(expr); } - private VariableDeclarationSyntax ParseVariableDeclaration(int startIndex) + private VariableDeclarationSyntax ParseVariableDeclaration() { ExpectSymbol(Symbol.Let); var name = ExpectIdentifier().Value; @@ -282,23 +270,23 @@ public sealed class Parser assignment = ParseExpression(); } - return new VariableDeclarationSyntax(GetTokens(startIndex), name, explicitType, assignment); + return new VariableDeclarationSyntax(name, explicitType, assignment); } - private StatementSyntax ParseBreak(int startIndex) + private StatementSyntax ParseBreak() { ExpectSymbol(Symbol.Break); Next(); - return new BreakSyntax(GetTokens(startIndex)); + return new BreakSyntax(); } - private StatementSyntax ParseContinue(int startIndex) + private StatementSyntax ParseContinue() { ExpectSymbol(Symbol.Continue); - return new ContinueSyntax(GetTokens(startIndex)); + return new ContinueSyntax(); } - private ReturnSyntax ParseReturn(int startIndex) + private ReturnSyntax ParseReturn() { ExpectSymbol(Symbol.Return); @@ -309,10 +297,10 @@ public sealed class Parser value = ParseExpression(); } - return new ReturnSyntax(GetTokens(startIndex), value); + return new ReturnSyntax(value); } - private IfSyntax ParseIf(int startIndex) + private IfSyntax ParseIf() { ExpectSymbol(Symbol.If); var condition = ParseExpression(); @@ -321,26 +309,24 @@ public sealed class Parser var elseStatement = Optional>.Empty(); if (TryExpectSymbol(Symbol.Else)) { - var newStartIndex = _tokenIndex; elseStatement = TryExpectSymbol(Symbol.If) - ? (Variant)ParseIf(newStartIndex) + ? (Variant)ParseIf() : (Variant)ParseBlock(); } - return new IfSyntax(GetTokens(startIndex), condition, body, elseStatement); + return new IfSyntax(condition, body, elseStatement); } - private WhileSyntax ParseWhile(int startIndex) + private WhileSyntax ParseWhile() { ExpectSymbol(Symbol.While); var condition = ParseExpression(); var body = ParseBlock(); - return new WhileSyntax(GetTokens(startIndex), condition, body); + return new WhileSyntax(condition, body); } private ExpressionSyntax ParseExpression(int precedence = 0) { - var startIndex = _tokenIndex; var left = ParsePrimaryExpression(); while (true) @@ -355,7 +341,7 @@ public sealed class Parser Next(); var right = ParseExpression(GetBinaryOperatorPrecedence(op.Value) + 1); - left = new BinaryExpressionSyntax(GetTokens(startIndex), left, op.Value, right); + left = new BinaryExpressionSyntax(left, op.Value, right); } return left; @@ -421,7 +407,6 @@ public sealed class Parser private ExpressionSyntax ParsePrimaryExpression() { - var startIndex = _tokenIndex; ExpressionSyntax expr; var token = ExpectToken(); @@ -429,7 +414,7 @@ public sealed class Parser { case LiteralToken literal: { - expr = new LiteralSyntax(GetTokens(startIndex), literal.Value, literal.Kind); + expr = new LiteralSyntax(literal.Value, literal.Kind); break; } case IdentifierToken identifier: @@ -442,7 +427,7 @@ public sealed class Parser name = ExpectIdentifier().Value; } - expr = new IdentifierSyntax(GetTokens(startIndex), @namespace, name); + expr = new IdentifierSyntax(@namespace, name); break; } case SymbolToken symbolToken: @@ -455,27 +440,24 @@ public sealed class Parser ExpectSymbol(Symbol.OpenParen); while (!TryExpectSymbol(Symbol.CloseParen)) { - var parameterStartIndex = _tokenIndex; var name = ExpectIdentifier(); - parameters.Add(new ArrowFuncParameterSyntax(GetTokens(parameterStartIndex), name.Value)); + parameters.Add(new ArrowFuncParameterSyntax(name.Value)); } BlockSyntax body; if (TryExpectSymbol(Symbol.Arrow)) { - var blockStartIndex = _tokenIndex; var returnValue = ParseExpression(); - var tokens = GetTokens(blockStartIndex); - var arrowExpression = new ReturnSyntax(tokens, returnValue); - body = new BlockSyntax(tokens, [arrowExpression]); + var arrowExpression = new ReturnSyntax(returnValue); + body = new BlockSyntax([arrowExpression]); } else { body = ParseBlock(); } - expr = new ArrowFuncSyntax(GetTokens(startIndex), parameters, body); + expr = new ArrowFuncSyntax(parameters, body); break; } case Symbol.OpenParen: @@ -488,13 +470,13 @@ public sealed class Parser case Symbol.Minus: { var expression = ParsePrimaryExpression(); - expr = new UnaryExpressionSyntax(GetTokens(startIndex), UnaryOperator.Negate, expression); + expr = new UnaryExpressionSyntax(UnaryOperator.Negate, expression); break; } case Symbol.Bang: { var expression = ParsePrimaryExpression(); - expr = new UnaryExpressionSyntax(GetTokens(startIndex), UnaryOperator.Invert, expression); + expr = new UnaryExpressionSyntax(UnaryOperator.Invert, expression); break; } case Symbol.OpenBracket: @@ -502,7 +484,7 @@ public sealed class Parser var capacity = ParseExpression(); ExpectSymbol(Symbol.CloseBracket); var type = ParseType(); - expr = new ArrayInitializerSyntax(GetTokens(startIndex), capacity, type); + expr = new ArrayInitializerSyntax(capacity, type); break; } case Symbol.Alloc: @@ -518,7 +500,7 @@ public sealed class Parser initializers.Add(name, value); } - expr = new StructInitializerSyntax(GetTokens(startIndex), type, initializers); + expr = new StructInitializerSyntax(type, initializers); break; } default: @@ -526,7 +508,6 @@ public sealed class Parser throw new ParseException(Diagnostic .Error($"Unexpected symbol '{symbolToken.Symbol}' in expression") .WithHelp("Expected literal, identifier, or '(' to start expression") - .At(symbolToken) .Build()); } } @@ -538,34 +519,33 @@ public sealed class Parser throw new ParseException(Diagnostic .Error($"Unexpected token '{token.GetType().Name}' in expression") .WithHelp("Expected literal, identifier, or parenthesized expression") - .At(token) .Build()); } } - return ParsePostfixOperators(startIndex, expr); + return ParsePostfixOperators(expr); } - private ExpressionSyntax ParsePostfixOperators(int startIndex, ExpressionSyntax expr) + private ExpressionSyntax ParsePostfixOperators(ExpressionSyntax expr) { while (true) { if (TryExpectSymbol(Symbol.Ampersand)) { - expr = new AddressOfSyntax(GetTokens(startIndex), expr); + expr = new AddressOfSyntax(expr); break; } if (TryExpectSymbol(Symbol.Caret)) { - expr = new DereferenceSyntax(GetTokens(startIndex), expr); + expr = new DereferenceSyntax(expr); continue; } if (TryExpectSymbol(Symbol.Period)) { var structMember = ExpectIdentifier().Value; - expr = new MemberAccessSyntax(GetTokens(startIndex), expr, structMember); + expr = new MemberAccessSyntax(expr, structMember); continue; } @@ -573,7 +553,7 @@ public sealed class Parser { var index = ParseExpression(); ExpectSymbol(Symbol.CloseBracket); - expr = new ArrayIndexAccessSyntax(GetTokens(startIndex), expr, index); + expr = new ArrayIndexAccessSyntax(expr, index); continue; } @@ -588,12 +568,11 @@ public sealed class Parser _diagnostics.Add(Diagnostic .Warning("Missing comma between function arguments") .WithHelp("Add a ',' to separate arguments") - .At(nextToken) .Build()); } } - expr = new FuncCallSyntax(GetTokens(startIndex), expr, parameters); + expr = new FuncCallSyntax(expr, parameters); continue; } @@ -605,7 +584,6 @@ public sealed class Parser private BlockSyntax ParseBlock() { - var startIndex = _tokenIndex; ExpectSymbol(Symbol.OpenBrace); List statements = []; while (Peek().HasValue && !TryExpectSymbol(Symbol.CloseBrace)) @@ -621,31 +599,29 @@ public sealed class Parser } } - return new BlockSyntax(GetTokens(startIndex), statements); + return new BlockSyntax(statements); } private TypeSyntax ParseType() { - var startIndex = _tokenIndex; - if (TryExpectIdentifier(out var name)) { return name.Value switch { - "void" => new VoidTypeSyntax(GetTokens(startIndex)), - "string" => new StringTypeSyntax(GetTokens(startIndex)), - "cstring" => new CStringTypeSyntax(GetTokens(startIndex)), - "i64" => new PrimitiveTypeSyntax(GetTokens(startIndex), PrimitiveTypeSyntaxKind.I64), - "i32" => new PrimitiveTypeSyntax(GetTokens(startIndex), PrimitiveTypeSyntaxKind.I32), - "i16" => new PrimitiveTypeSyntax(GetTokens(startIndex), PrimitiveTypeSyntaxKind.I16), - "i8" => new PrimitiveTypeSyntax(GetTokens(startIndex), PrimitiveTypeSyntaxKind.I8), - "u64" => new PrimitiveTypeSyntax(GetTokens(startIndex), PrimitiveTypeSyntaxKind.U64), - "u32" => new PrimitiveTypeSyntax(GetTokens(startIndex), PrimitiveTypeSyntaxKind.U32), - "u16" => new PrimitiveTypeSyntax(GetTokens(startIndex), PrimitiveTypeSyntaxKind.U16), - "u8" => new PrimitiveTypeSyntax(GetTokens(startIndex), PrimitiveTypeSyntaxKind.U8), - "f64" => new PrimitiveTypeSyntax(GetTokens(startIndex), PrimitiveTypeSyntaxKind.F64), - "f32" => new PrimitiveTypeSyntax(GetTokens(startIndex), PrimitiveTypeSyntaxKind.F32), - "bool" => new PrimitiveTypeSyntax(GetTokens(startIndex), PrimitiveTypeSyntaxKind.Bool), + "void" => new VoidTypeSyntax(), + "string" => new StringTypeSyntax(), + "cstring" => new CStringTypeSyntax(), + "i64" => new PrimitiveTypeSyntax(PrimitiveTypeSyntaxKind.I64), + "i32" => new PrimitiveTypeSyntax(PrimitiveTypeSyntaxKind.I32), + "i16" => new PrimitiveTypeSyntax(PrimitiveTypeSyntaxKind.I16), + "i8" => new PrimitiveTypeSyntax(PrimitiveTypeSyntaxKind.I8), + "u64" => new PrimitiveTypeSyntax(PrimitiveTypeSyntaxKind.U64), + "u32" => new PrimitiveTypeSyntax(PrimitiveTypeSyntaxKind.U32), + "u16" => new PrimitiveTypeSyntax(PrimitiveTypeSyntaxKind.U16), + "u8" => new PrimitiveTypeSyntax(PrimitiveTypeSyntaxKind.U8), + "f64" => new PrimitiveTypeSyntax(PrimitiveTypeSyntaxKind.F64), + "f32" => new PrimitiveTypeSyntax(PrimitiveTypeSyntaxKind.F32), + "bool" => new PrimitiveTypeSyntax(PrimitiveTypeSyntaxKind.Bool), _ => ParseCustomType() }; @@ -657,14 +633,14 @@ public sealed class Parser @namespace = ExpectIdentifier().Value; } - return new CustomTypeSyntax(GetTokens(startIndex), @namespace, name.Value); + return new CustomTypeSyntax(@namespace, name.Value); } } if (TryExpectSymbol(Symbol.Caret)) { var baseType = ParseType(); - return new PointerTypeSyntax(GetTokens(startIndex), baseType); + return new PointerTypeSyntax(baseType); } if (TryExpectSymbol(Symbol.Func)) @@ -680,21 +656,20 @@ public sealed class Parser _diagnostics.Add(Diagnostic .Warning("Missing comma between func type arguments") .WithHelp("Add a ',' to separate arguments") - .At(nextToken) .Build()); } } - var returnType = TryExpectSymbol(Symbol.Colon) ? ParseType() : new VoidTypeSyntax(GetTokens(startIndex)); + var returnType = TryExpectSymbol(Symbol.Colon) ? ParseType() : new VoidTypeSyntax(); - return new FuncTypeSyntax(GetTokens(startIndex), parameters, returnType); + return new FuncTypeSyntax(parameters, returnType); } if (TryExpectSymbol(Symbol.OpenBracket)) { ExpectSymbol(Symbol.CloseBracket); var baseType = ParseType(); - return new ArrayTypeSyntax(GetTokens(startIndex), baseType); + return new ArrayTypeSyntax(baseType); } if (!Peek().TryGetValue(out var peekToken)) @@ -702,14 +677,12 @@ public sealed class Parser throw new ParseException(Diagnostic .Error("Unexpected end of file while parsing type") .WithHelp("Expected a type name") - .At(_tokens[^1]) .Build()); } throw new ParseException(Diagnostic .Error("Invalid type Syntax") .WithHelp("Expected type name, '^' for pointer, or '[]' for array") - .At(peekToken) .Build()); } @@ -720,7 +693,6 @@ public sealed class Parser throw new ParseException(Diagnostic .Error("Unexpected end of file") .WithHelp("Expected more tokens to complete the Syntax") - .At(_tokens.Last()) .Build()); } @@ -736,7 +708,6 @@ public sealed class Parser throw new ParseException(Diagnostic .Error($"Expected symbol, but found {token.GetType().Name}") .WithHelp("This position requires a symbol like '(', ')', '{', '}', etc.") - .At(token) .Build()); } @@ -751,7 +722,6 @@ public sealed class Parser throw new ParseException(Diagnostic .Error($"Expected '{expectedSymbol}', but found '{token.Symbol}'") .WithHelp($"Insert '{expectedSymbol}' here") - .At(token) .Build()); } } @@ -788,7 +758,6 @@ public sealed class Parser throw new ParseException(Diagnostic .Error($"Expected identifier, but found {token.GetType().Name}") .WithHelp("Provide a valid identifier name here") - .At(token) .Build()); } @@ -810,11 +779,6 @@ public sealed class Parser { _tokenIndex++; } - - private List GetTokens(int startIndex) - { - return _tokens.Skip(startIndex).Take(Math.Min(_tokenIndex, _tokens.Count - 1) - startIndex).ToList(); - } } public class ParseException : Exception diff --git a/src/compiler/NubLang/Syntax/Tokenization/Token.cs b/src/compiler/NubLang/Syntax/Tokenization/Token.cs index 03b39de..c932895 100644 --- a/src/compiler/NubLang/Syntax/Tokenization/Token.cs +++ b/src/compiler/NubLang/Syntax/Tokenization/Token.cs @@ -1,16 +1,13 @@ namespace NubLang.Syntax.Tokenization; -public abstract class Token(SourceSpan span) -{ - public SourceSpan Span { get; } = span; -} +public abstract class Token; -public class IdentifierToken(SourceSpan span, string value) : Token(span) +public class IdentifierToken(string value) : Token { public string Value { get; } = value; } -public class LiteralToken(SourceSpan span, LiteralKind kind, string value) : Token(span) +public class LiteralToken(LiteralKind kind, string value) : Token { public LiteralKind Kind { get; } = kind; public string Value { get; } = value; @@ -24,7 +21,7 @@ public enum LiteralKind Bool } -public class SymbolToken(SourceSpan span, Symbol symbol) : Token(span) +public class SymbolToken(Symbol symbol) : Token { public Symbol Symbol { get; } = symbol; } diff --git a/src/compiler/NubLang/Syntax/Tokenization/Tokenizer.cs b/src/compiler/NubLang/Syntax/Tokenization/Tokenizer.cs index 0a43728..c80d237 100644 --- a/src/compiler/NubLang/Syntax/Tokenization/Tokenizer.cs +++ b/src/compiler/NubLang/Syntax/Tokenization/Tokenizer.cs @@ -24,7 +24,7 @@ public sealed class Tokenizer ["extern"] = Symbol.Extern, }; - private static readonly Dictionary Chians = new() + private static readonly Dictionary Symbols = new() { [['=', '=']] = Symbol.Equal, [['!', '=']] = Symbol.NotEqual, @@ -32,36 +32,32 @@ public sealed class Tokenizer [['>', '=']] = Symbol.GreaterThanOrEqual, [[':', ':']] = Symbol.DoubleColon, [['=', '>']] = Symbol.Arrow, + [[':']] = Symbol.Colon, + [['(']] = Symbol.OpenParen, + [[')']] = Symbol.CloseParen, + [['{']] = Symbol.OpenBrace, + [['}']] = Symbol.CloseBrace, + [['[']] = Symbol.OpenBracket, + [[']']] = Symbol.CloseBracket, + [[',']] = Symbol.Comma, + [['.']] = Symbol.Period, + [['=']] = Symbol.Assign, + [['<']] = Symbol.LessThan, + [['>']] = Symbol.GreaterThan, + [['+']] = Symbol.Plus, + [['-']] = Symbol.Minus, + [['*']] = Symbol.Star, + [['/']] = Symbol.ForwardSlash, + [['!']] = Symbol.Bang, + [['^']] = Symbol.Caret, + [['&']] = Symbol.Ampersand, + [[';']] = Symbol.Semi, }; - private static readonly Dictionary Chars = new() - { - [':'] = Symbol.Colon, - ['('] = Symbol.OpenParen, - [')'] = Symbol.CloseParen, - ['{'] = Symbol.OpenBrace, - ['}'] = Symbol.CloseBrace, - ['['] = Symbol.OpenBracket, - [']'] = Symbol.CloseBracket, - [','] = Symbol.Comma, - ['.'] = Symbol.Period, - ['='] = Symbol.Assign, - ['<'] = Symbol.LessThan, - ['>'] = Symbol.GreaterThan, - ['+'] = Symbol.Plus, - ['-'] = Symbol.Minus, - ['*'] = Symbol.Star, - ['/'] = Symbol.ForwardSlash, - ['!'] = Symbol.Bang, - ['^'] = Symbol.Caret, - ['&'] = Symbol.Ampersand, - [';'] = Symbol.Semi, - }; - - private readonly SourceText _sourceText; + private readonly string _sourceText; private int _index; - public Tokenizer(SourceText sourceText) + public Tokenizer(string sourceText) { _sourceText = sourceText; } @@ -122,15 +118,15 @@ public sealed class Tokenizer if (Keywords.TryGetValue(buffer, out var keywordSymbol)) { - return new SymbolToken(CreateSpan(startIndex), keywordSymbol); + return new SymbolToken(keywordSymbol); } if (buffer is "true" or "false") { - return new LiteralToken(CreateSpan(startIndex), LiteralKind.Bool, buffer); + return new LiteralToken(LiteralKind.Bool, buffer); } - return new IdentifierToken(CreateSpan(startIndex), buffer); + return new IdentifierToken(buffer); } if (char.IsDigit(current)) @@ -162,15 +158,12 @@ public sealed class Tokenizer } } - return new LiteralToken(CreateSpan(startIndex), isFloat ? LiteralKind.Float : LiteralKind.Integer, buffer); + return new LiteralToken(isFloat ? LiteralKind.Float : LiteralKind.Integer, buffer); } - // TODO: Revisit this - foreach (var chain in Chians) + foreach (var chain in Symbols) { - if (current != chain.Key[0]) continue; - - for (var i = 1; i < chain.Key.Length; i++) + for (var i = 0; i < chain.Key.Length; i++) { var c = Peek(i); if (!c.HasValue || c.Value != chain.Key[i]) break; @@ -182,17 +175,11 @@ public sealed class Tokenizer Next(); } - return new SymbolToken(CreateSpan(startIndex), chain.Value); + return new SymbolToken(chain.Value); } } } - if (Chars.TryGetValue(current, out var charSymbol)) - { - Next(); - return new SymbolToken(CreateSpan(startIndex), charSymbol); - } - if (current == '"') { Next(); @@ -215,42 +202,17 @@ public sealed class Tokenizer Next(); } - return new LiteralToken(CreateSpan(startIndex), LiteralKind.String, buffer); + return new LiteralToken(LiteralKind.String, buffer); } throw new Exception($"Unknown character {current}"); } - private SourceLocation CreateLocation(int index) - { - var line = 1; - var column = 1; - for (var i = 0; i < Math.Min(index, _sourceText.Content.Length - 1); i++) - { - if (_sourceText.Content[i] == '\n') - { - column = 1; - line += 1; - } - else - { - column += 1; - } - } - - return new SourceLocation(line, column); - } - - private SourceSpan CreateSpan(int startIndex) - { - return new SourceSpan(_sourceText, CreateLocation(startIndex), CreateLocation(_index)); - } - private Optional Peek(int offset = 0) { - if (_index + offset < _sourceText.Content.Length) + if (_index + offset < _sourceText.Length) { - return _sourceText.Content[_index + offset]; + return _sourceText[_index + offset]; } return Optional.Empty(); @@ -258,9 +220,9 @@ public sealed class Tokenizer private Optional Next() { - if (_index < _sourceText.Content.Length) + if (_index < _sourceText.Length) { - return _sourceText.Content[_index++]; + return _sourceText[_index++]; } _index++;