From d9caed577477df28bc0a5b2d50ce44c77d23da56 Mon Sep 17 00:00:00 2001 From: Andrey Penechko Date: Sat, 19 Aug 2023 19:05:56 +0300 Subject: [PATCH] Implement automatic tuple expansion in function calls --- source/tests/passing.d | 23 +++++++++++++++++++++++ source/vox/fe/ast/expr/call.d | 16 ++++++++++++++++ todo.txt | 2 ++ 3 files changed, 41 insertions(+) diff --git a/source/tests/passing.d b/source/tests/passing.d index 64281197..5d542145 100644 --- a/source/tests/passing.d +++ b/source/tests/passing.d @@ -6496,3 +6496,26 @@ void tester300(ref TestContext ctx) { auto run1 = ctx.getFunctionPtr!(size_t, size_t, uint)("run1"); assert(run1(42, 10) == 42 - 10); } + + +@TestInfo(&tester301) +immutable test301 = q{--- test301 + // Variadic args tuple forward into call + u32 run(u32 a, u32 b, u32 c) { + return caller(a, b, c); + } + u32 caller[Args...](Args... args) { + return sum(args); + } + u32 sum[Args...](Args... args) { + u32 res = 0; + #foreach(i, arg; args) { + res += arg; + } + return res; + } +}; +void tester301(ref TestContext ctx) { + auto run = ctx.getFunctionPtr!(uint, uint, uint, uint)("run"); + assert(run(100, 10, 1) == 111); +} diff --git a/source/vox/fe/ast/expr/call.d b/source/vox/fe/ast/expr/call.d index 23c16913..a6b0dc3b 100644 --- a/source/vox/fe/ast/expr/call.d +++ b/source/vox/fe/ast/expr/call.d @@ -62,9 +62,25 @@ void name_resolve_call(CallExprNode* node, ref NameResolveState state) { node.state = AstNodeState.name_resolve; require_name_resolve(node.callee, state); require_name_resolve(node.args, state); + expandTuples(node.args, state.context); node.state = AstNodeState.name_resolve_done; } +void expandTuples(ref AstNodes nodes, CompilationContext* c) { + uint length = nodes.length; + uint index; + while (index < length) { + auto node = nodes[index].get_node(c); + if (node.astType == AstType.decl_alias_array) { + auto aliasArray = node.as!AliasArrayDeclNode(c); + nodes.replaceAt(c.arrayArena, index, 1, aliasArray.items[]); + length = length - 1 + aliasArray.items.length; + continue; + } + ++index; + } +} + // Get type from function declaration void type_check_call(ref AstIndex callIndex, CallExprNode* node, ref TypeCheckState state) { diff --git a/todo.txt b/todo.txt index 1f71d444..ccace000 100644 --- a/todo.txt +++ b/todo.txt @@ -33,6 +33,8 @@ - only simple types - ifti of member functions needs to account for this parameter, because ifti is done before providing this arg + variadic template arguments (requires inference) + - alias tuple auto-expansion / manual expansion. + + auto tuple expansion in function call - a way to perform IFTI from user code (pass template args with names and runtime types and get) - #parameter(#type type, string name, type default_value, #alias[] attributes) - #function(string name, #type return_type, #parameter[] parameters, #alias[] attributes)