aboutsummaryrefslogtreecommitdiff
path: root/src/MoonP/moon_compiler.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/MoonP/moon_compiler.cpp')
-rw-r--r--src/MoonP/moon_compiler.cpp59
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
28namespace MoonP { 34namespace MoonP {
29using namespace std::string_view_literals; 35using namespace std::string_view_literals;
30using namespace parserlib; 36using namespace parserlib;
@@ -43,7 +49,7 @@ inline std::string s(std::string_view sv) {
43} 49}
44 50
45const std::string_view version() { 51const 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) {