Arrow func
This commit is contained in:
@@ -220,7 +220,7 @@ public sealed class Binder
|
||||
return node switch
|
||||
{
|
||||
AddressOfSyntax expression => BindAddressOf(expression),
|
||||
AnonymousFuncSyntax expression => BindAnonymousFunc(expression, expectedType),
|
||||
ArrowFuncSyntax expression => BindArrowFunc(expression, expectedType),
|
||||
ArrayIndexAccessSyntax expression => BindArrayIndexAccess(expression),
|
||||
ArrayInitializerSyntax expression => BindArrayInitializer(expression),
|
||||
BinaryExpressionSyntax expression => BindBinaryExpression(expression),
|
||||
@@ -241,16 +241,16 @@ public sealed class Binder
|
||||
return new BoundAddressOf(expression.Tokens, new NubPointerType(inner.Type), inner);
|
||||
}
|
||||
|
||||
private BoundAnonymousFunc BindAnonymousFunc(AnonymousFuncSyntax expression, NubType? expectedType = null)
|
||||
private BoundArrowFunc BindArrowFunc(ArrowFuncSyntax expression, NubType? expectedType = null)
|
||||
{
|
||||
if (expectedType == null)
|
||||
{
|
||||
throw new BindException(Diagnostic.Error("Cannot infer argument types for anonymous function").At(expression).Build());
|
||||
throw new BindException(Diagnostic.Error("Cannot infer argument types for arrow function").At(expression).Build());
|
||||
}
|
||||
|
||||
if (expectedType is not NubFuncType funcType)
|
||||
{
|
||||
throw new BindException(Diagnostic.Error($"Expected {expectedType}, but got anonymous function").At(expression).Build());
|
||||
throw new BindException(Diagnostic.Error($"Expected {expectedType}, but got arrow function").At(expression).Build());
|
||||
}
|
||||
|
||||
var parameters = new List<BoundFuncParameter>();
|
||||
@@ -259,7 +259,7 @@ public sealed class Binder
|
||||
{
|
||||
if (i >= funcType.Parameters.Count)
|
||||
{
|
||||
throw new BindException(Diagnostic.Error($"Anonymous function expected a maximum of {funcType.Parameters.Count} arguments").Build());
|
||||
throw new BindException(Diagnostic.Error($"Arrow function expected a maximum of {funcType.Parameters.Count} arguments").Build());
|
||||
}
|
||||
|
||||
var expectedParameterType = funcType.Parameters[i];
|
||||
@@ -269,7 +269,7 @@ public sealed class Binder
|
||||
|
||||
var body = BindFuncBody(expression.Body, funcType.ReturnType, parameters);
|
||||
|
||||
return new BoundAnonymousFunc(expression.Tokens, new NubFuncType(funcType.ReturnType, parameters.Select(x => x.Type).ToList()), parameters, funcType.ReturnType, body);
|
||||
return new BoundArrowFunc(expression.Tokens, new NubFuncType(funcType.ReturnType, parameters.Select(x => x.Type).ToList()), parameters, funcType.ReturnType, body);
|
||||
}
|
||||
|
||||
private BoundArrayIndexAccess BindArrayIndexAccess(ArrayIndexAccessSyntax expression)
|
||||
|
||||
@@ -40,7 +40,7 @@ public record BoundArrayInitializer(IReadOnlyList<Token> Tokens, NubType Type, B
|
||||
|
||||
public record BoundArrayIndexAccess(IReadOnlyList<Token> Tokens, NubType Type, BoundExpression Target, BoundExpression Index) : BoundExpression(Tokens, Type);
|
||||
|
||||
public record BoundAnonymousFunc(IReadOnlyList<Token> Tokens, NubType Type, IReadOnlyList<BoundFuncParameter> Parameters, NubType ReturnType, BoundBlock Body) : BoundExpression(Tokens, Type);
|
||||
public record BoundArrowFunc(IReadOnlyList<Token> Tokens, NubType Type, IReadOnlyList<BoundFuncParameter> Parameters, NubType ReturnType, BoundBlock Body) : BoundExpression(Tokens, Type);
|
||||
|
||||
public record BoundAddressOf(IReadOnlyList<Token> Tokens, NubType Type, BoundExpression Expression) : BoundExpression(Tokens, Type);
|
||||
|
||||
|
||||
@@ -37,9 +37,9 @@ public record ArrayInitializerSyntax(IReadOnlyList<Token> Tokens, ExpressionSynt
|
||||
|
||||
public record ArrayIndexAccessSyntax(IReadOnlyList<Token> Tokens, ExpressionSyntax Target, ExpressionSyntax Index) : ExpressionSyntax(Tokens);
|
||||
|
||||
public record AnonymousFuncParameterSyntax(IReadOnlyList<Token> Tokens, string Name) : ExpressionSyntax(Tokens);
|
||||
public record ArrowFuncParameterSyntax(IReadOnlyList<Token> Tokens, string Name) : ExpressionSyntax(Tokens);
|
||||
|
||||
public record AnonymousFuncSyntax(IReadOnlyList<Token> Tokens, IReadOnlyList<AnonymousFuncParameterSyntax> Parameters, BlockSyntax Body) : ExpressionSyntax(Tokens);
|
||||
public record ArrowFuncSyntax(IReadOnlyList<Token> Tokens, IReadOnlyList<ArrowFuncParameterSyntax> Parameters, BlockSyntax Body) : ExpressionSyntax(Tokens);
|
||||
|
||||
public record AddressOfSyntax(IReadOnlyList<Token> Tokens, ExpressionSyntax Expression) : ExpressionSyntax(Tokens);
|
||||
|
||||
|
||||
@@ -456,18 +456,31 @@ public sealed class Parser
|
||||
{
|
||||
case Symbol.Func:
|
||||
{
|
||||
List<AnonymousFuncParameterSyntax> parameters = [];
|
||||
List<ArrowFuncParameterSyntax> parameters = [];
|
||||
ExpectSymbol(Symbol.OpenParen);
|
||||
while (!TryExpectSymbol(Symbol.CloseParen))
|
||||
{
|
||||
var parameterStartIndex = _tokenIndex;
|
||||
var name = ExpectIdentifier();
|
||||
parameters.Add(new AnonymousFuncParameterSyntax(GetTokens(parameterStartIndex), name.Value));
|
||||
parameters.Add(new ArrowFuncParameterSyntax(GetTokens(parameterStartIndex), name.Value));
|
||||
}
|
||||
|
||||
var body = ParseBlock();
|
||||
BlockSyntax body;
|
||||
|
||||
expr = new AnonymousFuncSyntax(GetTokens(startIndex), parameters, body);
|
||||
if (TryExpectSymbol(Symbol.Arrow))
|
||||
{
|
||||
var blockStartIndex = _tokenIndex;
|
||||
var returnValue = ParseExpression();
|
||||
var tokens = GetTokens(blockStartIndex);
|
||||
var arrowExpression = new ReturnSyntax(tokens, returnValue);
|
||||
body = new BlockSyntax(tokens, [arrowExpression]);
|
||||
}
|
||||
else
|
||||
{
|
||||
body = ParseBlock();
|
||||
}
|
||||
|
||||
expr = new ArrowFuncSyntax(GetTokens(startIndex), parameters, body);
|
||||
break;
|
||||
}
|
||||
case Symbol.OpenParen:
|
||||
|
||||
@@ -71,5 +71,6 @@ public enum Symbol
|
||||
Impl,
|
||||
For,
|
||||
Extern,
|
||||
Semi
|
||||
Semi,
|
||||
Arrow,
|
||||
}
|
||||
@@ -32,6 +32,7 @@ public sealed class Tokenizer
|
||||
[['<', '=']] = Symbol.LessThanOrEqual,
|
||||
[['>', '=']] = Symbol.GreaterThanOrEqual,
|
||||
[[':', ':']] = Symbol.DoubleColon,
|
||||
[['=', '>']] = Symbol.Arrow,
|
||||
};
|
||||
|
||||
private static readonly Dictionary<char, Symbol> Chars = new()
|
||||
|
||||
Reference in New Issue
Block a user