This commit is contained in:
nub31
2025-07-22 22:44:55 +02:00
parent 4055002a8c
commit f6da9e9753
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) foreach (var file in options.Files)
{ {
var tokenizer = new Tokenizer(file.GetText()); var tokenizer = new Tokenizer(file.GetText());
var tokenizeResult = tokenizer.Tokenize(out var tokenizerDiagnostics); var tokens = tokenizer.Tokenize();
diagnostics.AddRange(tokenizerDiagnostics);
var parser = new Parser(tokenizeResult); var parser = new Parser();
var syntaxTree = parser.Parse(out var parserDiagnostics); var syntaxTree = parser.Parse(tokens);
diagnostics.AddRange(parserDiagnostics); diagnostics.AddRange(parser.GetDiagnostics());
syntaxTrees.Add(syntaxTree); syntaxTrees.Add(syntaxTree);
} }

View File

@@ -12,25 +12,25 @@ public sealed class BoundDefinitionTable
_definitions = syntaxTrees.SelectMany(x => x.Definitions).ToList(); _definitions = syntaxTrees.SelectMany(x => x.Definitions).ToList();
} }
public BoundLocalFunc LookupLocalFunc(string @namespace, string name) public BoundLocalFunc LookupLocalFunc(string name)
{ {
return _definitions return _definitions
.OfType<BoundLocalFunc>() .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 return _definitions
.OfType<BoundExternFunc>() .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 return _definitions
.OfType<BoundStruct>() .OfType<BoundStruct>()
.First(x => x.Namespace == @namespace && x.Name == name); .First(x => x.Name == name);
} }
public BoundStructField LookupStructField(BoundStruct @struct, string field) public BoundStructField LookupStructField(BoundStruct @struct, string field)
@@ -54,11 +54,11 @@ public sealed class BoundDefinitionTable
.First(x => x.Name == name); .First(x => x.Name == name);
} }
public BoundTrait LookupTrait(string @namespace, string name) public BoundTrait LookupTrait(string name)
{ {
return _definitions return _definitions
.OfType<BoundTrait>() .OfType<BoundTrait>()
.First(x => x.Namespace == @namespace && x.Name == name); .First(x => x.Name == name);
} }
public BoundTraitFunc LookupTraitFunc(BoundTrait trait, string name) public BoundTraitFunc LookupTraitFunc(BoundTrait trait, string name)

View File

@@ -224,13 +224,13 @@ public partial class QBEGenerator
private Val EmitExternFuncIdent(BoundExternFuncIdent externFuncIdent) 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); return new Val(ExternFuncName(func), externFuncIdent.Type, ValKind.Direct);
} }
private Val EmitLocalFuncIdent(BoundLocalFuncIdent localFuncIdent) 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); 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) 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) if (destination == null)
{ {
@@ -400,7 +400,7 @@ public partial class QBEGenerator
{ {
var target = EmitUnwrap(EmitExpression(structFieldAccess.Target)); 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 offset = OffsetOf(structDef, structFieldAccess.Field);
var output = TmpName(); var output = TmpName();

View File

@@ -373,7 +373,7 @@ public partial class QBEGenerator
private void EmitStructDefinition(BoundStruct structDef) 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>(); var types = new Dictionary<string, string>();
@@ -419,7 +419,7 @@ public partial class QBEGenerator
private void EmitTraitVTable(BoundTrait traitDef) 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) foreach (var func in traitDef.Functions)
{ {
@@ -500,7 +500,7 @@ public partial class QBEGenerator
private string LocalFuncName(BoundLocalFunc funcDef) private string LocalFuncName(BoundLocalFunc funcDef)
{ {
return $"${funcDef.Namespace}_{funcDef.Name}"; return $"${funcDef.Name}";
} }
private string ExternFuncName(BoundExternFunc funcDef) private string ExternFuncName(BoundExternFunc funcDef)
@@ -510,12 +510,12 @@ public partial class QBEGenerator
private string CustomTypeName(NubCustomType customType) 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 #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) private BoundDefinition BindDefinition(DefinitionSyntax node)
@@ -66,7 +66,7 @@ public sealed class Binder
functions.Add(new BoundTraitFunc(function.Name, BindFuncSignature(function.Signature))); 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) 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)); 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) 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) private BoundLocalFunc BindLocalFuncDefinition(LocalFuncSyntax node)
@@ -98,7 +98,7 @@ public sealed class Binder
var signature = BindFuncSignature(node.Signature); var signature = BindFuncSignature(node.Signature);
var body = BindFuncBody(node.Body, signature.ReturnType, signature.Parameters); 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) private BoundStatement BindStatement(StatementSyntax node)
@@ -299,13 +299,18 @@ public sealed class Binder
private BoundExpression BindIdentifier(IdentifierSyntax expression) private BoundExpression BindIdentifier(IdentifierSyntax expression)
{ {
var @namespace = expression.Namespace.Or(_syntaxTree.Namespace); var variable = Scope.Lookup(expression.Name);
var localFuncs = _definitionTable.LookupLocalFunc(@namespace, expression.Name).ToArray(); if (variable != null)
{
return new BoundVariableIdent(variable.Type, variable.Name);
}
var localFuncs = _definitionTable.LookupLocalFunc(expression.Name).ToArray();
if (localFuncs.Length > 0) if (localFuncs.Length > 0)
{ {
if (localFuncs.Length > 1) 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]; var localFunc = localFuncs[0];
@@ -313,15 +318,15 @@ public sealed class Binder
var returnType = BindType(localFunc.Signature.ReturnType); var returnType = BindType(localFunc.Signature.ReturnType);
var parameterTypes = localFunc.Signature.Parameters.Select(p => BindType(p.Type)).ToList(); var parameterTypes = localFunc.Signature.Parameters.Select(p => BindType(p.Type)).ToList();
var type = new NubFuncType(parameterTypes, returnType); 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 > 0)
{ {
if (externFuncs.Length > 1) 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]; var externFunc = externFuncs[0];
@@ -329,19 +334,10 @@ public sealed class Binder
var returnType = BindType(externFunc.Signature.ReturnType); var returnType = BindType(externFunc.Signature.ReturnType);
var parameterTypes = externFunc.Signature.Parameters.Select(p => BindType(p.Type)).ToList(); var parameterTypes = externFunc.Signature.Parameters.Select(p => BindType(p.Type)).ToList();
var type = new NubFuncType(parameterTypes, returnType); var type = new NubFuncType(parameterTypes, returnType);
return new BoundExternFuncIdent(type, @namespace, expression.Name); return new BoundExternFuncIdent(type, expression.Name);
} }
if (!expression.Namespace.HasValue) throw new BindException(Diagnostic.Error($"No identifier with the name {expression.Name} exists").Build());
{
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());
} }
private BoundLiteral BindLiteral(LiteralSyntax expression, NubType? expectedType = null) private BoundLiteral BindLiteral(LiteralSyntax expression, NubType? expectedType = null)
@@ -362,22 +358,6 @@ public sealed class Binder
{ {
var boundExpression = BindExpression(expression.Target); 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) if (boundExpression.Type is NubCustomType customType)
{ {
var traits = _definitionTable.LookupTrait(customType).ToArray(); var traits = _definitionTable.LookupTrait(customType).ToArray();
@@ -593,7 +573,7 @@ public sealed class Binder
{ {
ArrayTypeSyntax type => new NubArrayType(BindType(type.BaseType)), ArrayTypeSyntax type => new NubArrayType(BindType(type.BaseType)),
CStringTypeSyntax => new NubCStringType(), 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)), FuncTypeSyntax type => new NubFuncType(type.Parameters.Select(BindType).ToList(), BindType(type.ReturnType)),
PointerTypeSyntax type => new NubPointerType(BindType(type.BaseType)), PointerTypeSyntax type => new NubPointerType(BindType(type.BaseType)),
PrimitiveTypeSyntax type => new NubPrimitiveType(type.SyntaxKind switch PrimitiveTypeSyntax type => new NubPrimitiveType(type.SyntaxKind switch

View File

@@ -11,25 +11,25 @@ public class DefinitionTable
_definitions = syntaxTrees.SelectMany(x => x.Definitions).ToList(); _definitions = syntaxTrees.SelectMany(x => x.Definitions).ToList();
} }
public IEnumerable<LocalFuncSyntax> LookupLocalFunc(string @namespace, string name) public IEnumerable<LocalFuncSyntax> LookupLocalFunc(string name)
{ {
return _definitions return _definitions
.OfType<LocalFuncSyntax>() .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 return _definitions
.OfType<ExternFuncSyntax>() .OfType<ExternFuncSyntax>()
.Where(x => x.Namespace == @namespace && x.Name == name); .Where(x => x.Name == name);
} }
public IEnumerable<StructSyntax> LookupStruct(NubCustomType type) public IEnumerable<StructSyntax> LookupStruct(NubCustomType type)
{ {
return _definitions return _definitions
.OfType<StructSyntax>() .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) public IEnumerable<StructFieldSyntax> LookupStructField(StructSyntax structNode, string field)
@@ -37,20 +37,11 @@ public class DefinitionTable
return structNode.Fields.Where(x => x.Name == field); 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) public IEnumerable<InterfaceSyntax> LookupTrait(NubCustomType type)
{ {
return _definitions return _definitions
.OfType<InterfaceSyntax>() .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) public IEnumerable<InterfaceFuncSyntax> LookupTraitFunc(InterfaceSyntax @interface, string name)

View File

@@ -2,24 +2,24 @@
namespace NubLang.Syntax.Binding.Node; 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 BoundFuncParameter(string Name, NubType Type) : BoundNode;
public record BoundFuncSignature(IReadOnlyList<BoundFuncParameter> Parameters, NubType ReturnType) : 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 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 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 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 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); public record BoundArrayInitializer(NubType Type, BoundExpression Capacity, NubType ElementType) : BoundExpression(Type);

View File

@@ -2,7 +2,7 @@
namespace NubLang.Syntax.Binding.Node; 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; public abstract record BoundNode;

View File

@@ -226,21 +226,20 @@ public class NubStringType : NubComplexType
public override int GetHashCode() => HashCode.Combine(typeof(NubStringType)); 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 string Name { get; } = name;
public CustomTypeKind Kind(BoundDefinitionTable definitionTable) 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; 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}"); 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: case CustomTypeKind.Struct:
{ {
var structDef = definitionTable.LookupStruct(Namespace, Name); var structDef = definitionTable.LookupStruct(Name);
var size = 0; var size = 0;
var maxAlignment = 1; var maxAlignment = 1;
@@ -267,7 +266,7 @@ public class NubCustomType(string @namespace, string name) : NubComplexType
return AlignTo(size, maxAlignment); return AlignTo(size, maxAlignment);
} }
case CustomTypeKind.Trait: case CustomTypeKind.Interface:
{ {
return 16; return 16;
} }
@@ -281,23 +280,23 @@ public class NubCustomType(string @namespace, string name) : NubComplexType
switch (Kind(definitionTable)) switch (Kind(definitionTable))
{ {
case CustomTypeKind.Struct: case CustomTypeKind.Struct:
return definitionTable.LookupStruct(Namespace, Name).Fields.Max(f => f.Type.Alignment(definitionTable)); return definitionTable.LookupStruct(Name).Fields.Max(f => f.Type.Alignment(definitionTable));
case CustomTypeKind.Trait: case CustomTypeKind.Interface:
return 8; return 8;
default: default:
throw new ArgumentOutOfRangeException(); throw new ArgumentOutOfRangeException();
} }
} }
public override string ToString() => $"{Namespace}::{Name}"; public override string ToString() => Name;
public override bool Equals(NubType? other) => other is NubCustomType custom && Namespace == custom.Namespace && Name == custom.Name; public override bool Equals(NubType? other) => other is NubCustomType custom && Name == custom.Name;
public override int GetHashCode() => HashCode.Combine(typeof(NubCustomType), Namespace, Name); public override int GetHashCode() => HashCode.Combine(typeof(NubCustomType), Name);
} }
public enum CustomTypeKind public enum CustomTypeKind
{ {
Struct, Struct,
Trait Interface
} }
public class NubArrayType(NubType elementType) : NubComplexType public class NubArrayType(NubType elementType) : NubComplexType

View File

@@ -2,7 +2,7 @@ using NubLang.Common;
namespace NubLang.Syntax.Parsing.Node; 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 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() 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() 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() 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() 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() => []; 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() public override IEnumerable<SyntaxNode> GetChildren()
{ {

View File

@@ -27,7 +27,7 @@ public abstract record TypeSyntax : SyntaxNode
StringTypeSyntax => "string", StringTypeSyntax => "string",
PointerTypeSyntax ptr => $"ptr_{ptr.BaseType.MangledName()}", PointerTypeSyntax ptr => $"ptr_{ptr.BaseType.MangledName()}",
ArrayTypeSyntax arr => $"arr_{arr.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()}", FuncTypeSyntax func => $"func_{string.Join("_", func.Parameters.Select(x => x.MangledName()))}_to_{func.ReturnType.MangledName()}",
_ => throw new NotSupportedException($"Unknown type syntax: {GetType().Name}") _ => throw new NotSupportedException($"Unknown type syntax: {GetType().Name}")
}; };
@@ -75,7 +75,7 @@ public record StringTypeSyntax : TypeSyntax
public override IEnumerable<SyntaxNode> GetChildren() => []; public override IEnumerable<SyntaxNode> GetChildren() => [];
} }
public record CustomTypeSyntax(string Namespace, string Name) : TypeSyntax public record CustomTypeSyntax(string Name) : TypeSyntax
{ {
public override IEnumerable<SyntaxNode> GetChildren() => []; public override IEnumerable<SyntaxNode> GetChildren() => [];
} }

View File

@@ -8,27 +8,21 @@ namespace NubLang.Syntax.Parsing;
public sealed class Parser public sealed class Parser
{ {
private string _namespace; private IEnumerable<Token> _tokens = null!;
private readonly IReadOnlyList<Token> _tokens;
private List<Diagnostic> _diagnostics = []; private readonly List<Diagnostic> _diagnostics = [];
private int _tokenIndex; private int _tokenIndex;
public Parser(IReadOnlyList<Token> tokens) public IReadOnlyList<Diagnostic> GetDiagnostics()
{ {
_namespace = "default"; return _diagnostics;
_tokens = tokens;
} }
public SyntaxTree Parse(out IReadOnlyList<Diagnostic> diagnostics) public SyntaxTree Parse(IEnumerable<Token> tokens)
{ {
_diagnostics = []; _diagnostics.Clear();
_tokenIndex = 0; _tokenIndex = 0;
_tokens = tokens;
if (TryExpectSymbol(Symbol.Namespace))
{
_namespace = ExpectIdentifier().Value;
}
var definitions = new List<DefinitionSyntax>(); var definitions = new List<DefinitionSyntax>();
@@ -68,8 +62,7 @@ public sealed class Parser
} }
} }
diagnostics = _diagnostics; return new SyntaxTree(definitions);
return new SyntaxTree(_namespace, definitions);
} }
private FuncSignatureSyntax ParseFuncSignature(FuncParameterSyntax? thisArg = null) private FuncSignatureSyntax ParseFuncSignature(FuncParameterSyntax? thisArg = null)
@@ -134,7 +127,7 @@ public sealed class Parser
var signature = ParseFuncSignature(); var signature = ParseFuncSignature();
return new ExternFuncSyntax(_namespace, name.Value, callName, signature); return new ExternFuncSyntax(name.Value, callName, signature);
} }
private LocalFuncSyntax ParseFunc() private LocalFuncSyntax ParseFunc()
@@ -143,7 +136,7 @@ public sealed class Parser
var signature = ParseFuncSignature(); var signature = ParseFuncSignature();
var body = ParseBlock(); var body = ParseBlock();
return new LocalFuncSyntax(_namespace, name.Value, signature, body); return new LocalFuncSyntax(name.Value, signature, body);
} }
private DefinitionSyntax ParseStruct() private DefinitionSyntax ParseStruct()
@@ -162,7 +155,7 @@ public sealed class Parser
if (TryExpectSymbol(Symbol.Func)) if (TryExpectSymbol(Symbol.Func))
{ {
var funcName = ExpectIdentifier().Value; 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 funcSignature = ParseFuncSignature(thisArg);
var funcBody = ParseBlock(); 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() private InterfaceSyntax ParseInterface()
@@ -206,7 +199,7 @@ public sealed class Parser
functions.Add(new InterfaceFuncSyntax(funcName, signature)); functions.Add(new InterfaceFuncSyntax(funcName, signature));
} }
return new InterfaceSyntax(_namespace, name.Value, functions); return new InterfaceSyntax(name.Value, functions);
} }
private StatementSyntax ParseStatement() private StatementSyntax ParseStatement()
@@ -419,15 +412,7 @@ public sealed class Parser
} }
case IdentifierToken identifier: case IdentifierToken identifier:
{ {
var @namespace = Optional<string>.Empty(); expr = new IdentifierSyntax(identifier.Value);
var name = identifier.Value;
if (TryExpectSymbol(Symbol.DoubleColon))
{
@namespace = identifier.Value;
name = ExpectIdentifier().Value;
}
expr = new IdentifierSyntax(@namespace, name);
break; break;
} }
case SymbolToken symbolToken: case SymbolToken symbolToken:
@@ -622,19 +607,8 @@ public sealed class Parser
"f64" => new PrimitiveTypeSyntax(PrimitiveTypeSyntaxKind.F64), "f64" => new PrimitiveTypeSyntax(PrimitiveTypeSyntaxKind.F64),
"f32" => new PrimitiveTypeSyntax(PrimitiveTypeSyntaxKind.F32), "f32" => new PrimitiveTypeSyntax(PrimitiveTypeSyntaxKind.F32),
"bool" => new PrimitiveTypeSyntax(PrimitiveTypeSyntaxKind.Bool), "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)) if (TryExpectSymbol(Symbol.Caret))
@@ -672,14 +646,6 @@ public sealed class Parser
return new ArrayTypeSyntax(baseType); 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 throw new ParseException(Diagnostic
.Error("Invalid type Syntax") .Error("Invalid type Syntax")
.WithHelp("Expected type name, '^' for pointer, or '[]' for array") .WithHelp("Expected type name, '^' for pointer, or '[]' for array")

View File

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

View File

@@ -1,5 +1,4 @@
using NubLang.Common; using NubLang.Common;
using NubLang.Diagnostics;
namespace NubLang.Syntax.Tokenization; namespace NubLang.Syntax.Tokenization;
@@ -7,7 +6,6 @@ public sealed class Tokenizer
{ {
private static readonly Dictionary<string, Symbol> Keywords = new() private static readonly Dictionary<string, Symbol> Keywords = new()
{ {
["namespace"] = Symbol.Namespace,
["func"] = Symbol.Func, ["func"] = Symbol.Func,
["if"] = Symbol.If, ["if"] = Symbol.If,
["else"] = Symbol.Else, ["else"] = Symbol.Else,
@@ -30,7 +28,6 @@ public sealed class Tokenizer
[['!', '=']] = Symbol.NotEqual, [['!', '=']] = Symbol.NotEqual,
[['<', '=']] = Symbol.LessThanOrEqual, [['<', '=']] = Symbol.LessThanOrEqual,
[['>', '=']] = Symbol.GreaterThanOrEqual, [['>', '=']] = Symbol.GreaterThanOrEqual,
[[':', ':']] = Symbol.DoubleColon,
[['=', '>']] = Symbol.Arrow, [['=', '>']] = Symbol.Arrow,
[[':']] = Symbol.Colon, [[':']] = Symbol.Colon,
[['(']] = Symbol.OpenParen, [['(']] = Symbol.OpenParen,
@@ -54,6 +51,11 @@ public sealed class Tokenizer
[[';']] = Symbol.Semi, [[';']] = 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 readonly string _sourceText;
private int _index; private int _index;
@@ -62,48 +64,26 @@ public sealed class Tokenizer
_sourceText = sourceText; _sourceText = sourceText;
} }
public IReadOnlyList<Token> Tokenize(out IReadOnlyList<Diagnostic> diagnostics) public IEnumerable<Token> Tokenize()
{ {
_index = 0; _index = 0;
List<Token> tokens = []; while (Peek().TryGetValue(out var current))
while (ParseToken().TryGetValue(out var token))
{ {
tokens.Add(token); if (char.IsWhiteSpace(current))
}
// 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))
{ {
Next(); Next();
continue;
return ParseToken();
} }
if (current == '/' && Peek(1).TryGetValue(out var nextChar) && nextChar == '/') if (current == '/' && Peek(1).TryGetValue(out var nextChar) && nextChar == '/')
{ {
Next();
Next();
while (Peek().TryGetValue(out var ch) && ch != '\n') while (Peek().TryGetValue(out var ch) && ch != '\n')
{ {
Next(); Next();
} }
return ParseToken(); continue;
} }
if (char.IsLetter(current) || current == '_') if (char.IsLetter(current) || current == '_')
@@ -118,15 +98,18 @@ public sealed class Tokenizer
if (Keywords.TryGetValue(buffer, out var keywordSymbol)) if (Keywords.TryGetValue(buffer, out var keywordSymbol))
{ {
return new SymbolToken(keywordSymbol); yield return new SymbolToken(keywordSymbol);
continue;
} }
if (buffer is "true" or "false") 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)) if (char.IsDigit(current))
@@ -158,26 +141,8 @@ public sealed class Tokenizer
} }
} }
return new LiteralToken(isFloat ? LiteralKind.Float : LiteralKind.Integer, buffer); yield return new LiteralToken(isFloat ? LiteralKind.Float : LiteralKind.Integer, buffer);
} continue;
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);
}
}
} }
if (current == '"') if (current == '"')
@@ -202,11 +167,45 @@ public sealed class Tokenizer
Next(); 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}"); throw new Exception($"Unknown character {current}");
} }
}
private Optional<char> Peek(int offset = 0) private Optional<char> Peek(int offset = 0)
{ {
@@ -218,14 +217,8 @@ public sealed class Tokenizer
return Optional<char>.Empty(); return Optional<char>.Empty();
} }
private Optional<char> Next() private void Next()
{ {
if (_index < _sourceText.Length)
{
return _sourceText[_index++];
}
_index++; _index++;
return Optional<char>.Empty();
} }
} }