diff options
Diffstat (limited to 'src/MoonP/moon_compiler.cpp')
-rw-r--r-- | src/MoonP/moon_compiler.cpp | 59 |
1 files changed, 57 insertions, 2 deletions
diff --git a/src/MoonP/moon_compiler.cpp b/src/MoonP/moon_compiler.cpp index f7462dc..8dc5c94 100644 --- a/src/MoonP/moon_compiler.cpp +++ b/src/MoonP/moon_compiler.cpp | |||
@@ -25,6 +25,12 @@ extern "C" { | |||
25 | 25 | ||
26 | } // extern "C" | 26 | } // extern "C" |
27 | 27 | ||
28 | #if LUA_VERSION_NUM > 501 | ||
29 | #ifndef LUA_COMPAT_5_1 | ||
30 | #define lua_objlen lua_rawlen | ||
31 | #endif // LUA_COMPAT_5_1 | ||
32 | #endif // LUA_VERSION_NUM | ||
33 | |||
28 | namespace MoonP { | 34 | namespace MoonP { |
29 | using namespace std::string_view_literals; | 35 | using namespace std::string_view_literals; |
30 | using namespace parserlib; | 36 | using namespace parserlib; |
@@ -43,7 +49,7 @@ inline std::string s(std::string_view sv) { | |||
43 | } | 49 | } |
44 | 50 | ||
45 | const std::string_view version() { | 51 | const std::string_view version() { |
46 | return "0.4.0"sv; | 52 | return "0.4.1"sv; |
47 | } | 53 | } |
48 | 54 | ||
49 | // name of table stored in lua registry | 55 | // name of table stored in lua registry |
@@ -769,6 +775,7 @@ private: | |||
769 | case id<BreakLoop_t>(): transformBreakLoop(static_cast<BreakLoop_t*>(content), out); break; | 775 | case id<BreakLoop_t>(): transformBreakLoop(static_cast<BreakLoop_t*>(content), out); break; |
770 | case id<Label_t>(): transformLabel(static_cast<Label_t*>(content), out); break; | 776 | case id<Label_t>(): transformLabel(static_cast<Label_t*>(content), out); break; |
771 | case id<Goto_t>(): transformGoto(static_cast<Goto_t*>(content), out); break; | 777 | case id<Goto_t>(): transformGoto(static_cast<Goto_t*>(content), out); break; |
778 | case id<LocalAttrib_t>(): transformLocalAttrib(static_cast<LocalAttrib_t*>(content), out); break; | ||
772 | case id<ExpListAssign_t>(): { | 779 | case id<ExpListAssign_t>(): { |
773 | auto expListAssign = static_cast<ExpListAssign_t*>(content); | 780 | auto expListAssign = static_cast<ExpListAssign_t*>(content); |
774 | if (expListAssign->action) { | 781 | if (expListAssign->action) { |
@@ -2071,7 +2078,18 @@ private: | |||
2071 | last->needSep.set(nullptr); | 2078 | last->needSep.set(nullptr); |
2072 | auto bLast = ++nodes.rbegin(); | 2079 | auto bLast = ++nodes.rbegin(); |
2073 | if (bLast != nodes.rend()) { | 2080 | if (bLast != nodes.rend()) { |
2074 | static_cast<Statement_t*>(*bLast)->needSep.set(nullptr); | 2081 | bool isMacro = false; |
2082 | BLOCK_START | ||
2083 | BREAK_IF(expListLow->exprs.size() != 1); | ||
2084 | auto exp = static_cast<Exp_t*>(expListLow->exprs.back()); | ||
2085 | BREAK_IF(!exp->opValues.empty()); | ||
2086 | auto chainValue = exp->getByPath<unary_exp_t, Value_t, ChainValue_t>(); | ||
2087 | BREAK_IF(!chainValue); | ||
2088 | isMacro = isMacroChain(chainValue); | ||
2089 | BLOCK_END | ||
2090 | if (!isMacro) { | ||
2091 | ast_to<Statement_t>(*bLast)->needSep.set(nullptr); | ||
2092 | } | ||
2075 | } | 2093 | } |
2076 | BLOCK_END | 2094 | BLOCK_END |
2077 | break; | 2095 | break; |
@@ -5099,6 +5117,43 @@ private: | |||
5099 | out.push_back(join(temp)); | 5117 | out.push_back(join(temp)); |
5100 | } | 5118 | } |
5101 | 5119 | ||
5120 | void transformLocalAttrib(LocalAttrib_t* localAttrib, str_list& out) { | ||
5121 | auto x = localAttrib; | ||
5122 | auto attrib = _parser.toString(localAttrib->attrib); | ||
5123 | if (attrib != "close"sv && attrib != "const"sv) { | ||
5124 | throw std::logic_error(_info.errorMessage(s("unknown attribute '"sv) + attrib + '\'', localAttrib->attrib)); | ||
5125 | } | ||
5126 | auto expList = x->new_ptr<ExpList_t>(); | ||
5127 | str_list tmpVars; | ||
5128 | str_list vars; | ||
5129 | for (auto name : localAttrib->nameList->names.objects()) { | ||
5130 | auto callable = x->new_ptr<Callable_t>(); | ||
5131 | callable->item.set(name); | ||
5132 | auto chainValue = x->new_ptr<ChainValue_t>(); | ||
5133 | chainValue->items.push_back(callable); | ||
5134 | auto value = x->new_ptr<Value_t>(); | ||
5135 | value->item.set(chainValue); | ||
5136 | auto exp = newExp(value, x); | ||
5137 | expList->exprs.push_back(exp); | ||
5138 | tmpVars.push_back(getUnusedName("_var_"sv)); | ||
5139 | vars.push_back(_parser.toString(name)); | ||
5140 | } | ||
5141 | auto tmpVarStr = join(tmpVars, ","sv); | ||
5142 | auto tmpVarList = toAst<ExpList_t>(tmpVarStr, x); | ||
5143 | auto assignment = x->new_ptr<ExpListAssign_t>(); | ||
5144 | assignment->expList.set(tmpVarList); | ||
5145 | assignment->action.set(localAttrib->assign); | ||
5146 | str_list temp; | ||
5147 | transformAssignment(assignment, temp); | ||
5148 | attrib = s(" <"sv) + attrib + '>'; | ||
5149 | for (auto& var : vars) { | ||
5150 | forceAddToScope(var); | ||
5151 | var.append(attrib); | ||
5152 | } | ||
5153 | temp.push_back(indent() + s("local "sv) + join(vars) + s(" = "sv) + tmpVarStr + nll(x)); | ||
5154 | out.push_back(join(temp)); | ||
5155 | } | ||
5156 | |||
5102 | void transformBreakLoop(BreakLoop_t* breakLoop, str_list& out) { | 5157 | void transformBreakLoop(BreakLoop_t* breakLoop, str_list& out) { |
5103 | auto keyword = _parser.toString(breakLoop); | 5158 | auto keyword = _parser.toString(breakLoop); |
5104 | if (keyword == "break"sv) { | 5159 | if (keyword == "break"sv) { |