diff options
Diffstat (limited to '')
| -rw-r--r-- | src/MoonP/moon_compiler.cpp | 85 | ||||
| -rw-r--r-- | src/MoonP/moon_parser.cpp | 6 | ||||
| -rw-r--r-- | src/MoonP/stacktraceplus.h | 17 |
3 files changed, 67 insertions, 41 deletions
diff --git a/src/MoonP/moon_compiler.cpp b/src/MoonP/moon_compiler.cpp index 00b897d..c176c01 100644 --- a/src/MoonP/moon_compiler.cpp +++ b/src/MoonP/moon_compiler.cpp | |||
| @@ -43,7 +43,7 @@ inline std::string s(std::string_view sv) { | |||
| 43 | } | 43 | } |
| 44 | 44 | ||
| 45 | const char* moonScriptVersion() { | 45 | const char* moonScriptVersion() { |
| 46 | return "0.5.0-r0.3.3"; | 46 | return "0.5.0-r0.3.4"; |
| 47 | } | 47 | } |
| 48 | 48 | ||
| 49 | // name of table stored in lua registry | 49 | // name of table stored in lua registry |
| @@ -58,11 +58,11 @@ public: | |||
| 58 | L(sharedState), | 58 | L(sharedState), |
| 59 | _luaOpen(luaOpen), | 59 | _luaOpen(luaOpen), |
| 60 | _moduleName(moduleName) { | 60 | _moduleName(moduleName) { |
| 61 | int top = -1; | ||
| 62 | BLOCK_START | 61 | BLOCK_START |
| 63 | BREAK_IF(!sameModule); | 62 | BREAK_IF(!sameModule); |
| 64 | BREAK_IF(!L); | 63 | BREAK_IF(!L); |
| 65 | top = lua_gettop(L); | 64 | int top = lua_gettop(L); |
| 65 | DEFER(lua_settop(L, top)); | ||
| 66 | lua_pushliteral(L, MOONP_MODULE); // MOONP_MODULE | 66 | lua_pushliteral(L, MOONP_MODULE); // MOONP_MODULE |
| 67 | lua_rawget(L, LUA_REGISTRYINDEX); // reg[MOONP_MODULE], tb | 67 | lua_rawget(L, LUA_REGISTRYINDEX); // reg[MOONP_MODULE], tb |
| 68 | BREAK_IF(lua_istable(L, -1) == 0); | 68 | BREAK_IF(lua_istable(L, -1) == 0); |
| @@ -71,7 +71,6 @@ public: | |||
| 71 | _useModule = true; | 71 | _useModule = true; |
| 72 | _sameModule = true; | 72 | _sameModule = true; |
| 73 | BLOCK_END | 73 | BLOCK_END |
| 74 | if (top != -1) lua_settop(L, top); | ||
| 75 | } | 74 | } |
| 76 | 75 | ||
| 77 | ~MoonCompilerImpl() { | 76 | ~MoonCompilerImpl() { |
| @@ -2095,15 +2094,14 @@ private: | |||
| 2095 | 2094 | ||
| 2096 | bool isModuleLoaded(std::string_view name) { | 2095 | bool isModuleLoaded(std::string_view name) { |
| 2097 | int top = lua_gettop(L); | 2096 | int top = lua_gettop(L); |
| 2097 | DEFER(lua_settop(L, top)); | ||
| 2098 | lua_pushliteral(L, MOONP_MODULE); // MOONP_MODULE | 2098 | lua_pushliteral(L, MOONP_MODULE); // MOONP_MODULE |
| 2099 | lua_rawget(L, LUA_REGISTRYINDEX); // modules | 2099 | lua_rawget(L, LUA_REGISTRYINDEX); // modules |
| 2100 | lua_pushlstring(L, &name.front(), name.size()); | 2100 | lua_pushlstring(L, &name.front(), name.size()); |
| 2101 | lua_rawget(L, -2); // modules module | 2101 | lua_rawget(L, -2); // modules module |
| 2102 | if (lua_isnil(L, -1) != 0) { | 2102 | if (lua_isnil(L, -1) != 0) { |
| 2103 | lua_settop(L, top); | ||
| 2104 | return false; | 2103 | return false; |
| 2105 | } | 2104 | } |
| 2106 | lua_settop(L, top); | ||
| 2107 | return true; | 2105 | return true; |
| 2108 | } | 2106 | } |
| 2109 | 2107 | ||
| @@ -2153,7 +2151,7 @@ private: | |||
| 2153 | for (auto def_ : argsDef->definitions.objects()) { | 2151 | for (auto def_ : argsDef->definitions.objects()) { |
| 2154 | auto def = static_cast<FnArgDef_t*>(def_); | 2152 | auto def = static_cast<FnArgDef_t*>(def_); |
| 2155 | if (def->name.is<SelfName_t>()) { | 2153 | if (def->name.is<SelfName_t>()) { |
| 2156 | throw std::logic_error(_info.errorMessage("self name is not supported here"sv, def->name)); | 2154 | throw std::logic_error(_info.errorMessage("self name is not supported for macro function argument"sv, def->name)); |
| 2157 | } else { | 2155 | } else { |
| 2158 | std::string defVal; | 2156 | std::string defVal; |
| 2159 | if (def->defaultValue) { | 2157 | if (def->defaultValue) { |
| @@ -2177,18 +2175,17 @@ private: | |||
| 2177 | auto chunkName = clearBuf(); | 2175 | auto chunkName = clearBuf(); |
| 2178 | pushCurrentModule(); // cur | 2176 | pushCurrentModule(); // cur |
| 2179 | int top = lua_gettop(L) - 1; | 2177 | int top = lua_gettop(L) - 1; |
| 2178 | DEFER(lua_settop(L, top)); | ||
| 2180 | pushMoonp("loadstring"sv); // cur loadstring | 2179 | pushMoonp("loadstring"sv); // cur loadstring |
| 2181 | lua_pushlstring(L, macroCodes.c_str(), macroCodes.size()); // cur loadstring codes | 2180 | lua_pushlstring(L, macroCodes.c_str(), macroCodes.size()); // cur loadstring codes |
| 2182 | lua_pushlstring(L, chunkName.c_str(), chunkName.size()); // cur loadstring codes chunk | 2181 | lua_pushlstring(L, chunkName.c_str(), chunkName.size()); // cur loadstring codes chunk |
| 2183 | pushOptions(macro->m_begin.m_line - 1); // cur loadstring codes chunk options | 2182 | pushOptions(macro->m_begin.m_line - 1); // cur loadstring codes chunk options |
| 2184 | if (lua_pcall(L, 3, 2, 0) != 0) { // loadstring(codes,chunk,options), cur f err | 2183 | if (lua_pcall(L, 3, 2, 0) != 0) { // loadstring(codes,chunk,options), cur f err |
| 2185 | std::string err = lua_tostring(L, -1); | 2184 | std::string err = lua_tostring(L, -1); |
| 2186 | lua_settop(L, top); | ||
| 2187 | throw std::logic_error(_info.errorMessage(s("fail to load macro codes\n"sv) + err, macro->macroLit)); | 2185 | throw std::logic_error(_info.errorMessage(s("fail to load macro codes\n"sv) + err, macro->macroLit)); |
| 2188 | } // cur f err | 2186 | } // cur f err |
| 2189 | if (lua_isnil(L, -2) != 0) { // f == nil, cur f err | 2187 | if (lua_isnil(L, -2) != 0) { // f == nil, cur f err |
| 2190 | std::string err = lua_tostring(L, -1); | 2188 | std::string err = lua_tostring(L, -1); |
| 2191 | lua_settop(L, top); | ||
| 2192 | throw std::logic_error(_info.errorMessage(s("fail to load macro codes, at (macro "sv) + macroName + s("): "sv) + err, macro->macroLit)); | 2189 | throw std::logic_error(_info.errorMessage(s("fail to load macro codes, at (macro "sv) + macroName + s("): "sv) + err, macro->macroLit)); |
| 2193 | } | 2190 | } |
| 2194 | lua_pop(L, 1); // cur f | 2191 | lua_pop(L, 1); // cur f |
| @@ -2196,12 +2193,10 @@ private: | |||
| 2196 | lua_insert(L, -2); // cur pcall f | 2193 | lua_insert(L, -2); // cur pcall f |
| 2197 | if (lua_pcall(L, 1, 2, 0) != 0) { // f(), cur success macro | 2194 | if (lua_pcall(L, 1, 2, 0) != 0) { // f(), cur success macro |
| 2198 | std::string err = lua_tostring(L, -1); | 2195 | std::string err = lua_tostring(L, -1); |
| 2199 | lua_settop(L, top); | ||
| 2200 | throw std::logic_error(_info.errorMessage(s("fail to generate macro function\n"sv) + err, macro->macroLit)); | 2196 | throw std::logic_error(_info.errorMessage(s("fail to generate macro function\n"sv) + err, macro->macroLit)); |
| 2201 | } // cur success res | 2197 | } // cur success res |
| 2202 | if (lua_toboolean(L, -2) == 0) { | 2198 | if (lua_toboolean(L, -2) == 0) { |
| 2203 | std::string err = lua_tostring(L, -1); | 2199 | std::string err = lua_tostring(L, -1); |
| 2204 | lua_settop(L, top); | ||
| 2205 | throw std::logic_error(_info.errorMessage(s("fail to generate macro function\n"sv) + err, macro->macroLit)); | 2200 | throw std::logic_error(_info.errorMessage(s("fail to generate macro function\n"sv) + err, macro->macroLit)); |
| 2206 | } // cur true macro | 2201 | } // cur true macro |
| 2207 | lua_remove(L, -2); // cur macro | 2202 | lua_remove(L, -2); // cur macro |
| @@ -2215,7 +2210,6 @@ private: | |||
| 2215 | lua_pushlstring(L, macroName.c_str(), macroName.size()); // cur macro name | 2210 | lua_pushlstring(L, macroName.c_str(), macroName.size()); // cur macro name |
| 2216 | lua_insert(L, -2); // cur name macro | 2211 | lua_insert(L, -2); // cur name macro |
| 2217 | lua_rawset(L, -3); // cur[name] = macro, cur | 2212 | lua_rawset(L, -3); // cur[name] = macro, cur |
| 2218 | lua_settop(L, top); | ||
| 2219 | out.push_back(Empty); | 2213 | out.push_back(Empty); |
| 2220 | } | 2214 | } |
| 2221 | 2215 | ||
| @@ -2935,10 +2929,10 @@ private: | |||
| 2935 | } | 2929 | } |
| 2936 | pushCurrentModule(); // cur | 2930 | pushCurrentModule(); // cur |
| 2937 | int top = lua_gettop(L) - 1; | 2931 | int top = lua_gettop(L) - 1; |
| 2932 | DEFER(lua_settop(L, top)); | ||
| 2938 | lua_pushlstring(L, macroName.c_str(), macroName.size()); // cur macroName | 2933 | lua_pushlstring(L, macroName.c_str(), macroName.size()); // cur macroName |
| 2939 | lua_rawget(L, -2); // cur[macroName], cur macro | 2934 | lua_rawget(L, -2); // cur[macroName], cur macro |
| 2940 | if (lua_istable(L, -1) == 0) { | 2935 | if (lua_istable(L, -1) == 0) { |
| 2941 | lua_settop(L, top); | ||
| 2942 | throw std::logic_error(_info.errorMessage("can not resolve macro"sv, x)); | 2936 | throw std::logic_error(_info.errorMessage("can not resolve macro"sv, x)); |
| 2943 | } | 2937 | } |
| 2944 | lua_rawgeti(L, -1, 1); // cur macro func | 2938 | lua_rawgeti(L, -1, 1); // cur macro func |
| @@ -2968,9 +2962,23 @@ private: | |||
| 2968 | str = codes; | 2962 | str = codes; |
| 2969 | BLOCK_END | 2963 | BLOCK_END |
| 2970 | if (str.empty()) { | 2964 | if (str.empty()) { |
| 2971 | str = _parser.toString(exp->value); | 2965 | bool multiLineStr = false; |
| 2972 | for (auto opVal : exp->opValues.objects()) { | 2966 | BLOCK_START |
| 2973 | str += _parser.toString(opVal); | 2967 | auto value = singleValueFrom(exp); |
| 2968 | BREAK_IF(!value); | ||
| 2969 | auto lstr = value->getByPath<String_t, LuaString_t>(); | ||
| 2970 | BREAK_IF(!lstr); | ||
| 2971 | str = _parser.toString(lstr->content); | ||
| 2972 | multiLineStr = true; | ||
| 2973 | BLOCK_END | ||
| 2974 | if (!multiLineStr) { | ||
| 2975 | // convert sub nodes to strings in case exp is assembled | ||
| 2976 | // in transform stage, the toString() function won't be able | ||
| 2977 | // to convert its whole content | ||
| 2978 | str = _parser.toString(exp->value); | ||
| 2979 | for (auto opVal : exp->opValues.objects()) { | ||
| 2980 | str += _parser.toString(opVal); | ||
| 2981 | } | ||
| 2974 | } | 2982 | } |
| 2975 | } | 2983 | } |
| 2976 | } else str = _parser.toString(arg); | 2984 | } else str = _parser.toString(arg); |
| @@ -2981,39 +2989,48 @@ private: | |||
| 2981 | bool success = lua_pcall(L, static_cast<int>(args->size()) + 1, 2, 0) == 0; | 2989 | bool success = lua_pcall(L, static_cast<int>(args->size()) + 1, 2, 0) == 0; |
| 2982 | if (!success) { // cur macro err | 2990 | if (!success) { // cur macro err |
| 2983 | std::string err = lua_tostring(L, -1); | 2991 | std::string err = lua_tostring(L, -1); |
| 2984 | lua_settop(L, top); | ||
| 2985 | throw std::logic_error(_info.errorMessage(s("fail to expand macro: "sv) + err, x)); | 2992 | throw std::logic_error(_info.errorMessage(s("fail to expand macro: "sv) + err, x)); |
| 2986 | } // cur macro success res | 2993 | } // cur macro success res |
| 2987 | if (lua_toboolean(L, -2) == 0) { | 2994 | if (lua_toboolean(L, -2) == 0) { |
| 2988 | std::string err = lua_tostring(L, -1); | 2995 | std::string err = lua_tostring(L, -1); |
| 2989 | lua_settop(L, top); | ||
| 2990 | throw std::logic_error(_info.errorMessage(s("fail to expand macro: "sv) + err, x)); | 2996 | throw std::logic_error(_info.errorMessage(s("fail to expand macro: "sv) + err, x)); |
| 2991 | } | 2997 | } |
| 2992 | lua_remove(L, -2); // cur macro res | 2998 | lua_remove(L, -2); // cur macro res |
| 2993 | if (lua_isstring(L, -1) == 0) { | 2999 | if (lua_isstring(L, -1) == 0) { |
| 2994 | lua_settop(L, top); | ||
| 2995 | throw std::logic_error(_info.errorMessage(s("macro function must return string with expanded codes"sv), x)); | 3000 | throw std::logic_error(_info.errorMessage(s("macro function must return string with expanded codes"sv), x)); |
| 2996 | } // cur macro codes | 3001 | } // cur macro codes |
| 2997 | lua_rawgeti(L, -2, 2); // cur macro codes type | 3002 | lua_rawgeti(L, -2, 2); // cur macro codes type |
| 2998 | std::string type = lua_tostring(L, -1); | 3003 | std::string type = lua_tostring(L, -1); |
| 2999 | std::string codes = lua_tostring(L, -2); | 3004 | std::string codes = lua_tostring(L, -2); |
| 3000 | lua_settop(L, top); | ||
| 3001 | return {type, codes}; | 3005 | return {type, codes}; |
| 3002 | } | 3006 | } |
| 3003 | 3007 | ||
| 3004 | std::pair<ast_ptr<false,ast_node>, std::unique_ptr<input>> expandMacro(ChainValue_t* chainValue, ExpUsage usage) { | 3008 | std::tuple<ast_ptr<false,ast_node>, std::unique_ptr<input>, std::string> expandMacro(ChainValue_t* chainValue, ExpUsage usage) { |
| 3005 | auto x = ast_to<Callable_t>(chainValue->items.front())->item.to<MacroName_t>(); | 3009 | auto x = ast_to<Callable_t>(chainValue->items.front())->item.to<MacroName_t>(); |
| 3006 | const auto& chainList = chainValue->items.objects(); | 3010 | const auto& chainList = chainValue->items.objects(); |
| 3007 | std::string type, codes; | 3011 | std::string type, codes; |
| 3008 | std::tie(type, codes) = expandMacroStr(chainValue); | 3012 | std::tie(type, codes) = expandMacroStr(chainValue); |
| 3009 | std::string targetType(usage != ExpUsage::Common || chainList.size() > 2 ? "expr"sv : "block"sv); | 3013 | std::string targetType(usage != ExpUsage::Common || chainList.size() > 2 ? "expr"sv : "block"sv); |
| 3014 | if (type == "lua"sv) { | ||
| 3015 | if (targetType != "block"sv) { | ||
| 3016 | throw std::logic_error(_info.errorMessage("lua macro can only be placed where block macro is allowed"sv, x)); | ||
| 3017 | } | ||
| 3018 | auto macroChunk = s("=(macro "sv) + _parser.toString(x->name) + ')'; | ||
| 3019 | int top = lua_gettop(L); | ||
| 3020 | DEFER(lua_settop(L, top)); | ||
| 3021 | if (luaL_loadbuffer(L, codes.c_str(), codes.size(), macroChunk.c_str()) != 0) { | ||
| 3022 | std::string err = lua_tostring(L, -1); | ||
| 3023 | throw std::logic_error(_info.errorMessage(err, x)); | ||
| 3024 | } | ||
| 3025 | return {nullptr, nullptr, std::move(codes)}; | ||
| 3026 | } | ||
| 3010 | if (type != targetType) { | 3027 | if (type != targetType) { |
| 3011 | throw std::logic_error(_info.errorMessage(s("macro type mismatch, "sv) + targetType + s(" expected, got "sv) + type, x)); | 3028 | throw std::logic_error(_info.errorMessage(s("macro type mismatch, "sv) + targetType + s(" expected, got "sv) + type, x)); |
| 3012 | } | 3029 | } |
| 3013 | ParseInfo info; | 3030 | ParseInfo info; |
| 3014 | if (usage == ExpUsage::Common) { | 3031 | if (usage == ExpUsage::Common) { |
| 3015 | if (codes.empty()) { | 3032 | if (codes.empty()) { |
| 3016 | return {x->new_ptr<Block_t>().get(),std::move(info.codes)}; | 3033 | return {x->new_ptr<Block_t>().get(), std::move(info.codes), Empty}; |
| 3017 | } | 3034 | } |
| 3018 | if (type == "expr"sv) { | 3035 | if (type == "expr"sv) { |
| 3019 | info = _parser.parse<Exp_t>(codes); | 3036 | info = _parser.parse<Exp_t>(codes); |
| @@ -3070,14 +3087,27 @@ private: | |||
| 3070 | info.node.set(exp); | 3087 | info.node.set(exp); |
| 3071 | } | 3088 | } |
| 3072 | } | 3089 | } |
| 3073 | return {info.node,std::move(info.codes)}; | 3090 | return {info.node, std::move(info.codes), Empty}; |
| 3074 | } | 3091 | } |
| 3075 | 3092 | ||
| 3076 | void transformChainValue(ChainValue_t* chainValue, str_list& out, ExpUsage usage, ExpList_t* assignList = nullptr) { | 3093 | void transformChainValue(ChainValue_t* chainValue, str_list& out, ExpUsage usage, ExpList_t* assignList = nullptr) { |
| 3077 | if (isMacroChain(chainValue)) { | 3094 | if (isMacroChain(chainValue)) { |
| 3078 | ast_ptr<false,ast_node> node; | 3095 | ast_ptr<false,ast_node> node; |
| 3079 | std::unique_ptr<input> codes; | 3096 | std::unique_ptr<input> codes; |
| 3080 | std::tie(node, codes) = expandMacro(chainValue, usage); | 3097 | std::string luaCodes; |
| 3098 | std::tie(node, codes, luaCodes) = expandMacro(chainValue, usage); | ||
| 3099 | Utils::replace(luaCodes, "\r\n"sv, "\n"sv); | ||
| 3100 | Utils::trim(luaCodes); | ||
| 3101 | if (!node && !codes) { | ||
| 3102 | if (!luaCodes.empty()) { | ||
| 3103 | if (_config.reserveLineNumber) { | ||
| 3104 | luaCodes.insert(0, nll(chainValue).substr(1)); | ||
| 3105 | } | ||
| 3106 | luaCodes.append(nlr(chainValue)); | ||
| 3107 | } | ||
| 3108 | out.push_back(luaCodes); | ||
| 3109 | return; | ||
| 3110 | } | ||
| 3081 | if (usage == ExpUsage::Common) { | 3111 | if (usage == ExpUsage::Common) { |
| 3082 | transformBlock(node.to<Block_t>(), out, usage, assignList); | 3112 | transformBlock(node.to<Block_t>(), out, usage, assignList); |
| 3083 | } else { | 3113 | } else { |
| @@ -4700,15 +4730,14 @@ private: | |||
| 4700 | Utils::trim(moduleName); | 4730 | Utils::trim(moduleName); |
| 4701 | pushCurrentModule(); // cur | 4731 | pushCurrentModule(); // cur |
| 4702 | int top = lua_gettop(L) - 1; | 4732 | int top = lua_gettop(L) - 1; |
| 4733 | DEFER(lua_settop(L, top)); | ||
| 4703 | pushMoonp("find_modulepath"sv); // cur find_modulepath | 4734 | pushMoonp("find_modulepath"sv); // cur find_modulepath |
| 4704 | lua_pushlstring(L, moduleName.c_str(), moduleName.size()); // cur find_modulepath moduleName | 4735 | lua_pushlstring(L, moduleName.c_str(), moduleName.size()); // cur find_modulepath moduleName |
| 4705 | if (lua_pcall(L, 1, 1, 0) != 0) { | 4736 | if (lua_pcall(L, 1, 1, 0) != 0) { |
| 4706 | std::string err = lua_tostring(L, -1); | 4737 | std::string err = lua_tostring(L, -1); |
| 4707 | lua_settop(L, top); | ||
| 4708 | throw std::logic_error(_info.errorMessage(s("fail to resolve module path\n"sv) + err, x)); | 4738 | throw std::logic_error(_info.errorMessage(s("fail to resolve module path\n"sv) + err, x)); |
| 4709 | } | 4739 | } |
| 4710 | if (lua_isnil(L, -1) != 0) { | 4740 | if (lua_isnil(L, -1) != 0) { |
| 4711 | lua_settop(L, top); | ||
| 4712 | throw std::logic_error(_info.errorMessage(s("fail to find module '"sv) + moduleName + '\'', x)); | 4741 | throw std::logic_error(_info.errorMessage(s("fail to find module '"sv) + moduleName + '\'', x)); |
| 4713 | } | 4742 | } |
| 4714 | std::string moduleFullName = lua_tostring(L, -1); | 4743 | std::string moduleFullName = lua_tostring(L, -1); |
| @@ -4718,11 +4747,9 @@ private: | |||
| 4718 | lua_pushlstring(L, moduleFullName.c_str(), moduleFullName.size()); // cur load_text moduleFullName | 4747 | lua_pushlstring(L, moduleFullName.c_str(), moduleFullName.size()); // cur load_text moduleFullName |
| 4719 | if (lua_pcall(L, 1, 1, 0) != 0) { | 4748 | if (lua_pcall(L, 1, 1, 0) != 0) { |
| 4720 | std::string err = lua_tostring(L, -1); | 4749 | std::string err = lua_tostring(L, -1); |
| 4721 | lua_settop(L, top); | ||
| 4722 | throw std::logic_error(_info.errorMessage(s("fail to read module file\n"sv) + err, x)); | 4750 | throw std::logic_error(_info.errorMessage(s("fail to read module file\n"sv) + err, x)); |
| 4723 | } // cur text | 4751 | } // cur text |
| 4724 | if (lua_isnil(L, -1) != 0) { | 4752 | if (lua_isnil(L, -1) != 0) { |
| 4725 | lua_settop(L, top); | ||
| 4726 | throw std::logic_error(_info.errorMessage("fail to get module text"sv, x)); | 4753 | throw std::logic_error(_info.errorMessage("fail to get module text"sv, x)); |
| 4727 | } // cur text | 4754 | } // cur text |
| 4728 | std::string text = lua_tostring(L, -1); | 4755 | std::string text = lua_tostring(L, -1); |
| @@ -4736,7 +4763,6 @@ private: | |||
| 4736 | GlobalVars globals; | 4763 | GlobalVars globals; |
| 4737 | std::tie(codes, err, globals) = compiler.compile(text, config); | 4764 | std::tie(codes, err, globals) = compiler.compile(text, config); |
| 4738 | if (codes.empty() && !err.empty()) { | 4765 | if (codes.empty() && !err.empty()) { |
| 4739 | lua_settop(L, top); | ||
| 4740 | throw std::logic_error(_info.errorMessage(s("fail to compile module '"sv) + moduleName + s("\': "sv) + err, x)); | 4766 | throw std::logic_error(_info.errorMessage(s("fail to compile module '"sv) + moduleName + s("\': "sv) + err, x)); |
| 4741 | } | 4767 | } |
| 4742 | lua_pop(L, 1); // cur | 4768 | lua_pop(L, 1); // cur |
| @@ -4746,7 +4772,6 @@ private: | |||
| 4746 | lua_getfield(L, -1, pair.first.c_str()); | 4772 | lua_getfield(L, -1, pair.first.c_str()); |
| 4747 | lua_setfield(L, -3, pair.second.c_str()); | 4773 | lua_setfield(L, -3, pair.second.c_str()); |
| 4748 | } | 4774 | } |
| 4749 | lua_settop(L, top); | ||
| 4750 | } | 4775 | } |
| 4751 | if (newTab->values.empty()) { | 4776 | if (newTab->values.empty()) { |
| 4752 | out.push_back(Empty); | 4777 | out.push_back(Empty); |
diff --git a/src/MoonP/moon_parser.cpp b/src/MoonP/moon_parser.cpp index f0269d7..c8a3a23 100644 --- a/src/MoonP/moon_parser.cpp +++ b/src/MoonP/moon_parser.cpp | |||
| @@ -472,7 +472,7 @@ MoonParser::MoonParser() { | |||
| 472 | FunLit = -FnArgsDef >> Space >> fn_arrow >> -Body; | 472 | FunLit = -FnArgsDef >> Space >> fn_arrow >> -Body; |
| 473 | 473 | ||
| 474 | MacroName = expr('$') >> Name; | 474 | MacroName = expr('$') >> Name; |
| 475 | macro_type = expr("expr") | expr("block"); | 475 | macro_type = expr("expr") | expr("block") | expr("lua"); |
| 476 | macro_args_def = sym('(') >> White >> -FnArgDefList >> White >> sym(')'); | 476 | macro_args_def = sym('(') >> White >> -FnArgDefList >> White >> sym(')'); |
| 477 | MacroLit = -macro_args_def >> Space >> expr("->") >> Body; | 477 | MacroLit = -macro_args_def >> Space >> expr("->") >> Body; |
| 478 | Macro = key("macro") >> Space >> macro_type >> Space >> Name >> sym('=') >> MacroLit; | 478 | Macro = key("macro") >> Space >> macro_type >> Space >> Name >> sym('=') >> MacroLit; |
| @@ -608,8 +608,8 @@ namespace Utils { | |||
| 608 | 608 | ||
| 609 | void trim(std::string& str) { | 609 | void trim(std::string& str) { |
| 610 | if (str.empty()) return; | 610 | if (str.empty()) return; |
| 611 | str.erase(0, str.find_first_not_of(" \t")); | 611 | str.erase(0, str.find_first_not_of(" \t\n")); |
| 612 | str.erase(str.find_last_not_of(" \t") + 1); | 612 | str.erase(str.find_last_not_of(" \t\n") + 1); |
| 613 | } | 613 | } |
| 614 | } | 614 | } |
| 615 | 615 | ||
diff --git a/src/MoonP/stacktraceplus.h b/src/MoonP/stacktraceplus.h index fcd887a..ea53885 100644 --- a/src/MoonP/stacktraceplus.h +++ b/src/MoonP/stacktraceplus.h | |||
| @@ -334,16 +334,17 @@ local function getMoonLineNumber(fname, line) | |||
| 334 | end | 334 | end |
| 335 | end | 335 | end |
| 336 | if source then | 336 | if source then |
| 337 | local i, target = 1, tonumber(line) | 337 | local current, target = 1, tonumber(line) |
| 338 | local findLine = line | ||
| 338 | for lineCode in source:gmatch("([^\n]*)\n") do | 339 | for lineCode in source:gmatch("([^\n]*)\n") do |
| 339 | if i == target then | 340 | local num = lineCode:match("--%s*(%d+)%s*$") |
| 340 | local num = lineCode:match("--%s*(%d*)%s*$") | 341 | if num then |
| 341 | if num then | 342 | findLine = num |
| 342 | return fname, num | 343 | end |
| 343 | end | 344 | if current == target then |
| 344 | break | 345 | return fname, findLine or line |
| 345 | end | 346 | end |
| 346 | i = i + 1 | 347 | current = current + 1 |
| 347 | end | 348 | end |
| 348 | end | 349 | end |
| 349 | return fname, line | 350 | return fname, line |
