aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLi Jin <dragon-fly@qq.com>2022-11-11 09:29:01 +0800
committerLi Jin <dragon-fly@qq.com>2022-11-11 09:29:01 +0800
commit209fca096b0be5c47553f4c4a94d95de33b23d31 (patch)
treec170264dbab9c6bb2f076de17ca171782664872a
parente02780668e0ce2ebf7088bad2e70ad94b6824b08 (diff)
downloadyuescript-209fca096b0be5c47553f4c4a94d95de33b23d31.tar.gz
yuescript-209fca096b0be5c47553f4c4a94d95de33b23d31.tar.bz2
yuescript-209fca096b0be5c47553f4c4a94d95de33b23d31.zip
refactor parser to be a little faster.
-rw-r--r--src/yue.cpp13
-rw-r--r--src/yuescript/ast.hpp3
-rwxr-xr-xsrc/yuescript/yue_ast.h55
-rw-r--r--src/yuescript/yue_compiler.cpp402
-rw-r--r--src/yuescript/yue_compiler.h3
-rw-r--r--src/yuescript/yue_parser.cpp27
-rw-r--r--src/yuescript/yue_parser.h7
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)
460AST_END(variable_pair, "variable_pair"sv) 460AST_END(variable_pair, "variable_pair"sv)
461 461
462AST_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)
466AST_END(variable_pair_def, "variable_pair_def"sv)
467
462class String_t; 468class String_t;
463 469
464AST_NODE(normal_pair) 470AST_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)
468AST_END(normal_pair, "normal_pair"sv) 474AST_END(normal_pair, "normal_pair"sv)
469 475
470AST_NODE(default_pair) 476AST_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)
480AST_END(normal_pair_def, "normal_pair_def"sv)
481
482AST_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) 487AST_END(normal_def, "normal_def")
476AST_END(default_pair, "default_pair"sv)
477 488
478AST_NODE(meta_variable_pair) 489AST_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)
481AST_END(meta_variable_pair, "meta_variable_pair"sv) 492AST_END(meta_variable_pair, "meta_variable_pair"sv)
482 493
494AST_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)
498AST_END(meta_variable_pair_def, "meta_variable_pair_def"sv)
499
483AST_NODE(meta_normal_pair) 500AST_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)
487AST_END(meta_normal_pair, "meta_normal_pair"sv) 504AST_END(meta_normal_pair, "meta_normal_pair"sv)
488 505
489AST_NODE(meta_default_pair) 506AST_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; 510AST_END(meta_normal_pair_def, "meta_normal_pair_def"sv)
494 AST_MEMBER(meta_default_pair, &key, &sep, &value, &defVal)
495AST_END(meta_default_pair, "meta_default_pair"sv)
496 511
497AST_NODE(simple_table) 512AST_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)
620AST_LEAF(default_value) 635AST_LEAF(default_value)
621AST_END(default_value, "default_value"sv) 636AST_END(default_value, "default_value"sv)
622 637
623class default_pair_t;
624class meta_default_pair_t;
625
626AST_NODE(SpreadExp) 638AST_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)
631AST_NODE(TableLit) 643AST_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)
637AST_END(TableLit, "table_lit"sv) 649AST_END(TableLit, "table_lit"sv)
638 650
639AST_NODE(TableBlockIndent) 651AST_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)
645AST_END(TableBlockIndent, "table_block_indent"sv) 657AST_END(TableBlockIndent, "table_block_indent"sv)
646 658
647AST_NODE(TableBlock) 659AST_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)
652AST_END(TableBlock, "table_block"sv) 663AST_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
7THE 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.*/ 7THE 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
60typedef std::list<std::string> str_list; 61typedef std::list<std::string> str_list;
61 62
62const std::string_view version = "0.15.12"sv; 63const std::string_view version = "0.15.13"sv;
63const std::string_view extension = "yue"sv; 64const std::string_view extension = "yue"sv;
64 65
65class YueCompilerImpl { 66class 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
53class YueCompilerImpl; 56class 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)