diff options
Diffstat (limited to '')
| -rw-r--r-- | src/yuescript/yue_parser.cpp | 71 |
1 files changed, 48 insertions, 23 deletions
diff --git a/src/yuescript/yue_parser.cpp b/src/yuescript/yue_parser.cpp index f215ee4..99fea0a 100644 --- a/src/yuescript/yue_parser.cpp +++ b/src/yuescript/yue_parser.cpp | |||
| @@ -93,6 +93,11 @@ YueParser::YueParser() { | |||
| 93 | return false; | 93 | return false; |
| 94 | }); | 94 | }); |
| 95 | 95 | ||
| 96 | export_expression_error = pl::user(true_(), [](const item_t& item) { | ||
| 97 | throw ParserError("invalid export expression"sv, item.begin); | ||
| 98 | return false; | ||
| 99 | }); | ||
| 100 | |||
| 96 | #define ensure(patt, finally) ((patt) >> (finally) | (finally) >> cut) | 101 | #define ensure(patt, finally) ((patt) >> (finally) | (finally) >> cut) |
| 97 | 102 | ||
| 98 | #define key(str) (expr(str) >> not_alpha_num) | 103 | #define key(str) (expr(str) >> not_alpha_num) |
| @@ -666,29 +671,48 @@ YueParser::YueParser() { | |||
| 666 | State* st = reinterpret_cast<State*>(item.user_data); | 671 | State* st = reinterpret_cast<State*>(item.user_data); |
| 667 | st->exportCount++; | 672 | st->exportCount++; |
| 668 | return true; | 673 | return true; |
| 669 | }) >> (pl::user(space >> ExportDefault >> space >> Exp, [](const item_t& item) { | 674 | }) >> ( |
| 670 | State* st = reinterpret_cast<State*>(item.user_data); | 675 | pl::user(space >> ExportDefault >> space >> Exp, [](const item_t& item) { |
| 671 | if (st->exportDefault) { | 676 | State* st = reinterpret_cast<State*>(item.user_data); |
| 672 | throw ParserError("export default has already been declared"sv, item.begin); | 677 | if (st->exportDefault) { |
| 673 | } | 678 | throw ParserError("export default has already been declared"sv, item.begin); |
| 674 | if (st->exportCount > 1) { | 679 | } |
| 675 | throw ParserError("there are items already being exported"sv, item.begin); | 680 | if (st->exportCount > 1) { |
| 676 | } | 681 | throw ParserError("there are items already being exported"sv, item.begin); |
| 677 | st->exportDefault = true; | 682 | } |
| 678 | return true; | 683 | st->exportDefault = true; |
| 679 | }) | 684 | return true; |
| 680 | | (not_(space >> ExportDefault) >> pl::user(true_(), [](const item_t& item) { | 685 | }) | |
| 681 | State* st = reinterpret_cast<State*>(item.user_data); | 686 | not_(space >> ExportDefault) >> pl::user(true_(), [](const item_t& item) { |
| 682 | if (st->exportDefault && st->exportCount > 1) { | 687 | State* st = reinterpret_cast<State*>(item.user_data); |
| 683 | throw ParserError("can not export any more items when 'export default' is declared"sv, item.begin); | 688 | if (st->exportDefault && st->exportCount > 1) { |
| 684 | } | 689 | throw ParserError("can not export any more items when 'export default' is declared"sv, item.begin); |
| 685 | return true; | 690 | } |
| 686 | }) >> space >> ExpList >> -(space >> Assign)) | 691 | return true; |
| 687 | | space >> pl::user(Macro, [](const item_t& item) { | 692 | }) >> ( |
| 688 | State* st = reinterpret_cast<State*>(item.user_data); | 693 | and_(set(".[")) >> ((pl::user(and_('.' >> Metatable), [](const item_t& item) { |
| 689 | st->exportMacro = true; | 694 | State* st = reinterpret_cast<State*>(item.user_data); |
| 690 | return true; | 695 | if (st->exportMetatable) { |
| 691 | })) >> not_(space >> StatementAppendix); | 696 | throw ParserError("module metatable duplicated"sv, item.begin); |
| 697 | } | ||
| 698 | if (st->exportMetamethod) { | ||
| 699 | throw ParserError("metatable should be exported before metamethod"sv, item.begin); | ||
| 700 | } | ||
| 701 | st->exportMetatable = true; | ||
| 702 | return true; | ||
| 703 | }) | pl::user(and_(".<"), [](const item_t& item) { | ||
| 704 | State* st = reinterpret_cast<State*>(item.user_data); | ||
| 705 | st->exportMetamethod = true; | ||
| 706 | return true; | ||
| 707 | }) | true_()) >> (DotChainItem | index) >> space >> Assign | export_expression_error) | | ||
| 708 | space >> ExpList >> -(space >> Assign) | ||
| 709 | ) | | ||
| 710 | space >> pl::user(Macro, [](const item_t& item) { | ||
| 711 | State* st = reinterpret_cast<State*>(item.user_data); | ||
| 712 | st->exportMacro = true; | ||
| 713 | return true; | ||
| 714 | }) | ||
| 715 | ) >> not_(space >> StatementAppendix); | ||
| 692 | 716 | ||
| 693 | VariablePair = ':' >> Variable; | 717 | VariablePair = ':' >> Variable; |
| 694 | 718 | ||
| @@ -897,6 +921,7 @@ ParseInfo YueParser::parse(std::string_view codes, rule& r) { | |||
| 897 | res.moduleName = std::move(state.moduleName); | 921 | res.moduleName = std::move(state.moduleName); |
| 898 | res.exportDefault = state.exportDefault; | 922 | res.exportDefault = state.exportDefault; |
| 899 | res.exportMacro = state.exportMacro; | 923 | res.exportMacro = state.exportMacro; |
| 924 | res.exportMetatable = !state.exportMetatable && state.exportMetamethod; | ||
| 900 | } | 925 | } |
| 901 | } catch (const ParserError& err) { | 926 | } catch (const ParserError& err) { |
| 902 | res.error = {err.what(), err.line, err.col}; | 927 | res.error = {err.what(), err.line, err.col}; |
