From 65180a2d3e00931226d6c90a3b7ccf9db14722ae Mon Sep 17 00:00:00 2001 From: Li Jin Date: Fri, 14 Feb 2020 17:03:53 +0800 Subject: add placeholder support for backcall operator. --- spec/inputs/backcall.moon | 8 +++++++- src/MoonP/ast.hpp | 12 ++++++++++++ src/MoonP/moon_compiler.cpp | 22 +++++++++++++++++++--- 3 files changed, 38 insertions(+), 4 deletions(-) diff --git a/spec/inputs/backcall.moon b/spec/inputs/backcall.moon index a65bb0a..f5d0046 100644 --- a/spec/inputs/backcall.moon +++ b/spec/inputs/backcall.moon @@ -30,8 +30,14 @@ f = -> 998 |> func2 "abc", 233 |> func0 |> func1 998 |> func0("abc", 233) |> func1 |> func2 +1 |> f 2, 3, 4, 5 +val(2) |> f 1, _, 3, 4, 5 +arr[3] |> f 1, 2, _, 4, 5 + +a = {"1","2","3"} |> table.concat("") |> tonumber |> f1(1, 2, 3, _) |> f2(1, _, 3) + do - (x)<-map {1,2,3} + (x)<- map {1,2,3} x * 2 do diff --git a/src/MoonP/ast.hpp b/src/MoonP/ast.hpp index 8bcfc21..b56cfde 100644 --- a/src/MoonP/ast.hpp +++ b/src/MoonP/ast.hpp @@ -399,6 +399,18 @@ public: node->release(); } + bool swap(ast_node* node, ast_node* other) { + for (auto it = m_objects.begin(); it != m_objects.end(); ++it) { + if (*it == node) { + *it = other; + other->retain(); + node->release(); + return true; + } + } + return false; + } + const node_container& objects() const { return m_objects; } diff --git a/src/MoonP/moon_compiler.cpp b/src/MoonP/moon_compiler.cpp index 30adbae..d009fc9 100644 --- a/src/MoonP/moon_compiler.cpp +++ b/src/MoonP/moon_compiler.cpp @@ -29,7 +29,7 @@ inline std::string s(std::string_view sv) { } const char* moonScriptVersion() { - return "0.5.0-r0.1.0"; + return "0.5.0-r0.1.1"; } class MoonCompiler { @@ -1528,10 +1528,26 @@ private: } if (isChainValueCall(chainValue)) { auto last = chainValue->items.back(); + _ast_list* args = nullptr; if (auto invoke = ast_cast(last)) { - invoke->args.push_front(arg); + args = &invoke->args; } else { - ast_to(last)->args.push_front(arg); + args = &(ast_to(last)->args); + } + bool findPlaceHolder = false; + for (auto a : args->objects()) { + auto name = singleVariableFrom(a); + if (name == "_"sv) { + if (!findPlaceHolder) { + args->swap(a, arg); + findPlaceHolder = true; + } else { + throw std::logic_error(_info.errorMessage("backcall placeholder can be used only in one place."sv, a)); + } + } + } + if (!findPlaceHolder) { + args->push_front(arg); } } else { auto invoke = x->new_ptr(); -- cgit v1.2.3-55-g6feb