Arrow func
This commit is contained in:
@@ -34,7 +34,7 @@ func main(args: []cstring): i64
|
|||||||
}
|
}
|
||||||
|
|
||||||
human.print()
|
human.print()
|
||||||
print_result(12, func(num) { return num == 12 })
|
print_result(12, func (num) => num == 12)
|
||||||
|
|
||||||
let x: cstring = "test"
|
let x: cstring = "test"
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ public partial class QBEGenerator
|
|||||||
BoundStructInitializer structInitializer => EmitStructInitializer(structInitializer),
|
BoundStructInitializer structInitializer => EmitStructInitializer(structInitializer),
|
||||||
BoundAddressOf addressOf => EmitAddressOf(addressOf),
|
BoundAddressOf addressOf => EmitAddressOf(addressOf),
|
||||||
BoundDereference dereference => EmitDereference(dereference),
|
BoundDereference dereference => EmitDereference(dereference),
|
||||||
BoundAnonymousFunc anonymousFunc => EmitAnonymousFunc(anonymousFunc),
|
BoundArrowFunc arrowFunc => EmitArrowFunc(arrowFunc),
|
||||||
BoundBinaryExpression binaryExpression => EmitBinaryExpression(binaryExpression),
|
BoundBinaryExpression binaryExpression => EmitBinaryExpression(binaryExpression),
|
||||||
BoundFuncCall funcCallExpression => EmitFuncCall(funcCallExpression),
|
BoundFuncCall funcCallExpression => EmitFuncCall(funcCallExpression),
|
||||||
BoundExternFuncIdent externFuncIdent => EmitExternFuncIdent(externFuncIdent),
|
BoundExternFuncIdent externFuncIdent => EmitExternFuncIdent(externFuncIdent),
|
||||||
@@ -33,11 +33,11 @@ public partial class QBEGenerator
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private Val EmitAnonymousFunc(BoundAnonymousFunc anonymousFunc)
|
private Val EmitArrowFunc(BoundArrowFunc arrowFunc)
|
||||||
{
|
{
|
||||||
var name = $"$anon_func{++_anonymousFuncIndex}";
|
var name = $"$arrow_func{++_arrowFuncIndex}";
|
||||||
_anonymousFunctions.Enqueue((anonymousFunc, name));
|
_arrowFunctions.Enqueue((arrowFunc, name));
|
||||||
return new Val(name, anonymousFunc.Type, ValKind.Direct);
|
return new Val(name, arrowFunc.Type, ValKind.Direct);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Val EmitArrayIndexAccess(BoundArrayIndexAccess arrayIndexAccess)
|
private Val EmitArrayIndexAccess(BoundArrayIndexAccess arrayIndexAccess)
|
||||||
|
|||||||
@@ -16,12 +16,12 @@ public partial class QBEGenerator
|
|||||||
private readonly List<StringLiteral> _stringLiterals = [];
|
private readonly List<StringLiteral> _stringLiterals = [];
|
||||||
private readonly Stack<string> _breakLabels = [];
|
private readonly Stack<string> _breakLabels = [];
|
||||||
private readonly Stack<string> _continueLabels = [];
|
private readonly Stack<string> _continueLabels = [];
|
||||||
private readonly Queue<(BoundAnonymousFunc Func, string Name)> _anonymousFunctions = [];
|
private readonly Queue<(BoundArrowFunc Func, string Name)> _arrowFunctions = [];
|
||||||
private readonly Dictionary<BoundTraitFuncImpl, string> _implFunctions = [];
|
private readonly Dictionary<BoundTraitFuncImpl, string> _implFunctions = [];
|
||||||
private readonly Stack<Scope> _scopes = [];
|
private readonly Stack<Scope> _scopes = [];
|
||||||
private int _tmpIndex;
|
private int _tmpIndex;
|
||||||
private int _labelIndex;
|
private int _labelIndex;
|
||||||
private int _anonymousFuncIndex;
|
private int _arrowFuncIndex;
|
||||||
private int _cStringLiteralIndex;
|
private int _cStringLiteralIndex;
|
||||||
private int _stringLiteralIndex;
|
private int _stringLiteralIndex;
|
||||||
private int _implFuncNameIndex;
|
private int _implFuncNameIndex;
|
||||||
@@ -42,12 +42,12 @@ public partial class QBEGenerator
|
|||||||
_stringLiterals.Clear();
|
_stringLiterals.Clear();
|
||||||
_breakLabels.Clear();
|
_breakLabels.Clear();
|
||||||
_continueLabels.Clear();
|
_continueLabels.Clear();
|
||||||
_anonymousFunctions.Clear();
|
_arrowFunctions.Clear();
|
||||||
_implFunctions.Clear();
|
_implFunctions.Clear();
|
||||||
_scopes.Clear();
|
_scopes.Clear();
|
||||||
_tmpIndex = 0;
|
_tmpIndex = 0;
|
||||||
_labelIndex = 0;
|
_labelIndex = 0;
|
||||||
_anonymousFuncIndex = 0;
|
_arrowFuncIndex = 0;
|
||||||
_cStringLiteralIndex = 0;
|
_cStringLiteralIndex = 0;
|
||||||
_stringLiteralIndex = 0;
|
_stringLiteralIndex = 0;
|
||||||
_implFuncNameIndex = 0;
|
_implFuncNameIndex = 0;
|
||||||
@@ -71,9 +71,9 @@ public partial class QBEGenerator
|
|||||||
_writer.NewLine();
|
_writer.NewLine();
|
||||||
}
|
}
|
||||||
|
|
||||||
while (_anonymousFunctions.TryDequeue(out var anon))
|
while (_arrowFunctions.TryDequeue(out var arrowFunc))
|
||||||
{
|
{
|
||||||
EmitFuncDefinition(anon.Name, anon.Func.Parameters, anon.Func.ReturnType, anon.Func.Body);
|
EmitFuncDefinition(arrowFunc.Name, arrowFunc.Func.Parameters, arrowFunc.Func.ReturnType, arrowFunc.Func.Body);
|
||||||
_writer.NewLine();
|
_writer.NewLine();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -220,7 +220,7 @@ public sealed class Binder
|
|||||||
return node switch
|
return node switch
|
||||||
{
|
{
|
||||||
AddressOfSyntax expression => BindAddressOf(expression),
|
AddressOfSyntax expression => BindAddressOf(expression),
|
||||||
AnonymousFuncSyntax expression => BindAnonymousFunc(expression, expectedType),
|
ArrowFuncSyntax expression => BindArrowFunc(expression, expectedType),
|
||||||
ArrayIndexAccessSyntax expression => BindArrayIndexAccess(expression),
|
ArrayIndexAccessSyntax expression => BindArrayIndexAccess(expression),
|
||||||
ArrayInitializerSyntax expression => BindArrayInitializer(expression),
|
ArrayInitializerSyntax expression => BindArrayInitializer(expression),
|
||||||
BinaryExpressionSyntax expression => BindBinaryExpression(expression),
|
BinaryExpressionSyntax expression => BindBinaryExpression(expression),
|
||||||
@@ -241,16 +241,16 @@ public sealed class Binder
|
|||||||
return new BoundAddressOf(expression.Tokens, new NubPointerType(inner.Type), inner);
|
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)
|
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)
|
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>();
|
var parameters = new List<BoundFuncParameter>();
|
||||||
@@ -259,7 +259,7 @@ public sealed class Binder
|
|||||||
{
|
{
|
||||||
if (i >= funcType.Parameters.Count)
|
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];
|
var expectedParameterType = funcType.Parameters[i];
|
||||||
@@ -269,7 +269,7 @@ public sealed class Binder
|
|||||||
|
|
||||||
var body = BindFuncBody(expression.Body, funcType.ReturnType, parameters);
|
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)
|
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 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);
|
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 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);
|
public record AddressOfSyntax(IReadOnlyList<Token> Tokens, ExpressionSyntax Expression) : ExpressionSyntax(Tokens);
|
||||||
|
|
||||||
|
|||||||
@@ -456,18 +456,31 @@ public sealed class Parser
|
|||||||
{
|
{
|
||||||
case Symbol.Func:
|
case Symbol.Func:
|
||||||
{
|
{
|
||||||
List<AnonymousFuncParameterSyntax> parameters = [];
|
List<ArrowFuncParameterSyntax> parameters = [];
|
||||||
ExpectSymbol(Symbol.OpenParen);
|
ExpectSymbol(Symbol.OpenParen);
|
||||||
while (!TryExpectSymbol(Symbol.CloseParen))
|
while (!TryExpectSymbol(Symbol.CloseParen))
|
||||||
{
|
{
|
||||||
var parameterStartIndex = _tokenIndex;
|
var parameterStartIndex = _tokenIndex;
|
||||||
var name = ExpectIdentifier();
|
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;
|
break;
|
||||||
}
|
}
|
||||||
case Symbol.OpenParen:
|
case Symbol.OpenParen:
|
||||||
|
|||||||
@@ -71,5 +71,6 @@ public enum Symbol
|
|||||||
Impl,
|
Impl,
|
||||||
For,
|
For,
|
||||||
Extern,
|
Extern,
|
||||||
Semi
|
Semi,
|
||||||
|
Arrow,
|
||||||
}
|
}
|
||||||
@@ -32,6 +32,7 @@ public sealed class Tokenizer
|
|||||||
[['<', '=']] = Symbol.LessThanOrEqual,
|
[['<', '=']] = Symbol.LessThanOrEqual,
|
||||||
[['>', '=']] = Symbol.GreaterThanOrEqual,
|
[['>', '=']] = Symbol.GreaterThanOrEqual,
|
||||||
[[':', ':']] = Symbol.DoubleColon,
|
[[':', ':']] = Symbol.DoubleColon,
|
||||||
|
[['=', '>']] = Symbol.Arrow,
|
||||||
};
|
};
|
||||||
|
|
||||||
private static readonly Dictionary<char, Symbol> Chars = new()
|
private static readonly Dictionary<char, Symbol> Chars = new()
|
||||||
|
|||||||
Reference in New Issue
Block a user