diff options
author | Li Jin <dragon-fly@qq.com> | 2022-11-11 09:29:01 +0800 |
---|---|---|
committer | Li Jin <dragon-fly@qq.com> | 2022-11-11 09:29:01 +0800 |
commit | 209fca096b0be5c47553f4c4a94d95de33b23d31 (patch) | |
tree | c170264dbab9c6bb2f076de17ca171782664872a | |
parent | e02780668e0ce2ebf7088bad2e70ad94b6824b08 (diff) | |
download | yuescript-209fca096b0be5c47553f4c4a94d95de33b23d31.tar.gz yuescript-209fca096b0be5c47553f4c4a94d95de33b23d31.tar.bz2 yuescript-209fca096b0be5c47553f4c4a94d95de33b23d31.zip |
refactor parser to be a little faster.
-rw-r--r-- | src/yue.cpp | 13 | ||||
-rw-r--r-- | src/yuescript/ast.hpp | 3 | ||||
-rwxr-xr-x | src/yuescript/yue_ast.h | 55 | ||||
-rw-r--r-- | src/yuescript/yue_compiler.cpp | 402 | ||||
-rw-r--r-- | src/yuescript/yue_compiler.h | 3 | ||||
-rw-r--r-- | src/yuescript/yue_parser.cpp | 27 | ||||
-rw-r--r-- | src/yuescript/yue_parser.h | 7 |
7 files changed, 318 insertions, 192 deletions
diff --git a/src/yue.cpp b/src/yue.cpp index f25c702..5b4dccc 100644 --- a/src/yue.cpp +++ b/src/yue.cpp | |||
@@ -9,7 +9,6 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI | |||
9 | #include "yuescript/yue_compiler.h" | 9 | #include "yuescript/yue_compiler.h" |
10 | #include "yuescript/yue_parser.h" | 10 | #include "yuescript/yue_parser.h" |
11 | 11 | ||
12 | #include <chrono> | ||
13 | #include <cstdlib> | 12 | #include <cstdlib> |
14 | #include <fstream> | 13 | #include <fstream> |
15 | #include <future> | 14 | #include <future> |
@@ -472,19 +471,13 @@ int main(int narg, const char** args) { | |||
472 | } | 471 | } |
473 | } | 472 | } |
474 | if (dumpCompileTime) { | 473 | if (dumpCompileTime) { |
475 | auto start = std::chrono::high_resolution_clock::now(); | 474 | conf.profiling = true; |
476 | auto result = yue::YueCompiler{YUE_ARGS}.compile(s, conf); | 475 | auto result = yue::YueCompiler{YUE_ARGS}.compile(s, conf); |
477 | auto end = std::chrono::high_resolution_clock::now(); | ||
478 | if (!result.codes.empty()) { | 476 | if (!result.codes.empty()) { |
479 | std::chrono::duration<double> diff = end - start; | ||
480 | start = std::chrono::high_resolution_clock::now(); | ||
481 | yue::YueParser{}.parse<yue::File_t>(s); | ||
482 | end = std::chrono::high_resolution_clock::now(); | ||
483 | std::chrono::duration<double> parseDiff = end - start; | ||
484 | std::ostringstream buf; | 477 | std::ostringstream buf; |
485 | buf << file.first << " \n"sv; | 478 | buf << file.first << " \n"sv; |
486 | buf << "Parse time: "sv << std::setprecision(5) << parseDiff.count() * 1000 << " ms\n"; | 479 | buf << "Parse time: "sv << std::setprecision(5) << result.parseTime * 1000 << " ms\n"; |
487 | buf << "Compile time: "sv << std::setprecision(5) << (diff.count() - parseDiff.count()) * 1000 << " ms\n\n"; | 480 | buf << "Compile time: "sv << std::setprecision(5) << result.compileTime * 1000 << " ms\n\n"; |
488 | return std::tuple{0, file.first, buf.str()}; | 481 | return std::tuple{0, file.first, buf.str()}; |
489 | } else { | 482 | } else { |
490 | std::ostringstream buf; | 483 | std::ostringstream buf; |
diff --git a/src/yuescript/ast.hpp b/src/yuescript/ast.hpp index 681c27f..3443c7f 100644 --- a/src/yuescript/ast.hpp +++ b/src/yuescript/ast.hpp | |||
@@ -455,8 +455,7 @@ public: | |||
455 | 455 | ||
456 | void dup(const _ast_list& src) { | 456 | void dup(const _ast_list& src) { |
457 | for (ast_node* obj : src.m_objects) { | 457 | for (ast_node* obj : src.m_objects) { |
458 | m_objects.push_back(obj); | 458 | push_back(obj); |
459 | obj->retain(); | ||
460 | } | 459 | } |
461 | } | 460 | } |
462 | 461 | ||
diff --git a/src/yuescript/yue_ast.h b/src/yuescript/yue_ast.h index 21266c9..32dd8ba 100755 --- a/src/yuescript/yue_ast.h +++ b/src/yuescript/yue_ast.h | |||
@@ -459,6 +459,12 @@ AST_NODE(variable_pair) | |||
459 | AST_MEMBER(variable_pair, &name) | 459 | AST_MEMBER(variable_pair, &name) |
460 | AST_END(variable_pair, "variable_pair"sv) | 460 | AST_END(variable_pair, "variable_pair"sv) |
461 | 461 | ||
462 | AST_NODE(variable_pair_def) | ||
463 | ast_ptr<true, variable_pair_t> pair; | ||
464 | ast_ptr<false, Exp_t> defVal; | ||
465 | AST_MEMBER(variable_pair_def, &pair, &defVal) | ||
466 | AST_END(variable_pair_def, "variable_pair_def"sv) | ||
467 | |||
462 | class String_t; | 468 | class String_t; |
463 | 469 | ||
464 | AST_NODE(normal_pair) | 470 | AST_NODE(normal_pair) |
@@ -467,32 +473,41 @@ AST_NODE(normal_pair) | |||
467 | AST_MEMBER(normal_pair, &key, &value) | 473 | AST_MEMBER(normal_pair, &key, &value) |
468 | AST_END(normal_pair, "normal_pair"sv) | 474 | AST_END(normal_pair, "normal_pair"sv) |
469 | 475 | ||
470 | AST_NODE(default_pair) | 476 | AST_NODE(normal_pair_def) |
471 | ast_sel<true, Variable_t, KeyName_t, Exp_t, String_t> key; | 477 | ast_ptr<true, normal_pair_t> pair; |
478 | ast_ptr<false, Exp_t> defVal; | ||
479 | AST_MEMBER(normal_pair_def, &pair, &defVal) | ||
480 | AST_END(normal_pair_def, "normal_pair_def"sv) | ||
481 | |||
482 | AST_NODE(normal_def) | ||
483 | ast_ptr<true, Exp_t> item; | ||
472 | ast_ptr<true, Seperator_t> sep; | 484 | ast_ptr<true, Seperator_t> sep; |
473 | ast_ptr<false, Exp_t> value; | 485 | ast_ptr<false, Exp_t> defVal; |
474 | ast_ptr<true, Exp_t> defVal; | 486 | AST_MEMBER(normal_def, &item, &sep, &defVal) |
475 | AST_MEMBER(default_pair, &key, &sep, &value, &defVal) | 487 | AST_END(normal_def, "normal_def") |
476 | AST_END(default_pair, "default_pair"sv) | ||
477 | 488 | ||
478 | AST_NODE(meta_variable_pair) | 489 | AST_NODE(meta_variable_pair) |
479 | ast_ptr<true, Variable_t> name; | 490 | ast_ptr<true, Variable_t> name; |
480 | AST_MEMBER(meta_variable_pair, &name) | 491 | AST_MEMBER(meta_variable_pair, &name) |
481 | AST_END(meta_variable_pair, "meta_variable_pair"sv) | 492 | AST_END(meta_variable_pair, "meta_variable_pair"sv) |
482 | 493 | ||
494 | AST_NODE(meta_variable_pair_def) | ||
495 | ast_ptr<true, meta_variable_pair_t> pair; | ||
496 | ast_ptr<false, Exp_t> defVal; | ||
497 | AST_MEMBER(meta_variable_pair_def, &pair, &defVal) | ||
498 | AST_END(meta_variable_pair_def, "meta_variable_pair_def"sv) | ||
499 | |||
483 | AST_NODE(meta_normal_pair) | 500 | AST_NODE(meta_normal_pair) |
484 | ast_sel<false, Name_t, Exp_t, String_t> key; | 501 | ast_sel<false, Name_t, Exp_t, String_t> key; |
485 | ast_sel<true, Exp_t, TableBlock_t> value; | 502 | ast_sel<true, Exp_t, TableBlock_t> value; |
486 | AST_MEMBER(meta_normal_pair, &key, &value) | 503 | AST_MEMBER(meta_normal_pair, &key, &value) |
487 | AST_END(meta_normal_pair, "meta_normal_pair"sv) | 504 | AST_END(meta_normal_pair, "meta_normal_pair"sv) |
488 | 505 | ||
489 | AST_NODE(meta_default_pair) | 506 | AST_NODE(meta_normal_pair_def) |
490 | ast_sel<false, Variable_t, Name_t, Exp_t, String_t> key; | 507 | ast_ptr<true, meta_normal_pair_t> pair; |
491 | ast_ptr<true, Seperator_t> sep; | 508 | ast_ptr<false, Exp_t> defVal; |
492 | ast_ptr<false, Exp_t> value; | 509 | AST_MEMBER(meta_normal_pair_def, &pair, &defVal) |
493 | ast_ptr<true, Exp_t> defVal; | 510 | AST_END(meta_normal_pair_def, "meta_normal_pair_def"sv) |
494 | AST_MEMBER(meta_default_pair, &key, &sep, &value, &defVal) | ||
495 | AST_END(meta_default_pair, "meta_default_pair"sv) | ||
496 | 511 | ||
497 | AST_NODE(simple_table) | 512 | AST_NODE(simple_table) |
498 | ast_ptr<true, Seperator_t> sep; | 513 | ast_ptr<true, Seperator_t> sep; |
@@ -620,9 +635,6 @@ AST_END(Value, "value"sv) | |||
620 | AST_LEAF(default_value) | 635 | AST_LEAF(default_value) |
621 | AST_END(default_value, "default_value"sv) | 636 | AST_END(default_value, "default_value"sv) |
622 | 637 | ||
623 | class default_pair_t; | ||
624 | class meta_default_pair_t; | ||
625 | |||
626 | AST_NODE(SpreadExp) | 638 | AST_NODE(SpreadExp) |
627 | ast_ptr<true, Exp_t> exp; | 639 | ast_ptr<true, Exp_t> exp; |
628 | AST_MEMBER(SpreadExp, &exp) | 640 | AST_MEMBER(SpreadExp, &exp) |
@@ -631,23 +643,22 @@ AST_END(SpreadExp, "spread_exp"sv) | |||
631 | AST_NODE(TableLit) | 643 | AST_NODE(TableLit) |
632 | ast_ptr<true, Seperator_t> sep; | 644 | ast_ptr<true, Seperator_t> sep; |
633 | ast_sel_list<false, | 645 | ast_sel_list<false, |
634 | variable_pair_t, normal_pair_t, SpreadExp_t, Exp_t, default_pair_t, | 646 | variable_pair_def_t, normal_pair_def_t, SpreadExp_t, normal_def_t, |
635 | meta_variable_pair_t, meta_normal_pair_t, meta_default_pair_t> values; | 647 | meta_variable_pair_def_t, meta_normal_pair_def_t> values; |
636 | AST_MEMBER(TableLit, &sep, &values) | 648 | AST_MEMBER(TableLit, &sep, &values) |
637 | AST_END(TableLit, "table_lit"sv) | 649 | AST_END(TableLit, "table_lit"sv) |
638 | 650 | ||
639 | AST_NODE(TableBlockIndent) | 651 | AST_NODE(TableBlockIndent) |
640 | ast_ptr<true, Seperator_t> sep; | 652 | ast_ptr<true, Seperator_t> sep; |
641 | ast_sel_list<false, | 653 | ast_sel_list<false, |
642 | variable_pair_t, normal_pair_t, TableBlockIndent_t, default_pair_t, | 654 | variable_pair_t, normal_pair_t, Exp_t, TableBlockIndent_t, |
643 | meta_variable_pair_t, meta_normal_pair_t, meta_default_pair_t> values; | 655 | meta_variable_pair_t, meta_normal_pair_t> values; |
644 | AST_MEMBER(TableBlockIndent, &sep, &values) | 656 | AST_MEMBER(TableBlockIndent, &sep, &values) |
645 | AST_END(TableBlockIndent, "table_block_indent"sv) | 657 | AST_END(TableBlockIndent, "table_block_indent"sv) |
646 | 658 | ||
647 | AST_NODE(TableBlock) | 659 | AST_NODE(TableBlock) |
648 | ast_ptr<true, Seperator_t> sep; | 660 | ast_ptr<true, Seperator_t> sep; |
649 | ast_sel_list<false, variable_pair_t, normal_pair_t, TableBlockIndent_t, Exp_t, TableBlock_t, SpreadExp_t, default_pair_t, | 661 | ast_sel_list<false, variable_pair_t, normal_pair_t, TableBlockIndent_t, Exp_t, TableBlock_t, SpreadExp_t, meta_variable_pair_t, meta_normal_pair_t> values; |
650 | meta_variable_pair_t, meta_normal_pair_t, meta_default_pair_t> values; | ||
651 | AST_MEMBER(TableBlock, &sep, &values) | 662 | AST_MEMBER(TableBlock, &sep, &values) |
652 | AST_END(TableBlock, "table_block"sv) | 663 | AST_END(TableBlock, "table_block"sv) |
653 | 664 | ||
diff --git a/src/yuescript/yue_compiler.cpp b/src/yuescript/yue_compiler.cpp index f5436d1..c359e02 100644 --- a/src/yuescript/yue_compiler.cpp +++ b/src/yuescript/yue_compiler.cpp | |||
@@ -6,6 +6,7 @@ The above copyright notice and this permission notice shall be included in all c | |||
6 | 6 | ||
7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.*/ | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.*/ |
8 | 8 | ||
9 | #include <chrono> | ||
9 | #include <memory> | 10 | #include <memory> |
10 | #include <optional> | 11 | #include <optional> |
11 | #include <set> | 12 | #include <set> |
@@ -59,7 +60,7 @@ namespace yue { | |||
59 | 60 | ||
60 | typedef std::list<std::string> str_list; | 61 | typedef std::list<std::string> str_list; |
61 | 62 | ||
62 | const std::string_view version = "0.15.12"sv; | 63 | const std::string_view version = "0.15.13"sv; |
63 | const std::string_view extension = "yue"sv; | 64 | const std::string_view extension = "yue"sv; |
64 | 65 | ||
65 | class YueCompilerImpl { | 66 | class YueCompilerImpl { |
@@ -98,7 +99,17 @@ public: | |||
98 | #ifndef YUE_NO_MACRO | 99 | #ifndef YUE_NO_MACRO |
99 | if (L) passOptions(); | 100 | if (L) passOptions(); |
100 | #endif // YUE_NO_MACRO | 101 | #endif // YUE_NO_MACRO |
101 | _info = _parser.parse<File_t>(codes); | 102 | double parseTime = 0.0; |
103 | double compileTime = 0.0; | ||
104 | if (config.profiling) { | ||
105 | auto start = std::chrono::high_resolution_clock::now(); | ||
106 | _info = _parser.parse<File_t>(codes); | ||
107 | auto stop = std::chrono::high_resolution_clock::now(); | ||
108 | std::chrono::duration<double> diff = stop - start; | ||
109 | parseTime = diff.count(); | ||
110 | } else { | ||
111 | _info = _parser.parse<File_t>(codes); | ||
112 | } | ||
102 | std::unique_ptr<GlobalVars> globals; | 113 | std::unique_ptr<GlobalVars> globals; |
103 | std::unique_ptr<Options> options; | 114 | std::unique_ptr<Options> options; |
104 | if (!config.options.empty()) { | 115 | if (!config.options.empty()) { |
@@ -149,9 +160,19 @@ public: | |||
149 | _gotoScopes.push(0); | 160 | _gotoScopes.push(0); |
150 | _gotoScope = 1; | 161 | _gotoScope = 1; |
151 | _varArgs.push({true, false}); | 162 | _varArgs.push({true, false}); |
152 | transformBlock(block, out, | 163 | if (_config.profiling) { |
153 | config.implicitReturnRoot ? ExpUsage::Return : ExpUsage::Common, | 164 | auto start = std::chrono::high_resolution_clock::now(); |
154 | nullptr, true); | 165 | transformBlock(block, out, |
166 | config.implicitReturnRoot ? ExpUsage::Return : ExpUsage::Common, | ||
167 | nullptr, true); | ||
168 | auto stop = std::chrono::high_resolution_clock::now(); | ||
169 | std::chrono::duration<double> diff = stop - start; | ||
170 | compileTime = diff.count(); | ||
171 | } else { | ||
172 | transformBlock(block, out, | ||
173 | config.implicitReturnRoot ? ExpUsage::Return : ExpUsage::Common, | ||
174 | nullptr, true); | ||
175 | } | ||
155 | popScope(); | 176 | popScope(); |
156 | if (!gotos.empty()) { | 177 | if (!gotos.empty()) { |
157 | for (const auto& gotoNode : gotos) { | 178 | for (const auto& gotoNode : gotos) { |
@@ -207,12 +228,12 @@ public: | |||
207 | } | 228 | } |
208 | } | 229 | } |
209 | #endif // YUE_NO_MACRO | 230 | #endif // YUE_NO_MACRO |
210 | return {std::move(out.back()), Empty, std::move(globals), std::move(options)}; | 231 | return {std::move(out.back()), Empty, std::move(globals), std::move(options), parseTime, compileTime}; |
211 | } catch (const std::logic_error& error) { | 232 | } catch (const std::logic_error& error) { |
212 | return {Empty, error.what(), std::move(globals), std::move(options)}; | 233 | return {Empty, error.what(), std::move(globals), std::move(options), parseTime, compileTime}; |
213 | } | 234 | } |
214 | } else { | 235 | } else { |
215 | return {Empty, std::move(_info.error), std::move(globals), std::move(options)}; | 236 | return {Empty, std::move(_info.error), std::move(globals), std::move(options), parseTime, compileTime}; |
216 | } | 237 | } |
217 | } | 238 | } |
218 | 239 | ||
@@ -2055,6 +2076,16 @@ private: | |||
2055 | tableItems = &table->values.objects(); | 2076 | tableItems = &table->values.objects(); |
2056 | break; | 2077 | break; |
2057 | } | 2078 | } |
2079 | case id<TableLit_t>(): { | ||
2080 | auto table = ast_cast<TableLit_t>(node); | ||
2081 | tableItems = &table->values.objects(); | ||
2082 | break; | ||
2083 | } | ||
2084 | case id<simple_table_t>(): { | ||
2085 | auto table = ast_cast<simple_table_t>(node); | ||
2086 | tableItems = &table->pairs.objects(); | ||
2087 | break; | ||
2088 | } | ||
2058 | default: YUEE("AST node mismatch", node); break; | 2089 | default: YUEE("AST node mismatch", node); break; |
2059 | } | 2090 | } |
2060 | if (!tableItems) throw std::logic_error(_info.errorMessage("invalid destructure value"sv, node)); | 2091 | if (!tableItems) throw std::logic_error(_info.errorMessage("invalid destructure value"sv, node)); |
@@ -2063,7 +2094,13 @@ private: | |||
2063 | auto subMetaDestruct = node->new_ptr<TableLit_t>(); | 2094 | auto subMetaDestruct = node->new_ptr<TableLit_t>(); |
2064 | for (auto pair : *tableItems) { | 2095 | for (auto pair : *tableItems) { |
2065 | switch (pair->getId()) { | 2096 | switch (pair->getId()) { |
2066 | case id<Exp_t>(): { | 2097 | case id<Exp_t>(): |
2098 | case id<normal_def_t>(): { | ||
2099 | Exp_t* defVal = nullptr; | ||
2100 | if (auto nd = ast_cast<normal_def_t>(pair)) { | ||
2101 | pair = nd->item.get(); | ||
2102 | defVal = nd->defVal.get(); | ||
2103 | } | ||
2067 | ++index; | 2104 | ++index; |
2068 | if (!isAssignable(static_cast<Exp_t*>(pair))) { | 2105 | if (!isAssignable(static_cast<Exp_t*>(pair))) { |
2069 | throw std::logic_error(_info.errorMessage("can't destructure value"sv, pair)); | 2106 | throw std::logic_error(_info.errorMessage("can't destructure value"sv, pair)); |
@@ -2087,21 +2124,33 @@ private: | |||
2087 | pairs.push_back({exp, | 2124 | pairs.push_back({exp, |
2088 | varName, | 2125 | varName, |
2089 | chain, | 2126 | chain, |
2090 | nullptr}); | 2127 | defVal}); |
2091 | } | 2128 | } |
2092 | break; | 2129 | break; |
2093 | } | 2130 | } |
2094 | case id<variable_pair_t>(): { | 2131 | case id<variable_pair_t>(): |
2132 | case id<variable_pair_def_t>(): { | ||
2133 | Exp_t* defVal = nullptr; | ||
2134 | if (auto vpd = ast_cast<variable_pair_def_t>(pair)) { | ||
2135 | pair = vpd->pair.get(); | ||
2136 | defVal = vpd->defVal.get(); | ||
2137 | } | ||
2095 | auto vp = static_cast<variable_pair_t*>(pair); | 2138 | auto vp = static_cast<variable_pair_t*>(pair); |
2096 | auto name = _parser.toString(vp->name); | 2139 | auto name = _parser.toString(vp->name); |
2097 | auto chain = toAst<ChainValue_t>('.' + name, vp->name); | 2140 | auto chain = toAst<ChainValue_t>('.' + name, vp->name); |
2098 | pairs.push_back({toAst<Exp_t>(name, vp).get(), | 2141 | pairs.push_back({toAst<Exp_t>(name, vp).get(), |
2099 | name, | 2142 | name, |
2100 | chain, | 2143 | chain, |
2101 | nullptr}); | 2144 | defVal}); |
2102 | break; | 2145 | break; |
2103 | } | 2146 | } |
2104 | case id<normal_pair_t>(): { | 2147 | case id<normal_pair_t>(): |
2148 | case id<normal_pair_def_t>(): { | ||
2149 | Exp_t* defVal = nullptr; | ||
2150 | if (auto npd = ast_cast<normal_pair_def_t>(pair)) { | ||
2151 | pair = npd->pair.get(); | ||
2152 | defVal = npd->defVal.get(); | ||
2153 | } | ||
2105 | auto np = static_cast<normal_pair_t*>(pair); | 2154 | auto np = static_cast<normal_pair_t*>(pair); |
2106 | ast_ptr<true, ast_node> keyIndex; | 2155 | ast_ptr<true, ast_node> keyIndex; |
2107 | if (np->key) { | 2156 | if (np->key) { |
@@ -2144,7 +2193,7 @@ private: | |||
2144 | pairs.push_back({exp, | 2193 | pairs.push_back({exp, |
2145 | varName, | 2194 | varName, |
2146 | chain, | 2195 | chain, |
2147 | nullptr}); | 2196 | defVal}); |
2148 | } | 2197 | } |
2149 | break; | 2198 | break; |
2150 | } | 2199 | } |
@@ -2171,97 +2220,28 @@ private: | |||
2171 | } | 2220 | } |
2172 | break; | 2221 | break; |
2173 | } | 2222 | } |
2174 | case id<default_pair_t>(): { | 2223 | case id<meta_variable_pair_t>(): |
2175 | auto dp = static_cast<default_pair_t*>(pair); | 2224 | case id<meta_variable_pair_def_t>(): { |
2176 | if (auto exp = dp->key.as<Exp_t>()) { | 2225 | Exp_t* defVal = nullptr; |
2177 | ++index; | 2226 | if (auto mvpd = ast_cast<meta_variable_pair_def_t>(pair)) { |
2178 | if (!isAssignable(static_cast<Exp_t*>(exp))) { | 2227 | pair = mvpd->pair.get(); |
2179 | throw std::logic_error(_info.errorMessage("can't destructure value"sv, exp)); | 2228 | defVal = mvpd->defVal.get(); |
2180 | } | ||
2181 | auto value = singleValueFrom(exp); | ||
2182 | auto item = value->item.get(); | ||
2183 | if (ast_is<simple_table_t>(item) || item->getByPath<TableLit_t>()) { | ||
2184 | throw std::logic_error(_info.errorMessage("invalid use of default value"sv, dp->defVal)); | ||
2185 | } else { | ||
2186 | auto varName = singleVariableFrom(exp, false); | ||
2187 | pairs.push_back({exp, | ||
2188 | varName, | ||
2189 | toAst<ChainValue_t>('[' + std::to_string(index) + ']', value), | ||
2190 | dp->defVal}); | ||
2191 | } | ||
2192 | break; | ||
2193 | } | ||
2194 | auto chain = dp->new_ptr<ChainValue_t>(); | ||
2195 | std::string valueStr; | ||
2196 | if (dp->key) { | ||
2197 | if (auto key = dp->key->getByPath<Name_t>()) { | ||
2198 | auto keyName = _parser.toString(key); | ||
2199 | if (!dp->value) valueStr = keyName; | ||
2200 | if (LuaKeywords.find(keyName) != LuaKeywords.end()) { | ||
2201 | chain->items.push_back(toAst<Exp_t>('"' + keyName + '"', key)); | ||
2202 | } else { | ||
2203 | chain->items.push_back(toAst<DotChainItem_t>('.' + keyName, key)); | ||
2204 | } | ||
2205 | } else if (auto key = dp->key->getByPath<SelfName_t>()) { | ||
2206 | auto callable = dp->new_ptr<Callable_t>(); | ||
2207 | callable->item.set(key); | ||
2208 | auto chainValue = dp->new_ptr<ChainValue_t>(); | ||
2209 | chainValue->items.push_back(callable); | ||
2210 | chain->items.push_back(newExp(chainValue, dp)); | ||
2211 | } else if (auto key = dp->key.as<String_t>()) { | ||
2212 | chain->items.push_back(newExp(key, dp)); | ||
2213 | } else if (auto key = dp->key.as<Exp_t>()) { | ||
2214 | chain->items.push_back(key); | ||
2215 | } else | ||
2216 | throw std::logic_error(_info.errorMessage("unsupported key for destructuring"sv, dp)); | ||
2217 | } | ||
2218 | if (auto exp = dp->value.get()) { | ||
2219 | if (!isAssignable(exp)) throw std::logic_error(_info.errorMessage("can't destructure value"sv, exp)); | ||
2220 | auto varName = singleVariableFrom(exp, false); | ||
2221 | pairs.push_back({exp, | ||
2222 | varName, | ||
2223 | chain, | ||
2224 | dp->defVal}); | ||
2225 | } else { | ||
2226 | pairs.push_back({toAst<Exp_t>(valueStr, dp).get(), | ||
2227 | valueStr, | ||
2228 | chain, | ||
2229 | dp->defVal}); | ||
2230 | } | ||
2231 | break; | ||
2232 | } | ||
2233 | case id<meta_default_pair_t>(): { | ||
2234 | auto mp = static_cast<meta_default_pair_t*>(pair); | ||
2235 | auto newPair = pair->new_ptr<default_pair_t>(); | ||
2236 | if (mp->key) { | ||
2237 | if (!ast_is<Variable_t, Name_t>(mp->key)) { | ||
2238 | throw std::logic_error(_info.errorMessage("destructuring with metatable accessed by expression is not supported."sv, mp->key)); | ||
2239 | } | ||
2240 | auto key = _parser.toString(mp->key); | ||
2241 | _buf << "__"sv << key; | ||
2242 | auto newKey = toAst<KeyName_t>(clearBuf(), mp->key); | ||
2243 | newPair->key.set(newKey); | ||
2244 | if (newPair->value) { | ||
2245 | newPair->value.set(mp->value); | ||
2246 | } else { | ||
2247 | newPair->value.set(toAst<Exp_t>(key, mp->key)); | ||
2248 | } | ||
2249 | } else { | ||
2250 | newPair->value.set(mp->value); | ||
2251 | } | 2229 | } |
2252 | newPair->defVal.set(mp->defVal); | ||
2253 | subMetaDestruct->values.push_back(newPair); | ||
2254 | break; | ||
2255 | } | ||
2256 | case id<meta_variable_pair_t>(): { | ||
2257 | auto mp = static_cast<meta_variable_pair_t*>(pair); | 2230 | auto mp = static_cast<meta_variable_pair_t*>(pair); |
2258 | auto name = _parser.toString(mp->name); | 2231 | auto name = _parser.toString(mp->name); |
2259 | _buf << "__"sv << name << ':' << name; | 2232 | _buf << "__"sv << name << ':' << name; |
2260 | auto newPair = toAst<normal_pair_t>(clearBuf(), pair); | 2233 | auto newPairDef = toAst<normal_pair_def_t>(clearBuf(), pair); |
2261 | subMetaDestruct->values.push_back(newPair); | 2234 | newPairDef->defVal.set(defVal); |
2235 | subMetaDestruct->values.push_back(newPairDef); | ||
2262 | break; | 2236 | break; |
2263 | } | 2237 | } |
2264 | case id<meta_normal_pair_t>(): { | 2238 | case id<meta_normal_pair_t>(): |
2239 | case id<meta_normal_pair_def_t>(): { | ||
2240 | Exp_t* defVal = nullptr; | ||
2241 | if (auto mnpd = ast_cast<meta_normal_pair_def_t>(pair)) { | ||
2242 | pair = mnpd->pair.get(); | ||
2243 | defVal = mnpd->defVal.get(); | ||
2244 | } | ||
2265 | auto mp = static_cast<meta_normal_pair_t*>(pair); | 2245 | auto mp = static_cast<meta_normal_pair_t*>(pair); |
2266 | auto newPair = pair->new_ptr<normal_pair_t>(); | 2246 | auto newPair = pair->new_ptr<normal_pair_t>(); |
2267 | if (mp->key) { | 2247 | if (mp->key) { |
@@ -2280,7 +2260,10 @@ private: | |||
2280 | } | 2260 | } |
2281 | } | 2261 | } |
2282 | newPair->value.set(mp->value); | 2262 | newPair->value.set(mp->value); |
2283 | subMetaDestruct->values.push_back(newPair); | 2263 | auto newPairDef = mp->new_ptr<normal_pair_def_t>(); |
2264 | newPairDef->pair.set(newPair); | ||
2265 | newPairDef->defVal.set(defVal); | ||
2266 | subMetaDestruct->values.push_back(newPairDef); | ||
2284 | break; | 2267 | break; |
2285 | } | 2268 | } |
2286 | default: YUEE("AST node mismatch", pair); break; | 2269 | default: YUEE("AST node mismatch", pair); break; |
@@ -2361,32 +2344,52 @@ private: | |||
2361 | } | 2344 | } |
2362 | for (auto item : *dlist) { | 2345 | for (auto item : *dlist) { |
2363 | switch (item->getId()) { | 2346 | switch (item->getId()) { |
2364 | case id<meta_default_pair_t>(): { | 2347 | case id<meta_variable_pair_def_t>(): { |
2365 | auto mp = static_cast<meta_default_pair_t*>(item); | 2348 | auto mvp = static_cast<meta_variable_pair_def_t*>(item); |
2366 | auto newPair = item->new_ptr<default_pair_t>(); | 2349 | auto mp = mvp->pair.get(); |
2350 | auto name = _parser.toString(mp->name); | ||
2351 | _buf << "__"sv << name << ':' << name; | ||
2352 | auto newPairDef = toAst<normal_pair_def_t>(clearBuf(), item); | ||
2353 | newPairDef->defVal.set(mvp->defVal); | ||
2354 | subMetaDestruct->values.push_back(newPairDef); | ||
2355 | break; | ||
2356 | } | ||
2357 | case id<meta_normal_pair_def_t>(): { | ||
2358 | auto mnp = static_cast<meta_normal_pair_def_t*>(item); | ||
2359 | auto mp = mnp->pair.get(); | ||
2360 | auto newPair = item->new_ptr<normal_pair_t>(); | ||
2367 | if (mp->key) { | 2361 | if (mp->key) { |
2368 | auto key = _parser.toString(mp->key); | 2362 | switch (mp->key->getId()) { |
2369 | _buf << "__"sv << key; | 2363 | case id<Name_t>(): { |
2370 | auto newKey = toAst<KeyName_t>(clearBuf(), mp->key); | 2364 | auto key = _parser.toString(mp->key); |
2371 | newPair->key.set(newKey); | 2365 | _buf << "__"sv << key; |
2372 | if (newPair->value) { | 2366 | auto newKey = toAst<KeyName_t>(clearBuf(), mp->key); |
2373 | newPair->value.set(mp->value); | 2367 | newPair->key.set(newKey); |
2374 | } else { | 2368 | break; |
2375 | newPair->value.set(toAst<Exp_t>(key, mp->key)); | 2369 | } |
2370 | case id<String_t>(): { | ||
2371 | newPair->key.set(mp->key); | ||
2372 | break; | ||
2373 | } | ||
2374 | case id<Exp_t>(): | ||
2375 | newPair->key.set(mp->key); | ||
2376 | break; | ||
2377 | default: YUEE("AST node mismatch", mp->key); break; | ||
2376 | } | 2378 | } |
2377 | } else { | ||
2378 | newPair->value.set(mp->value); | ||
2379 | } | 2379 | } |
2380 | newPair->defVal.set(mp->defVal); | 2380 | newPair->value.set(mp->value); |
2381 | subMetaDestruct->values.push_back(newPair); | 2381 | auto newPairDef = item->new_ptr<normal_pair_def_t>(); |
2382 | newPairDef->pair.set(newPair); | ||
2383 | newPairDef->defVal.set(mnp->defVal); | ||
2384 | subMetaDestruct->values.push_back(newPairDef); | ||
2382 | break; | 2385 | break; |
2383 | } | 2386 | } |
2384 | case id<meta_variable_pair_t>(): { | 2387 | case id<meta_variable_pair_t>(): { |
2385 | auto mp = static_cast<meta_variable_pair_t*>(item); | 2388 | auto mp = static_cast<meta_variable_pair_t*>(item); |
2386 | auto name = _parser.toString(mp->name); | 2389 | auto name = _parser.toString(mp->name); |
2387 | _buf << "__"sv << name << ':' << name; | 2390 | _buf << "__"sv << name << ':' << name; |
2388 | auto newPair = toAst<normal_pair_t>(clearBuf(), item); | 2391 | auto newPairDef = toAst<normal_pair_def_t>(clearBuf(), item); |
2389 | subMetaDestruct->values.push_back(newPair); | 2392 | subMetaDestruct->values.push_back(newPairDef); |
2390 | break; | 2393 | break; |
2391 | } | 2394 | } |
2392 | case id<meta_normal_pair_t>(): { | 2395 | case id<meta_normal_pair_t>(): { |
@@ -2414,7 +2417,23 @@ private: | |||
2414 | } | 2417 | } |
2415 | } | 2418 | } |
2416 | newPair->value.set(mp->value); | 2419 | newPair->value.set(mp->value); |
2417 | subMetaDestruct->values.push_back(newPair); | 2420 | auto newPairDef = item->new_ptr<normal_pair_def_t>(); |
2421 | newPairDef->pair.set(newPair); | ||
2422 | subMetaDestruct->values.push_back(newPairDef); | ||
2423 | break; | ||
2424 | } | ||
2425 | case id<variable_pair_t>(): { | ||
2426 | auto pair = static_cast<variable_pair_t*>(item); | ||
2427 | auto newPairDef = item->new_ptr<variable_pair_def_t>(); | ||
2428 | newPairDef->pair.set(pair); | ||
2429 | subDestruct->values.push_back(newPairDef); | ||
2430 | break; | ||
2431 | } | ||
2432 | case id<normal_pair_t>(): { | ||
2433 | auto pair = static_cast<normal_pair_t*>(item); | ||
2434 | auto newPairDef = item->new_ptr<normal_pair_def_t>(); | ||
2435 | newPairDef->pair.set(pair); | ||
2436 | subDestruct->values.push_back(newPairDef); | ||
2418 | break; | 2437 | break; |
2419 | } | 2438 | } |
2420 | default: | 2439 | default: |
@@ -5197,14 +5216,28 @@ private: | |||
5197 | transformForEach(forEach, temp); | 5216 | transformForEach(forEach, temp); |
5198 | break; | 5217 | break; |
5199 | } | 5218 | } |
5200 | case id<variable_pair_t>(): { | 5219 | case id<variable_pair_t>(): |
5220 | case id<variable_pair_def_t>(): { | ||
5221 | if (auto pair = ast_cast<variable_pair_def_t>(item)) { | ||
5222 | if (pair->defVal) { | ||
5223 | throw std::logic_error(_info.errorMessage("invalid default value"sv, pair->defVal)); | ||
5224 | } | ||
5225 | item = pair->pair.get(); | ||
5226 | } | ||
5201 | auto variablePair = static_cast<variable_pair_t*>(item); | 5227 | auto variablePair = static_cast<variable_pair_t*>(item); |
5202 | auto nameStr = _parser.toString(variablePair->name); | 5228 | auto nameStr = _parser.toString(variablePair->name); |
5203 | auto assignment = toAst<ExpListAssign_t>(tableVar + '.' + nameStr + '=' + nameStr, item); | 5229 | auto assignment = toAst<ExpListAssign_t>(tableVar + '.' + nameStr + '=' + nameStr, item); |
5204 | transformAssignment(assignment, temp); | 5230 | transformAssignment(assignment, temp); |
5205 | break; | 5231 | break; |
5206 | } | 5232 | } |
5207 | case id<normal_pair_t>(): { | 5233 | case id<normal_pair_t>(): |
5234 | case id<normal_pair_def_t>(): { | ||
5235 | if (auto pair = ast_cast<normal_pair_def_t>(item)) { | ||
5236 | if (pair->defVal) { | ||
5237 | throw std::logic_error(_info.errorMessage("invalid default value"sv, pair->defVal)); | ||
5238 | } | ||
5239 | item = pair->pair.get(); | ||
5240 | } | ||
5208 | auto normalPair = static_cast<normal_pair_t*>(item); | 5241 | auto normalPair = static_cast<normal_pair_t*>(item); |
5209 | auto assignment = toAst<ExpListAssign_t>(tableVar + "=nil"s, item); | 5242 | auto assignment = toAst<ExpListAssign_t>(tableVar + "=nil"s, item); |
5210 | auto chainValue = singleValueFrom(ast_to<Exp_t>(assignment->expList->exprs.front()))->item.to<ChainValue_t>(); | 5243 | auto chainValue = singleValueFrom(ast_to<Exp_t>(assignment->expList->exprs.front()))->item.to<ChainValue_t>(); |
@@ -5248,10 +5281,18 @@ private: | |||
5248 | transformAssignment(assignment, temp); | 5281 | transformAssignment(assignment, temp); |
5249 | break; | 5282 | break; |
5250 | } | 5283 | } |
5251 | case id<Exp_t>(): { | 5284 | case id<Exp_t>(): |
5285 | case id<normal_def_t>(): { | ||
5286 | auto current = item; | ||
5287 | if (auto pair = ast_cast<normal_def_t>(item)) { | ||
5288 | if (pair->defVal) { | ||
5289 | throw std::logic_error(_info.errorMessage("invalid default value"sv, pair->defVal)); | ||
5290 | } | ||
5291 | item = pair->item.get(); | ||
5292 | } | ||
5252 | bool lastVarArg = false; | 5293 | bool lastVarArg = false; |
5253 | BLOCK_START | 5294 | BLOCK_START |
5254 | BREAK_IF(item != values.back()); | 5295 | BREAK_IF(current != values.back()); |
5255 | auto value = singleValueFrom(item); | 5296 | auto value = singleValueFrom(item); |
5256 | BREAK_IF(!value); | 5297 | BREAK_IF(!value); |
5257 | auto chainValue = value->item.as<ChainValue_t>(); | 5298 | auto chainValue = value->item.as<ChainValue_t>(); |
@@ -5291,14 +5332,28 @@ private: | |||
5291 | transformAssignment(assignment, temp); | 5332 | transformAssignment(assignment, temp); |
5292 | break; | 5333 | break; |
5293 | } | 5334 | } |
5294 | case id<meta_variable_pair_t>(): { | 5335 | case id<meta_variable_pair_t>(): |
5336 | case id<meta_variable_pair_def_t>(): { | ||
5337 | if (auto pair = ast_cast<meta_variable_pair_def_t>(item)) { | ||
5338 | if (pair->defVal) { | ||
5339 | throw std::logic_error(_info.errorMessage("invalid default value"sv, pair->defVal)); | ||
5340 | } | ||
5341 | item = pair->pair.get(); | ||
5342 | } | ||
5295 | auto metaVarPair = static_cast<meta_variable_pair_t*>(item); | 5343 | auto metaVarPair = static_cast<meta_variable_pair_t*>(item); |
5296 | auto nameStr = _parser.toString(metaVarPair->name); | 5344 | auto nameStr = _parser.toString(metaVarPair->name); |
5297 | auto assignment = toAst<ExpListAssign_t>(tableVar + ".<"s + nameStr + ">="s + nameStr, item); | 5345 | auto assignment = toAst<ExpListAssign_t>(tableVar + ".<"s + nameStr + ">="s + nameStr, item); |
5298 | transformAssignment(assignment, temp); | 5346 | transformAssignment(assignment, temp); |
5299 | break; | 5347 | break; |
5300 | } | 5348 | } |
5301 | case id<meta_normal_pair_t>(): { | 5349 | case id<meta_normal_pair_t>(): |
5350 | case id<meta_normal_pair_def_t>(): { | ||
5351 | if (auto pair = ast_cast<meta_normal_pair_def_t>(item)) { | ||
5352 | if (pair->defVal) { | ||
5353 | throw std::logic_error(_info.errorMessage("invalid default value"sv, pair->defVal)); | ||
5354 | } | ||
5355 | item = pair->pair.get(); | ||
5356 | } | ||
5302 | auto metaNormalPair = static_cast<meta_normal_pair_t*>(item); | 5357 | auto metaNormalPair = static_cast<meta_normal_pair_t*>(item); |
5303 | auto assignment = toAst<ExpListAssign_t>(tableVar + "=nil"s, item); | 5358 | auto assignment = toAst<ExpListAssign_t>(tableVar + "=nil"s, item); |
5304 | auto chainValue = singleValueFrom(ast_to<Exp_t>(assignment->expList->exprs.front()))->item.to<ChainValue_t>(); | 5359 | auto chainValue = singleValueFrom(ast_to<Exp_t>(assignment->expList->exprs.front()))->item.to<ChainValue_t>(); |
@@ -5326,14 +5381,6 @@ private: | |||
5326 | transformAssignment(assignment, temp); | 5381 | transformAssignment(assignment, temp); |
5327 | break; | 5382 | break; |
5328 | } | 5383 | } |
5329 | case id<default_pair_t>(): { | ||
5330 | throw std::logic_error(_info.errorMessage("invalid default value"sv, static_cast<default_pair_t*>(item)->defVal)); | ||
5331 | break; | ||
5332 | } | ||
5333 | case id<meta_default_pair_t>(): { | ||
5334 | throw std::logic_error(_info.errorMessage("invalid default value"sv, static_cast<meta_default_pair_t*>(item)->defVal)); | ||
5335 | break; | ||
5336 | } | ||
5337 | default: YUEE("AST node mismatch", item); break; | 5384 | default: YUEE("AST node mismatch", item); break; |
5338 | } | 5385 | } |
5339 | } | 5386 | } |
@@ -5381,7 +5428,50 @@ private: | |||
5381 | incIndentOffset(); | 5428 | incIndentOffset(); |
5382 | auto metatable = x->new_ptr<simple_table_t>(); | 5429 | auto metatable = x->new_ptr<simple_table_t>(); |
5383 | ast_sel<false, Exp_t, TableBlock_t> metatableItem; | 5430 | ast_sel<false, Exp_t, TableBlock_t> metatableItem; |
5384 | for (auto item : values) { | 5431 | for (auto value : values) { |
5432 | auto item = value; | ||
5433 | switch (item->getId()) { | ||
5434 | case id<variable_pair_def_t>(): { | ||
5435 | auto pair = static_cast<variable_pair_def_t*>(item); | ||
5436 | if (pair->defVal) { | ||
5437 | throw std::logic_error(_info.errorMessage("invalid default value"sv, pair->defVal)); | ||
5438 | } | ||
5439 | item = pair->pair.get(); | ||
5440 | break; | ||
5441 | } | ||
5442 | case id<normal_pair_def_t>(): { | ||
5443 | auto pair = static_cast<normal_pair_def_t*>(item); | ||
5444 | if (pair->defVal) { | ||
5445 | throw std::logic_error(_info.errorMessage("invalid default value"sv, pair->defVal)); | ||
5446 | } | ||
5447 | item = pair->pair.get(); | ||
5448 | break; | ||
5449 | } | ||
5450 | case id<meta_variable_pair_def_t>(): { | ||
5451 | auto pair = static_cast<meta_variable_pair_def_t*>(item); | ||
5452 | if (pair->defVal) { | ||
5453 | throw std::logic_error(_info.errorMessage("invalid default value"sv, pair->defVal)); | ||
5454 | } | ||
5455 | item = pair->pair.get(); | ||
5456 | break; | ||
5457 | } | ||
5458 | case id<meta_normal_pair_def_t>(): { | ||
5459 | auto pair = static_cast<meta_normal_pair_def_t*>(item); | ||
5460 | if (pair->defVal) { | ||
5461 | throw std::logic_error(_info.errorMessage("invalid default value"sv, pair->defVal)); | ||
5462 | } | ||
5463 | item = pair->pair.get(); | ||
5464 | break; | ||
5465 | } | ||
5466 | case id<normal_def_t>(): { | ||
5467 | auto pair = static_cast<normal_def_t*>(item); | ||
5468 | if (pair->defVal) { | ||
5469 | throw std::logic_error(_info.errorMessage("invalid default value"sv, pair->defVal)); | ||
5470 | } | ||
5471 | item = pair->item.get(); | ||
5472 | break; | ||
5473 | } | ||
5474 | } | ||
5385 | bool isMetamethod = false; | 5475 | bool isMetamethod = false; |
5386 | switch (item->getId()) { | 5476 | switch (item->getId()) { |
5387 | case id<Exp_t>(): transformExp(static_cast<Exp_t*>(item), temp, ExpUsage::Closure); break; | 5477 | case id<Exp_t>(): transformExp(static_cast<Exp_t*>(item), temp, ExpUsage::Closure); break; |
@@ -5437,18 +5527,10 @@ private: | |||
5437 | } | 5527 | } |
5438 | break; | 5528 | break; |
5439 | } | 5529 | } |
5440 | case id<default_pair_t>(): { | ||
5441 | throw std::logic_error(_info.errorMessage("invalid default value"sv, static_cast<default_pair_t*>(item)->defVal)); | ||
5442 | break; | ||
5443 | } | ||
5444 | case id<meta_default_pair_t>(): { | ||
5445 | throw std::logic_error(_info.errorMessage("invalid default value"sv, static_cast<meta_default_pair_t*>(item)->defVal)); | ||
5446 | break; | ||
5447 | } | ||
5448 | default: YUEE("AST node mismatch", item); break; | 5530 | default: YUEE("AST node mismatch", item); break; |
5449 | } | 5531 | } |
5450 | if (!isMetamethod) { | 5532 | if (!isMetamethod) { |
5451 | temp.back() = indent() + (item == values.back() ? temp.back() : temp.back() + ',') + nll(item); | 5533 | temp.back() = indent() + (value == values.back() ? temp.back() : temp.back() + ',') + nll(value); |
5452 | } | 5534 | } |
5453 | } | 5535 | } |
5454 | if (metatable->pairs.empty() && !metatableItem) { | 5536 | if (metatable->pairs.empty() && !metatableItem) { |
@@ -7518,7 +7600,41 @@ private: | |||
7518 | } else if (auto tabLit = ast_cast<ImportTabLit_t>(target)) { | 7600 | } else if (auto tabLit = ast_cast<ImportTabLit_t>(target)) { |
7519 | auto simpleValue = x->new_ptr<SimpleValue_t>(); | 7601 | auto simpleValue = x->new_ptr<SimpleValue_t>(); |
7520 | auto tableLit = x->new_ptr<TableLit_t>(); | 7602 | auto tableLit = x->new_ptr<TableLit_t>(); |
7521 | tableLit->values.dup(tabLit->items); | 7603 | for (auto pair : tabLit->items.objects()) { |
7604 | switch (pair->getId()) { | ||
7605 | case id<variable_pair_t>(): { | ||
7606 | auto pairDef = pair->new_ptr<variable_pair_def_t>(); | ||
7607 | pairDef->pair.set(pair); | ||
7608 | tableLit->values.push_back(pairDef); | ||
7609 | break; | ||
7610 | } | ||
7611 | case id<normal_pair_t>(): { | ||
7612 | auto pairDef = pair->new_ptr<normal_pair_def_t>(); | ||
7613 | pairDef->pair.set(pair); | ||
7614 | tableLit->values.push_back(pairDef); | ||
7615 | break; | ||
7616 | } | ||
7617 | case id<Exp_t>(): { | ||
7618 | auto pairDef = pair->new_ptr<normal_def_t>(); | ||
7619 | pairDef->item.set(pair); | ||
7620 | tableLit->values.push_back(pairDef); | ||
7621 | break; | ||
7622 | } | ||
7623 | case id<meta_variable_pair_t>(): { | ||
7624 | auto pairDef = pair->new_ptr<meta_variable_pair_def_t>(); | ||
7625 | pairDef->pair.set(pair); | ||
7626 | tableLit->values.push_back(pairDef); | ||
7627 | break; | ||
7628 | } | ||
7629 | case id<meta_normal_pair_t>(): { | ||
7630 | auto pairDef = pair->new_ptr<meta_normal_pair_def_t>(); | ||
7631 | pairDef->pair.set(pair); | ||
7632 | tableLit->values.push_back(pairDef); | ||
7633 | break; | ||
7634 | } | ||
7635 | default: YUEE("AST node mismatch", pair); break; | ||
7636 | } | ||
7637 | } | ||
7522 | simpleValue->value.set(tableLit); | 7638 | simpleValue->value.set(tableLit); |
7523 | value->item.set(simpleValue); | 7639 | value->item.set(simpleValue); |
7524 | } else { | 7640 | } else { |
diff --git a/src/yuescript/yue_compiler.h b/src/yuescript/yue_compiler.h index 9ca641a..a3f4367 100644 --- a/src/yuescript/yue_compiler.h +++ b/src/yuescript/yue_compiler.h | |||
@@ -30,6 +30,7 @@ struct YueConfig { | |||
30 | bool reserveLineNumber = true; | 30 | bool reserveLineNumber = true; |
31 | bool useSpaceOverTab = false; | 31 | bool useSpaceOverTab = false; |
32 | bool exporting = false; | 32 | bool exporting = false; |
33 | bool profiling = false; | ||
33 | int lineOffset = 0; | 34 | int lineOffset = 0; |
34 | std::string module; | 35 | std::string module; |
35 | Options options; | 36 | Options options; |
@@ -48,6 +49,8 @@ struct CompileInfo { | |||
48 | std::string error; | 49 | std::string error; |
49 | std::unique_ptr<GlobalVars> globals; | 50 | std::unique_ptr<GlobalVars> globals; |
50 | std::unique_ptr<Options> options; | 51 | std::unique_ptr<Options> options; |
52 | double parseTime; | ||
53 | double compileTime; | ||
51 | }; | 54 | }; |
52 | 55 | ||
53 | class YueCompilerImpl; | 56 | class YueCompilerImpl; |
diff --git a/src/yuescript/yue_parser.cpp b/src/yuescript/yue_parser.cpp index 0d9a183..758865e 100644 --- a/src/yuescript/yue_parser.cpp +++ b/src/yuescript/yue_parser.cpp | |||
@@ -406,10 +406,10 @@ YueParser::YueParser() { | |||
406 | simple_table = Seperator >> KeyValue >> *(sym(',') >> KeyValue); | 406 | simple_table = Seperator >> KeyValue >> *(sym(',') >> KeyValue); |
407 | Value = SimpleValue | simple_table | ChainValue | Space >> String; | 407 | Value = SimpleValue | simple_table | ChainValue | Space >> String; |
408 | 408 | ||
409 | single_string_inner = expr("\\'") | "\\\\" | not_(expr('\'')) >> Any; | 409 | single_string_inner = expr('\\') >> set("'\\") | not_(expr('\'')) >> Any; |
410 | SingleString = symx('\'') >> *single_string_inner >> symx('\''); | 410 | SingleString = symx('\'') >> *single_string_inner >> symx('\''); |
411 | interp = symx("#{") >> Exp >> sym('}'); | 411 | interp = symx("#{") >> Exp >> sym('}'); |
412 | double_string_plain = expr("\\\"") | "\\\\" | not_(expr('"')) >> Any; | 412 | double_string_plain = expr('\\') >> set("\"\\") | not_(expr('"')) >> Any; |
413 | double_string_inner = +(not_(interp) >> double_string_plain); | 413 | double_string_inner = +(not_(interp) >> double_string_plain); |
414 | double_string_content = double_string_inner | interp; | 414 | double_string_content = double_string_inner | interp; |
415 | DoubleString = symx('"') >> Seperator >> *double_string_content >> symx('"'); | 415 | DoubleString = symx('"') >> Seperator >> *double_string_content >> symx('"'); |
@@ -484,7 +484,13 @@ YueParser::YueParser() { | |||
484 | 484 | ||
485 | SpreadExp = sym("...") >> Exp; | 485 | SpreadExp = sym("...") >> Exp; |
486 | 486 | ||
487 | TableValue = ((KeyValue | SpreadExp | Exp) >> not_(sym('='))) | meta_default_pair | default_pair; | 487 | TableValue = |
488 | variable_pair_def | | ||
489 | normal_pair_def | | ||
490 | meta_variable_pair_def | | ||
491 | meta_normal_pair_def | | ||
492 | SpreadExp | | ||
493 | normal_def; | ||
488 | 494 | ||
489 | table_lit_lines = SpaceBreak >> TableLitLine >> *(-sym(',') >> SpaceBreak >> TableLitLine) >> -sym(','); | 495 | table_lit_lines = SpaceBreak >> TableLitLine >> *(-sym(',') >> SpaceBreak >> TableLitLine) >> -sym(','); |
490 | 496 | ||
@@ -564,21 +570,16 @@ YueParser::YueParser() { | |||
564 | symx(':') >> not_(':') >> | 570 | symx(':') >> not_(':') >> |
565 | (Exp | TableBlock | +SpaceBreak >> Exp); | 571 | (Exp | TableBlock | +SpaceBreak >> Exp); |
566 | 572 | ||
567 | default_pair = ( | ||
568 | sym(':') >> Variable >> Seperator | | ||
569 | KeyName >> symx(':') >> not_(':') >> Seperator >> exp_not_tab | | ||
570 | Space >> String >> symx(':') >> not_(':') >> Seperator >> exp_not_tab | | ||
571 | exp_not_tab >> Seperator) >> sym('=') >> Exp; | ||
572 | |||
573 | meta_variable_pair = sym(":<") >> Space >> Variable >> sym('>'); | 573 | meta_variable_pair = sym(":<") >> Space >> Variable >> sym('>'); |
574 | 574 | ||
575 | meta_normal_pair = sym('<') >> Space >> -meta_index >> sym(">:") >> | 575 | meta_normal_pair = sym('<') >> Space >> -meta_index >> sym(">:") >> |
576 | (Exp | TableBlock | +(SpaceBreak) >> Exp); | 576 | (Exp | TableBlock | +(SpaceBreak) >> Exp); |
577 | 577 | ||
578 | meta_default_pair = ( | 578 | variable_pair_def = variable_pair >> -(sym('=') >> Exp); |
579 | sym(":<") >> Space >> Variable >> sym('>') >> Seperator | | 579 | normal_pair_def = normal_pair >> -(sym('=') >> Exp); |
580 | sym('<') >> Space >> -meta_index >> sym(">:") >> Seperator >> exp_not_tab | 580 | meta_variable_pair_def = meta_variable_pair >> -(sym('=') >> Exp); |
581 | ) >> sym('=') >> Exp; | 581 | meta_normal_pair_def = meta_normal_pair >> -(sym('=') >> Exp); |
582 | normal_def = Exp >> Seperator >> -(sym('=') >> Exp); | ||
582 | 583 | ||
583 | KeyValue = variable_pair | normal_pair | meta_variable_pair | meta_normal_pair; | 584 | KeyValue = variable_pair | normal_pair | meta_variable_pair | meta_normal_pair; |
584 | KeyValueList = KeyValue >> *(sym(',') >> KeyValue); | 585 | KeyValueList = KeyValue >> *(sym(',') >> KeyValue); |
diff --git a/src/yuescript/yue_parser.h b/src/yuescript/yue_parser.h index 88d688c..a4ecafd 100644 --- a/src/yuescript/yue_parser.h +++ b/src/yuescript/yue_parser.h | |||
@@ -332,10 +332,13 @@ private: | |||
332 | AST_RULE(Export) | 332 | AST_RULE(Export) |
333 | AST_RULE(variable_pair) | 333 | AST_RULE(variable_pair) |
334 | AST_RULE(normal_pair) | 334 | AST_RULE(normal_pair) |
335 | AST_RULE(default_pair) | ||
336 | AST_RULE(meta_variable_pair) | 335 | AST_RULE(meta_variable_pair) |
337 | AST_RULE(meta_normal_pair) | 336 | AST_RULE(meta_normal_pair) |
338 | AST_RULE(meta_default_pair) | 337 | AST_RULE(variable_pair_def) |
338 | AST_RULE(normal_pair_def) | ||
339 | AST_RULE(normal_def) | ||
340 | AST_RULE(meta_variable_pair_def) | ||
341 | AST_RULE(meta_normal_pair_def) | ||
339 | AST_RULE(FnArgDef) | 342 | AST_RULE(FnArgDef) |
340 | AST_RULE(FnArgDefList) | 343 | AST_RULE(FnArgDefList) |
341 | AST_RULE(outer_var_shadow) | 344 | AST_RULE(outer_var_shadow) |