diff options
Diffstat (limited to 'src/yuescript/yue_parser.cpp')
-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}; |