From eb009b6ac03b2c0953482611f87a9943eb78d5bd Mon Sep 17 00:00:00 2001 From: nub31 Date: Tue, 22 Jul 2025 22:44:55 +0200 Subject: [PATCH] ... --- src/compiler/NubLang.CLI/Program.cs | 9 +- .../NubLang.CLI/assets/libruntime_x64.a | Bin 7558 -> 7550 bytes .../Generation/BoundDefinitionTable.cs | 16 +- .../Generation/QBE/QBEGenerator.Expression.cs | 8 +- .../NubLang/Generation/QBE/QBEGenerator.cs | 12 +- src/compiler/NubLang/Syntax/Binding/Binder.cs | 58 ++--- .../NubLang/Syntax/Binding/DefinitionTable.cs | 21 +- .../Syntax/Binding/Node/BoundDefinition.cs | 12 +- .../Syntax/Binding/Node/BoundExpression.cs | 4 +- .../Syntax/Binding/Node/BoundSyntaxTree.cs | 2 +- .../NubLang/Syntax/Binding/NubType.cs | 25 +- .../Syntax/Parsing/Node/DefinitionSyntax.cs | 10 +- .../Syntax/Parsing/Node/ExpressionSyntax.cs | 2 +- .../NubLang/Syntax/Parsing/Node/SyntaxNode.cs | 2 +- .../NubLang/Syntax/Parsing/Node/TypeSyntax.cs | 4 +- src/compiler/NubLang/Syntax/Parsing/Parser.cs | 64 ++--- .../NubLang/Syntax/Tokenization/Token.cs | 2 - .../NubLang/Syntax/Tokenization/Tokenizer.cs | 223 +++++++++--------- 18 files changed, 200 insertions(+), 274 deletions(-) diff --git a/src/compiler/NubLang.CLI/Program.cs b/src/compiler/NubLang.CLI/Program.cs index 8baec03..ba1639f 100644 --- a/src/compiler/NubLang.CLI/Program.cs +++ b/src/compiler/NubLang.CLI/Program.cs @@ -81,12 +81,11 @@ foreach (var file in options.Files) foreach (var file in options.Files) { var tokenizer = new Tokenizer(file.GetText()); - var tokenizeResult = tokenizer.Tokenize(out var tokenizerDiagnostics); - diagnostics.AddRange(tokenizerDiagnostics); + var tokens = tokenizer.Tokenize(); - var parser = new Parser(tokenizeResult); - var syntaxTree = parser.Parse(out var parserDiagnostics); - diagnostics.AddRange(parserDiagnostics); + var parser = new Parser(); + var syntaxTree = parser.Parse(tokens); + diagnostics.AddRange(parser.GetDiagnostics()); syntaxTrees.Add(syntaxTree); } diff --git a/src/compiler/NubLang.CLI/assets/libruntime_x64.a b/src/compiler/NubLang.CLI/assets/libruntime_x64.a index 61d3d147fe9ed262e561690488212ad4e1290ce2..d43a5680dbe79e118fb2c5f907a572b0754c015a 100644 GIT binary patch delta 63 zcmV-F0Kor-JN`PbOcVk%G?PvgFafBue-wWLvj!KK0s*kIpBX;^0mzfz8ovQRlb;*E V0nn3Q9LE6-le-f)0RWR<9Vf)+6|(>U delta 80 zcmexo)n>iHM}*1LXtJM(0po_v^&<6594V=3iKRIu@tgmN&0u2Ov3a_rJtO0V$=9X! iGkQ#(F1?@e#^i9Bw|IanCLVDaR5NqGQ?BpMz7 diff --git a/src/compiler/NubLang/Generation/BoundDefinitionTable.cs b/src/compiler/NubLang/Generation/BoundDefinitionTable.cs index 1fc7c87..233f945 100644 --- a/src/compiler/NubLang/Generation/BoundDefinitionTable.cs +++ b/src/compiler/NubLang/Generation/BoundDefinitionTable.cs @@ -12,25 +12,25 @@ public sealed class BoundDefinitionTable _definitions = syntaxTrees.SelectMany(x => x.Definitions).ToList(); } - public BoundLocalFunc LookupLocalFunc(string @namespace, string name) + public BoundLocalFunc LookupLocalFunc(string name) { return _definitions .OfType() - .First(x => x.Namespace == @namespace && x.Name == name); + .First(x => x.Name == name); } - public BoundExternFunc LookupExternFunc(string @namespace, string name) + public BoundExternFunc LookupExternFunc(string name) { return _definitions .OfType() - .First(x => x.Namespace == @namespace && x.Name == name); + .First(x => x.Name == name); } - public BoundStruct LookupStruct(string @namespace, string name) + public BoundStruct LookupStruct(string name) { return _definitions .OfType() - .First(x => x.Namespace == @namespace && x.Name == name); + .First(x => x.Name == name); } public BoundStructField LookupStructField(BoundStruct @struct, string field) @@ -54,11 +54,11 @@ public sealed class BoundDefinitionTable .First(x => x.Name == name); } - public BoundTrait LookupTrait(string @namespace, string name) + public BoundTrait LookupTrait(string name) { return _definitions .OfType() - .First(x => x.Namespace == @namespace && x.Name == name); + .First(x => x.Name == name); } public BoundTraitFunc LookupTraitFunc(BoundTrait trait, string name) diff --git a/src/compiler/NubLang/Generation/QBE/QBEGenerator.Expression.cs b/src/compiler/NubLang/Generation/QBE/QBEGenerator.Expression.cs index e26fd6c..7e493ea 100644 --- a/src/compiler/NubLang/Generation/QBE/QBEGenerator.Expression.cs +++ b/src/compiler/NubLang/Generation/QBE/QBEGenerator.Expression.cs @@ -224,13 +224,13 @@ public partial class QBEGenerator private Val EmitExternFuncIdent(BoundExternFuncIdent externFuncIdent) { - var func = _definitionTable.LookupExternFunc(externFuncIdent.Namespace, externFuncIdent.Name); + var func = _definitionTable.LookupExternFunc(externFuncIdent.Name); return new Val(ExternFuncName(func), externFuncIdent.Type, ValKind.Direct); } private Val EmitLocalFuncIdent(BoundLocalFuncIdent localFuncIdent) { - var func = _definitionTable.LookupLocalFunc(localFuncIdent.Namespace, localFuncIdent.Name); + var func = _definitionTable.LookupLocalFunc(localFuncIdent.Name); return new Val(LocalFuncName(func), localFuncIdent.Type, ValKind.Direct); } @@ -323,7 +323,7 @@ public partial class QBEGenerator private Val EmitStructInitializer(BoundStructInitializer structInitializer, string? destination = null) { - var @struct = _definitionTable.LookupStruct(structInitializer.StructType.Namespace, structInitializer.StructType.Name); + var @struct = _definitionTable.LookupStruct(structInitializer.StructType.Name); if (destination == null) { @@ -400,7 +400,7 @@ public partial class QBEGenerator { var target = EmitUnwrap(EmitExpression(structFieldAccess.Target)); - var structDef = _definitionTable.LookupStruct(structFieldAccess.StructType.Namespace, structFieldAccess.StructType.Name); + var structDef = _definitionTable.LookupStruct(structFieldAccess.StructType.Name); var offset = OffsetOf(structDef, structFieldAccess.Field); var output = TmpName(); diff --git a/src/compiler/NubLang/Generation/QBE/QBEGenerator.cs b/src/compiler/NubLang/Generation/QBE/QBEGenerator.cs index b53dd19..a4ff66a 100644 --- a/src/compiler/NubLang/Generation/QBE/QBEGenerator.cs +++ b/src/compiler/NubLang/Generation/QBE/QBEGenerator.cs @@ -373,7 +373,7 @@ public partial class QBEGenerator private void EmitStructDefinition(BoundStruct structDef) { - _writer.WriteLine($"type {CustomTypeName(structDef.Namespace, structDef.Name)} = {{ "); + _writer.WriteLine($"type {CustomTypeName(structDef.Name)} = {{ "); var types = new Dictionary(); @@ -419,7 +419,7 @@ public partial class QBEGenerator private void EmitTraitVTable(BoundTrait traitDef) { - _writer.WriteLine($"type {CustomTypeName(traitDef.Namespace, traitDef.Name)} = {{"); + _writer.WriteLine($"type {CustomTypeName(traitDef.Name)} = {{"); foreach (var func in traitDef.Functions) { @@ -500,7 +500,7 @@ public partial class QBEGenerator private string LocalFuncName(BoundLocalFunc funcDef) { - return $"${funcDef.Namespace}_{funcDef.Name}"; + return $"${funcDef.Name}"; } private string ExternFuncName(BoundExternFunc funcDef) @@ -510,12 +510,12 @@ public partial class QBEGenerator private string CustomTypeName(NubCustomType customType) { - return CustomTypeName(customType.Namespace, customType.Name); + return CustomTypeName(customType.Name); } - private string CustomTypeName(string @namespace, string name) + private string CustomTypeName(string name) { - return $":{@namespace}_{name}"; + return $":{name}"; } #endregion diff --git a/src/compiler/NubLang/Syntax/Binding/Binder.cs b/src/compiler/NubLang/Syntax/Binding/Binder.cs index 50243fe..c5ee868 100644 --- a/src/compiler/NubLang/Syntax/Binding/Binder.cs +++ b/src/compiler/NubLang/Syntax/Binding/Binder.cs @@ -42,7 +42,7 @@ public sealed class Binder } } - return new BoundSyntaxTree(_syntaxTree.Namespace, definitions, diagnostics); + return new BoundSyntaxTree(definitions, diagnostics); } private BoundDefinition BindDefinition(DefinitionSyntax node) @@ -66,7 +66,7 @@ public sealed class Binder functions.Add(new BoundTraitFunc(function.Name, BindFuncSignature(function.Signature))); } - return new BoundTrait(node.Namespace, node.Name, functions); + return new BoundTrait(node.Name, functions); } private BoundStruct BindStruct(StructSyntax node) @@ -85,12 +85,12 @@ public sealed class Binder structFields.Add(new BoundStructField(field.Index, field.Name, BindType(field.Type), value)); } - return new BoundStruct(node.Namespace, node.Name, structFields); + return new BoundStruct(node.Name, structFields); } private BoundExternFunc BindExternFuncDefinition(ExternFuncSyntax node) { - return new BoundExternFunc(node.Namespace, node.Name, node.CallName, BindFuncSignature(node.Signature)); + return new BoundExternFunc(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.Namespace, node.Name, signature, body); + return new BoundLocalFunc(node.Name, signature, body); } private BoundStatement BindStatement(StatementSyntax node) @@ -299,13 +299,18 @@ public sealed class Binder private BoundExpression BindIdentifier(IdentifierSyntax expression) { - var @namespace = expression.Namespace.Or(_syntaxTree.Namespace); - var localFuncs = _definitionTable.LookupLocalFunc(@namespace, expression.Name).ToArray(); + var variable = Scope.Lookup(expression.Name); + if (variable != null) + { + return new BoundVariableIdent(variable.Type, variable.Name); + } + + var localFuncs = _definitionTable.LookupLocalFunc(expression.Name).ToArray(); if (localFuncs.Length > 0) { if (localFuncs.Length > 1) { - throw new BindException(Diagnostic.Error($"Extern func {expression.Namespace}::{expression.Name} has multiple definitions").Build()); + throw new BindException(Diagnostic.Error($"Extern func {expression.Name} has multiple definitions").Build()); } var localFunc = localFuncs[0]; @@ -313,15 +318,15 @@ 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(type, @namespace, expression.Name); + return new BoundLocalFuncIdent(type, expression.Name); } - var externFuncs = _definitionTable.LookupExternFunc(@namespace, expression.Name).ToArray(); + var externFuncs = _definitionTable.LookupExternFunc(expression.Name).ToArray(); if (externFuncs.Length > 0) { if (externFuncs.Length > 1) { - throw new BindException(Diagnostic.Error($"Extern func {expression.Namespace}::{expression.Name} has multiple definitions").Build()); + throw new BindException(Diagnostic.Error($"Extern func {expression.Name} has multiple definitions").Build()); } var externFunc = externFuncs[0]; @@ -329,19 +334,10 @@ 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(type, @namespace, expression.Name); + return new BoundExternFuncIdent(type, expression.Name); } - if (!expression.Namespace.HasValue) - { - var variable = Scope.Lookup(expression.Name); - if (variable != null) - { - return new BoundVariableIdent(variable.Type, variable.Name); - } - } - - throw new BindException(Diagnostic.Error($"No identifier with the name {(expression.Namespace.HasValue ? $"{expression.Namespace.Value}::" : "")}{expression.Name} exists").Build()); + throw new BindException(Diagnostic.Error($"No identifier with the name {expression.Name} exists").Build()); } private BoundLiteral BindLiteral(LiteralSyntax expression, NubType? expectedType = null) @@ -362,22 +358,6 @@ public sealed class Binder { var boundExpression = BindExpression(expression.Target); - // var traitFuncImpls = _definitionTable.LookupTraitFuncImpl(boundExpression.Type, expression.Member).ToArray(); - // if (traitFuncImpls.Length > 0) - // { - // if (traitFuncImpls.Length > 1) - // { - // throw new BindException(Diagnostic.Error($"Type {boundExpression.Type} implements multiple traits with the function {expression.Member}").Build()); - // } - // - // var impl = traitFuncImpls[0]; - // - // 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(type, boundExpression, expression.Member); - // } - if (boundExpression.Type is NubCustomType customType) { var traits = _definitionTable.LookupTrait(customType).ToArray(); @@ -593,7 +573,7 @@ public sealed class Binder { ArrayTypeSyntax type => new NubArrayType(BindType(type.BaseType)), CStringTypeSyntax => new NubCStringType(), - CustomTypeSyntax type => new NubCustomType(type.Namespace, type.MangledName()), + CustomTypeSyntax type => new NubCustomType(type.MangledName()), FuncTypeSyntax type => new NubFuncType(type.Parameters.Select(BindType).ToList(), BindType(type.ReturnType)), PointerTypeSyntax type => new NubPointerType(BindType(type.BaseType)), PrimitiveTypeSyntax type => new NubPrimitiveType(type.SyntaxKind switch diff --git a/src/compiler/NubLang/Syntax/Binding/DefinitionTable.cs b/src/compiler/NubLang/Syntax/Binding/DefinitionTable.cs index 7cddd36..4513060 100644 --- a/src/compiler/NubLang/Syntax/Binding/DefinitionTable.cs +++ b/src/compiler/NubLang/Syntax/Binding/DefinitionTable.cs @@ -11,25 +11,25 @@ public class DefinitionTable _definitions = syntaxTrees.SelectMany(x => x.Definitions).ToList(); } - public IEnumerable LookupLocalFunc(string @namespace, string name) + public IEnumerable LookupLocalFunc(string name) { return _definitions .OfType() - .Where(x => x.Namespace == @namespace && x.Name == name); + .Where(x => x.Name == name); } - public IEnumerable LookupExternFunc(string @namespace, string name) + public IEnumerable LookupExternFunc(string name) { return _definitions .OfType() - .Where(x => x.Namespace == @namespace && x.Name == name); + .Where(x => x.Name == name); } public IEnumerable LookupStruct(NubCustomType type) { return _definitions .OfType() - .Where(x => x.Namespace == type.Namespace && x.Name == type.Name); + .Where(x => x.Name == type.Name); } public IEnumerable LookupStructField(StructSyntax structNode, string field) @@ -37,20 +37,11 @@ public class DefinitionTable return structNode.Fields.Where(x => x.Name == field); } - // public IEnumerable LookupTraitFuncImpl(NubType forType, string name) - // { - // return _definitions - // .OfType() - // .Where(x => x.ForType == forType) - // .SelectMany(x => x.Functions) - // .Where(x => x.Name == name); - // } - public IEnumerable LookupTrait(NubCustomType type) { return _definitions .OfType() - .Where(x => x.Namespace == type.Namespace && x.Name == type.Name); + .Where(x => x.Name == type.Name); } public IEnumerable LookupTraitFunc(InterfaceSyntax @interface, string name) diff --git a/src/compiler/NubLang/Syntax/Binding/Node/BoundDefinition.cs b/src/compiler/NubLang/Syntax/Binding/Node/BoundDefinition.cs index b980cb7..922a9e8 100644 --- a/src/compiler/NubLang/Syntax/Binding/Node/BoundDefinition.cs +++ b/src/compiler/NubLang/Syntax/Binding/Node/BoundDefinition.cs @@ -2,24 +2,24 @@ namespace NubLang.Syntax.Binding.Node; -public abstract record BoundDefinition(string Namespace) : BoundNode; +public abstract record BoundDefinition : BoundNode; public record BoundFuncParameter(string Name, NubType Type) : BoundNode; public record BoundFuncSignature(IReadOnlyList Parameters, NubType ReturnType) : BoundNode; -public record BoundLocalFunc(string Namespace, string Name, BoundFuncSignature Signature, BoundBlock Body) : BoundDefinition(Namespace); +public record BoundLocalFunc(string Name, BoundFuncSignature Signature, BoundBlock Body) : BoundDefinition; -public record BoundExternFunc(string Namespace, string Name, string CallName, BoundFuncSignature Signature) : BoundDefinition(Namespace); +public record BoundExternFunc(string Name, string CallName, BoundFuncSignature Signature) : BoundDefinition; public record BoundStructField(int Index, string Name, NubType Type, Optional Value) : BoundNode; -public record BoundStruct(string Namespace, string Name, IReadOnlyList Fields) : BoundDefinition(Namespace); +public record BoundStruct(string Name, IReadOnlyList Fields) : BoundDefinition; public record BoundTraitFunc(string Name, BoundFuncSignature Signature) : BoundNode; -public record BoundTrait(string Namespace, string Name, IReadOnlyList Functions) : BoundDefinition(Namespace); +public record BoundTrait(string Name, IReadOnlyList Functions) : BoundDefinition; public record BoundTraitFuncImpl(string Name, BoundFuncSignature Signature, BoundBlock Body) : BoundNode; -public record BoundTraitImpl(string Namespace, NubType TraitType, NubType ForType, IReadOnlyList Functions) : BoundDefinition(Namespace); \ No newline at end of file +public record BoundTraitImpl(NubType TraitType, NubType ForType, IReadOnlyList Functions) : BoundDefinition; \ 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 c01f1a8..d5e3796 100644 --- a/src/compiler/NubLang/Syntax/Binding/Node/BoundExpression.cs +++ b/src/compiler/NubLang/Syntax/Binding/Node/BoundExpression.cs @@ -32,9 +32,9 @@ public record BoundFuncCall(NubType Type, BoundExpression Expression, IReadOnlyL public record BoundVariableIdent(NubType Type, string Name) : BoundExpression(Type); -public record BoundLocalFuncIdent(NubType Type, string Namespace, string Name) : BoundExpression(Type); +public record BoundLocalFuncIdent(NubType Type, string Name) : BoundExpression(Type); -public record BoundExternFuncIdent(NubType Type, string Namespace, string Name) : BoundExpression(Type); +public record BoundExternFuncIdent(NubType Type, string Name) : BoundExpression(Type); public record BoundArrayInitializer(NubType Type, BoundExpression Capacity, NubType ElementType) : BoundExpression(Type); diff --git a/src/compiler/NubLang/Syntax/Binding/Node/BoundSyntaxTree.cs b/src/compiler/NubLang/Syntax/Binding/Node/BoundSyntaxTree.cs index b3c3067..7867e39 100644 --- a/src/compiler/NubLang/Syntax/Binding/Node/BoundSyntaxTree.cs +++ b/src/compiler/NubLang/Syntax/Binding/Node/BoundSyntaxTree.cs @@ -2,7 +2,7 @@ namespace NubLang.Syntax.Binding.Node; -public record BoundSyntaxTree(string Namespace, IReadOnlyList Definitions, IReadOnlyList Diagnostics); +public record BoundSyntaxTree(IReadOnlyList Definitions, IReadOnlyList Diagnostics); public abstract record BoundNode; diff --git a/src/compiler/NubLang/Syntax/Binding/NubType.cs b/src/compiler/NubLang/Syntax/Binding/NubType.cs index f40805a..f884732 100644 --- a/src/compiler/NubLang/Syntax/Binding/NubType.cs +++ b/src/compiler/NubLang/Syntax/Binding/NubType.cs @@ -226,21 +226,20 @@ public class NubStringType : NubComplexType public override int GetHashCode() => HashCode.Combine(typeof(NubStringType)); } -public class NubCustomType(string @namespace, string name) : NubComplexType +public class NubCustomType(string name) : NubComplexType { - public string Namespace { get; } = @namespace; public string Name { get; } = name; public CustomTypeKind Kind(BoundDefinitionTable definitionTable) { - if (definitionTable.GetStructs().Any(x => x.Namespace == Namespace && x.Name == Name)) + if (definitionTable.GetStructs().Any(x => x.Name == Name)) { return CustomTypeKind.Struct; } - if (definitionTable.GetTraits().Any(x => x.Namespace == Namespace && x.Name == Name)) + if (definitionTable.GetTraits().Any(x => x.Name == Name)) { - return CustomTypeKind.Trait; + return CustomTypeKind.Interface; } throw new ArgumentException($"Definition table does not have any type information for {this}"); @@ -252,7 +251,7 @@ public class NubCustomType(string @namespace, string name) : NubComplexType { case CustomTypeKind.Struct: { - var structDef = definitionTable.LookupStruct(Namespace, Name); + var structDef = definitionTable.LookupStruct(Name); var size = 0; var maxAlignment = 1; @@ -267,7 +266,7 @@ public class NubCustomType(string @namespace, string name) : NubComplexType return AlignTo(size, maxAlignment); } - case CustomTypeKind.Trait: + case CustomTypeKind.Interface: { return 16; } @@ -281,23 +280,23 @@ public class NubCustomType(string @namespace, string name) : NubComplexType switch (Kind(definitionTable)) { case CustomTypeKind.Struct: - return definitionTable.LookupStruct(Namespace, Name).Fields.Max(f => f.Type.Alignment(definitionTable)); - case CustomTypeKind.Trait: + return definitionTable.LookupStruct(Name).Fields.Max(f => f.Type.Alignment(definitionTable)); + case CustomTypeKind.Interface: return 8; default: throw new ArgumentOutOfRangeException(); } } - public override string ToString() => $"{Namespace}::{Name}"; - public override bool Equals(NubType? other) => other is NubCustomType custom && Namespace == custom.Namespace && Name == custom.Name; - public override int GetHashCode() => HashCode.Combine(typeof(NubCustomType), Namespace, Name); + public override string ToString() => Name; + public override bool Equals(NubType? other) => other is NubCustomType custom && Name == custom.Name; + public override int GetHashCode() => HashCode.Combine(typeof(NubCustomType), Name); } public enum CustomTypeKind { Struct, - Trait + Interface } public class NubArrayType(NubType elementType) : NubComplexType diff --git a/src/compiler/NubLang/Syntax/Parsing/Node/DefinitionSyntax.cs b/src/compiler/NubLang/Syntax/Parsing/Node/DefinitionSyntax.cs index 1f607a1..82b5b07 100644 --- a/src/compiler/NubLang/Syntax/Parsing/Node/DefinitionSyntax.cs +++ b/src/compiler/NubLang/Syntax/Parsing/Node/DefinitionSyntax.cs @@ -2,7 +2,7 @@ using NubLang.Common; namespace NubLang.Syntax.Parsing.Node; -public abstract record DefinitionSyntax(string Namespace) : SyntaxNode; +public abstract record DefinitionSyntax : SyntaxNode; public record FuncParameterSyntax(string Name, TypeSyntax Type) : SyntaxNode { @@ -25,7 +25,7 @@ public record FuncSignatureSyntax(IReadOnlyList Parameters, } } -public record LocalFuncSyntax(string Namespace, string Name, FuncSignatureSyntax Signature, BlockSyntax Body) : DefinitionSyntax(Namespace) +public record LocalFuncSyntax(string Name, FuncSignatureSyntax Signature, BlockSyntax Body) : DefinitionSyntax { public override IEnumerable GetChildren() { @@ -34,7 +34,7 @@ public record LocalFuncSyntax(string Namespace, string Name, FuncSignatureSyntax } } -public record ExternFuncSyntax(string Namespace, string Name, string CallName, FuncSignatureSyntax Signature) : DefinitionSyntax(Namespace) +public record ExternFuncSyntax(string Name, string CallName, FuncSignatureSyntax Signature) : DefinitionSyntax { public override IEnumerable GetChildren() { @@ -63,7 +63,7 @@ public record StructFuncSyntax(string Name, FuncSignatureSyntax Signature, Block } } -public record StructSyntax(string Namespace, string Name, IReadOnlyList Fields, IReadOnlyList Functions) : DefinitionSyntax(Namespace) +public record StructSyntax(string Name, IReadOnlyList Fields, IReadOnlyList Functions) : DefinitionSyntax { public override IEnumerable GetChildren() { @@ -87,7 +87,7 @@ public record InterfaceFuncSyntax(string Name, FuncSignatureSyntax Signature) : } } -public record InterfaceSyntax(string Namespace, string Name, IReadOnlyList Functions) : DefinitionSyntax(Namespace) +public record InterfaceSyntax(string Name, IReadOnlyList Functions) : DefinitionSyntax { 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 d95e616..2defc18 100644 --- a/src/compiler/NubLang/Syntax/Parsing/Node/ExpressionSyntax.cs +++ b/src/compiler/NubLang/Syntax/Parsing/Node/ExpressionSyntax.cs @@ -54,7 +54,7 @@ public record FuncCallSyntax(ExpressionSyntax Expression, IReadOnlyList Namespace, string Name) : ExpressionSyntax +public record IdentifierSyntax(string Name) : ExpressionSyntax { public override IEnumerable GetChildren() => []; } diff --git a/src/compiler/NubLang/Syntax/Parsing/Node/SyntaxNode.cs b/src/compiler/NubLang/Syntax/Parsing/Node/SyntaxNode.cs index 0ae50bd..4eaf513 100644 --- a/src/compiler/NubLang/Syntax/Parsing/Node/SyntaxNode.cs +++ b/src/compiler/NubLang/Syntax/Parsing/Node/SyntaxNode.cs @@ -18,7 +18,7 @@ public abstract record SyntaxNode } } -public record SyntaxTree(string Namespace, IReadOnlyList Definitions) : SyntaxNode +public record SyntaxTree(IReadOnlyList Definitions) : 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 26a29f5..c70d371 100644 --- a/src/compiler/NubLang/Syntax/Parsing/Node/TypeSyntax.cs +++ b/src/compiler/NubLang/Syntax/Parsing/Node/TypeSyntax.cs @@ -27,7 +27,7 @@ public abstract record TypeSyntax : SyntaxNode StringTypeSyntax => "string", PointerTypeSyntax ptr => $"ptr_{ptr.BaseType.MangledName()}", ArrayTypeSyntax arr => $"arr_{arr.BaseType.MangledName()}", - CustomTypeSyntax custom => $"{custom.Namespace}_{custom.Name}", + CustomTypeSyntax custom => $"custom_{custom.Name}", FuncTypeSyntax func => $"func_{string.Join("_", func.Parameters.Select(x => x.MangledName()))}_to_{func.ReturnType.MangledName()}", _ => throw new NotSupportedException($"Unknown type syntax: {GetType().Name}") }; @@ -75,7 +75,7 @@ public record StringTypeSyntax : TypeSyntax public override IEnumerable GetChildren() => []; } -public record CustomTypeSyntax(string Namespace, string Name) : TypeSyntax +public record CustomTypeSyntax(string Name) : TypeSyntax { public override IEnumerable GetChildren() => []; } diff --git a/src/compiler/NubLang/Syntax/Parsing/Parser.cs b/src/compiler/NubLang/Syntax/Parsing/Parser.cs index 40f0763..532ded2 100644 --- a/src/compiler/NubLang/Syntax/Parsing/Parser.cs +++ b/src/compiler/NubLang/Syntax/Parsing/Parser.cs @@ -8,27 +8,21 @@ namespace NubLang.Syntax.Parsing; public sealed class Parser { - private string _namespace; - private readonly IReadOnlyList _tokens; + private IEnumerable _tokens = null!; - private List _diagnostics = []; + private readonly List _diagnostics = []; private int _tokenIndex; - public Parser(IReadOnlyList tokens) + public IReadOnlyList GetDiagnostics() { - _namespace = "default"; - _tokens = tokens; + return _diagnostics; } - public SyntaxTree Parse(out IReadOnlyList diagnostics) + public SyntaxTree Parse(IEnumerable tokens) { - _diagnostics = []; + _diagnostics.Clear(); _tokenIndex = 0; - - if (TryExpectSymbol(Symbol.Namespace)) - { - _namespace = ExpectIdentifier().Value; - } + _tokens = tokens; var definitions = new List(); @@ -68,8 +62,7 @@ public sealed class Parser } } - diagnostics = _diagnostics; - return new SyntaxTree(_namespace, definitions); + return new SyntaxTree(definitions); } private FuncSignatureSyntax ParseFuncSignature(FuncParameterSyntax? thisArg = null) @@ -134,7 +127,7 @@ public sealed class Parser var signature = ParseFuncSignature(); - return new ExternFuncSyntax(_namespace, name.Value, callName, signature); + return new ExternFuncSyntax(name.Value, callName, signature); } private LocalFuncSyntax ParseFunc() @@ -143,7 +136,7 @@ public sealed class Parser var signature = ParseFuncSignature(); var body = ParseBlock(); - return new LocalFuncSyntax(_namespace, name.Value, signature, body); + return new LocalFuncSyntax(name.Value, signature, body); } private DefinitionSyntax ParseStruct() @@ -162,7 +155,7 @@ public sealed class Parser 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(name.Value)); var funcSignature = ParseFuncSignature(thisArg); var funcBody = ParseBlock(); @@ -185,7 +178,7 @@ public sealed class Parser } } - return new StructSyntax(_namespace, name.Value, fields, funcs); + return new StructSyntax(name.Value, fields, funcs); } private InterfaceSyntax ParseInterface() @@ -206,7 +199,7 @@ public sealed class Parser functions.Add(new InterfaceFuncSyntax(funcName, signature)); } - return new InterfaceSyntax(_namespace, name.Value, functions); + return new InterfaceSyntax(name.Value, functions); } private StatementSyntax ParseStatement() @@ -419,15 +412,7 @@ public sealed class Parser } case IdentifierToken identifier: { - var @namespace = Optional.Empty(); - var name = identifier.Value; - if (TryExpectSymbol(Symbol.DoubleColon)) - { - @namespace = identifier.Value; - name = ExpectIdentifier().Value; - } - - expr = new IdentifierSyntax(@namespace, name); + expr = new IdentifierSyntax(identifier.Value); break; } case SymbolToken symbolToken: @@ -622,19 +607,8 @@ public sealed class Parser "f64" => new PrimitiveTypeSyntax(PrimitiveTypeSyntaxKind.F64), "f32" => new PrimitiveTypeSyntax(PrimitiveTypeSyntaxKind.F32), "bool" => new PrimitiveTypeSyntax(PrimitiveTypeSyntaxKind.Bool), - _ => ParseCustomType() + _ => new CustomTypeSyntax(name.Value) }; - - TypeSyntax ParseCustomType() - { - var @namespace = _namespace; - if (TryExpectSymbol(Symbol.DoubleColon)) - { - @namespace = ExpectIdentifier().Value; - } - - return new CustomTypeSyntax(@namespace, name.Value); - } } if (TryExpectSymbol(Symbol.Caret)) @@ -672,14 +646,6 @@ public sealed class Parser return new ArrayTypeSyntax(baseType); } - if (!Peek().TryGetValue(out var peekToken)) - { - throw new ParseException(Diagnostic - .Error("Unexpected end of file while parsing type") - .WithHelp("Expected a type name") - .Build()); - } - throw new ParseException(Diagnostic .Error("Invalid type Syntax") .WithHelp("Expected type name, '^' for pointer, or '[]' for array") diff --git a/src/compiler/NubLang/Syntax/Tokenization/Token.cs b/src/compiler/NubLang/Syntax/Tokenization/Token.cs index c932895..a3ad076 100644 --- a/src/compiler/NubLang/Syntax/Tokenization/Token.cs +++ b/src/compiler/NubLang/Syntax/Tokenization/Token.cs @@ -59,8 +59,6 @@ public enum Symbol Struct, Caret, Ampersand, - DoubleColon, - Namespace, Let, Alloc, Calls, diff --git a/src/compiler/NubLang/Syntax/Tokenization/Tokenizer.cs b/src/compiler/NubLang/Syntax/Tokenization/Tokenizer.cs index c80d237..3df4b06 100644 --- a/src/compiler/NubLang/Syntax/Tokenization/Tokenizer.cs +++ b/src/compiler/NubLang/Syntax/Tokenization/Tokenizer.cs @@ -1,5 +1,4 @@ using NubLang.Common; -using NubLang.Diagnostics; namespace NubLang.Syntax.Tokenization; @@ -7,7 +6,6 @@ public sealed class Tokenizer { private static readonly Dictionary Keywords = new() { - ["namespace"] = Symbol.Namespace, ["func"] = Symbol.Func, ["if"] = Symbol.If, ["else"] = Symbol.Else, @@ -30,7 +28,6 @@ public sealed class Tokenizer [['!', '=']] = Symbol.NotEqual, [['<', '=']] = Symbol.LessThanOrEqual, [['>', '=']] = Symbol.GreaterThanOrEqual, - [[':', ':']] = Symbol.DoubleColon, [['=', '>']] = Symbol.Arrow, [[':']] = Symbol.Colon, [['(']] = Symbol.OpenParen, @@ -54,6 +51,11 @@ public sealed class Tokenizer [[';']] = Symbol.Semi, }; + private static readonly (char[] Pattern, Symbol Symbol)[] OrderedSymbols = Symbols + .OrderByDescending(kvp => kvp.Key.Length) + .Select(kvp => (kvp.Key, kvp.Value)) + .ToArray(); + private readonly string _sourceText; private int _index; @@ -62,150 +64,147 @@ public sealed class Tokenizer _sourceText = sourceText; } - public IReadOnlyList Tokenize(out IReadOnlyList diagnostics) + public IEnumerable Tokenize() { _index = 0; - List tokens = []; - while (ParseToken().TryGetValue(out var token)) + while (Peek().TryGetValue(out var current)) { - tokens.Add(token); - } - - // TODO: Implement diagnostics - diagnostics = []; - return tokens; - } - - private Optional ParseToken() - { - var startIndex = _index; - - if (!Peek().TryGetValue(out var current)) - { - return Optional.Empty(); - } - - if (Peek().TryGetValue(out var character) && char.IsWhiteSpace(character)) - { - Next(); - - return ParseToken(); - } - - if (current == '/' && Peek(1).TryGetValue(out var nextChar) && nextChar == '/') - { - Next(); - Next(); - - while (Peek().TryGetValue(out var ch) && ch != '\n') + if (char.IsWhiteSpace(current)) { Next(); + continue; } - return ParseToken(); - } - - if (char.IsLetter(current) || current == '_') - { - var buffer = string.Empty; - - while (Peek().TryGetValue(out var next) && (char.IsLetterOrDigit(next) || next == '_')) + if (current == '/' && Peek(1).TryGetValue(out var nextChar) && nextChar == '/') { - buffer += next; - Next(); - } - - if (Keywords.TryGetValue(buffer, out var keywordSymbol)) - { - return new SymbolToken(keywordSymbol); - } - - if (buffer is "true" or "false") - { - return new LiteralToken(LiteralKind.Bool, buffer); - } - - return new IdentifierToken(buffer); - } - - if (char.IsDigit(current)) - { - var isFloat = false; - var buffer = string.Empty; - - while (Peek().TryGetValue(out var next)) - { - if (next == '.') + while (Peek().TryGetValue(out var ch) && ch != '\n') { - if (isFloat) - { - throw new Exception("More than one period found in float literal"); - } - - isFloat = true; - buffer += next; Next(); } - else if (char.IsDigit(next)) + + continue; + } + + if (char.IsLetter(current) || current == '_') + { + var buffer = string.Empty; + + while (Peek().TryGetValue(out var next) && (char.IsLetterOrDigit(next) || next == '_')) { buffer += next; Next(); } - else + + if (Keywords.TryGetValue(buffer, out var keywordSymbol)) { - break; + yield return new SymbolToken(keywordSymbol); + continue; } + + if (buffer is "true" or "false") + { + yield return new LiteralToken(LiteralKind.Bool, buffer); + continue; + } + + yield return new IdentifierToken(buffer); + continue; } - return new LiteralToken(isFloat ? LiteralKind.Float : LiteralKind.Integer, buffer); - } - - foreach (var chain in Symbols) - { - for (var i = 0; i < chain.Key.Length; i++) + if (char.IsDigit(current)) { - var c = Peek(i); - if (!c.HasValue || c.Value != chain.Key[i]) break; + var isFloat = false; + var buffer = string.Empty; - if (i == chain.Key.Length - 1) + while (Peek().TryGetValue(out var next)) { - for (var j = 0; j <= i; j++) + if (next == '.') { + if (isFloat) + { + throw new Exception("More than one period found in float literal"); + } + + isFloat = true; + buffer += next; Next(); } - - return new SymbolToken(chain.Value); + else if (char.IsDigit(next)) + { + buffer += next; + Next(); + } + else + { + break; + } } + + yield return new LiteralToken(isFloat ? LiteralKind.Float : LiteralKind.Integer, buffer); + continue; } - } - if (current == '"') - { - Next(); - var buffer = string.Empty; - - while (true) + if (current == '"') { - if (!Peek().TryGetValue(out var next)) + Next(); + var buffer = string.Empty; + + while (true) { - throw new Exception("Unclosed string literal"); + if (!Peek().TryGetValue(out var next)) + { + throw new Exception("Unclosed string literal"); + } + + if (next == '"') + { + Next(); + break; + } + + buffer += next; + Next(); } - if (next == '"') + yield return new LiteralToken(LiteralKind.String, buffer); + continue; + } + + var foundMatch = false; + foreach (var (pattern, symbol) in OrderedSymbols) + { + for (var i = 0; i < pattern.Length; i++) + { + var c = Peek(i); + if (!c.HasValue || c.Value != pattern[i]) break; + + if (i == pattern.Length - 1) + { + for (var j = 0; j <= i; j++) + { + Next(); + } + + yield return new SymbolToken(symbol); + foundMatch = true; + break; + } + } + + if (foundMatch) { - Next(); break; } - - buffer += next; - Next(); } - return new LiteralToken(LiteralKind.String, buffer); - } + if (foundMatch) + { + continue; + } - throw new Exception($"Unknown character {current}"); + throw new Exception($"Unknown character {current}"); + } } private Optional Peek(int offset = 0) @@ -218,14 +217,8 @@ public sealed class Tokenizer return Optional.Empty(); } - private Optional Next() + private void Next() { - if (_index < _sourceText.Length) - { - return _sourceText[_index++]; - } - _index++; - return Optional.Empty(); } } \ No newline at end of file