diff options
Diffstat (limited to 'src/MoonP/moon_compiler.cpp')
| -rw-r--r-- | src/MoonP/moon_compiler.cpp | 56 |
1 files changed, 38 insertions, 18 deletions
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) { | |||
| 53 | return std::string(sv); | 53 | return std::string(sv); |
| 54 | } | 54 | } |
| 55 | 55 | ||
| 56 | const std::string_view version = "0.4.16"sv; | 56 | const std::string_view version = "0.4.17"sv; |
| 57 | const std::string_view extension = "mp"sv; | 57 | const std::string_view extension = "mp"sv; |
| 58 | 58 | ||
| 59 | class MoonCompilerImpl { | 59 | class MoonCompilerImpl { |
| @@ -4911,11 +4911,12 @@ private: | |||
| 4911 | auto name = moduleNameFrom(import->literal); | 4911 | auto name = moduleNameFrom(import->literal); |
| 4912 | import->target.set(toAst<Variable_t>(name, x)); | 4912 | import->target.set(toAst<Variable_t>(name, x)); |
| 4913 | } | 4913 | } |
| 4914 | if (auto tableLit = import->target.as<TableLit_t>()) { | 4914 | if (auto tabLit = import->target.as<ImportTabLit_t>()) { |
| 4915 | auto newTab = x->new_ptr<TableLit_t>(); | 4915 | auto newTab = x->new_ptr<ImportTabLit_t>(); |
| 4916 | #ifndef MOONP_NO_MACRO | 4916 | #ifndef MOONP_NO_MACRO |
| 4917 | bool importAllMacro = false; | ||
| 4917 | std::list<std::pair<std::string,std::string>> macroPairs; | 4918 | std::list<std::pair<std::string,std::string>> macroPairs; |
| 4918 | for (auto item : tableLit->values.objects()) { | 4919 | for (auto item : tabLit->items.objects()) { |
| 4919 | switch (item->getId()) { | 4920 | switch (item->getId()) { |
| 4920 | case id<MacroName_t>(): { | 4921 | case id<MacroName_t>(): { |
| 4921 | auto macroName = static_cast<MacroName_t*>(item); | 4922 | auto macroName = static_cast<MacroName_t*>(item); |
| @@ -4925,21 +4926,27 @@ private: | |||
| 4925 | } | 4926 | } |
| 4926 | case id<macro_name_pair_t>(): { | 4927 | case id<macro_name_pair_t>(): { |
| 4927 | auto pair = static_cast<macro_name_pair_t*>(item); | 4928 | auto pair = static_cast<macro_name_pair_t*>(item); |
| 4928 | macroPairs.emplace_back(_parser.toString(pair->value->name), _parser.toString(pair->key->name)); | 4929 | macroPairs.emplace_back(_parser.toString(pair->key->name), _parser.toString(pair->value->name)); |
| 4929 | break; | 4930 | break; |
| 4930 | } | 4931 | } |
| 4931 | default: | 4932 | case id<import_all_macro_t>(): |
| 4932 | newTab->values.push_back(item); | 4933 | if (importAllMacro) throw std::logic_error(_info.errorMessage(s("import all macro symbol duplicated"sv), item)); |
| 4934 | importAllMacro = true; | ||
| 4935 | break; | ||
| 4936 | case id<variable_pair_t>(): | ||
| 4937 | case id<normal_pair_t>(): | ||
| 4938 | newTab->items.push_back(item); | ||
| 4933 | break; | 4939 | break; |
| 4940 | default: assert(false); break; | ||
| 4934 | } | 4941 | } |
| 4935 | } | 4942 | } |
| 4936 | if (!macroPairs.empty()) { | 4943 | if (importAllMacro || !macroPairs.empty()) { |
| 4937 | auto moduleName = _parser.toString(import->literal); | 4944 | auto moduleName = _parser.toString(import->literal); |
| 4938 | Utils::replace(moduleName, "'"sv, ""sv); | 4945 | Utils::replace(moduleName, "'"sv, ""sv); |
| 4939 | Utils::replace(moduleName, "\""sv, ""sv); | 4946 | Utils::replace(moduleName, "\""sv, ""sv); |
| 4940 | Utils::trim(moduleName); | 4947 | Utils::trim(moduleName); |
| 4941 | pushCurrentModule(); // cur | 4948 | pushCurrentModule(); // cur |
| 4942 | int top = lua_gettop(L) - 1; | 4949 | int top = lua_gettop(L) - 1; // Lua state may be setup by pushCurrentModule() |
| 4943 | DEFER(lua_settop(L, top)); | 4950 | DEFER(lua_settop(L, top)); |
| 4944 | pushMoonp("find_modulepath"sv); // cur find_modulepath | 4951 | pushMoonp("find_modulepath"sv); // cur find_modulepath |
| 4945 | lua_pushlstring(L, moduleName.c_str(), moduleName.size()); // cur find_modulepath moduleName | 4952 | lua_pushlstring(L, moduleName.c_str(), moduleName.size()); // cur find_modulepath moduleName |
| @@ -4977,27 +4984,38 @@ private: | |||
| 4977 | } | 4984 | } |
| 4978 | lua_pop(L, 1); // cur | 4985 | lua_pop(L, 1); // cur |
| 4979 | } | 4986 | } |
| 4980 | pushModuleTable(moduleFullName); // cur module | 4987 | pushModuleTable(moduleFullName); // cur mod |
| 4988 | if (importAllMacro) { | ||
| 4989 | lua_pushnil(L); // cur mod startKey | ||
| 4990 | while (lua_next(L, -2) != 0) { // cur mod key value | ||
| 4991 | lua_pushvalue(L, -2); // cur mod key value key | ||
| 4992 | lua_insert(L, -2); // cur mod key key value | ||
| 4993 | lua_rawset(L, -5); // cur[key] = value, cur mod key | ||
| 4994 | } | ||
| 4995 | } | ||
| 4981 | for (const auto& pair : macroPairs) { | 4996 | for (const auto& pair : macroPairs) { |
| 4982 | lua_getfield(L, -1, pair.first.c_str()); | 4997 | lua_getfield(L, -1, pair.first.c_str()); // mod[first], cur mod val |
| 4983 | lua_setfield(L, -3, pair.second.c_str()); | 4998 | lua_setfield(L, -3, pair.second.c_str()); // cur[second] = val, cur mod |
| 4984 | } | 4999 | } |
| 4985 | } | 5000 | } |
| 4986 | #else // MOONP_NO_MACRO | 5001 | #else // MOONP_NO_MACRO |
| 4987 | for (auto item : tableLit->values.objects()) { | 5002 | for (auto item : tabLit->items.objects()) { |
| 4988 | switch (item->getId()) { | 5003 | switch (item->getId()) { |
| 4989 | case id<MacroName_t>(): | 5004 | case id<MacroName_t>(): |
| 4990 | case id<macro_name_pair_t>(): { | 5005 | case id<macro_name_pair_t>(): |
| 5006 | case id<import_all_macro_t>(): { | ||
| 4991 | throw std::logic_error(_info.errorMessage("macro feature not supported"sv, item)); | 5007 | throw std::logic_error(_info.errorMessage("macro feature not supported"sv, item)); |
| 4992 | break; | 5008 | break; |
| 4993 | } | 5009 | } |
| 4994 | default: | 5010 | case id<variable_pair_t>(): |
| 4995 | newTab->values.push_back(item); | 5011 | case id<normal_pair_t>(): |
| 5012 | newTab->items.push_back(item); | ||
| 4996 | break; | 5013 | break; |
| 5014 | default: assert(false); break; | ||
| 4997 | } | 5015 | } |
| 4998 | } | 5016 | } |
| 4999 | #endif // MOONP_NO_MACRO | 5017 | #endif // MOONP_NO_MACRO |
| 5000 | if (newTab->values.empty()) { | 5018 | if (newTab->items.empty()) { |
| 5001 | out.push_back(Empty); | 5019 | out.push_back(Empty); |
| 5002 | return; | 5020 | return; |
| 5003 | } else { | 5021 | } else { |
| @@ -5013,8 +5031,10 @@ private: | |||
| 5013 | chainValue->items.push_back(callable); | 5031 | chainValue->items.push_back(callable); |
| 5014 | value->item.set(chainValue); | 5032 | value->item.set(chainValue); |
| 5015 | } else { | 5033 | } else { |
| 5016 | auto tableLit = ast_to<TableLit_t>(target); | 5034 | auto tabLit = ast_to<ImportTabLit_t>(target); |
| 5017 | auto simpleValue = x->new_ptr<SimpleValue_t>(); | 5035 | auto simpleValue = x->new_ptr<SimpleValue_t>(); |
| 5036 | auto tableLit = x->new_ptr<TableLit_t>(); | ||
| 5037 | tableLit->values.dup(tabLit->items); | ||
| 5018 | simpleValue->value.set(tableLit); | 5038 | simpleValue->value.set(tableLit); |
| 5019 | value->item.set(simpleValue); | 5039 | value->item.set(simpleValue); |
| 5020 | } | 5040 | } |
