diff options
Diffstat (limited to 'src/MoonP/moon_compiler.cpp')
-rw-r--r-- | src/MoonP/moon_compiler.cpp | 59 |
1 files changed, 22 insertions, 37 deletions
diff --git a/src/MoonP/moon_compiler.cpp b/src/MoonP/moon_compiler.cpp index 28db051..00b897d 100644 --- a/src/MoonP/moon_compiler.cpp +++ b/src/MoonP/moon_compiler.cpp | |||
@@ -33,6 +33,9 @@ using namespace parserlib; | |||
33 | #define BLOCK_END } while (false); | 33 | #define BLOCK_END } while (false); |
34 | #define BREAK_IF(cond) if (cond) break | 34 | #define BREAK_IF(cond) if (cond) break |
35 | 35 | ||
36 | #define _DEFER(code,line) std::shared_ptr<void> _defer_##line(nullptr, [&](auto){code;}) | ||
37 | #define DEFER(code) _DEFER(code,__LINE__) | ||
38 | |||
36 | typedef std::list<std::string> str_list; | 39 | typedef std::list<std::string> str_list; |
37 | 40 | ||
38 | inline std::string s(std::string_view sv) { | 41 | inline std::string s(std::string_view sv) { |
@@ -40,7 +43,7 @@ inline std::string s(std::string_view sv) { | |||
40 | } | 43 | } |
41 | 44 | ||
42 | const char* moonScriptVersion() { | 45 | const char* moonScriptVersion() { |
43 | return "0.5.0-r0.3.2"; | 46 | return "0.5.0-r0.3.3"; |
44 | } | 47 | } |
45 | 48 | ||
46 | // name of table stored in lua registry | 49 | // name of table stored in lua registry |
@@ -82,6 +85,7 @@ public: | |||
82 | _config = config; | 85 | _config = config; |
83 | _info = _parser.parse<File_t>(codes); | 86 | _info = _parser.parse<File_t>(codes); |
84 | GlobalVars globals; | 87 | GlobalVars globals; |
88 | DEFER(clear()); | ||
85 | if (_info.node) { | 89 | if (_info.node) { |
86 | try { | 90 | try { |
87 | str_list out; | 91 | str_list out; |
@@ -99,15 +103,12 @@ public: | |||
99 | globals->push_back({var.first, line, col}); | 103 | globals->push_back({var.first, line, col}); |
100 | } | 104 | } |
101 | } | 105 | } |
102 | clear(); | ||
103 | return {std::move(out.back()), Empty, std::move(globals)}; | 106 | return {std::move(out.back()), Empty, std::move(globals)}; |
104 | } catch (const std::logic_error& error) { | 107 | } catch (const std::logic_error& error) { |
105 | clear(); | ||
106 | return {Empty, error.what(), std::move(globals)}; | 108 | return {Empty, error.what(), std::move(globals)}; |
107 | } | 109 | } |
108 | } else { | 110 | } else { |
109 | clear(); | 111 | return {Empty, std::move(_info.error), std::move(globals)}; |
110 | return {Empty, _info.error, std::move(globals)}; | ||
111 | } | 112 | } |
112 | } | 113 | } |
113 | 114 | ||
@@ -115,15 +116,14 @@ public: | |||
115 | _indentOffset = 0; | 116 | _indentOffset = 0; |
116 | _scopes.clear(); | 117 | _scopes.clear(); |
117 | _codeCache.clear(); | 118 | _codeCache.clear(); |
118 | std::stack<std::string> emptyWith; | ||
119 | _withVars.swap(emptyWith); | ||
120 | std::stack<std::string> emptyContinue; | ||
121 | _continueVars.swap(emptyContinue); | ||
122 | _buf.str(""); | 119 | _buf.str(""); |
123 | _buf.clear(); | 120 | _buf.clear(); |
124 | _joinBuf.str(""); | 121 | _joinBuf.str(""); |
125 | _joinBuf.clear(); | 122 | _joinBuf.clear(); |
126 | _globals.clear(); | 123 | _globals.clear(); |
124 | _info = {}; | ||
125 | _withVars = {}; | ||
126 | _continueVars = {}; | ||
127 | if (_useModule) { | 127 | if (_useModule) { |
128 | _useModule = false; | 128 | _useModule = false; |
129 | if (!_sameModule) { | 129 | if (!_sameModule) { |
@@ -626,7 +626,7 @@ private: | |||
626 | BREAK_IF(!callable->item.is<MacroName_t>()); | 626 | BREAK_IF(!callable->item.is<MacroName_t>()); |
627 | if (chainList.size() == 1 || | 627 | if (chainList.size() == 1 || |
628 | !ast_is<Invoke_t,InvokeArgs_t>(*(++chainList.begin()))) { | 628 | !ast_is<Invoke_t,InvokeArgs_t>(*(++chainList.begin()))) { |
629 | throw std::logic_error(_info.errorMessage("macro expression must be followed by argument list"sv, callable)); | 629 | throw std::logic_error(_info.errorMessage("macro expression must be followed by arguments list"sv, callable)); |
630 | } | 630 | } |
631 | return true; | 631 | return true; |
632 | BLOCK_END | 632 | BLOCK_END |
@@ -2093,19 +2093,6 @@ private: | |||
2093 | lua_pop(L, 3); // item | 2093 | lua_pop(L, 3); // item |
2094 | } | 2094 | } |
2095 | 2095 | ||
2096 | void hideStackTrace(bool hide) { | ||
2097 | lua_getglobal(L, "package"); // package | ||
2098 | lua_getfield(L, -1, "loaded"); // package loaded | ||
2099 | lua_getfield(L, -1, "moonp"); // package loaded moonp | ||
2100 | if (hide) { | ||
2101 | lua_pushboolean(L, 1); // package loaded moonp true | ||
2102 | } else { | ||
2103 | lua_pushnil(L); // package loaded moonp nil | ||
2104 | } | ||
2105 | lua_setfield(L, -2, "_hide_stacktrace_"); | ||
2106 | lua_pop(L, 3); // empty | ||
2107 | } | ||
2108 | |||
2109 | bool isModuleLoaded(std::string_view name) { | 2096 | bool isModuleLoaded(std::string_view name) { |
2110 | int top = lua_gettop(L); | 2097 | int top = lua_gettop(L); |
2111 | lua_pushliteral(L, MOONP_MODULE); // MOONP_MODULE | 2098 | lua_pushliteral(L, MOONP_MODULE); // MOONP_MODULE |
@@ -2941,10 +2928,10 @@ private: | |||
2941 | 2928 | ||
2942 | std::pair<std::string,std::string> expandMacroStr(ChainValue_t* chainValue) { | 2929 | std::pair<std::string,std::string> expandMacroStr(ChainValue_t* chainValue) { |
2943 | const auto& chainList = chainValue->items.objects(); | 2930 | const auto& chainList = chainValue->items.objects(); |
2944 | auto callable = ast_cast<Callable_t>(chainList.front()); | 2931 | auto x = ast_to<Callable_t>(chainList.front())->item.to<MacroName_t>(); |
2945 | auto macroName = _parser.toString(callable->item.to<MacroName_t>()->name); | 2932 | auto macroName = _parser.toString(x->name); |
2946 | if (!_useModule) { | 2933 | if (!_useModule) { |
2947 | throw std::logic_error(_info.errorMessage("can not resolve macro", callable->item)); | 2934 | throw std::logic_error(_info.errorMessage("can not resolve macro"sv, x)); |
2948 | } | 2935 | } |
2949 | pushCurrentModule(); // cur | 2936 | pushCurrentModule(); // cur |
2950 | int top = lua_gettop(L) - 1; | 2937 | int top = lua_gettop(L) - 1; |
@@ -2952,7 +2939,7 @@ private: | |||
2952 | lua_rawget(L, -2); // cur[macroName], cur macro | 2939 | lua_rawget(L, -2); // cur[macroName], cur macro |
2953 | if (lua_istable(L, -1) == 0) { | 2940 | if (lua_istable(L, -1) == 0) { |
2954 | lua_settop(L, top); | 2941 | lua_settop(L, top); |
2955 | throw std::logic_error(_info.errorMessage("can not resolve macro", callable->item)); | 2942 | throw std::logic_error(_info.errorMessage("can not resolve macro"sv, x)); |
2956 | } | 2943 | } |
2957 | lua_rawgeti(L, -1, 1); // cur macro func | 2944 | lua_rawgeti(L, -1, 1); // cur macro func |
2958 | pushMoonp("pcall"sv); // cur macro func pcall | 2945 | pushMoonp("pcall"sv); // cur macro func pcall |
@@ -2988,26 +2975,24 @@ private: | |||
2988 | } | 2975 | } |
2989 | } else str = _parser.toString(arg); | 2976 | } else str = _parser.toString(arg); |
2990 | Utils::trim(str); | 2977 | Utils::trim(str); |
2991 | Utils::replace(str, "\r\n"sv, "\n"); | 2978 | Utils::replace(str, "\r\n"sv, "\n"sv); |
2992 | lua_pushlstring(L, str.c_str(), str.size()); | 2979 | lua_pushlstring(L, str.c_str(), str.size()); |
2993 | } // cur macro pcall func args... | 2980 | } // cur macro pcall func args... |
2994 | hideStackTrace(true); | ||
2995 | bool success = lua_pcall(L, static_cast<int>(args->size()) + 1, 2, 0) == 0; | 2981 | bool success = lua_pcall(L, static_cast<int>(args->size()) + 1, 2, 0) == 0; |
2996 | if (!success) { // cur macro err | 2982 | if (!success) { // cur macro err |
2997 | std::string err = lua_tostring(L, -1); | 2983 | std::string err = lua_tostring(L, -1); |
2998 | lua_settop(L, top); | 2984 | lua_settop(L, top); |
2999 | throw std::logic_error(_info.errorMessage(s("fail to expand macro\n"sv) + err, callable)); | 2985 | throw std::logic_error(_info.errorMessage(s("fail to expand macro: "sv) + err, x)); |
3000 | } // cur macro success res | 2986 | } // cur macro success res |
3001 | hideStackTrace(false); | ||
3002 | if (lua_toboolean(L, -2) == 0) { | 2987 | if (lua_toboolean(L, -2) == 0) { |
3003 | std::string err = lua_tostring(L, -1); | 2988 | std::string err = lua_tostring(L, -1); |
3004 | lua_settop(L, top); | 2989 | lua_settop(L, top); |
3005 | throw std::logic_error(_info.errorMessage(s("fail to expand macro\n"sv) + err, callable)); | 2990 | throw std::logic_error(_info.errorMessage(s("fail to expand macro: "sv) + err, x)); |
3006 | } | 2991 | } |
3007 | lua_remove(L, -2); // cur macro res | 2992 | lua_remove(L, -2); // cur macro res |
3008 | if (lua_isstring(L, -1) == 0) { | 2993 | if (lua_isstring(L, -1) == 0) { |
3009 | lua_settop(L, top); | 2994 | lua_settop(L, top); |
3010 | throw std::logic_error(_info.errorMessage(s("macro function must return string with expanded codes"sv), callable)); | 2995 | throw std::logic_error(_info.errorMessage(s("macro function must return string with expanded codes"sv), x)); |
3011 | } // cur macro codes | 2996 | } // cur macro codes |
3012 | lua_rawgeti(L, -2, 2); // cur macro codes type | 2997 | lua_rawgeti(L, -2, 2); // cur macro codes type |
3013 | std::string type = lua_tostring(L, -1); | 2998 | std::string type = lua_tostring(L, -1); |
@@ -3017,13 +3002,13 @@ private: | |||
3017 | } | 3002 | } |
3018 | 3003 | ||
3019 | std::pair<ast_ptr<false,ast_node>, std::unique_ptr<input>> expandMacro(ChainValue_t* chainValue, ExpUsage usage) { | 3004 | std::pair<ast_ptr<false,ast_node>, std::unique_ptr<input>> expandMacro(ChainValue_t* chainValue, ExpUsage usage) { |
3020 | auto x = chainValue; | 3005 | auto x = ast_to<Callable_t>(chainValue->items.front())->item.to<MacroName_t>(); |
3021 | const auto& chainList = chainValue->items.objects(); | 3006 | const auto& chainList = chainValue->items.objects(); |
3022 | std::string type, codes; | 3007 | std::string type, codes; |
3023 | std::tie(type, codes) = expandMacroStr(chainValue); | 3008 | std::tie(type, codes) = expandMacroStr(chainValue); |
3024 | std::string targetType(usage != ExpUsage::Common || chainList.size() > 2 ? "expr"sv : "block"sv); | 3009 | std::string targetType(usage != ExpUsage::Common || chainList.size() > 2 ? "expr"sv : "block"sv); |
3025 | if (type != targetType) { | 3010 | if (type != targetType) { |
3026 | throw std::logic_error(_info.errorMessage(s("macro type mismatch, "sv) + targetType + s(" expected, got "sv) + type + '.', x)); | 3011 | throw std::logic_error(_info.errorMessage(s("macro type mismatch, "sv) + targetType + s(" expected, got "sv) + type, x)); |
3027 | } | 3012 | } |
3028 | ParseInfo info; | 3013 | ParseInfo info; |
3029 | if (usage == ExpUsage::Common) { | 3014 | if (usage == ExpUsage::Common) { |
@@ -3039,7 +3024,8 @@ private: | |||
3039 | info = _parser.parse<Exp_t>(codes); | 3024 | info = _parser.parse<Exp_t>(codes); |
3040 | } | 3025 | } |
3041 | if (!info.node) { | 3026 | if (!info.node) { |
3042 | throw std::logic_error(_info.errorMessage("fail to expand macro: " + info.error, x)); | 3027 | info.error = info.error.substr(info.error.find(':') + 2); |
3028 | throw std::logic_error(_info.errorMessage("fail to parse expanded codes: " + info.error, x)); | ||
3043 | } | 3029 | } |
3044 | int line = x->m_begin.m_line; | 3030 | int line = x->m_begin.m_line; |
3045 | int col = x->m_begin.m_col; | 3031 | int col = x->m_begin.m_col; |
@@ -5002,4 +4988,3 @@ std::tuple<std::string,std::string,GlobalVars> MoonCompiler::compile(std::string | |||
5002 | } | 4988 | } |
5003 | 4989 | ||
5004 | } // namespace MoonP | 4990 | } // namespace MoonP |
5005 | |||