diff options
author | Li Jin <dragon-fly@qq.com> | 2020-02-14 17:03:53 +0800 |
---|---|---|
committer | Li Jin <dragon-fly@qq.com> | 2020-02-14 17:03:53 +0800 |
commit | 65180a2d3e00931226d6c90a3b7ccf9db14722ae (patch) | |
tree | 3bd3d0f869ca829e86ee23d5fb732d438389f86a | |
parent | d0583829535462a070e7ae90c6ea13f14244d060 (diff) | |
download | yuescript-65180a2d3e00931226d6c90a3b7ccf9db14722ae.tar.gz yuescript-65180a2d3e00931226d6c90a3b7ccf9db14722ae.tar.bz2 yuescript-65180a2d3e00931226d6c90a3b7ccf9db14722ae.zip |
add placeholder support for backcall operator.
-rw-r--r-- | spec/inputs/backcall.moon | 8 | ||||
-rw-r--r-- | src/MoonP/ast.hpp | 12 | ||||
-rw-r--r-- | 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 = -> | |||
30 | 998 |> func2 "abc", 233 |> func0 |> func1 | 30 | 998 |> func2 "abc", 233 |> func0 |> func1 |
31 | 998 |> func0("abc", 233) |> func1 |> func2 | 31 | 998 |> func0("abc", 233) |> func1 |> func2 |
32 | 32 | ||
33 | 1 |> f 2, 3, 4, 5 | ||
34 | val(2) |> f 1, _, 3, 4, 5 | ||
35 | arr[3] |> f 1, 2, _, 4, 5 | ||
36 | |||
37 | a = {"1","2","3"} |> table.concat("") |> tonumber |> f1(1, 2, 3, _) |> f2(1, _, 3) | ||
38 | |||
33 | do | 39 | do |
34 | (x)<-map {1,2,3} | 40 | (x)<- map {1,2,3} |
35 | x * 2 | 41 | x * 2 |
36 | 42 | ||
37 | do | 43 | 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: | |||
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 | ||
31 | const char* moonScriptVersion() { | 31 | const char* moonScriptVersion() { |
32 | return "0.5.0-r0.1.0"; | 32 | return "0.5.0-r0.1.1"; |
33 | } | 33 | } |
34 | 34 | ||
35 | class MoonCompiler { | 35 | class 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>(); |