...
This commit is contained in:
@@ -50,30 +50,14 @@ public sealed class Binder
|
||||
return node switch
|
||||
{
|
||||
ExternFuncSyntax definition => BindExternFuncDefinition(definition),
|
||||
TraitImplSyntax definition => BindTraitImplementation(definition),
|
||||
TraitSyntax definition => BindTraitDefinition(definition),
|
||||
InterfaceSyntax definition => BindTraitDefinition(definition),
|
||||
LocalFuncSyntax definition => BindLocalFuncDefinition(definition),
|
||||
StructSyntax definition => BindStruct(definition),
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(node))
|
||||
};
|
||||
}
|
||||
|
||||
private BoundTraitImpl BindTraitImplementation(TraitImplSyntax node)
|
||||
{
|
||||
var functions = new List<BoundTraitFuncImpl>();
|
||||
|
||||
foreach (var func in node.Functions)
|
||||
{
|
||||
var signature = BindFuncSignature(func.Signature);
|
||||
var body = BindFuncBody(func.Body, signature.ReturnType, signature.Parameters);
|
||||
|
||||
functions.Add(new BoundTraitFuncImpl(func.Tokens, func.Name, signature, body));
|
||||
}
|
||||
|
||||
return new BoundTraitImpl(node.Tokens, node.Namespace, BindType(node.TraitType), BindType(node.ForType), functions);
|
||||
}
|
||||
|
||||
private BoundTrait BindTraitDefinition(TraitSyntax node)
|
||||
private BoundTrait BindTraitDefinition(InterfaceSyntax node)
|
||||
{
|
||||
var functions = new List<BoundTraitFunc>();
|
||||
|
||||
|
||||
@@ -46,15 +46,15 @@ public class DefinitionTable
|
||||
// .Where(x => x.Name == name);
|
||||
// }
|
||||
|
||||
public IEnumerable<TraitSyntax> LookupTrait(NubCustomType type)
|
||||
public IEnumerable<InterfaceSyntax> LookupTrait(NubCustomType type)
|
||||
{
|
||||
return _definitions
|
||||
.OfType<TraitSyntax>()
|
||||
.OfType<InterfaceSyntax>()
|
||||
.Where(x => x.Namespace == type.Namespace && x.Name == type.Name);
|
||||
}
|
||||
|
||||
public IEnumerable<TraitFuncSyntax> LookupTraitFunc(TraitSyntax trait, string name)
|
||||
public IEnumerable<InterfaceFuncSyntax> LookupTraitFunc(InterfaceSyntax @interface, string name)
|
||||
{
|
||||
return trait.Functions.Where(x => x.Name == name);
|
||||
return @interface.Functions.Where(x => x.Name == name);
|
||||
}
|
||||
}
|
||||
@@ -17,12 +17,10 @@ public record ExternFuncSyntax(IReadOnlyList<Token> Tokens, string Namespace, IR
|
||||
|
||||
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, IReadOnlyList<TemplateParameterSyntax> Parameters, string Name, IReadOnlyList<StructFieldSyntax> Fields) : DefinitionSyntax(Tokens, Namespace, Parameters);
|
||||
public record StructFuncSyntax(IReadOnlyList<Token> Tokens, string Name, FuncSignatureSyntax Signature, BlockSyntax Body) : SyntaxNode(Tokens);
|
||||
|
||||
public record TraitFuncSyntax(IReadOnlyList<Token> Tokens, string Name, FuncSignatureSyntax Signature) : SyntaxNode(Tokens);
|
||||
public record StructSyntax(IReadOnlyList<Token> Tokens, string Namespace, IReadOnlyList<TemplateParameterSyntax> Parameters, string Name, IReadOnlyList<StructFieldSyntax> Fields, IReadOnlyList<StructFuncSyntax> Funcs) : DefinitionSyntax(Tokens, Namespace, Parameters);
|
||||
|
||||
public record TraitSyntax(IReadOnlyList<Token> Tokens, string Namespace, IReadOnlyList<TemplateParameterSyntax> Parameters, string Name, IReadOnlyList<TraitFuncSyntax> Functions) : DefinitionSyntax(Tokens, Namespace, Parameters);
|
||||
public record InterfaceFuncSyntax(IReadOnlyList<Token> Tokens, string Name, FuncSignatureSyntax Signature) : SyntaxNode(Tokens);
|
||||
|
||||
public record TraitFuncImplSyntax(IReadOnlyList<Token> Tokens, string Name, FuncSignatureSyntax Signature, BlockSyntax Body) : SyntaxNode(Tokens);
|
||||
|
||||
public record TraitImplSyntax(IReadOnlyList<Token> Tokens, string Namespace, IReadOnlyList<TemplateParameterSyntax> Parameters, TypeSyntax TraitType, TypeSyntax ForType, IReadOnlyList<TraitFuncImplSyntax> Functions) : DefinitionSyntax(Tokens, Namespace, Parameters);
|
||||
public record InterfaceSyntax(IReadOnlyList<Token> Tokens, string Namespace, IReadOnlyList<TemplateParameterSyntax> Parameters, string Name, IReadOnlyList<InterfaceFuncSyntax> Functions) : DefinitionSyntax(Tokens, Namespace, Parameters);
|
||||
@@ -67,8 +67,7 @@ public sealed class Parser
|
||||
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),
|
||||
Symbol.Interface => ParseInterface(startIndex, name, templateParameters),
|
||||
_ => throw new ParseException(Diagnostic
|
||||
.Error($"Expected 'extern', 'func', 'struct', 'trait' or 'impl' but found '{keyword.Symbol}'")
|
||||
.WithHelp("Valid definition keywords are 'extern', 'func', 'struct', 'trait' and 'impl'")
|
||||
@@ -84,7 +83,7 @@ public sealed class Parser
|
||||
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 })
|
||||
if (token is SymbolToken { Symbol: Symbol.Extern or Symbol.Func or Symbol.Struct or Symbol.Interface })
|
||||
{
|
||||
break;
|
||||
}
|
||||
@@ -176,35 +175,47 @@ public sealed class Parser
|
||||
ExpectSymbol(Symbol.OpenBrace);
|
||||
|
||||
List<StructFieldSyntax> fields = [];
|
||||
List<StructFuncSyntax> funcs = [];
|
||||
|
||||
var fieldIndex = 0;
|
||||
|
||||
while (!TryExpectSymbol(Symbol.CloseBrace))
|
||||
{
|
||||
var fieldStartIndex = _tokenIndex;
|
||||
var memberStartIndex = _tokenIndex;
|
||||
|
||||
var fieldName = ExpectIdentifier().Value;
|
||||
ExpectSymbol(Symbol.Colon);
|
||||
var fieldType = ParseType();
|
||||
|
||||
var fieldValue = Optional<ExpressionSyntax>.Empty();
|
||||
|
||||
if (TryExpectSymbol(Symbol.Assign))
|
||||
if (TryExpectSymbol(Symbol.Func))
|
||||
{
|
||||
fieldValue = ParseExpression();
|
||||
var funcName = ExpectIdentifier().Value;
|
||||
var funcSignature = ParseFuncSignature(new FuncParameterSyntax([], "this", new CustomTypeSyntax([], _namespace, name.Value)));
|
||||
var funcBody = ParseBlock();
|
||||
|
||||
funcs.Add(new StructFuncSyntax(GetTokens(memberStartIndex), funcName, funcSignature, funcBody));
|
||||
}
|
||||
else
|
||||
{
|
||||
var fieldName = ExpectIdentifier().Value;
|
||||
ExpectSymbol(Symbol.Colon);
|
||||
var fieldType = ParseType();
|
||||
|
||||
fields.Add(new StructFieldSyntax(GetTokens(fieldStartIndex), fieldIndex++, fieldName, fieldType, fieldValue));
|
||||
var fieldValue = Optional<ExpressionSyntax>.Empty();
|
||||
|
||||
if (TryExpectSymbol(Symbol.Assign))
|
||||
{
|
||||
fieldValue = ParseExpression();
|
||||
}
|
||||
|
||||
fields.Add(new StructFieldSyntax(GetTokens(memberStartIndex), fieldIndex++, fieldName, fieldType, fieldValue));
|
||||
}
|
||||
}
|
||||
|
||||
return new StructSyntax(GetTokens(startIndex), _namespace, templateParameters, name.Value, fields);
|
||||
return new StructSyntax(GetTokens(startIndex), _namespace, templateParameters, name.Value, fields, funcs);
|
||||
}
|
||||
|
||||
private TraitSyntax ParseTrait(int startIndex, IdentifierToken name, IReadOnlyList<TemplateParameterSyntax> templateParameters)
|
||||
private InterfaceSyntax ParseInterface(int startIndex, IdentifierToken name, IReadOnlyList<TemplateParameterSyntax> templateParameters)
|
||||
{
|
||||
ExpectSymbol(Symbol.OpenBrace);
|
||||
|
||||
List<TraitFuncSyntax> functions = [];
|
||||
List<InterfaceFuncSyntax> functions = [];
|
||||
|
||||
while (!TryExpectSymbol(Symbol.CloseBrace))
|
||||
{
|
||||
@@ -215,34 +226,10 @@ public sealed class Parser
|
||||
var funcName = ExpectIdentifier().Value;
|
||||
var signature = ParseFuncSignature();
|
||||
|
||||
functions.Add(new TraitFuncSyntax(GetTokens(funcStartIndex), funcName, signature));
|
||||
functions.Add(new InterfaceFuncSyntax(GetTokens(funcStartIndex), funcName, signature));
|
||||
}
|
||||
|
||||
return new TraitSyntax(GetTokens(startIndex), _namespace, templateParameters, name.Value, functions);
|
||||
}
|
||||
|
||||
private TraitImplSyntax ParseImpl(int startIndex, IdentifierToken name, IReadOnlyList<TemplateParameterSyntax> templateParameters)
|
||||
{
|
||||
var traitType = ParseType();
|
||||
ExpectSymbol(Symbol.For);
|
||||
var forType = ParseType();
|
||||
|
||||
List<TraitFuncImplSyntax> functions = [];
|
||||
|
||||
ExpectSymbol(Symbol.OpenBrace);
|
||||
while (!TryExpectSymbol(Symbol.CloseBrace))
|
||||
{
|
||||
var funcStartIndex = _tokenIndex;
|
||||
ExpectSymbol(Symbol.Func);
|
||||
var functionName = ExpectIdentifier().Value;
|
||||
|
||||
var signature = ParseFuncSignature(new FuncParameterSyntax([], "this", forType));
|
||||
var body = ParseBlock();
|
||||
|
||||
functions.AddRange(new TraitFuncImplSyntax(GetTokens(funcStartIndex), functionName, signature, body));
|
||||
}
|
||||
|
||||
return new TraitImplSyntax(GetTokens(startIndex), _namespace, templateParameters, traitType, forType, functions);
|
||||
return new InterfaceSyntax(GetTokens(startIndex), _namespace, templateParameters, name.Value, functions);
|
||||
}
|
||||
|
||||
private StatementSyntax ParseStatement()
|
||||
@@ -252,7 +239,7 @@ public sealed class Parser
|
||||
{
|
||||
throw new ParseException(Diagnostic
|
||||
.Error("Unexpected end of file while parsing statement")
|
||||
.At(_tokens.Last())
|
||||
.At(_tokens[^1])
|
||||
.Build());
|
||||
}
|
||||
|
||||
|
||||
@@ -67,8 +67,7 @@ public enum Symbol
|
||||
Let,
|
||||
Alloc,
|
||||
Calls,
|
||||
Trait,
|
||||
Impl,
|
||||
Interface,
|
||||
For,
|
||||
Extern,
|
||||
Semi,
|
||||
|
||||
@@ -19,8 +19,7 @@ public sealed class Tokenizer
|
||||
["struct"] = Symbol.Struct,
|
||||
["let"] = Symbol.Let,
|
||||
["calls"] = Symbol.Calls,
|
||||
["trait"] = Symbol.Trait,
|
||||
["impl"] = Symbol.Impl,
|
||||
["interface"] = Symbol.Interface,
|
||||
["for"] = Symbol.For,
|
||||
["extern"] = Symbol.Extern,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user