From 2a7256ea8cb8a292d8f395c13ed2462df4c084a0 Mon Sep 17 00:00:00 2001 From: Li Jin Date: Thu, 15 Oct 2020 09:38:01 +0800 Subject: add support to import all macros from a module with symbol '$' in import-as statement. fix import macro rename issue. --- spec/inputs/macro.mp | 5 +++- spec/inputs/macro_export.mp | 2 +- src/MoonP/moon_ast.h | 40 ++++++++++++++++++++++++-------- src/MoonP/moon_compiler.cpp | 56 ++++++++++++++++++++++++++++++--------------- src/MoonP/moon_parser.cpp | 53 +++++++++++++++++++++--------------------- src/MoonP/moon_parser.h | 13 +++++++---- 6 files changed, 110 insertions(+), 59 deletions(-) diff --git a/spec/inputs/macro.mp b/spec/inputs/macro.mp index c7ec79c..103df95 100644 --- a/spec/inputs/macro.mp +++ b/spec/inputs/macro.mp @@ -5,7 +5,10 @@ macro block init = -> $init! -import "macro_export" as {$myconfig:$config, :$showMacro, :$asserts, :$assert} +import "macro_export" as { + $, -- import all macros + $config:$myconfig, -- rename macro $config to $myconfig +} $asserts item == nil diff --git a/spec/inputs/macro_export.mp b/spec/inputs/macro_export.mp index 759c6d1..7208b2a 100644 --- a/spec/inputs/macro_export.mp +++ b/spec/inputs/macro_export.mp @@ -11,7 +11,7 @@ export macro expr showMacro = (name,res)-> print txt txt" else - "#{res}" + res export macro block asserts = (cond)-> if debugMode diff --git a/src/MoonP/moon_ast.h b/src/MoonP/moon_ast.h index 90508a5..dfe70ea 100644 --- a/src/MoonP/moon_ast.h +++ b/src/MoonP/moon_ast.h @@ -35,7 +35,15 @@ public: \ }; \ template<> constexpr int id() { return COUNTER_READ; } -AST_LEAF(Num) +AST_LEAF(Decimal) +AST_END(Decimal) + +AST_LEAF(Integer) +AST_END(Integer) + +AST_NODE(Num) + ast_sel num; + AST_MEMBER(Num, &num) AST_END(Num) AST_LEAF(Name) @@ -146,9 +154,29 @@ AST_NODE(ImportFrom) AST_MEMBER(ImportFrom, &sep, &names, &exp) AST_END(ImportFrom) +class MacroName_t; + +AST_NODE(macro_name_pair) + ast_ptr key; + ast_ptr value; + AST_MEMBER(macro_name_pair, &key, &value) +AST_END(macro_name_pair) + +AST_LEAF(import_all_macro) +AST_END(import_all_macro) + +class variable_pair_t; +class normal_pair_t; + +AST_NODE(ImportTabLit) + ast_ptr sep; + ast_sel_list items; + AST_MEMBER(ImportTabLit, &sep, &items) +AST_END(ImportTabLit) + AST_NODE(ImportAs) ast_ptr literal; - ast_sel target; + ast_sel target; AST_MEMBER(ImportAs, &literal, &target) AST_END(ImportAs) @@ -515,15 +543,9 @@ AST_END(Value) AST_LEAF(default_value) AST_END(default_value) -AST_NODE(macro_name_pair) - ast_ptr key; - ast_ptr value; - AST_MEMBER(macro_name_pair, &key, &value) -AST_END(macro_name_pair) - AST_NODE(TableLit) ast_ptr sep; - ast_sel_list values; + ast_sel_list values; AST_MEMBER(TableLit, &sep, &values) AST_END(TableLit) diff --git a/src/MoonP/moon_compiler.cpp b/src/MoonP/moon_compiler.cpp index 6e7db2c..f5835db 100644 --- a/src/MoonP/moon_compiler.cpp +++ b/src/MoonP/moon_compiler.cpp @@ -53,7 +53,7 @@ inline std::string s(std::string_view sv) { return std::string(sv); } -const std::string_view version = "0.4.16"sv; +const std::string_view version = "0.4.17"sv; const std::string_view extension = "mp"sv; class MoonCompilerImpl { @@ -4911,11 +4911,12 @@ private: auto name = moduleNameFrom(import->literal); import->target.set(toAst(name, x)); } - if (auto tableLit = import->target.as()) { - auto newTab = x->new_ptr(); + if (auto tabLit = import->target.as()) { + auto newTab = x->new_ptr(); #ifndef MOONP_NO_MACRO + bool importAllMacro = false; std::list> macroPairs; - for (auto item : tableLit->values.objects()) { + for (auto item : tabLit->items.objects()) { switch (item->getId()) { case id(): { auto macroName = static_cast(item); @@ -4925,21 +4926,27 @@ private: } case id(): { auto pair = static_cast(item); - macroPairs.emplace_back(_parser.toString(pair->value->name), _parser.toString(pair->key->name)); + macroPairs.emplace_back(_parser.toString(pair->key->name), _parser.toString(pair->value->name)); break; } - default: - newTab->values.push_back(item); + case id(): + if (importAllMacro) throw std::logic_error(_info.errorMessage(s("import all macro symbol duplicated"sv), item)); + importAllMacro = true; + break; + case id(): + case id(): + newTab->items.push_back(item); break; + default: assert(false); break; } } - if (!macroPairs.empty()) { + if (importAllMacro || !macroPairs.empty()) { auto moduleName = _parser.toString(import->literal); Utils::replace(moduleName, "'"sv, ""sv); Utils::replace(moduleName, "\""sv, ""sv); Utils::trim(moduleName); pushCurrentModule(); // cur - int top = lua_gettop(L) - 1; + int top = lua_gettop(L) - 1; // Lua state may be setup by pushCurrentModule() DEFER(lua_settop(L, top)); pushMoonp("find_modulepath"sv); // cur find_modulepath lua_pushlstring(L, moduleName.c_str(), moduleName.size()); // cur find_modulepath moduleName @@ -4977,27 +4984,38 @@ private: } lua_pop(L, 1); // cur } - pushModuleTable(moduleFullName); // cur module + pushModuleTable(moduleFullName); // cur mod + if (importAllMacro) { + lua_pushnil(L); // cur mod startKey + while (lua_next(L, -2) != 0) { // cur mod key value + lua_pushvalue(L, -2); // cur mod key value key + lua_insert(L, -2); // cur mod key key value + lua_rawset(L, -5); // cur[key] = value, cur mod key + } + } for (const auto& pair : macroPairs) { - lua_getfield(L, -1, pair.first.c_str()); - lua_setfield(L, -3, pair.second.c_str()); + lua_getfield(L, -1, pair.first.c_str()); // mod[first], cur mod val + lua_setfield(L, -3, pair.second.c_str()); // cur[second] = val, cur mod } } #else // MOONP_NO_MACRO - for (auto item : tableLit->values.objects()) { + for (auto item : tabLit->items.objects()) { switch (item->getId()) { case id(): - case id(): { + case id(): + case id(): { throw std::logic_error(_info.errorMessage("macro feature not supported"sv, item)); break; } - default: - newTab->values.push_back(item); + case id(): + case id(): + newTab->items.push_back(item); break; + default: assert(false); break; } } #endif // MOONP_NO_MACRO - if (newTab->values.empty()) { + if (newTab->items.empty()) { out.push_back(Empty); return; } else { @@ -5013,8 +5031,10 @@ private: chainValue->items.push_back(callable); value->item.set(chainValue); } else { - auto tableLit = ast_to(target); + auto tabLit = ast_to(target); auto simpleValue = x->new_ptr(); + auto tableLit = x->new_ptr(); + tableLit->values.dup(tabLit->items); simpleValue->value.set(tableLit); value->item.set(simpleValue); } diff --git a/src/MoonP/moon_parser.cpp b/src/MoonP/moon_parser.cpp index 41db324..6485e46 100644 --- a/src/MoonP/moon_parser.cpp +++ b/src/MoonP/moon_parser.cpp @@ -51,19 +51,23 @@ MoonParser::MoonParser() { EmptyLine = SpaceBreak; AlphaNum = range('a', 'z') | range('A', 'Z') | range('0', '9') | '_'; Name = (range('a', 'z') | range('A', 'Z') | '_') >> *AlphaNum; - Num = + Decimal = ( + ( + +range('0', '9') >> -('.' >> +range('0', '9')) + ) | ( + '.' >> +range('0', '9') + ) + ) >> -(set("eE") >> -expr('-') >> +range('0', '9')); + Integer = ( "0x" >> +(range('0', '9') | range('a', 'f') | range('A', 'F')) >> -(-set("uU") >> set("lL") >> set("lL")) ) | ( +range('0', '9') >> -set("uU") >> set("lL") >> set("lL") - ) | ( - ( - (+range('0', '9') >> -('.' >> +range('0', '9'))) | - ('.' >> +range('0', '9')) - ) >> -(set("eE") >> -expr('-') >> +range('0', '9')) ); + Num = Integer | Decimal; + Cut = false_(); Seperator = true_(); @@ -185,26 +189,28 @@ MoonParser::MoonParser() { colon_import_name = sym('\\') >> Space >> Variable; ImportName = colon_import_name | Space >> Variable; ImportNameList = Seperator >> *SpaceBreak >> ImportName >> *((+SpaceBreak | sym(',') >> *SpaceBreak) >> ImportName); + ImportFrom = ImportNameList >> *SpaceBreak >> key("from") >> Exp; import_literal_inner = (range('a', 'z') | range('A', 'Z') | set("_-")) >> *(AlphaNum | '-'); import_literal_chain = Seperator >> import_literal_inner >> *(expr('.') >> import_literal_inner); ImportLiteral = sym('\'') >> import_literal_chain >> symx('\'') | sym('"') >> import_literal_chain >> symx('"'); - ImportFrom = ImportNameList >> *SpaceBreak >> key("from") >> Exp; - - EnableMacroPair = pl::user(true_(), [](const item_t& item) { - State* st = reinterpret_cast(item.user_data); - st->macroPairEnabled = true; - return true; - }); - - DiableMacroPair = pl::user(true_(), [](const item_t& item) { - State* st = reinterpret_cast(item.user_data); - st->macroPairEnabled = false; - return true; - }); + macro_name_pair = Space >> MacroName >> Space >> symx(':') >> Space >> MacroName; + import_all_macro = expr('$'); + ImportTabItem = variable_pair | normal_pair | sym(':') >> MacroName | macro_name_pair | Space >> import_all_macro; + ImportTabList = ImportTabItem >> *(sym(',') >> ImportTabItem); + ImportTabLine = ( + PushIndent >> (ImportTabList >> PopIndent | PopIndent) + ) | Space; + import_tab_lines = SpaceBreak >> ImportTabLine >> *(-sym(',') >> SpaceBreak >> ImportTabLine) >> -sym(','); + ImportTabLit = + sym('{') >> Seperator >> + -ImportTabList >> + -sym(',') >> + -import_tab_lines >> + White >> sym('}'); - ImportAs = ImportLiteral >> -(key("as") >> (Space >> Variable | EnableMacroPair >> ensure(TableLit, DiableMacroPair))); + ImportAs = ImportLiteral >> -(key("as") >> (Space >> Variable | ImportTabLit)); Import = key("import") >> (ImportAs | ImportFrom); @@ -483,12 +489,7 @@ MoonParser::MoonParser() { symx(':') >> (Exp | TableBlock | +(SpaceBreak) >> Exp); - macro_name_pair = Space >> MacroName >> Space >> symx(':') >> Space >> MacroName; - - KeyValue = variable_pair | normal_pair | pl::user(sym(':') >> MacroName | macro_name_pair, [](const item_t& item) { - State* st = reinterpret_cast(item.user_data); - return st->macroPairEnabled; - }); + KeyValue = variable_pair | normal_pair; KeyValueList = KeyValue >> *(sym(',') >> KeyValue); KeyValueLine = CheckIndent >> (KeyValueList >> -sym(',') | TableBlockIndent | Space >> expr('*') >> Exp); diff --git a/src/MoonP/moon_parser.h b/src/MoonP/moon_parser.h index 6b7f224..bd62e86 100644 --- a/src/MoonP/moon_parser.h +++ b/src/MoonP/moon_parser.h @@ -75,7 +75,6 @@ protected: State() { indents.push(0); } - bool macroPairEnabled = false; bool exportDefault = false; int exportCount = 0; int moduleFix = 0; @@ -130,11 +129,13 @@ private: rule ImportName; rule ImportNameList; rule import_literal_chain; + rule ImportTabItem; + rule ImportTabList; + rule ImportTabLine; + rule import_tab_lines; rule WithExp; rule DisableDo; rule PopDo; - rule EnableMacroPair; - rule DiableMacroPair; rule SwitchElse; rule SwitchBlock; rule IfElseIf; @@ -182,6 +183,8 @@ private: rule Line; rule Shebang; + AST_RULE(Decimal) + AST_RULE(Integer) AST_RULE(Num) AST_RULE(Name) AST_RULE(Variable) @@ -204,6 +207,9 @@ private: AST_RULE(import_literal_inner) AST_RULE(ImportLiteral) AST_RULE(ImportFrom) + AST_RULE(macro_name_pair) + AST_RULE(import_all_macro) + AST_RULE(ImportTabLit) AST_RULE(ImportAs) AST_RULE(Import) AST_RULE(Label) @@ -275,7 +281,6 @@ private: AST_RULE(Export) AST_RULE(variable_pair) AST_RULE(normal_pair) - AST_RULE(macro_name_pair) AST_RULE(FnArgDef) AST_RULE(FnArgDefList) AST_RULE(outer_var_shadow) -- cgit v1.2.3-55-g6feb