diff options
Diffstat (limited to 'src')
-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; |