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. --- src/MoonP/moon_compiler.cpp | 56 ++++++++++++++++++++++++++++++--------------- 1 file changed, 38 insertions(+), 18 deletions(-) (limited to 'src/MoonP/moon_compiler.cpp') 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); } -- cgit v1.2.3-55-g6feb