...
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
Binary file not shown.
@@ -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)
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
{
|
||||
|
||||
@@ -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() => [];
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
{
|
||||
|
||||
@@ -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() => [];
|
||||
}
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -59,8 +59,6 @@ public enum Symbol
|
||||
Struct,
|
||||
Caret,
|
||||
Ampersand,
|
||||
DoubleColon,
|
||||
Namespace,
|
||||
Let,
|
||||
Alloc,
|
||||
Calls,
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user