diff options
| author | Li Jin <dragon-fly@qq.com> | 2022-11-08 10:20:52 +0800 |
|---|---|---|
| committer | Li Jin <dragon-fly@qq.com> | 2022-11-09 11:29:32 +0800 |
| commit | b9b1cf94e1324e344df6f7204c8d479329c56718 (patch) | |
| tree | b288f3c48bfd17f673968f101f0f6f886f00c3c9 /src | |
| parent | 95fd6ea93c2af6fb1707e480669d84ebe37fccbe (diff) | |
| download | yuescript-b9b1cf94e1324e344df6f7204c8d479329c56718.tar.gz yuescript-b9b1cf94e1324e344df6f7204c8d479329c56718.tar.bz2 yuescript-b9b1cf94e1324e344df6f7204c8d479329c56718.zip | |
fix issue #114.
Diffstat (limited to '')
| -rw-r--r-- | src/yuescript/yue_compiler.cpp | 16 | ||||
| -rw-r--r-- | src/yuescript/yue_parser.cpp | 18 | ||||
| -rw-r--r-- | src/yuescript/yue_parser.h | 7 |
3 files changed, 27 insertions, 14 deletions
diff --git a/src/yuescript/yue_compiler.cpp b/src/yuescript/yue_compiler.cpp index e061604..d0f2dbb 100644 --- a/src/yuescript/yue_compiler.cpp +++ b/src/yuescript/yue_compiler.cpp | |||
| @@ -14,7 +14,6 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI | |||
| 14 | #include <unordered_map> | 14 | #include <unordered_map> |
| 15 | #include <unordered_set> | 15 | #include <unordered_set> |
| 16 | #include <vector> | 16 | #include <vector> |
| 17 | #include <optional> | ||
| 18 | 17 | ||
| 19 | #include "yuescript/yue_compiler.h" | 18 | #include "yuescript/yue_compiler.h" |
| 20 | #include "yuescript/yue_parser.h" | 19 | #include "yuescript/yue_parser.h" |
| @@ -60,7 +59,7 @@ namespace yue { | |||
| 60 | 59 | ||
| 61 | typedef std::list<std::string> str_list; | 60 | typedef std::list<std::string> str_list; |
| 62 | 61 | ||
| 63 | const std::string_view version = "0.15.8"sv; | 62 | const std::string_view version = "0.15.9"sv; |
| 64 | const std::string_view extension = "yue"sv; | 63 | const std::string_view extension = "yue"sv; |
| 65 | 64 | ||
| 66 | class YueCompilerImpl { | 65 | class YueCompilerImpl { |
| @@ -2122,7 +2121,8 @@ private: | |||
| 2122 | keyIndex = key; | 2121 | keyIndex = key; |
| 2123 | } else if (auto key = np->key.as<String_t>()) { | 2122 | } else if (auto key = np->key.as<String_t>()) { |
| 2124 | keyIndex = newExp(key, np->key).get(); | 2123 | keyIndex = newExp(key, np->key).get(); |
| 2125 | } else throw std::logic_error(_info.errorMessage("unsupported key for destructuring"sv, np)); | 2124 | } else |
| 2125 | throw std::logic_error(_info.errorMessage("unsupported key for destructuring"sv, np)); | ||
| 2126 | } | 2126 | } |
| 2127 | if (auto exp = np->value.as<Exp_t>()) { | 2127 | if (auto exp = np->value.as<Exp_t>()) { |
| 2128 | if (!isAssignable(exp)) throw std::logic_error(_info.errorMessage("can't do destructure value"sv, exp)); | 2128 | if (!isAssignable(exp)) throw std::logic_error(_info.errorMessage("can't do destructure value"sv, exp)); |
| @@ -2211,7 +2211,8 @@ private: | |||
| 2211 | chain->items.push_back(newExp(key, dp)); | 2211 | chain->items.push_back(newExp(key, dp)); |
| 2212 | } else if (auto key = dp->key.as<Exp_t>()) { | 2212 | } else if (auto key = dp->key.as<Exp_t>()) { |
| 2213 | chain->items.push_back(key); | 2213 | chain->items.push_back(key); |
| 2214 | } else throw std::logic_error(_info.errorMessage("unsupported key for destructuring"sv, dp)); | 2214 | } else |
| 2215 | throw std::logic_error(_info.errorMessage("unsupported key for destructuring"sv, dp)); | ||
| 2215 | } | 2216 | } |
| 2216 | if (auto exp = dp->value.get()) { | 2217 | if (auto exp = dp->value.get()) { |
| 2217 | if (!isAssignable(exp)) throw std::logic_error(_info.errorMessage("can't destructure value"sv, exp)); | 2218 | if (!isAssignable(exp)) throw std::logic_error(_info.errorMessage("can't destructure value"sv, exp)); |
| @@ -6520,6 +6521,13 @@ private: | |||
| 6520 | _buf << "\t\t"sv << baseVar << '[' << key << "]="sv << val << " if "sv << baseVar << '[' << key << "]==nil and (not "sv << cls << " or not "sv << key << "\\match \"^__\")"sv; | 6521 | _buf << "\t\t"sv << baseVar << '[' << key << "]="sv << val << " if "sv << baseVar << '[' << key << "]==nil and (not "sv << cls << " or not "sv << key << "\\match \"^__\")"sv; |
| 6521 | transformBlock(toAst<Block_t>(clearBuf(), x), temp, ExpUsage::Common); | 6522 | transformBlock(toAst<Block_t>(clearBuf(), x), temp, ExpUsage::Common); |
| 6522 | } | 6523 | } |
| 6524 | if (!parentVar.empty()) { | ||
| 6525 | auto key = getUnusedName("_key_"sv); | ||
| 6526 | auto val = getUnusedName("_val_"sv); | ||
| 6527 | _buf << "for "sv << key << ',' << val << " in pairs "sv << parentVar << ".__base"sv << '\n' | ||
| 6528 | << '\t' << baseVar << '[' << key << "]="sv << val << " if "sv << baseVar << '[' << key << "]==nil and "sv << key << "\\match(\"^__\") and not ("sv << key << "==\"__index\" and "sv << val << "=="sv << parentVar << ".__base)"sv; | ||
| 6529 | transformBlock(toAst<Block_t>(clearBuf(), x), temp, ExpUsage::Common); | ||
| 6530 | } | ||
| 6523 | transformAssignment(toAst<ExpListAssign_t>(baseVar + ".__index ?\?= "s + baseVar, classDecl), temp); | 6531 | transformAssignment(toAst<ExpListAssign_t>(baseVar + ".__index ?\?= "s + baseVar, classDecl), temp); |
| 6524 | str_list tmp; | 6532 | str_list tmp; |
| 6525 | if (usage == ExpUsage::Assignment) { | 6533 | if (usage == ExpUsage::Assignment) { |
diff --git a/src/yuescript/yue_parser.cpp b/src/yuescript/yue_parser.cpp index 4aeb79a..e4de0b5 100644 --- a/src/yuescript/yue_parser.cpp +++ b/src/yuescript/yue_parser.cpp | |||
| @@ -71,7 +71,7 @@ YueParser::YueParser() { | |||
| 71 | Cut = false_(); | 71 | Cut = false_(); |
| 72 | Seperator = true_(); | 72 | Seperator = true_(); |
| 73 | 73 | ||
| 74 | invalid_empty_block = pl::user(true_(), [](const item_t& item) { | 74 | empty_block_error = pl::user(true_(), [](const item_t& item) { |
| 75 | throw ParserError("must be followed by a statement or an indented block", *item.begin, *item.end); | 75 | throw ParserError("must be followed by a statement or an indented block", *item.begin, *item.end); |
| 76 | return false; | 76 | return false; |
| 77 | }); | 77 | }); |
| @@ -84,9 +84,9 @@ YueParser::YueParser() { | |||
| 84 | #define disable_chain(patt) (DisableChain >> ((patt) >> EnableChain | EnableChain >> Cut)) | 84 | #define disable_chain(patt) (DisableChain >> ((patt) >> EnableChain | EnableChain >> Cut)) |
| 85 | #define disable_do_chain_arg_table_block(patt) (DisableDoChainArgTableBlock >> ((patt) >> EnableDoChainArgTableBlock | EnableDoChainArgTableBlock >> Cut)) | 85 | #define disable_do_chain_arg_table_block(patt) (DisableDoChainArgTableBlock >> ((patt) >> EnableDoChainArgTableBlock | EnableDoChainArgTableBlock >> Cut)) |
| 86 | #define disable_arg_table_block(patt) (DisableArgTableBlock >> ((patt) >> EnableArgTableBlock | EnableArgTableBlock >> Cut)) | 86 | #define disable_arg_table_block(patt) (DisableArgTableBlock >> ((patt) >> EnableArgTableBlock | EnableArgTableBlock >> Cut)) |
| 87 | #define body_with(str) (Space >> (key(str) >> Space >> (InBlock | Statement) | InBlock | invalid_empty_block)) | 87 | #define body_with(str) (Space >> (key(str) >> Space >> (InBlock | Statement) | InBlock | empty_block_error)) |
| 88 | #define opt_body_with(str) (Space >> (key(str) >> Space >> (InBlock | Statement) | InBlock)) | 88 | #define opt_body_with(str) (Space >> (key(str) >> Space >> (InBlock | Statement) | InBlock)) |
| 89 | #define body (Space >> (InBlock | Statement | invalid_empty_block)) | 89 | #define body (Space >> (InBlock | Statement | empty_block_error)) |
| 90 | 90 | ||
| 91 | Variable = pl::user(Name, [](const item_t& item) { | 91 | Variable = pl::user(Name, [](const item_t& item) { |
| 92 | State* st = reinterpret_cast<State*>(item.user_data); | 92 | State* st = reinterpret_cast<State*>(item.user_data); |
| @@ -630,15 +630,17 @@ YueParser::YueParser() { | |||
| 630 | SpaceBreak >> Advance >> ArgBlock >> -arg_table_block | 630 | SpaceBreak >> Advance >> ArgBlock >> -arg_table_block |
| 631 | ) | arg_table_block; | 631 | ) | arg_table_block; |
| 632 | 632 | ||
| 633 | leading_spaces_error = pl::user(+space_one >> expr('(') >> Exp >> +(sym(',') >> Exp) >> sym(')'), [](const item_t& item) { | ||
| 634 | throw ParserError("write invoke arguments in parentheses without leading spaces or leading spaces without parentheses", *item.begin, *item.end); | ||
| 635 | return false; | ||
| 636 | }); | ||
| 637 | |||
| 633 | InvokeArgs = | 638 | InvokeArgs = |
| 634 | not_(set("-~")) >> Seperator >> | 639 | not_(set("-~")) >> Seperator >> |
| 635 | ( | 640 | ( |
| 636 | (Exp >> *(sym(',') >> Exp) >> -invoke_args_with_table) | | 641 | (Exp >> *(sym(',') >> Exp) >> -invoke_args_with_table) | |
| 637 | arg_table_block | | 642 | arg_table_block | |
| 638 | pl::user(+space_one >> expr('(') >> Exp >> +(sym(',') >> Exp) >> sym(')'), [](const item_t& item) { | 643 | leading_spaces_error |
| 639 | throw ParserError("write invoke arguments in parentheses without spaces or space seperated without parentheses", *item.begin, *item.end); | ||
| 640 | return false; | ||
| 641 | }) | ||
| 642 | ); | 644 | ); |
| 643 | 645 | ||
| 644 | const_value = (expr("nil") | expr("true") | expr("false")) >> not_(AlphaNum); | 646 | const_value = (expr("nil") | expr("true") | expr("false")) >> not_(AlphaNum); |
| @@ -666,7 +668,7 @@ YueParser::YueParser() { | |||
| 666 | Return | Local | Global | Export | Macro | | 668 | Return | Local | Global | Export | Macro | |
| 667 | MacroInPlace | BreakLoop | Label | Goto | ShortTabAppending | | 669 | MacroInPlace | BreakLoop | Label | Goto | ShortTabAppending | |
| 668 | LocalAttrib | Backcall | PipeBody | ExpListAssign | | 670 | LocalAttrib | Backcall | PipeBody | ExpListAssign | |
| 669 | statement_appendix >> invalid_empty_block | 671 | statement_appendix >> empty_block_error |
| 670 | ) >> Space >> | 672 | ) >> Space >> |
| 671 | -statement_appendix >> -statement_sep; | 673 | -statement_appendix >> -statement_sep; |
| 672 | 674 | ||
diff --git a/src/yuescript/yue_parser.h b/src/yuescript/yue_parser.h index 461b381..9e2a621 100644 --- a/src/yuescript/yue_parser.h +++ b/src/yuescript/yue_parser.h | |||
| @@ -48,7 +48,9 @@ public: | |||
| 48 | }; | 48 | }; |
| 49 | 49 | ||
| 50 | template <typename T> | 50 | template <typename T> |
| 51 | struct identity { typedef T type; }; | 51 | struct identity { |
| 52 | typedef T type; | ||
| 53 | }; | ||
| 52 | 54 | ||
| 53 | #define AST_RULE(type) \ | 55 | #define AST_RULE(type) \ |
| 54 | rule type; \ | 56 | rule type; \ |
| @@ -113,7 +115,8 @@ private: | |||
| 113 | return Cut; | 115 | return Cut; |
| 114 | } | 116 | } |
| 115 | 117 | ||
| 116 | rule invalid_empty_block; | 118 | rule empty_block_error; |
| 119 | rule leading_spaces_error; | ||
| 117 | 120 | ||
| 118 | rule num_char; | 121 | rule num_char; |
| 119 | rule num_char_hex; | 122 | rule num_char_hex; |
