diff options
-rw-r--r-- | src/MoonP/moon_compiler.cpp | 59 | ||||
-rw-r--r-- | src/MoonP/stacktraceplus.h | 44 |
2 files changed, 29 insertions, 74 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 | |||
diff --git a/src/MoonP/stacktraceplus.h b/src/MoonP/stacktraceplus.h index a309578..fcd887a 100644 --- a/src/MoonP/stacktraceplus.h +++ b/src/MoonP/stacktraceplus.h | |||
@@ -358,7 +358,7 @@ end | |||
358 | -- @param message An optional error string or object. | 358 | -- @param message An optional error string or object. |
359 | -- @param level An optional number telling at which level to start the traceback (default is 1) | 359 | -- @param level An optional number telling at which level to start the traceback (default is 1) |
360 | -- | 360 | -- |
361 | -- Returns a string with the stack trace and a string with the original error. | 361 | -- Returns a string with the stack trace. |
362 | -- | 362 | -- |
363 | function _M.stacktrace(thread, message, level) | 363 | function _M.stacktrace(thread, message, level) |
364 | if type(thread) ~= "thread" then | 364 | if type(thread) ~= "thread" then |
@@ -389,26 +389,16 @@ function _M.stacktrace(thread, message, level) | |||
389 | dumper:add("\r\n}") | 389 | dumper:add("\r\n}") |
390 | elseif type(message) == "string" then | 390 | elseif type(message) == "string" then |
391 | local fname, line, msg = message:match('(.+):(%d+): (.*)$') | 391 | local fname, line, msg = message:match('(.+):(%d+): (.*)$') |
392 | local nfname, nline, nmsg = fname:match('(.+):(%d+): (.*)$') | 392 | if fname then |
393 | if nfname then | 393 | local nfname, nline, nmsg = fname:match('(.+):(%d+): (.*)$') |
394 | fname = nmsg | 394 | if nfname then |
395 | fname = nmsg | ||
396 | end | ||
395 | end | 397 | end |
396 | if fname then | 398 | if fname then |
397 | fname = fname:gsub("%[string \"", "") | 399 | fname = fname:gsub("%[string \"", "") |
398 | fname = fname:gsub("\"%]", "") | 400 | fname = fname:gsub("\"%]", "") |
399 | fname = fname:gsub("^%s*(.-)%s*$", "%1") | 401 | fname = fname:gsub("^%s*(.-)%s*$", "%1") |
400 | local extension = fname:match("%.([^%.\\/]*)$") | ||
401 | if not extension then | ||
402 | local fext = fname .. ".lua" | ||
403 | if moonp.file_exist(fext) then | ||
404 | fname = fext | ||
405 | else | ||
406 | fext = fname .. ".moon" | ||
407 | if moonp.file_exist(fext) then | ||
408 | fname = fext | ||
409 | end | ||
410 | end | ||
411 | end | ||
412 | fname, line = getMoonLineNumber(fname, line) | 402 | fname, line = getMoonLineNumber(fname, line) |
413 | if _M.simplified then | 403 | if _M.simplified then |
414 | message = table.concat({ | 404 | message = table.concat({ |
@@ -425,13 +415,6 @@ function _M.stacktrace(thread, message, level) | |||
425 | dumper:add(message) | 415 | dumper:add(message) |
426 | end | 416 | end |
427 | 417 | ||
428 | local moonp = require("moonp") | ||
429 | if moonp._hide_stacktrace_ then | ||
430 | local msg = dumper:concat_lines() | ||
431 | moonp._hide_stacktrace_ = nil | ||
432 | return message | ||
433 | end | ||
434 | |||
435 | dumper:add("\r\n") | 418 | dumper:add("\r\n") |
436 | dumper:add[[ | 419 | dumper:add[[ |
437 | Stack Traceback | 420 | Stack Traceback |
@@ -448,20 +431,7 @@ Stack Traceback | |||
448 | elseif info.what == "main" or info.what == "Lua" then | 431 | elseif info.what == "main" or info.what == "Lua" then |
449 | info.source = info.source | 432 | info.source = info.source |
450 | end | 433 | end |
451 | local fname = info.source | 434 | info.source, info.currentline = getMoonLineNumber(info.source, info.currentline) |
452 | local extension = fname:match("%.([^%.\\/]*)$") | ||
453 | if not extension then | ||
454 | local fext = fname .. ".lua" | ||
455 | if moonp.file_exist(fext) then | ||
456 | fname = fext | ||
457 | else | ||
458 | fext = fname .. ".moon" | ||
459 | if moonp.file_exist(fext) then | ||
460 | fname = fext | ||
461 | end | ||
462 | end | ||
463 | end | ||
464 | info.source, info.currentline = getMoonLineNumber(fname, info.currentline) | ||
465 | if info.what == "main" then | 435 | if info.what == "main" then |
466 | if _M.simplified then | 436 | if _M.simplified then |
467 | dumper:add_f("(%d) '%s':%d\r\n", level_to_show, info.source, info.currentline) | 437 | dumper:add_f("(%d) '%s':%d\r\n", level_to_show, info.source, info.currentline) |