This commit is contained in:
nub31
2025-07-22 22:44:55 +02:00
parent 6b733b9cdf
commit eb009b6ac0
18 changed files with 200 additions and 274 deletions

View File

@@ -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);
}

View File

@@ -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<BoundLocalFunc>()
.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<BoundExternFunc>()
.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<BoundStruct>()
.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<BoundTrait>()
.First(x => x.Namespace == @namespace && x.Name == name);
.First(x => x.Name == name);
}
public BoundTraitFunc LookupTraitFunc(BoundTrait trait, string name)

View File

@@ -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();

View File

@@ -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<string, string>();
@@ -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

View File

@@ -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

View File

@@ -11,25 +11,25 @@ public class DefinitionTable
_definitions = syntaxTrees.SelectMany(x => x.Definitions).ToList();
}
public IEnumerable<LocalFuncSyntax> LookupLocalFunc(string @namespace, string name)
public IEnumerable<LocalFuncSyntax> LookupLocalFunc(string name)
{
return _definitions
.OfType<LocalFuncSyntax>()
.Where(x => x.Namespace == @namespace && x.Name == name);
.Where(x => x.Name == name);
}
public IEnumerable<ExternFuncSyntax> LookupExternFunc(string @namespace, string name)
public IEnumerable<ExternFuncSyntax> LookupExternFunc(string name)
{
return _definitions
.OfType<ExternFuncSyntax>()
.Where(x => x.Namespace == @namespace && x.Name == name);
.Where(x => x.Name == name);
}
public IEnumerable<StructSyntax> LookupStruct(NubCustomType type)
{
return _definitions
.OfType<StructSyntax>()
.Where(x => x.Namespace == type.Namespace && x.Name == type.Name);
.Where(x => x.Name == type.Name);
}
public IEnumerable<StructFieldSyntax> LookupStructField(StructSyntax structNode, string field)
@@ -37,20 +37,11 @@ public class DefinitionTable
return structNode.Fields.Where(x => x.Name == field);
}
// public IEnumerable<TraitFuncImplSyntax> LookupTraitFuncImpl(NubType forType, string name)
// {
// return _definitions
// .OfType<TraitImplSyntax>()
// .Where(x => x.ForType == forType)
// .SelectMany(x => x.Functions)
// .Where(x => x.Name == name);
// }
public IEnumerable<InterfaceSyntax> LookupTrait(NubCustomType type)
{
return _definitions
.OfType<InterfaceSyntax>()
.Where(x => x.Namespace == type.Namespace && x.Name == type.Name);
.Where(x => x.Name == type.Name);
}
public IEnumerable<InterfaceFuncSyntax> LookupTraitFunc(InterfaceSyntax @interface, string name)

View File

@@ -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<BoundFuncParameter> 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<BoundExpression> Value) : BoundNode;
public record BoundStruct(string Namespace, string Name, IReadOnlyList<BoundStructField> Fields) : BoundDefinition(Namespace);
public record BoundStruct(string Name, IReadOnlyList<BoundStructField> Fields) : BoundDefinition;
public record BoundTraitFunc(string Name, BoundFuncSignature Signature) : BoundNode;
public record BoundTrait(string Namespace, string Name, IReadOnlyList<BoundTraitFunc> Functions) : BoundDefinition(Namespace);
public record BoundTrait(string Name, IReadOnlyList<BoundTraitFunc> Functions) : BoundDefinition;
public record BoundTraitFuncImpl(string Name, BoundFuncSignature Signature, BoundBlock Body) : BoundNode;
public record BoundTraitImpl(string Namespace, NubType TraitType, NubType ForType, IReadOnlyList<BoundTraitFuncImpl> Functions) : BoundDefinition(Namespace);
public record BoundTraitImpl(NubType TraitType, NubType ForType, IReadOnlyList<BoundTraitFuncImpl> Functions) : BoundDefinition;

View File

@@ -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);

View File

@@ -2,7 +2,7 @@
namespace NubLang.Syntax.Binding.Node;
public record BoundSyntaxTree(string Namespace, IReadOnlyList<BoundDefinition> Definitions, IReadOnlyList<Diagnostic> Diagnostics);
public record BoundSyntaxTree(IReadOnlyList<BoundDefinition> Definitions, IReadOnlyList<Diagnostic> Diagnostics);
public abstract record BoundNode;

View File

@@ -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

View File

@@ -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<FuncParameterSyntax> 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<SyntaxNode> 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<SyntaxNode> GetChildren()
{
@@ -63,7 +63,7 @@ public record StructFuncSyntax(string Name, FuncSignatureSyntax Signature, Block
}
}
public record StructSyntax(string Namespace, string Name, IReadOnlyList<StructFieldSyntax> Fields, IReadOnlyList<StructFuncSyntax> Functions) : DefinitionSyntax(Namespace)
public record StructSyntax(string Name, IReadOnlyList<StructFieldSyntax> Fields, IReadOnlyList<StructFuncSyntax> Functions) : DefinitionSyntax
{
public override IEnumerable<SyntaxNode> GetChildren()
{
@@ -87,7 +87,7 @@ public record InterfaceFuncSyntax(string Name, FuncSignatureSyntax Signature) :
}
}
public record InterfaceSyntax(string Namespace, string Name, IReadOnlyList<InterfaceFuncSyntax> Functions) : DefinitionSyntax(Namespace)
public record InterfaceSyntax(string Name, IReadOnlyList<InterfaceFuncSyntax> Functions) : DefinitionSyntax
{
public override IEnumerable<SyntaxNode> GetChildren()
{

View File

@@ -54,7 +54,7 @@ public record FuncCallSyntax(ExpressionSyntax Expression, IReadOnlyList<Expressi
}
}
public record IdentifierSyntax(Optional<string> Namespace, string Name) : ExpressionSyntax
public record IdentifierSyntax(string Name) : ExpressionSyntax
{
public override IEnumerable<SyntaxNode> GetChildren() => [];
}

View File

@@ -18,7 +18,7 @@ public abstract record SyntaxNode
}
}
public record SyntaxTree(string Namespace, IReadOnlyList<DefinitionSyntax> Definitions) : SyntaxNode
public record SyntaxTree(IReadOnlyList<DefinitionSyntax> Definitions) : SyntaxNode
{
public override IEnumerable<SyntaxNode> GetChildren()
{

View File

@@ -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<SyntaxNode> GetChildren() => [];
}
public record CustomTypeSyntax(string Namespace, string Name) : TypeSyntax
public record CustomTypeSyntax(string Name) : TypeSyntax
{
public override IEnumerable<SyntaxNode> GetChildren() => [];
}

View File

@@ -8,27 +8,21 @@ namespace NubLang.Syntax.Parsing;
public sealed class Parser
{
private string _namespace;
private readonly IReadOnlyList<Token> _tokens;
private IEnumerable<Token> _tokens = null!;
private List<Diagnostic> _diagnostics = [];
private readonly List<Diagnostic> _diagnostics = [];
private int _tokenIndex;
public Parser(IReadOnlyList<Token> tokens)
public IReadOnlyList<Diagnostic> GetDiagnostics()
{
_namespace = "default";
_tokens = tokens;
return _diagnostics;
}
public SyntaxTree Parse(out IReadOnlyList<Diagnostic> diagnostics)
public SyntaxTree Parse(IEnumerable<Token> tokens)
{
_diagnostics = [];
_diagnostics.Clear();
_tokenIndex = 0;
if (TryExpectSymbol(Symbol.Namespace))
{
_namespace = ExpectIdentifier().Value;
}
_tokens = tokens;
var definitions = new List<DefinitionSyntax>();
@@ -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<string>.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")

View File

@@ -59,8 +59,6 @@ public enum Symbol
Struct,
Caret,
Ampersand,
DoubleColon,
Namespace,
Let,
Alloc,
Calls,

View File

@@ -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<string, Symbol> 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,48 +64,26 @@ public sealed class Tokenizer
_sourceText = sourceText;
}
public IReadOnlyList<Token> Tokenize(out IReadOnlyList<Diagnostic> diagnostics)
public IEnumerable<Token> Tokenize()
{
_index = 0;
List<Token> tokens = [];
while (ParseToken().TryGetValue(out var token))
while (Peek().TryGetValue(out var current))
{
tokens.Add(token);
}
// TODO: Implement diagnostics
diagnostics = [];
return tokens;
}
private Optional<Token> ParseToken()
{
var startIndex = _index;
if (!Peek().TryGetValue(out var current))
{
return Optional<Token>.Empty();
}
if (Peek().TryGetValue(out var character) && char.IsWhiteSpace(character))
if (char.IsWhiteSpace(current))
{
Next();
return ParseToken();
continue;
}
if (current == '/' && Peek(1).TryGetValue(out var nextChar) && nextChar == '/')
{
Next();
Next();
while (Peek().TryGetValue(out var ch) && ch != '\n')
{
Next();
}
return ParseToken();
continue;
}
if (char.IsLetter(current) || current == '_')
@@ -118,15 +98,18 @@ public sealed class Tokenizer
if (Keywords.TryGetValue(buffer, out var keywordSymbol))
{
return new SymbolToken(keywordSymbol);
yield return new SymbolToken(keywordSymbol);
continue;
}
if (buffer is "true" or "false")
{
return new LiteralToken(LiteralKind.Bool, buffer);
yield return new LiteralToken(LiteralKind.Bool, buffer);
continue;
}
return new IdentifierToken(buffer);
yield return new IdentifierToken(buffer);
continue;
}
if (char.IsDigit(current))
@@ -158,26 +141,8 @@ public sealed class Tokenizer
}
}
return new LiteralToken(isFloat ? LiteralKind.Float : LiteralKind.Integer, buffer);
}
foreach (var chain in Symbols)
{
for (var i = 0; i < chain.Key.Length; i++)
{
var c = Peek(i);
if (!c.HasValue || c.Value != chain.Key[i]) break;
if (i == chain.Key.Length - 1)
{
for (var j = 0; j <= i; j++)
{
Next();
}
return new SymbolToken(chain.Value);
}
}
yield return new LiteralToken(isFloat ? LiteralKind.Float : LiteralKind.Integer, buffer);
continue;
}
if (current == '"')
@@ -202,11 +167,45 @@ public sealed class Tokenizer
Next();
}
return new LiteralToken(LiteralKind.String, buffer);
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)
{
break;
}
}
if (foundMatch)
{
continue;
}
throw new Exception($"Unknown character {current}");
}
}
private Optional<char> Peek(int offset = 0)
{
@@ -218,14 +217,8 @@ public sealed class Tokenizer
return Optional<char>.Empty();
}
private Optional<char> Next()
private void Next()
{
if (_index < _sourceText.Length)
{
return _sourceText[_index++];
}
_index++;
return Optional<char>.Empty();
}
}