...
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
template<T> struct Box
|
struct Box<T>
|
||||||
{
|
{
|
||||||
value: T
|
value: T
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,24 +3,26 @@ using NubLang.Syntax.Tokenization;
|
|||||||
|
|
||||||
namespace NubLang.Syntax.Parsing.Node;
|
namespace NubLang.Syntax.Parsing.Node;
|
||||||
|
|
||||||
public abstract record DefinitionSyntax(IReadOnlyList<Token> Tokens, string Namespace) : SyntaxNode(Tokens);
|
public record TemplateParameterSyntax(IReadOnlyList<Token> Tokens, string Name) : SyntaxNode(Tokens);
|
||||||
|
|
||||||
|
public abstract record DefinitionSyntax(IReadOnlyList<Token> Tokens, string Namespace, IReadOnlyList<TemplateParameterSyntax> Parameters) : SyntaxNode(Tokens);
|
||||||
|
|
||||||
public record FuncParameterSyntax(IReadOnlyList<Token> Tokens, string Name, TypeSyntax Type) : SyntaxNode(Tokens);
|
public record FuncParameterSyntax(IReadOnlyList<Token> Tokens, string Name, TypeSyntax Type) : SyntaxNode(Tokens);
|
||||||
|
|
||||||
public record FuncSignatureSyntax(IReadOnlyList<Token> Tokens, IReadOnlyList<FuncParameterSyntax> Parameters, TypeSyntax ReturnType) : SyntaxNode(Tokens);
|
public record FuncSignatureSyntax(IReadOnlyList<Token> Tokens, IReadOnlyList<FuncParameterSyntax> Parameters, TypeSyntax ReturnType) : SyntaxNode(Tokens);
|
||||||
|
|
||||||
public record LocalFuncSyntax(IReadOnlyList<Token> Tokens, string Namespace, string Name, FuncSignatureSyntax Signature, BlockSyntax Body) : DefinitionSyntax(Tokens, Namespace);
|
public record LocalFuncSyntax(IReadOnlyList<Token> Tokens, string Namespace, IReadOnlyList<TemplateParameterSyntax> Parameters, string Name, FuncSignatureSyntax Signature, BlockSyntax Body) : DefinitionSyntax(Tokens, Namespace, Parameters);
|
||||||
|
|
||||||
public record ExternFuncSyntax(IReadOnlyList<Token> Tokens, string Namespace, string Name, string CallName, FuncSignatureSyntax Signature) : DefinitionSyntax(Tokens, Namespace);
|
public record ExternFuncSyntax(IReadOnlyList<Token> Tokens, string Namespace, IReadOnlyList<TemplateParameterSyntax> Parameters, string Name, string CallName, FuncSignatureSyntax Signature) : DefinitionSyntax(Tokens, Namespace, Parameters);
|
||||||
|
|
||||||
public record StructFieldSyntax(IReadOnlyList<Token> Tokens, int Index, string Name, TypeSyntax Type, Optional<ExpressionSyntax> Value) : SyntaxNode(Tokens);
|
public record StructFieldSyntax(IReadOnlyList<Token> Tokens, int Index, string Name, TypeSyntax Type, Optional<ExpressionSyntax> Value) : SyntaxNode(Tokens);
|
||||||
|
|
||||||
public record StructSyntax(IReadOnlyList<Token> Tokens, string Namespace, string Name, IReadOnlyList<StructFieldSyntax> Fields) : DefinitionSyntax(Tokens, Namespace);
|
public record StructSyntax(IReadOnlyList<Token> Tokens, string Namespace, IReadOnlyList<TemplateParameterSyntax> Parameters, string Name, IReadOnlyList<StructFieldSyntax> Fields) : DefinitionSyntax(Tokens, Namespace, Parameters);
|
||||||
|
|
||||||
public record TraitFuncSyntax(IReadOnlyList<Token> Tokens, string Name, FuncSignatureSyntax Signature) : SyntaxNode(Tokens);
|
public record TraitFuncSyntax(IReadOnlyList<Token> Tokens, string Name, FuncSignatureSyntax Signature) : SyntaxNode(Tokens);
|
||||||
|
|
||||||
public record TraitSyntax(IReadOnlyList<Token> Tokens, string Namespace, string Name, IReadOnlyList<TraitFuncSyntax> Functions) : DefinitionSyntax(Tokens, Namespace);
|
public record TraitSyntax(IReadOnlyList<Token> Tokens, string Namespace, IReadOnlyList<TemplateParameterSyntax> Parameters, string Name, IReadOnlyList<TraitFuncSyntax> Functions) : DefinitionSyntax(Tokens, Namespace, Parameters);
|
||||||
|
|
||||||
public record TraitFuncImplSyntax(IReadOnlyList<Token> Tokens, string Name, FuncSignatureSyntax Signature, BlockSyntax Body) : SyntaxNode(Tokens);
|
public record TraitFuncImplSyntax(IReadOnlyList<Token> Tokens, string Name, FuncSignatureSyntax Signature, BlockSyntax Body) : SyntaxNode(Tokens);
|
||||||
|
|
||||||
public record TraitImplSyntax(IReadOnlyList<Token> Tokens, string Namespace, TypeSyntax TraitType, TypeSyntax ForType, IReadOnlyList<TraitFuncImplSyntax> Functions) : DefinitionSyntax(Tokens, Namespace);
|
public record TraitImplSyntax(IReadOnlyList<Token> Tokens, string Namespace, IReadOnlyList<TemplateParameterSyntax> Parameters, TypeSyntax TraitType, TypeSyntax ForType, IReadOnlyList<TraitFuncImplSyntax> Functions) : DefinitionSyntax(Tokens, Namespace, Parameters);
|
||||||
@@ -37,30 +37,38 @@ public sealed class Parser
|
|||||||
var startIndex = _tokenIndex;
|
var startIndex = _tokenIndex;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
|
||||||
var definition = ParseDefinition(startIndex);
|
|
||||||
definitions.Add(definition);
|
|
||||||
}
|
|
||||||
catch (ParseException ex)
|
|
||||||
{
|
|
||||||
_diagnostics.Add(ex.Diagnostic);
|
|
||||||
RecoverToNextDefinition();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return new SyntaxTree(_namespace, definitions, _diagnostics);
|
|
||||||
}
|
|
||||||
|
|
||||||
private DefinitionSyntax ParseDefinition(int startIndex)
|
|
||||||
{
|
{
|
||||||
var keyword = ExpectSymbol();
|
var keyword = ExpectSymbol();
|
||||||
var node = keyword.Symbol switch
|
var name = ExpectIdentifier();
|
||||||
|
var templateParameters = new List<TemplateParameterSyntax>();
|
||||||
|
|
||||||
|
if (TryExpectSymbol(Symbol.LessThan))
|
||||||
{
|
{
|
||||||
Symbol.Extern => ParseExtern(startIndex),
|
while (!TryExpectSymbol(Symbol.GreaterThan))
|
||||||
Symbol.Func => ParseFunc(startIndex),
|
{
|
||||||
Symbol.Struct => ParseStruct(startIndex),
|
var argumentStartIndex = _tokenIndex;
|
||||||
Symbol.Trait => ParseTrait(startIndex),
|
var identifier = ExpectIdentifier();
|
||||||
Symbol.Impl => ParseImpl(startIndex),
|
if (!TryExpectSymbol(Symbol.Comma) && Peek().TryGetValue(out var token) && token is not SymbolToken { Symbol: Symbol.GreaterThan })
|
||||||
|
{
|
||||||
|
_diagnostics.Add(Diagnostic
|
||||||
|
.Warning("Missing comma between template parameters")
|
||||||
|
.WithHelp("Add a ',' to separate parameters")
|
||||||
|
.At(token)
|
||||||
|
.Build());
|
||||||
|
}
|
||||||
|
|
||||||
|
var parameter = new TemplateParameterSyntax(GetTokens(argumentStartIndex), identifier.Value);
|
||||||
|
templateParameters.Add(parameter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var definition = keyword.Symbol switch
|
||||||
|
{
|
||||||
|
Symbol.Extern => ParseExtern(startIndex, name, templateParameters),
|
||||||
|
Symbol.Func => ParseFunc(startIndex, name, templateParameters),
|
||||||
|
Symbol.Struct => ParseStruct(startIndex, name, templateParameters),
|
||||||
|
Symbol.Trait => ParseTrait(startIndex, name, templateParameters),
|
||||||
|
Symbol.Impl => ParseImpl(startIndex, name, templateParameters),
|
||||||
_ => throw new ParseException(Diagnostic
|
_ => throw new ParseException(Diagnostic
|
||||||
.Error($"Expected 'extern', 'func', 'struct', 'trait' or 'impl' but found '{keyword.Symbol}'")
|
.Error($"Expected 'extern', 'func', 'struct', 'trait' or 'impl' but found '{keyword.Symbol}'")
|
||||||
.WithHelp("Valid definition keywords are 'extern', 'func', 'struct', 'trait' and 'impl'")
|
.WithHelp("Valid definition keywords are 'extern', 'func', 'struct', 'trait' and 'impl'")
|
||||||
@@ -68,7 +76,25 @@ public sealed class Parser
|
|||||||
.Build())
|
.Build())
|
||||||
};
|
};
|
||||||
|
|
||||||
return node;
|
definitions.Add(definition);
|
||||||
|
}
|
||||||
|
catch (ParseException ex)
|
||||||
|
{
|
||||||
|
_diagnostics.Add(ex.Diagnostic);
|
||||||
|
while (Peek().HasValue)
|
||||||
|
{
|
||||||
|
var token = Peek().Value;
|
||||||
|
if (token is SymbolToken { Symbol: Symbol.Extern or Symbol.Func or Symbol.Struct or Symbol.Trait or Symbol.Impl })
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
Next();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new SyntaxTree(_namespace, definitions, _diagnostics);
|
||||||
}
|
}
|
||||||
|
|
||||||
private FuncSignatureSyntax ParseFuncSignature(FuncParameterSyntax? thisArg = null)
|
private FuncSignatureSyntax ParseFuncSignature(FuncParameterSyntax? thisArg = null)
|
||||||
@@ -113,19 +139,18 @@ public sealed class Parser
|
|||||||
return new FuncParameterSyntax(GetTokens(startIndex), name.Value, type);
|
return new FuncParameterSyntax(GetTokens(startIndex), name.Value, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
private DefinitionSyntax ParseExtern(int startIndex)
|
private DefinitionSyntax ParseExtern(int startIndex, IdentifierToken name, IReadOnlyList<TemplateParameterSyntax> templateParameters)
|
||||||
{
|
{
|
||||||
var keyword = ExpectSymbol();
|
var keyword = ExpectSymbol();
|
||||||
return keyword.Symbol switch
|
return keyword.Symbol switch
|
||||||
{
|
{
|
||||||
Symbol.Func => ParseExternFunc(startIndex),
|
Symbol.Func => ParseExternFunc(startIndex, name, templateParameters),
|
||||||
_ => throw new ParseException(Diagnostic.Error($"Unexpected symbol {keyword.Symbol} after extern declaration").At(keyword).Build())
|
_ => throw new ParseException(Diagnostic.Error($"Unexpected symbol {keyword.Symbol} after extern declaration").At(keyword).Build())
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private ExternFuncSyntax ParseExternFunc(int startIndex)
|
private ExternFuncSyntax ParseExternFunc(int startIndex, IdentifierToken name, IReadOnlyList<TemplateParameterSyntax> templateParameters)
|
||||||
{
|
{
|
||||||
var name = ExpectIdentifier();
|
|
||||||
var callName = name.Value;
|
var callName = name.Value;
|
||||||
|
|
||||||
if (TryExpectSymbol(Symbol.Calls))
|
if (TryExpectSymbol(Symbol.Calls))
|
||||||
@@ -135,25 +160,22 @@ public sealed class Parser
|
|||||||
|
|
||||||
var signature = ParseFuncSignature();
|
var signature = ParseFuncSignature();
|
||||||
|
|
||||||
return new ExternFuncSyntax(GetTokens(startIndex), _namespace, name.Value, callName, signature);
|
return new ExternFuncSyntax(GetTokens(startIndex), _namespace, templateParameters, name.Value, callName, signature);
|
||||||
}
|
}
|
||||||
|
|
||||||
private LocalFuncSyntax ParseFunc(int startIndex)
|
private LocalFuncSyntax ParseFunc(int startIndex, IdentifierToken name, IReadOnlyList<TemplateParameterSyntax> templateParameters)
|
||||||
{
|
{
|
||||||
var name = ExpectIdentifier();
|
|
||||||
var signature = ParseFuncSignature();
|
var signature = ParseFuncSignature();
|
||||||
var body = ParseBlock();
|
var body = ParseBlock();
|
||||||
|
|
||||||
return new LocalFuncSyntax(GetTokens(startIndex), _namespace, name.Value, signature, body);
|
return new LocalFuncSyntax(GetTokens(startIndex), _namespace, templateParameters, name.Value, signature, body);
|
||||||
}
|
}
|
||||||
|
|
||||||
private StructSyntax ParseStruct(int startIndex)
|
private DefinitionSyntax ParseStruct(int startIndex, IdentifierToken name, IReadOnlyList<TemplateParameterSyntax> templateParameters)
|
||||||
{
|
{
|
||||||
var name = ExpectIdentifier().Value;
|
|
||||||
|
|
||||||
ExpectSymbol(Symbol.OpenBrace);
|
ExpectSymbol(Symbol.OpenBrace);
|
||||||
|
|
||||||
List<StructFieldSyntax> variables = [];
|
List<StructFieldSyntax> fields = [];
|
||||||
|
|
||||||
var fieldIndex = 0;
|
var fieldIndex = 0;
|
||||||
|
|
||||||
@@ -161,27 +183,25 @@ public sealed class Parser
|
|||||||
{
|
{
|
||||||
var fieldStartIndex = _tokenIndex;
|
var fieldStartIndex = _tokenIndex;
|
||||||
|
|
||||||
var variableName = ExpectIdentifier().Value;
|
var fieldName = ExpectIdentifier().Value;
|
||||||
ExpectSymbol(Symbol.Colon);
|
ExpectSymbol(Symbol.Colon);
|
||||||
var variableType = ParseType();
|
var fieldType = ParseType();
|
||||||
|
|
||||||
var variableValue = Optional<ExpressionSyntax>.Empty();
|
var fieldValue = Optional<ExpressionSyntax>.Empty();
|
||||||
|
|
||||||
if (TryExpectSymbol(Symbol.Assign))
|
if (TryExpectSymbol(Symbol.Assign))
|
||||||
{
|
{
|
||||||
variableValue = ParseExpression();
|
fieldValue = ParseExpression();
|
||||||
}
|
}
|
||||||
|
|
||||||
variables.Add(new StructFieldSyntax(GetTokens(fieldStartIndex), fieldIndex++, variableName, variableType, variableValue));
|
fields.Add(new StructFieldSyntax(GetTokens(fieldStartIndex), fieldIndex++, fieldName, fieldType, fieldValue));
|
||||||
}
|
}
|
||||||
|
|
||||||
return new StructSyntax(GetTokens(startIndex), _namespace, name, variables);
|
return new StructSyntax(GetTokens(startIndex), _namespace, templateParameters, name.Value, fields);
|
||||||
}
|
}
|
||||||
|
|
||||||
private TraitSyntax ParseTrait(int startIndex)
|
private TraitSyntax ParseTrait(int startIndex, IdentifierToken name, IReadOnlyList<TemplateParameterSyntax> templateParameters)
|
||||||
{
|
{
|
||||||
var name = ExpectIdentifier().Value;
|
|
||||||
|
|
||||||
ExpectSymbol(Symbol.OpenBrace);
|
ExpectSymbol(Symbol.OpenBrace);
|
||||||
|
|
||||||
List<TraitFuncSyntax> functions = [];
|
List<TraitFuncSyntax> functions = [];
|
||||||
@@ -198,10 +218,10 @@ public sealed class Parser
|
|||||||
functions.Add(new TraitFuncSyntax(GetTokens(funcStartIndex), funcName, signature));
|
functions.Add(new TraitFuncSyntax(GetTokens(funcStartIndex), funcName, signature));
|
||||||
}
|
}
|
||||||
|
|
||||||
return new TraitSyntax(GetTokens(startIndex), _namespace, name, functions);
|
return new TraitSyntax(GetTokens(startIndex), _namespace, templateParameters, name.Value, functions);
|
||||||
}
|
}
|
||||||
|
|
||||||
private TraitImplSyntax ParseImpl(int startIndex)
|
private TraitImplSyntax ParseImpl(int startIndex, IdentifierToken name, IReadOnlyList<TemplateParameterSyntax> templateParameters)
|
||||||
{
|
{
|
||||||
var traitType = ParseType();
|
var traitType = ParseType();
|
||||||
ExpectSymbol(Symbol.For);
|
ExpectSymbol(Symbol.For);
|
||||||
@@ -222,7 +242,7 @@ public sealed class Parser
|
|||||||
functions.AddRange(new TraitFuncImplSyntax(GetTokens(funcStartIndex), functionName, signature, body));
|
functions.AddRange(new TraitFuncImplSyntax(GetTokens(funcStartIndex), functionName, signature, body));
|
||||||
}
|
}
|
||||||
|
|
||||||
return new TraitImplSyntax(GetTokens(startIndex), _namespace, traitType, forType, functions);
|
return new TraitImplSyntax(GetTokens(startIndex), _namespace, templateParameters, traitType, forType, functions);
|
||||||
}
|
}
|
||||||
|
|
||||||
private StatementSyntax ParseStatement()
|
private StatementSyntax ParseStatement()
|
||||||
@@ -813,20 +833,6 @@ public sealed class Parser
|
|||||||
return identifier;
|
return identifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void RecoverToNextDefinition()
|
|
||||||
{
|
|
||||||
while (Peek().HasValue)
|
|
||||||
{
|
|
||||||
var token = Peek().Value;
|
|
||||||
if (token is SymbolToken { Symbol: Symbol.Extern or Symbol.Func or Symbol.Struct or Symbol.Trait or Symbol.Impl or Symbol.Template })
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
Next();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Optional<Token> Peek(int offset = 0)
|
private Optional<Token> Peek(int offset = 0)
|
||||||
{
|
{
|
||||||
var peekIndex = _tokenIndex + offset;
|
var peekIndex = _tokenIndex + offset;
|
||||||
|
|||||||
@@ -73,5 +73,4 @@ public enum Symbol
|
|||||||
Extern,
|
Extern,
|
||||||
Semi,
|
Semi,
|
||||||
Arrow,
|
Arrow,
|
||||||
Template
|
|
||||||
}
|
}
|
||||||
@@ -23,7 +23,6 @@ public sealed class Tokenizer
|
|||||||
["impl"] = Symbol.Impl,
|
["impl"] = Symbol.Impl,
|
||||||
["for"] = Symbol.For,
|
["for"] = Symbol.For,
|
||||||
["extern"] = Symbol.Extern,
|
["extern"] = Symbol.Extern,
|
||||||
["template"] = Symbol.Template,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
private static readonly Dictionary<char[], Symbol> Chians = new()
|
private static readonly Dictionary<char[], Symbol> Chians = new()
|
||||||
|
|||||||
Reference in New Issue
Block a user