aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/MoonP/moon_compiler.cpp59
-rw-r--r--src/MoonP/stacktraceplus.h44
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
36typedef std::list<std::string> str_list; 39typedef std::list<std::string> str_list;
37 40
38inline std::string s(std::string_view sv) { 41inline std::string s(std::string_view sv) {
@@ -40,7 +43,7 @@ inline std::string s(std::string_view sv) {
40} 43}
41 44
42const char* moonScriptVersion() { 45const 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--
363function _M.stacktrace(thread, message, level) 363function _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[[
437Stack Traceback 420Stack 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)