This commit is contained in:
nub31
2025-07-21 17:06:31 +02:00
parent 1f6f4eab95
commit 69982017c5
6 changed files with 42 additions and 75 deletions

View File

@@ -50,30 +50,14 @@ public sealed class Binder
return node switch return node switch
{ {
ExternFuncSyntax definition => BindExternFuncDefinition(definition), ExternFuncSyntax definition => BindExternFuncDefinition(definition),
TraitImplSyntax definition => BindTraitImplementation(definition), InterfaceSyntax definition => BindTraitDefinition(definition),
TraitSyntax definition => BindTraitDefinition(definition),
LocalFuncSyntax definition => BindLocalFuncDefinition(definition), LocalFuncSyntax definition => BindLocalFuncDefinition(definition),
StructSyntax definition => BindStruct(definition), StructSyntax definition => BindStruct(definition),
_ => throw new ArgumentOutOfRangeException(nameof(node)) _ => throw new ArgumentOutOfRangeException(nameof(node))
}; };
} }
private BoundTraitImpl BindTraitImplementation(TraitImplSyntax node) private BoundTrait BindTraitDefinition(InterfaceSyntax 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)
{ {
var functions = new List<BoundTraitFunc>(); var functions = new List<BoundTraitFunc>();

View File

@@ -46,15 +46,15 @@ public class DefinitionTable
// .Where(x => x.Name == name); // .Where(x => x.Name == name);
// } // }
public IEnumerable<TraitSyntax> LookupTrait(NubCustomType type) public IEnumerable<InterfaceSyntax> LookupTrait(NubCustomType type)
{ {
return _definitions return _definitions
.OfType<TraitSyntax>() .OfType<InterfaceSyntax>()
.Where(x => x.Namespace == type.Namespace && x.Name == type.Name); .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);
} }
} }

View File

@@ -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 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 InterfaceSyntax(IReadOnlyList<Token> Tokens, string Namespace, IReadOnlyList<TemplateParameterSyntax> Parameters, string Name, IReadOnlyList<InterfaceFuncSyntax> Functions) : DefinitionSyntax(Tokens, Namespace, Parameters);
public record TraitImplSyntax(IReadOnlyList<Token> Tokens, string Namespace, IReadOnlyList<TemplateParameterSyntax> Parameters, TypeSyntax TraitType, TypeSyntax ForType, IReadOnlyList<TraitFuncImplSyntax> Functions) : DefinitionSyntax(Tokens, Namespace, Parameters);

View File

@@ -67,8 +67,7 @@ public sealed class Parser
Symbol.Extern => ParseExtern(startIndex, name, templateParameters), Symbol.Extern => ParseExtern(startIndex, name, templateParameters),
Symbol.Func => ParseFunc(startIndex, name, templateParameters), Symbol.Func => ParseFunc(startIndex, name, templateParameters),
Symbol.Struct => ParseStruct(startIndex, name, templateParameters), Symbol.Struct => ParseStruct(startIndex, name, templateParameters),
Symbol.Trait => ParseTrait(startIndex, name, templateParameters), Symbol.Interface => ParseInterface(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'")
@@ -84,7 +83,7 @@ public sealed class Parser
while (Peek().HasValue) while (Peek().HasValue)
{ {
var token = Peek().Value; 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; break;
} }
@@ -176,35 +175,47 @@ public sealed class Parser
ExpectSymbol(Symbol.OpenBrace); ExpectSymbol(Symbol.OpenBrace);
List<StructFieldSyntax> fields = []; List<StructFieldSyntax> fields = [];
List<StructFuncSyntax> funcs = [];
var fieldIndex = 0; var fieldIndex = 0;
while (!TryExpectSymbol(Symbol.CloseBrace)) while (!TryExpectSymbol(Symbol.CloseBrace))
{ {
var fieldStartIndex = _tokenIndex; var memberStartIndex = _tokenIndex;
var fieldName = ExpectIdentifier().Value; if (TryExpectSymbol(Symbol.Func))
ExpectSymbol(Symbol.Colon);
var fieldType = ParseType();
var fieldValue = Optional<ExpressionSyntax>.Empty();
if (TryExpectSymbol(Symbol.Assign))
{ {
fieldValue = ParseExpression(); var funcName = ExpectIdentifier().Value;
} var funcSignature = ParseFuncSignature(new FuncParameterSyntax([], "this", new CustomTypeSyntax([], _namespace, name.Value)));
var funcBody = ParseBlock();
fields.Add(new StructFieldSyntax(GetTokens(fieldStartIndex), fieldIndex++, fieldName, fieldType, fieldValue)); funcs.Add(new StructFuncSyntax(GetTokens(memberStartIndex), funcName, funcSignature, funcBody));
}
else
{
var fieldName = ExpectIdentifier().Value;
ExpectSymbol(Symbol.Colon);
var fieldType = ParseType();
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); ExpectSymbol(Symbol.OpenBrace);
List<TraitFuncSyntax> functions = []; List<InterfaceFuncSyntax> functions = [];
while (!TryExpectSymbol(Symbol.CloseBrace)) while (!TryExpectSymbol(Symbol.CloseBrace))
{ {
@@ -215,34 +226,10 @@ public sealed class Parser
var funcName = ExpectIdentifier().Value; var funcName = ExpectIdentifier().Value;
var signature = ParseFuncSignature(); 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); return new InterfaceSyntax(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);
} }
private StatementSyntax ParseStatement() private StatementSyntax ParseStatement()
@@ -252,7 +239,7 @@ public sealed class Parser
{ {
throw new ParseException(Diagnostic throw new ParseException(Diagnostic
.Error("Unexpected end of file while parsing statement") .Error("Unexpected end of file while parsing statement")
.At(_tokens.Last()) .At(_tokens[^1])
.Build()); .Build());
} }

View File

@@ -67,8 +67,7 @@ public enum Symbol
Let, Let,
Alloc, Alloc,
Calls, Calls,
Trait, Interface,
Impl,
For, For,
Extern, Extern,
Semi, Semi,

View File

@@ -19,8 +19,7 @@ public sealed class Tokenizer
["struct"] = Symbol.Struct, ["struct"] = Symbol.Struct,
["let"] = Symbol.Let, ["let"] = Symbol.Let,
["calls"] = Symbol.Calls, ["calls"] = Symbol.Calls,
["trait"] = Symbol.Trait, ["interface"] = Symbol.Interface,
["impl"] = Symbol.Impl,
["for"] = Symbol.For, ["for"] = Symbol.For,
["extern"] = Symbol.Extern, ["extern"] = Symbol.Extern,
}; };