aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLi Jin <dragon-fly@qq.com>2020-02-14 17:03:53 +0800
committerLi Jin <dragon-fly@qq.com>2020-02-14 17:03:53 +0800
commit65180a2d3e00931226d6c90a3b7ccf9db14722ae (patch)
tree3bd3d0f869ca829e86ee23d5fb732d438389f86a
parentd0583829535462a070e7ae90c6ea13f14244d060 (diff)
downloadyuescript-65180a2d3e00931226d6c90a3b7ccf9db14722ae.tar.gz
yuescript-65180a2d3e00931226d6c90a3b7ccf9db14722ae.tar.bz2
yuescript-65180a2d3e00931226d6c90a3b7ccf9db14722ae.zip
add placeholder support for backcall operator.
-rw-r--r--spec/inputs/backcall.moon8
-rw-r--r--src/MoonP/ast.hpp12
-rw-r--r--src/MoonP/moon_compiler.cpp22
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 = ->
30998 |> func2 "abc", 233 |> func0 |> func1 30998 |> func2 "abc", 233 |> func0 |> func1
31998 |> func0("abc", 233) |> func1 |> func2 31998 |> func0("abc", 233) |> func1 |> func2
32 32
331 |> f 2, 3, 4, 5
34val(2) |> f 1, _, 3, 4, 5
35arr[3] |> f 1, 2, _, 4, 5
36
37a = {"1","2","3"} |> table.concat("") |> tonumber |> f1(1, 2, 3, _) |> f2(1, _, 3)
38
33do 39do
34 (x)<-map {1,2,3} 40 (x)<- map {1,2,3}
35 x * 2 41 x * 2
36 42
37do 43do
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:
399 node->release(); 399 node->release();
400 } 400 }
401 401
402 bool swap(ast_node* node, ast_node* other) {
403 for (auto it = m_objects.begin(); it != m_objects.end(); ++it) {
404 if (*it == node) {
405 *it = other;
406 other->retain();
407 node->release();
408 return true;
409 }
410 }
411 return false;
412 }
413
402 const node_container& objects() const { 414 const node_container& objects() const {
403 return m_objects; 415 return m_objects;
404 } 416 }
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) {
29} 29}
30 30
31const char* moonScriptVersion() { 31const char* moonScriptVersion() {
32 return "0.5.0-r0.1.0"; 32 return "0.5.0-r0.1.1";
33} 33}
34 34
35class MoonCompiler { 35class MoonCompiler {
@@ -1528,10 +1528,26 @@ private:
1528 } 1528 }
1529 if (isChainValueCall(chainValue)) { 1529 if (isChainValueCall(chainValue)) {
1530 auto last = chainValue->items.back(); 1530 auto last = chainValue->items.back();
1531 _ast_list* args = nullptr;
1531 if (auto invoke = ast_cast<InvokeArgs_t>(last)) { 1532 if (auto invoke = ast_cast<InvokeArgs_t>(last)) {
1532 invoke->args.push_front(arg); 1533 args = &invoke->args;
1533 } else { 1534 } else {
1534 ast_to<Invoke_t>(last)->args.push_front(arg); 1535 args = &(ast_to<Invoke_t>(last)->args);
1536 }
1537 bool findPlaceHolder = false;
1538 for (auto a : args->objects()) {
1539 auto name = singleVariableFrom(a);
1540 if (name == "_"sv) {
1541 if (!findPlaceHolder) {
1542 args->swap(a, arg);
1543 findPlaceHolder = true;
1544 } else {
1545 throw std::logic_error(_info.errorMessage("backcall placeholder can be used only in one place."sv, a));
1546 }
1547 }
1548 }
1549 if (!findPlaceHolder) {
1550 args->push_front(arg);
1535 } 1551 }
1536 } else { 1552 } else {
1537 auto invoke = x->new_ptr<Invoke_t>(); 1553 auto invoke = x->new_ptr<Invoke_t>();