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. --- src/MoonP/ast.hpp | 12 ++++++++++++ src/MoonP/moon_compiler.cpp | 22 +++++++++++++++++++--- 2 files changed, 31 insertions(+), 3 deletions(-) (limited to 'src') 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