aboutsummaryrefslogtreecommitdiff
path: root/MoonParser/moon_ast.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'MoonParser/moon_ast.cpp')
-rw-r--r--MoonParser/moon_ast.cpp1556
1 files changed, 1108 insertions, 448 deletions
diff --git a/MoonParser/moon_ast.cpp b/MoonParser/moon_ast.cpp
index a98e75e..3c433ae 100644
--- a/MoonParser/moon_ast.cpp
+++ b/MoonParser/moon_ast.cpp
@@ -151,16 +151,16 @@ public:
151 void complile(const std::string& codes) { 151 void complile(const std::string& codes) {
152 input input = _converter.from_bytes(codes); 152 input input = _converter.from_bytes(codes);
153 error_list el; 153 error_list el;
154 BlockEnd_t* root = nullptr;
155 State st; 154 State st;
156 if (parse(input, BlockEnd, el, root, &st)) { 155 auto root = parse<BlockEnd_t>(input, BlockEnd, el, &st);
157 std::cout << "matched!\n"; 156 if (root) {
157 std::cout << "compiled!\n\n";
158 std::vector<std::string> out; 158 std::vector<std::string> out;
159 root->eachChild([&](ast_node* node) { 159 root->eachChild([&](ast_node* node) {
160 switch (node->getId()) { 160 switch (node->getId()) {
161 case "Block"_id: 161 case "Block"_id:
162 pushScope(); 162 pushScope();
163 transformBody(node, out); 163 transformBody(static_cast<Body_t*>(node), out, true);
164 popScope(); 164 popScope();
165 break; 165 break;
166 default: break; 166 default: break;
@@ -170,20 +170,21 @@ public:
170 if (out.size() == 1) { 170 if (out.size() == 1) {
171 result = std::move(out.front()); 171 result = std::move(out.front());
172 } else if (out.size() > 1) { 172 } else if (out.size() > 1) {
173 result = join(out, "\n"); 173 result = join(out, "\n"sv);
174 } 174 }
175 std::cout << result << '\n'; 175 std::cout << result << '\n';
176 } else { 176 } else {
177 std::cout << "not matched!\n"; 177 std::cout << "compile failed!\n";
178 for (error_list::iterator it = el.begin(); it != el.end(); ++it) { 178 for (error_list::iterator it = el.begin(); it != el.end(); ++it) {
179 const error& err = *it; 179 const error& err = *it;
180 std::cout << "line " << err.m_begin.m_line << ", col " << err.m_begin.m_col << ": syntax error\n"; 180 std::cout << "line " << err.m_begin.m_line << ", col " << err.m_begin.m_col << ": syntax error\n";
181 } 181 }
182 } 182 }
183 _codeCache.clear();
183 } 184 }
184
185private: 185private:
186 Converter _converter; 186 Converter _converter;
187 std::vector<input> _codeCache;
187 std::ostringstream _buf; 188 std::ostringstream _buf;
188 std::string _newLine = "\n"; 189 std::string _newLine = "\n";
189 std::vector<int> _lineTable; 190 std::vector<int> _lineTable;
@@ -199,7 +200,11 @@ private:
199 _scopes.back().vars = MakeUnique<std::unordered_set<std::string>>(); 200 _scopes.back().vars = MakeUnique<std::unordered_set<std::string>>();
200 } 201 }
201 202
202 bool isDefined(const std::string& name, bool checkShadowScope = false) { 203 void popScope() {
204 _scopes.pop_back();
205 }
206
207 bool isDefined(const std::string& name, bool checkShadowScopeOnly = false) {
203 bool isDefined = false; 208 bool isDefined = false;
204 for (auto it = _scopes.rbegin(); it != _scopes.rend(); ++it) { 209 for (auto it = _scopes.rbegin(); it != _scopes.rend(); ++it) {
205 auto vars = it->vars.get(); 210 auto vars = it->vars.get();
@@ -207,7 +212,7 @@ private:
207 isDefined = true; 212 isDefined = true;
208 break; 213 break;
209 } 214 }
210 if (checkShadowScope && it->allows) break; 215 if (checkShadowScopeOnly && it->allows) break;
211 } 216 }
212 return isDefined; 217 return isDefined;
213 } 218 }
@@ -244,8 +249,15 @@ private:
244 return !defined; 249 return !defined;
245 } 250 }
246 251
247 void popScope() { 252 std::string getValidName(std::string_view name) {
248 _scopes.pop_back(); 253 int index = 0;
254 std::string newName;
255 do {
256 _buf << name << index;
257 newName = clearBuf();
258 index++;
259 } while (isDefined(newName));
260 return newName;
249 } 261 }
250 262
251 const std::string nll(ast_node* node) { 263 const std::string nll(ast_node* node) {
@@ -259,7 +271,11 @@ private:
259 } 271 }
260 272
261 std::string indent() { 273 std::string indent() {
262 return std::string(_scopes.size() - 1, '\t'); 274 return std::string((_scopes.size() - 1) * 2, ' ');
275 }
276
277 std::string indent(int offset) {
278 return std::string((_scopes.size() - 1 + offset) * 2, ' ');
263 } 279 }
264 280
265 std::string clearBuf() { 281 std::string clearBuf() {
@@ -285,335 +301,530 @@ private:
285 } 301 }
286 302
287 std::string toString(ast_node* node) { 303 std::string toString(ast_node* node) {
288 auto str = _converter.to_bytes(std::u32string(node->m_begin.m_it, node->m_end.m_it)); 304 auto str = _converter.to_bytes(std::wstring(node->m_begin.m_it, node->m_end.m_it));
305 return trim(str);
306 }
307
308 std::string toString(input::iterator begin, input::iterator end) {
309 auto str = _converter.to_bytes(std::wstring(begin, end));
289 return trim(str); 310 return trim(str);
290 } 311 }
291 312
292 void noop(ast_node* node, std::vector<std::string>& out) { 313 void noop(ast_node* node, std::vector<std::string>& out) {
293 auto str = _converter.to_bytes(std::u32string(node->m_begin.m_it, node->m_end.m_it)); 314 auto str = _converter.to_bytes(std::wstring(node->m_begin.m_it, node->m_end.m_it));
294 out.push_back(s("<"sv) + node->getName() + s(">"sv) + trim(str)); 315 out.push_back(s("<"sv) + node->getName() + s(">"sv) + trim(str));
295 // out.push_back(trim(str)); 316 // out.push_back(trim(str));
296 } 317 }
297 318
298 void noopnl(ast_node* node, std::vector<std::string>& out) { 319 void noopnl(ast_node* node, std::vector<std::string>& out) {
299 auto str = _converter.to_bytes(std::u32string(node->m_begin.m_it, node->m_end.m_it)); 320 auto str = _converter.to_bytes(std::wstring(node->m_begin.m_it, node->m_end.m_it));
300 out.push_back(s("<"sv) + node->getName() + s(">"sv) + trim(str) + nll(node)); 321 out.push_back(s("<"sv) + node->getName() + s(">"sv) + trim(str) + nll(node));
301 // out.push_back(trim(str) + nll(node)); 322 // out.push_back(trim(str) + nll(node));
302 } 323 }
303 324
304 void transformStatement(ast_node* statement, std::vector<std::string>& out) { 325 Value_t* singleValueFrom(ast_node* expList) {
305 std::vector<std::string> temp; 326 ast_node* singleValue = nullptr;
306 auto transformContent = [&](ast_node* node, std::vector<std::string>& out) { 327 expList->traverse([&](ast_node* n) {
307 switch (node->getId()) { 328 if (n->getId() == "Value"_id) {
308 case "Import"_id: transformImport(node, temp); break; 329 if (!singleValue) {
309 case "While"_id: transformWhile(node, temp); break; 330 singleValue = n;
310 case "With"_id: transformWith(node, temp); break; 331 return traversal::Return;
311 case "For"_id: transformFor(node, temp); break; 332 } else {
312 case "ForEach"_id: transformForEach(node, temp); break; 333 singleValue = nullptr;
313 case "Switch"_id: transformSwitch(node, temp); break; 334 return traversal::Stop;
314 case "Return"_id: transformReturn(node, temp); break; 335 }
315 case "Local"_id: transformLocal(node, temp); break; 336 }
316 case "Export"_id: transformExport(node, temp); break; 337 return traversal::Continue;
317 case "BreakLoop"_id: transformBreakLoop(node, temp); break; 338 });
318 case "Assignment"_id: transformAssignment(node, temp); break; 339 return static_cast<Value_t*>(singleValue);
319 case "ExpList"_id: 340 }
320 transformExpList(node, temp); 341
321 temp.back() = indent() + temp.back() + nll(node); 342 Statement_t* lastStatementFrom(ast_node* body) {
343 ast_node* last = nullptr;
344 body->traverse([&](ast_node* n) {
345 switch (n->getId()) {
346 case "Statement"_id:
347 last = n;
348 return traversal::Return;
349 default: return traversal::Continue;
350 }
351 });
352 return static_cast<Statement_t*>(last);
353 }
354
355 template <class T>
356 ast_ptr<T, false, false> toAst(std::string_view codes, rule& r) {
357 _codeCache.push_back(_converter.from_bytes(s(codes)));
358 error_list el;
359 State st;
360 return parse<T>(_codeCache.back(), r, el, &st);
361 }
362
363 void transformStatement(Statement_t* statement, std::vector<std::string>& out) {
364 if (statement->appendix) {
365 auto appendix = statement->appendix;
366 switch (appendix->item->getId()) {
367 case "if_else_line"_id: {
368 auto if_else_line = static_cast<if_else_line_t*>(appendix->item.get());
369 auto ifCond = new_ptr<IfCond_t>();
370 ifCond->condition = if_else_line->condition;
371
372 auto exprList = new_ptr<ExpList_t>();
373 exprList->exprs.add(if_else_line->elseExpr);
374 auto stmt = new_ptr<Statement_t>();
375 stmt->content.set(exprList);
376 auto body = new_ptr<Body_t>();
377 body->content.set(stmt);
378 auto ifElseIf = new_ptr<IfElseIf_t>();
379 ifElseIf->body.set(body);
380
381 stmt = new_ptr<Statement_t>();
382 stmt->content.set(statement->content);
383 body = new_ptr<Body_t>();
384 body->content.set(stmt);
385 auto ifNode = new_ptr<If_t>();
386 ifNode->firstCondition.set(ifCond);
387 ifNode->firstBody.set(body);
388 ifNode->branches.add(ifElseIf);
389
390 statement->appendix.set(nullptr);
391 auto simpleValue = new_ptr<SimpleValue_t>();
392 simpleValue->value.set(ifNode);
393 auto value = new_ptr<Value_t>();
394 value->item.set(simpleValue);
395 auto exp = new_ptr<Exp_t>();
396 exp->value.set(value);
397 exprList = new_ptr<ExpList_t>();
398 exprList->exprs.add(exp);
399 statement->content.set(exprList);
322 break; 400 break;
401 }
402 case "unless_line"_id: {
403 break;
404 }
405 case "CompInner"_id: {
406 break;
407 }
323 default: break; 408 default: break;
324 } 409 }
325 };
326 if (statement->getChildCount() > 1) {
327 pushScope();
328 transformContent(statement->getChild(0), out);
329 popScope();
330 transform_statement_appendix(statement->getChild(1), temp);
331 } else {
332 transformContent(statement->getChild(0), out);
333 } 410 }
334 switch (temp.size()) { 411 auto node = statement->content.get();
335 case 1: // body 412 if (!node) {
336 out.push_back(std::move(temp.front())); 413 out.push_back(Empty);
337 break; 414 return;
338 case 2: // body, if 415 }
339 out.push_back(join({std::move(temp[1]), std::move(temp[0]), s("end"sv) + nlr(statement)})); 416 switch (node->getId()) {
340 break; 417 case "Import"_id: transformImport(node, out); break;
341 case 3: // body, if, else 418 case "While"_id: transformWhile(node, out); break;
342 out.push_back(join({std::move(temp[1]), std::move(temp[0]), std::move(temp[2]), s("end"sv) + nlr(statement)})); 419 case "With"_id: transformWith(node, out); break;
420 case "For"_id: transformFor(static_cast<For_t*>(node), out); break;
421 case "ForEach"_id: transformForEach(static_cast<ForEach_t*>(node), out); break;
422 case "Switch"_id: transformSwitch(node, out); break;
423 case "Return"_id: transformReturn(static_cast<Return_t*>(node), out); break;
424 case "Local"_id: transformLocal(node, out); break;
425 case "Export"_id: transformExport(node, out); break;
426 case "BreakLoop"_id: transformBreakLoop(node, out); break;
427 case "Assignment"_id: transformStatementAssign(statement, out); break;
428 case "ExpList"_id: {
429 auto expList = static_cast<ExpList_t*>(node);
430 if (expList->exprs.objects().empty()) {
431 out.push_back(Empty);
432 break;
433 }
434 if (auto singleValue = singleValueFrom(expList)) {
435 if (auto ifNode = static_cast<If_t*>(singleValue->getByPath({"SimpleValue"_id, "If"_id}))) {
436 transformIf(ifNode, out);
437 break;
438 }
439 if (singleValue->getByPath({"ChainValue"_id, "InvokeArgs"_id})) {
440 transformValue(singleValue, out);
441 out.back() = indent() + out.back() + nlr(singleValue);
442 break;
443 }
444 }
445 std::string preDefine;
446 if (addToScope(s("_"sv))) {
447 preDefine = indent() + s("local _"sv) + nll(expList);
448 }
449 preDefine.append(indent() + s("_ = "sv));
450 std::vector<std::string> temp;
451 transformExpList(expList, temp);
452 out.push_back(preDefine + temp.back() + nlr(expList));
343 break; 453 break;
454 }
455 default: break;
344 } 456 }
345 } 457 }
346 458
347 void transform_statement_appendix(ast_node* appendix, std::vector<std::string>& out) { 459 std::string transformAssignDefs(ExpList_t* expList) {
348 appendix->eachChild([&](ast_node* node) { 460 std::vector<std::string> preDefs;
349 switch (node->getId()) { 461 std::vector<ast_node*> values;
350 case "if_else_line"_id: transform_if_else_line(node, out); break; 462 expList->traverse([&](ast_node* child) {
351 case "unless_line"_id: transform_unless_line(node, out); break; 463 if (child->getId() == "Value"_id) {
352 case "CompInner"_id: transformCompInner(node, out); break; 464 auto target = child->getByPath({"ChainValue"_id, "Callable"_id, "Name"_id});
353 default: break; 465 if (target) {
466 auto name = toString(target);
467 if (addToScope(name)) {
468 preDefs.push_back(name);
469 }
470 }
471 return traversal::Return;
354 } 472 }
473 return traversal::Continue;
355 }); 474 });
475 if (!preDefs.empty()) {
476 return indent() + s("local "sv) + join(preDefs, ", "sv);
477 }
478 return std::string();
356 } 479 }
357 480
358 void transform_if_else_line(ast_node* if_else_line, std::vector<std::string>& out) { 481 void transformStatementAssign(Statement_t* statement, std::vector<std::string>& out) {
359 std::vector<std::string> temp; 482 auto assignment = static_cast<Assignment_t*>(statement->content.get());
360 if_else_line->eachChild([&](ast_node* node) { 483 if (auto ifNode = assignment->getByPath({"Assign"_id, "If"_id})) {
361 switch (node->getId()) { 484 auto expList = assignment->assignable.get();
362 case "Exp"_id: 485 std::vector<std::string> temp;
486 std::list<std::pair<IfCond_t*, Body_t*>> ifCondPairs;
487 ifCondPairs.emplace_back();
488 std::string preDefine = transformAssignDefs(expList);
489 if (!preDefine.empty()) temp.push_back(preDefine + nll(expList));
490 ifNode->traverse([&](ast_node* node) {
491 switch (node->getId()) {
492 case "IfCond"_id:
493 ifCondPairs.back().first = static_cast<IfCond_t*>(node);
494 return traversal::Return;
495 case "Body"_id:
496 ifCondPairs.back().second = static_cast<Body_t*>(node);
497 ifCondPairs.emplace_back();
498 return traversal::Return;
499 default: return traversal::Continue;
500 }
501 });
502 for (const auto& pair : ifCondPairs) {
503 if (pair.first) {
504 std::vector<std::string> tmp;
505 auto condition = pair.first->condition.get();
506 transformExp(condition, tmp);
507 _buf << indent() << (pair == ifCondPairs.front() ? ""sv : "else"sv) <<
508 "if "sv << tmp.front() << " then"sv << nll(condition);
509 temp.push_back(clearBuf());
510 }
511 if (pair.second) {
512 if (!pair.first) {
513 temp.push_back(indent() + s("else"sv) + nll(pair.second));
514 }
515 auto last = lastStatementFrom(pair.second);
516 auto valueList = last ? last->content.as<ExpList_t>() : nullptr;
517 if (last && valueList) {
518 auto newAssignment = new_ptr<Assignment_t>();
519 newAssignment->assignable.set(expList);
520 auto assign = new_ptr<Assign_t>();
521 if (valueList->getChildCount() == 2) {
522 if (auto subIfNode = valueList->getByPath({
523 "Exp"_id, "Value"_id, "SimpleValue"_id, "If"_id})) {
524 assign->value.set(subIfNode);
525 }
526 }
527 if (!assign->value) {
528 auto expListLow = new_ptr<ExpListLow_t>();
529 expListLow->exprs = valueList->exprs;
530 assign->value.set(expListLow);
531 }
532 newAssignment->target.set(assign);
533 last->content.set(newAssignment);
534 }
363 pushScope(); 535 pushScope();
364 transformExp(node, temp); 536 transformBody(pair.second, temp);
365 popScope(); 537 popScope();
366 break; 538 if (!pair.first) {
367 default: break; 539 temp.push_back(indent() + s("end"sv) + nll(pair.second));
540 }
541 }
368 } 542 }
369 }); 543 out.push_back(join(temp));
370 out.push_back(indent() + s("if "sv) + temp[0] + s(" then"sv) + nll(if_else_line)); 544 return;
371 out.push_back(indent() + s("else "sv) + nll(if_else_line) + indent() + '\t' + temp[1] + nll(if_else_line)); 545 }
546 if (auto expList = assignment->getByPath({"Assign"_id, "ExpListLow"_id})) {
547 auto singleValue = singleValueFrom(expList);
548 if (singleValue && singleValue->item->getId() == "SimpleValue"_id) {
549 auto valueItem = singleValue->item->getFirstChild();
550 switch (valueItem->getId()) {
551 case "Comprehension"_id: {
552 std::vector<std::string> temp;
553 auto expList = assignment->assignable.get();
554 transformExpList(expList, temp);
555 transformCompInPlace(static_cast<Comprehension_t*>(valueItem), temp.front(), temp);
556 std::string preDefine = transformAssignDefs(expList);
557 out.push_back(preDefine + nll(statement) + temp.back());
558 return;
559 }
560 case "For"_id: {
561 std::vector<std::string> temp;
562 auto expList = assignment->assignable.get();
563 std::string preDefine = transformAssignDefs(expList);
564 transformForInPlace(static_cast<For_t*>(valueItem), temp, expList);
565 out.push_back(preDefine + nll(statement) + temp.front());
566 return;
567 }
568 case "ForEach"_id: {
569 std::vector<std::string> temp;
570 auto expList = assignment->assignable.get();
571 std::string preDefine = transformAssignDefs(expList);
572 transformForEachInPlace(static_cast<ForEach_t*>(valueItem), temp, expList);
573 out.push_back(preDefine + nll(statement) + temp.front());
574 return;
575 }
576 }
577 }
578 }
579 transformAssignment(assignment, out);
372 } 580 }
373 581
374 void transformAssignment(ast_node* assignment, std::vector<std::string>& out) { 582 void transformAssignment(Assignment_t* assignment, std::vector<std::string>& out) {
375 std::vector<std::string> temp; 583 std::vector<std::string> temp;
376 std::string preDefined; 584 auto expList = assignment->assignable.get();
377 assignment->eachChild([&](ast_node* node) { 585 auto action = assignment->target.get();
378 switch (node->getId()) { 586 std::string preDefine = transformAssignDefs(expList);
379 case "ExpList"_id: { 587 transformExpList(expList, temp);
380 std::vector<std::string> preDefs; 588 bool oneLined = expList->getChildCount() == 2 &&
381 std::vector<ast_node*> values; 589 traversal::Stop != action->traverse([&](ast_node* node) {
382 node->traverse([&](ast_node* child) { 590 if (node->getId() == "FunLit"_id) {
383 if (child->getId() == "Value"_id) { 591 if (auto body = node->getByPath({"Body"_id})) {
384 auto target = child->getByPath({"ChainValue"_id, "Callable"_id, "Name"_id}); 592 if (traversal::Stop == body->traverse([&](ast_node* n) {
385 if (target) { 593 if (n->getId() == "Callable"_id) {
386 auto name = toString(target); 594 if (auto name = n->getByPath({"Name"_id})) {
387 if (addToScope(name)) { 595 if (temp.front() ==toString(name)) {
388 preDefs.push_back(name); 596 return traversal::Stop;
597 }
389 } 598 }
390 } 599 }
391 return traversal::Return; 600 return traversal::Continue;
601 })) {
602 return traversal::Stop;
392 } 603 }
393 return traversal::Continue;
394 });
395 if (!preDefs.empty()) {
396 preDefined = indent() + s("local "sv) + join(preDefs, ", "sv) + nll(node);
397 } 604 }
398 transformExpList(node, temp);
399 break;
400 } 605 }
401 case "Update"_id: transformUpdate(node, temp); break; 606 return traversal::Continue;
402 case "Assign"_id: { 607 });
403 auto child = node->getChild(0); 608 switch (action->getId()) {
404 switch (child->getId()) { 609 case "Update"_id: transformUpdate(action, temp); break;
405 case "With"_id: transformWith(child, temp); break; 610 case "Assign"_id: {
406 case "If"_id: 611 auto child = action->getFirstChild();
407 transformIfClosure(child, temp); 612 switch (child->getId()) {
408 break; 613 case "With"_id: transformWith(child, temp); break;
409 case "Switch"_id: transformSwitch(child, temp); break; 614 case "If"_id: transformIfClosure(static_cast<If_t*>(child), temp); break;
410 case "TableBlock"_id: transformTableBlock(child, temp); break; 615 case "Switch"_id: transformSwitch(child, temp); break;
411 case "ExpListLow"_id: 616 case "TableBlock"_id: transformTableBlock(child, temp); break;
412 transformExpListLow(child, temp); 617 case "ExpListLow"_id: transformExpListLow(static_cast<ExpListLow_t*>(child), temp); break;
413 break; 618 default: break;
414 default: break;
415 }
416 break;
417 } 619 }
418 default: break; 620 break;
419 } 621 }
420 }); 622 default: break;
421 out.push_back(preDefined + indent() + temp[0] + s(" = "sv) + temp[1] + nll(assignment)); 623 }
624 if (oneLined) {
625 out.push_back((preDefine.empty() ? indent() + temp[0] : preDefine) + s(" = "sv) + temp[1] + nll(assignment));
626 } else {
627 out.push_back((preDefine.empty() ? Empty : preDefine + nll(assignment)) + indent() + temp[0] + s(" = "sv) + temp[1] + nll(assignment));
628 }
422 } 629 }
423 void transformIfClosure(ast_node* ifNode, std::vector<std::string>& out) { 630
631 void transformIf(If_t* ifNode, std::vector<std::string>& out, bool withClosure = false) {
424 std::vector<std::string> temp; 632 std::vector<std::string> temp;
425 temp.push_back(s("(function()"sv) + nll(ifNode)); 633 if (withClosure) {
426 pushScope(); 634 temp.push_back(s("(function()"sv) + nll(ifNode));
635 pushScope();
636 }
637 std::list<std::pair<IfCond_t*, Body_t*>> ifCondPairs;
638 ifCondPairs.emplace_back();
427 ifNode->traverse([&](ast_node* node) { 639 ifNode->traverse([&](ast_node* node) {
428 switch (node->getId()) { 640 switch (node->getId()) {
429 case "IfCond"_id: { 641 case "IfCond"_id:
430 std::vector<std::string> tmp; 642 ifCondPairs.back().first = static_cast<IfCond_t*>(node);
431 auto exp = node->getChild(0);
432 transformExp(exp, tmp);
433 _buf << indent() << "if "sv << tmp.front() << " then"sv << nll(exp);
434 temp.push_back(clearBuf());
435 return traversal::Return; 643 return traversal::Return;
436 }
437 case "Body"_id: 644 case "Body"_id:
438 transformBody(node, temp); 645 ifCondPairs.back().second = static_cast<Body_t*>(node);
646 ifCondPairs.emplace_back();
439 return traversal::Return; 647 return traversal::Return;
440 default: return traversal::Continue; 648 default: return traversal::Continue;
441 } 649 }
442 }); 650 });
443 popScope(); 651 for (const auto& pair : ifCondPairs) {
444 temp.push_back(indent() + s("end)()"sv)); 652 if (pair.first) {
653 std::vector<std::string> tmp;
654 auto condition = pair.first->condition.get();
655 transformExp(condition, tmp);
656 _buf << indent() << (pair == ifCondPairs.front() ? ""sv : "else"sv) <<
657 "if "sv << tmp.front() << " then"sv << nll(condition);
658 temp.push_back(clearBuf());
659 }
660 if (pair.second) {
661 if (!pair.first) {
662 temp.push_back(indent() + s("else"sv) + nll(pair.second));
663 }
664 pushScope();
665 transformBody(pair.second, temp, withClosure);
666 popScope();
667 if (!pair.first) {
668 temp.push_back(indent() + s("end"sv) + nll(pair.second));
669 }
670 }
671 }
672 if (withClosure) {
673 popScope();
674 temp.push_back(indent() + s("end)()"sv));
675 }
445 out.push_back(join(temp)); 676 out.push_back(join(temp));
446 } 677 }
447 678
448 void transformExpList(ast_node* expList, std::vector<std::string>& out) { 679 void transformIfClosure(If_t* ifNode, std::vector<std::string>& out) {
680 transformIf(ifNode, out, true);
681 }
682
683 void transformExpList(ExpList_t* expList, std::vector<std::string>& out) {
449 std::vector<std::string> temp; 684 std::vector<std::string> temp;
450 expList->eachChild([&](ast_node* node) { 685 for (auto exp : expList->exprs.objects()) {
451 switch (node->getId()) { 686 transformExp(static_cast<Exp_t*>(exp), temp);
452 case "Exp"_id: transformExp(node, temp); break; 687 }
453 default: break;
454 }
455 });
456 out.push_back(join(temp, ", "sv)); 688 out.push_back(join(temp, ", "sv));
457 } 689 }
458 690
459 void transformExpListLow(ast_node* expListLow, std::vector<std::string>& out) { 691 void transformExpListLow(ExpListLow_t* expListLow, std::vector<std::string>& out) {
460 std::vector<std::string> temp; 692 std::vector<std::string> temp;
461 expListLow->eachChild([&](ast_node* node) { 693 for (auto exp : expListLow->exprs.objects()) {
462 switch (node->getId()) { 694 transformExp(static_cast<Exp_t*>(exp), temp);
463 case "Exp"_id: transformExp(node, temp); break; 695 }
464 default: break;
465 }
466 });
467 out.push_back(join(temp, ", "sv)); 696 out.push_back(join(temp, ", "sv));
468 } 697 }
469 698
470 void transformExp(ast_node* exp, std::vector<std::string>& out) { 699 void transformExp(Exp_t* exp, std::vector<std::string>& out) {
471 std::vector<std::string> temp; 700 std::vector<std::string> temp;
472 exp->eachChild([&](ast_node* node) { 701 transformValue(exp->value, temp);
473 switch (node->getId()) { 702 for (auto _opValue : exp->opValues.objects()) {
474 case "Value"_id: transformValue(node, temp); break; 703 auto opValue = static_cast<exp_op_value_t*>(_opValue);
475 case "exp_op_value"_id: transform_exp_op_value(node, temp); break; 704 transformBinaryOperator(opValue->op, temp);
476 default: break; 705 transformValue(opValue->value, temp);
477 } 706 }
478 });
479 out.push_back(join(temp, " "sv)); 707 out.push_back(join(temp, " "sv));
480 } 708 }
481 709
482 void transform_exp_op_value(ast_node* exp_op_value, std::vector<std::string>& out) { 710 void transformValue(Value_t* value, std::vector<std::string>& out) {
483 exp_op_value->eachChild([&](ast_node* node) { 711 auto item = value->item.get();
484 switch (node->getId()) { 712 switch (item->getId()) {
485 case "BinaryOperator"_id: transformBinaryOperator(node, out); break; 713 case "SimpleValue"_id: transformSimpleValue(static_cast<SimpleValue_t*>(item), out); break;
486 case "Value"_id: transformValue(node, out); break; 714 case "simple_table"_id: transform_simple_table(item, out); break;
487 default: break; 715 case "ChainValue"_id: transformChainValue(static_cast<ChainValue_t*>(item), out); break;
488 } 716 case "String"_id: transformString(static_cast<String_t*>(item), out); break;
489 }); 717 default: break;
490 } 718 }
491
492 void transformValue(ast_node* value, std::vector<std::string>& out) {
493 value->eachChild([&](ast_node* node) {
494 switch (node->getId()) {
495 case "SimpleValue"_id: transformSimpleValue(node, out); break;
496 case "simple_table"_id: transform_simple_table(node, out); break;
497 case "ChainValue"_id: transformChainValue(node, out); break;
498 case "String"_id: transformString(node, out); break;
499 default: break;
500 }
501 });
502 } 719 }
503 720
504 void transformChainValue(ast_node* chainValue, std::vector<std::string>& out) { 721 void transformChainValue(ChainValue_t* chainValue, std::vector<std::string>& out) {
505 std::vector<std::string> temp; 722 std::vector<std::string> temp;
506 bool hasInvokeArgs = false; 723 auto caller = chainValue->caller.get();
507 chainValue->eachChild([&](ast_node* node) { 724 switch (caller->getId()) {
508 switch (node->getId()) { 725 case "Chain"_id: transformChain(static_cast<Chain_t*>(caller), temp); break;
509 case "Chain"_id: transformChain(node, temp); break; 726 case "Callable"_id: transformCallable(static_cast<Callable_t*>(caller), temp, chainValue->arguments); break;
510 case "Callable"_id: transformCallable(node, temp); break; 727 default: break;
511 case "InvokeArgs"_id: 728 }
512 hasInvokeArgs = true; 729 if (chainValue->arguments) {
513 transformInvokeArgs(node, temp); 730 transformInvokeArgs(chainValue->arguments, temp);
514 break; 731 out.push_back(temp[0] + s("("sv) + temp[1] + s(")"sv));
515 default: break; 732 } else {
516 } 733 out.push_back(temp[0]);
517 }); 734 }
518 out.push_back(hasInvokeArgs ? (temp[0] + s("("sv) + temp[1] + s(")"sv)) : temp[0]);
519 } 735 }
520 736
521 void transformCallable(ast_node* callable, std::vector<std::string>& out) { 737 void transformCallable(Callable_t* callable, std::vector<std::string>& out, bool invoke) {
522 callable->eachChild([&](ast_node* node) { 738 auto item = callable->item.get();
523 switch (node->getId()) { 739 switch (item->getId()) {
524 case "Name"_id: transformName(node, out); break; 740 case "Name"_id: transformName(static_cast<Name_t*>(item), out); break;
525 case "SelfName"_id: transformSelfName(node, out); break; 741 case "SelfName"_id: transformSelfName(static_cast<SelfName_t*>(item), out, invoke); break;
526 case "VarArg"_id: transformVarArg(node, out); break; 742 case "VarArg"_id: out.push_back(s("..."sv)); break;
527 case "Parens"_id: transformParens(node, out); break; 743 case "Parens"_id: transformParens(static_cast<Parens_t*>(item), out); break;
528 default: break; 744 default: break;
529 } 745 }
530 });
531 } 746 }
532 747
533 void transformParens(ast_node* parans, std::vector<std::string>& out) { 748 void transformParens(Parens_t* parans, std::vector<std::string>& out) {
534 std::vector<std::string> temp; 749 std::vector<std::string> temp;
535 parans->eachChild([&](ast_node* node) { 750 transformExp(parans->expr, temp);
536 switch (node->getId()) {
537 case "Exp"_id: transformExp(node, temp); break;
538 default: break;
539 }
540 });
541 out.push_back(s("("sv) + temp.front() + s(")"sv)); 751 out.push_back(s("("sv) + temp.front() + s(")"sv));
542 } 752 }
543 753
544 void transformSimpleValue(ast_node* simpleValue, std::vector<std::string>& out) { 754 void transformSimpleValue(SimpleValue_t* simpleValue, std::vector<std::string>& out) {
545 simpleValue->eachChild([&](ast_node* node) { 755 auto node = simpleValue->value.get();
546 switch (node->getId()) { 756 switch (node->getId()) {
547 case "const_value"_id: transform_const_value(node, out); break; 757 case "const_value"_id: transform_const_value(node, out); break;
548 case "If"_id: transformIf(node, out); break; 758 case "If"_id: transformIfClosure(static_cast<If_t*>(node), out); break;
549 case "Switch"_id: transformSwitch(node, out); break; 759 case "Switch"_id: transformSwitch(node, out); break;
550 case "With"_id: transformWith(node, out); break; 760 case "With"_id: transformWith(node, out); break;
551 case "ClassDecl"_id: transformClassDecl(node, out); break; 761 case "ClassDecl"_id: transformClassDecl(node, out); break;
552 case "ForEach"_id: transformForEach(node, out); break; 762 case "ForEach"_id: transformForEachClosure(static_cast<ForEach_t*>(node), out); break;
553 case "For"_id: transformFor(node, out); break; 763 case "For"_id: transformForClosure(static_cast<For_t*>(node), out); break;
554 case "While"_id: transformWhile(node, out); break; 764 case "While"_id: transformWhile(node, out); break;
555 case "Do"_id: transformDo(node, out); break; 765 case "Do"_id: transformDo(node, out); break;
556 case "unary_exp"_id: transform_unary_exp(node, out); break; 766 case "unary_exp"_id: transform_unary_exp(static_cast<unary_exp_t*>(node), out); break;
557 case "TblComprehension"_id: transformTblComprehension(node, out); break; 767 case "TblComprehension"_id: transformTblComprehension(node, out); break;
558 case "TableLit"_id: transformTableLit(node, out); break; 768 case "TableLit"_id: transformTableLit(static_cast<TableLit_t*>(node), out); break;
559 case "Comprehension"_id: transformComprehension(node, out); break; 769 case "Comprehension"_id: transformComprehension(static_cast<Comprehension_t*>(node), out); break;
560 case "FunLit"_id: transformFunLit(node, out); break; 770 case "FunLit"_id: transformFunLit(static_cast<FunLit_t*>(node), out); break;
561 case "Num"_id: transformNum(node, out); break; 771 case "Num"_id: transformNum(static_cast<Num_t*>(node), out); break;
562 default: break; 772 default: break;
563 } 773 }
564 });
565 } 774 }
566 775
567 void transformFunLit(ast_node* funLit, std::vector<std::string>& out) { 776 void transformFunLit(FunLit_t* funLit, std::vector<std::string>& out) {
568 std::vector<std::string> temp; 777 std::vector<std::string> temp;
569 bool isFatArrow = false; 778 bool isFatArrow = toString(funLit->arrow) == "=>"sv;
570 bool hasArgsDef = false;
571 ast_node* body = nullptr;
572 pushScope(); 779 pushScope();
573 funLit->eachChild([&](ast_node* node) { 780 if (auto argsDef = funLit->argsDef.get()) {
574 switch (node->getId()) { 781 transformFnArgsDef(argsDef, temp);
575 case "FnArgsDef"_id: 782 if (funLit->body) {
576 hasArgsDef = true; 783 transformBody(funLit->body, temp, true);
577 transformFnArgsDef(node, temp); 784 } else {
578 break; 785 temp.push_back(Empty);
579 case "fn_arrow"_id:
580 isFatArrow = toString(node) == "=>"sv;
581 break;
582 case "Body"_id:
583 transformBody(node, temp);
584 body = node;
585 break;
586 default: break;
587 } 786 }
588 });
589 popScope();
590 if (hasArgsDef) {
591 auto& args = temp[0]; 787 auto& args = temp[0];
592 auto& initArgs = temp[1]; 788 auto& initArgs = temp[1];
593 auto& bodyCodes = temp[2]; 789 auto& bodyCodes = temp[2];
594 _buf << "function("sv << 790 _buf << "function("sv <<
595 (isFatArrow ? s("self"sv) + s(args.empty() ? ""sv : ", "sv) : Empty) << 791 (isFatArrow ? s("self, "sv) : Empty) <<
596 args << ')' << nll(funLit) << 792 args << ')' << nlr(argsDef) <<
597 (initArgs.empty() ? Empty : initArgs) << 793 initArgs << bodyCodes;
598 (body ? bodyCodes : Empty) <<
599 indent() << "end"sv;
600 out.push_back(clearBuf());
601 } else { 794 } else {
602 auto& bodyCodes = temp[0]; 795 if (funLit->body) {
603 out.push_back( 796 transformBody(funLit->body, temp, true);
604 s("function()"sv) + nll(funLit) + 797 } else {
605 (body ? bodyCodes : Empty) + 798 temp.push_back(Empty);
606 indent() + s("end"sv) 799 }
607 ); 800 auto& bodyCodes = temp.back();
801 _buf << "function("sv <<
802 (isFatArrow ? s("self"sv) : Empty) <<
803 ')' << nll(funLit) << bodyCodes;
608 } 804 }
805 popScope();
806 _buf << indent() << "end"sv;
807 out.push_back(clearBuf());
609 } 808 }
610 809
611 void transformBody(ast_node* body, std::vector<std::string>& out) { 810 void transformBody(Body_t* body, std::vector<std::string>& out, bool implicitReturn = false) {
811 if (implicitReturn) {
812 auto last = lastStatementFrom(body);
813 if (ast_is<ExpList_t>(last->content)) {
814 auto expList = static_cast<ExpList_t*>(last->content.get());
815 auto expListLow = new_ptr<ExpListLow_t>();
816 expListLow->exprs = expList->exprs;
817 auto returnNode = new_ptr<Return_t>();
818 returnNode->valueList.set(expListLow);
819 auto statement = ast_cast<Statement_t>(last);
820 statement->content.set(returnNode);
821 }
822 }
612 std::vector<std::string> temp; 823 std::vector<std::string> temp;
613 body->traverse([&](ast_node* node) { 824 body->traverse([&](ast_node* node) {
614 switch (node->getId()) { 825 switch (node->getId()) {
615 case "Statement"_id: 826 case "Statement"_id:
616 transformStatement(node, temp); 827 transformStatement(static_cast<Statement_t*>(node), temp);
617 return traversal::Return; 828 return traversal::Return;
618 default: return traversal::Continue; 829 default: return traversal::Continue;
619 } 830 }
@@ -621,290 +832,739 @@ private:
621 out.push_back(join(temp)); 832 out.push_back(join(temp));
622 } 833 }
623 834
624 void transformFnArgsDef(ast_node* argsDef, std::vector<std::string>& out) { 835 void transformReturn(Return_t* returnNode, std::vector<std::string>& out) {
625 argsDef->eachChild([&](ast_node* node) { 836 if (auto valueList = returnNode->valueList.get()) {
626 switch (node->getId()) { 837 if (auto singleValue = singleValueFrom(valueList)) {
627 case "FnArgDefList"_id: transformFnArgDefList(node, out); break; 838 if (auto comp = singleValue->getByPath({"SimpleValue"_id, "Comprehension"_id})) {
628 case "outer_var_shadow"_id: transform_outer_var_shadow(node, out); break; 839 transformCompReturn(static_cast<Comprehension_t*>(comp), out);
629 default: break; 840 } else {
841 transformValue(singleValue, out);
842 out.back() = indent() + s("return "sv) + out.back() + nlr(returnNode);
843 }
844 } else {
845 std::vector<std::string> temp;
846 transformExpListLow(valueList, temp);
847 out.push_back(indent() + s("return "sv) + temp.front() + nlr(returnNode));
630 } 848 }
631 }); 849 } else {
850 out.push_back(s("return"sv) + nll(returnNode));
851 }
632 } 852 }
633 853
634 void transform_outer_var_shadow(ast_node* shadow, std::vector<std::string>& out) { 854 void transformFnArgsDef(FnArgsDef_t* argsDef, std::vector<std::string>& out) {
855 if (!argsDef->defList) {
856 out.push_back(Empty);
857 return;
858 }
859 transformFnArgDefList(argsDef->defList, out);
860 if (argsDef->shadowOption) {
861 transform_outer_var_shadow(argsDef->shadowOption, out);
862 }
863 }
864
865 void transform_outer_var_shadow(outer_var_shadow_t* shadow, std::vector<std::string>& out) {
635 markVarShadowed(); 866 markVarShadowed();
636 shadow->eachChild([&](ast_node* node) { 867 if (shadow->varList) {
637 switch (node->getId()) { 868 for (auto name : shadow->varList->names.objects()) {
638 case "NameList"_id: 869 addToAllowList(toString(name));
639 node->eachChild([&](ast_node* child) {
640 if (child->getId() == "Name"_id) {
641 this->addToAllowList(toString(child));
642 }
643 });
644 break;
645 default: break;
646 } 870 }
647 }); 871 }
648 } 872 }
649 873
650 void transformFnArgDefList(ast_node* argDefList, std::vector<std::string>& out) { 874 void transformFnArgDefList(FnArgDefList_t* argDefList, std::vector<std::string>& out) {
651 std::vector<std::vector<std::string>> argItems; 875 struct ArgItem {
652 const int Name = 0; 876 std::string name;
653 const int AssignSelf = 1; 877 std::string assignSelf;
654 const int DefaultVal = 2; 878 std::string defaultVal;
655 argDefList->eachChild([&](ast_node* node) { 879 };
656 switch (node->getId()) { 880 std::list<ArgItem> argItems;
657 case "FnArgDef"_id: { 881 std::vector<std::string> temp;
658 argItems.emplace_back(2); 882 std::string varNames;
659 auto& arg = argItems.back(); 883 bool assignSelf = false;
660 node->eachChild([&](ast_node* child) { 884 for (auto _def : argDefList->definitions.objects()) {
661 switch (child->getId()) { 885 auto def = static_cast<FnArgDef_t*>(_def);
662 case "Name"_id: arg[Name] = toString(child); break; 886 auto& arg = argItems.emplace_back();
663 case "SelfName"_id: 887 switch (def->name->getId()) {
664 child->eachChild([&](ast_node* inner) { 888 case "Name"_id: arg.name = toString(def->name); break;
665 switch (inner->getId()) { 889 case "SelfName"_id: {
666 case "self_class_name"_id: 890 assignSelf = true;
667 arg[Name] = toString(inner->getChild(0)); 891 auto selfName = static_cast<SelfName_t*>(def->name.get());
668 arg[AssignSelf] = s("self.__class."sv) + arg.front(); 892 switch (selfName->name->getId()) {
669 break; 893 case "self_class_name"_id:
670 case "self_class"_id: 894 arg.name = toString(selfName->name->getFirstChild());
671 arg[Name] = "self.__class"sv; 895 arg.assignSelf = s("self.__class."sv) + arg.name;
672 break; 896 break;
673 case "self_name"_id: 897 case "self_class"_id:
674 arg[Name] = toString(inner->getChild(0)); 898 arg.name = "self.__class"sv;
675 arg[AssignSelf] = s("self."sv) + arg.front(); 899 break;
676 break; 900 case "self_name"_id:
677 case "self"_id: 901 arg.name = toString(selfName->name->getFirstChild());
678 arg[Name] = "self"sv; 902 arg.assignSelf = s("self."sv) + arg.name;
679 break; 903 break;
680 } 904 case "self"_id:
681 }); 905 arg.name = "self"sv;
682 break; 906 break;
683 case "Exp"_id: transformExp(child, arg); break; 907 default: break;
684 default: break; 908 }
685 }
686 });
687 break; 909 break;
688 } 910 }
689 case "VarArg"_id:
690 argItems.emplace_back(2);
691 argItems.back()[Name] = "..."sv;
692 break;
693 default: break;
694 } 911 }
695 }); 912 if (def->defaultValue) {
696 std::string varNames; 913 transformExp(static_cast<Exp_t*>(def->defaultValue.get()), temp);
697 for (const auto& item : argItems) { 914 arg.defaultVal = temp.front();
698 if (varNames.empty()) { 915 temp.clear();
699 varNames = item[Name]; 916 _buf << indent() << "if "sv << arg.name << " == nil then"sv << nll(def) <<
700 } else { 917 indent(1) << arg.name << " = "sv << arg.defaultVal << nll(def) <<
701 varNames.append(s(", "sv) + item[Name]); 918 indent() << "end"sv << nll(def);
702 } 919 }
703 forceAddToScope(item[Name]); 920 if (varNames.empty()) varNames = arg.name;
921 else varNames.append(s(", "sv) + arg.name);
922 forceAddToScope(arg.name);
704 } 923 }
705 for (const auto& item : argItems) { 924 if (argDefList->varArg) {
706 if (item.size() == 3 && !item[DefaultVal].empty()) { 925 auto& arg = argItems.emplace_back();
707 _buf << indent() << "if "sv << item[Name] << " == nil then"sv << nll(argDefList) << 926 arg.name = "..."sv;
708 indent() << '\t' << item[Name] << " = "sv << item[DefaultVal] << nll(argDefList) << 927 if (varNames.empty()) varNames = arg.name;
709 indent() << "end"sv << nll(argDefList); 928 else varNames.append(s(", "sv) + arg.name);
710 }
711 } 929 }
712 std::string initCodes = clearBuf(); 930 std::string initCodes = clearBuf();
713 std::vector<std::array<const std::string*, 2>> assignSelfVars; 931 if (assignSelf) {
714 for (const auto& item : argItems) { 932 auto sjoin = [](const decltype(argItems)& items, int index) {
715 if (!item[AssignSelf].empty()) { 933 std::string result;
716 assignSelfVars.push_back({&item[AssignSelf], &item[Name]}); 934 for (auto it = items.begin(); it != items.end(); ++it) {
717 } 935 if (it->assignSelf.empty()) continue;
718 } 936 if (result.empty()) result = (&it->name)[index];
719 auto sjoin = [](const decltype(assignSelfVars)& items, int index) { 937 else result.append(s(", "sv) + (&it->name)[index]);
720 std::string result; 938 }
721 for (auto it = items.begin(); it != items.end(); ++it) { 939 return result;
722 if (result.empty()) result = *((*it)[index]); 940 };
723 else result.append(s(", "sv) + *((*it)[index])); 941 std::string sleft = sjoin(argItems, 1);
724 } 942 std::string sright = sjoin(argItems, 0);
725 return result; 943 initCodes.append(indent() + sleft + s(" = "sv) + sright + nll(argDefList));
726 };
727 std::string sleft = sjoin(assignSelfVars, 0);
728 std::string sright = sjoin(assignSelfVars, 1);
729 if (!assignSelfVars.empty()) {
730 initCodes.append(sleft + s(" = "sv) + sright + nll(argDefList));
731 } 944 }
732 out.push_back(varNames); 945 out.push_back(varNames);
733 out.push_back(initCodes); 946 out.push_back(initCodes);
734 } 947 }
735 948
736 void transformChain(ast_node* chain, std::vector<std::string>& out) { 949 void transformSelfName(SelfName_t* selfName, std::vector<std::string>& out, bool invoke) {
737 chain->eachChild([&](ast_node* node) { 950 auto name = selfName->name.get();
738 switch (node->getId()) { 951 switch (name->getId()) {
739 case "chain_call"_id: transform_chain_call(node, out); break; 952 case "self_class_name"_id:
740 case "chain_item"_id: transform_chain_item(node, out); break; 953 out.push_back(s("self.__class."sv) + toString(name->getFirstChild()));
741 case "chain_dot_chain"_id: transform_chain_dot_chain(node, out); break; 954 break;
742 case "ColonChain"_id: transformColonChain(node, out); break; 955 case "self_class"_id:
743 default: break; 956 out.push_back(s("self.__class"sv));
744 } 957 break;
745 }); 958 case "self_name"_id:
959 out.push_back(s("self"sv) + s(invoke ? ":"sv : "."sv) + toString(name->getFirstChild()));
960 break;
961 case "self"_id:
962 out.push_back(s("self"sv));
963 break;
964 }
965 }
966
967 void transformChain(Chain_t* chain, std::vector<std::string>& out) {
968 auto item = chain->item.get();
969 switch (item->getId()) {
970 case "chain_call"_id: transform_chain_call(static_cast<chain_call_t*>(item), out); break;
971 case "chain_item"_id: transformChainItems(static_cast<chain_item_t*>(item)->chain, out); break;
972 case "chain_dot_chain"_id: transform_chain_dot_chain(item, out); break;
973 case "ColonChain"_id: transformColonChain(static_cast<ColonChain_t*>(item), out); break;
974 default: break;
975 }
746 } 976 }
747 977
748 void transform_chain_call(ast_node* chain_call, std::vector<std::string>& out) { 978 void transform_chain_call(chain_call_t* chain_call, std::vector<std::string>& out) {
749 std::vector<std::string> temp; 979 std::vector<std::string> temp;
750 chain_call->eachChild([&](ast_node* node) { 980 auto caller = chain_call->caller.get();
751 switch (node->getId()) { 981 switch (caller->getId()) {
752 case "Callable"_id: transformCallable(node, temp); break; 982 case "Callable"_id: transformCallable(static_cast<Callable_t*>(caller), temp, true); break;
753 case "String"_id: transformString(node, temp); break; 983 case "String"_id: transformString(static_cast<String_t*>(caller), temp); break;
754 case "ChainItems"_id: transformChainItems(node, temp); break; 984 default: break;
755 default: break; 985 }
756 } 986 transformChainItems(chain_call->chain, temp);
757 });
758 out.push_back(join(temp)); 987 out.push_back(join(temp));
759 } 988 }
760 989
761 void transformChainItems(ast_node* chainItems, std::vector<std::string>& out) { 990 void transformChainItems(ChainItems_t* chainItems, std::vector<std::string>& out) {
762 std::vector<std::string> temp; 991 std::vector<std::string> temp;
763 chainItems->eachChild([&](ast_node* node) { 992 for (auto _chainItem : chainItems->simpleChain.objects()) {
764 switch (node->getId()) { 993 auto chainItem = static_cast<ChainItem_t*>(_chainItem);
765 case "ChainItem"_id: transformChainItem(node, temp); break; 994 transformChainItem(chainItem, temp);
766 case "ColonChain"_id: transformColonChain(node, temp); break; 995 }
767 default: break; 996 if (chainItems->colonChain) {
768 } 997 transformColonChain(chainItems->colonChain, temp);
769 }); 998 }
770 out.push_back(join(temp)); 999 out.push_back(join(temp));
771 } 1000 }
772 1001
773 void transformChainItem(ast_node* chainItem, std::vector<std::string>& out) { 1002 void transformChainItem(ChainItem_t* chainItem, std::vector<std::string>& out) {
774 chainItem->eachChild([&](ast_node* node) { 1003 auto item = chainItem->item.get();
775 switch (node->getId()) { 1004 switch (item->getId()) {
776 case "Invoke"_id: transformInvoke(node, out); break; 1005 case "Invoke"_id: transformInvoke(static_cast<Invoke_t*>(item), out); break;
777 case "DotChainItem"_id: 1006 case "DotChainItem"_id:
778 out.push_back(s("."sv) + toString(node->getChild(0))); 1007 out.push_back(s("."sv) + toString(item->getFirstChild()));
779 break; 1008 break;
780 case "Slice"_id: transformSlice(node, out); break; 1009 case "Slice"_id: transformSlice(item, out); break;
1010 case "Exp"_id:
1011 transformExp(static_cast<Exp_t*>(item), out);
1012 out.back() = s("["sv) + out.back() + s("]"sv);
1013 break;
1014 default: break;
1015 }
1016 }
1017
1018 void transformInvoke(Invoke_t* invoke, std::vector<std::string>& out) {
1019 auto argument = invoke->argument.get();
1020 switch (argument->getId()) {
1021 case "FnArgs"_id: transformFnArgs(static_cast<FnArgs_t*>(argument), out); break;
1022 case "SingleString"_id: transformSingleString(static_cast<SingleString_t*>(argument), out); break;
1023 case "DoubleString"_id: transformDoubleString(static_cast<DoubleString_t*>(argument), out); break;
1024 case "LuaString"_id: transformLuaString(static_cast<LuaString_t*>(argument), out); break;
1025 default: break;
1026 }
1027 }
1028
1029 void transformFnArgs(FnArgs_t* fnArgs, std::vector<std::string>& out) {
1030 std::vector<std::string> temp;
1031 for (auto node : fnArgs->args.objects()) {
1032 transformExp(static_cast<Exp_t*>(node), temp);
1033 }
1034 std::string args = join(temp, ", "sv);
1035 out.push_back(args.empty() ? s("()"sv) : s("("sv) + args + s(")"sv));
1036 }
1037
1038 void transformColonChain(ColonChain_t* colonChain, std::vector<std::string>& out) {
1039 std::vector<std::string> temp;
1040 temp.push_back(s(":"sv) + toString(colonChain->colonChain->name));
1041 if (colonChain->invokeChain) {
1042 transform_invoke_chain(colonChain->invokeChain, temp);
1043 }
1044 out.push_back(join(temp));
1045 }
1046
1047 void transform_invoke_chain(invoke_chain_t* invoke_chain, std::vector<std::string>& out) {
1048 std::vector<std::string> temp;
1049 transformInvoke(invoke_chain->invoke, temp);
1050 if (invoke_chain->chain) {
1051 transformChainItems(invoke_chain->chain, temp);
1052 }
1053 out.push_back(join(temp));
1054 }
1055
1056 void transform_unary_exp(unary_exp_t* unary_exp, std::vector<std::string>& out) {
1057 std::string op = toString(unary_exp->m_begin.m_it, unary_exp->item->m_begin.m_it);
1058 std::vector<std::string> temp{op + (op == "not"sv ? op + " " : Empty)};
1059 transformExp(unary_exp->item, temp);
1060 out.push_back(join(temp));
1061 }
1062
1063 void transformName(Name_t* name, std::vector<std::string>& out) {
1064 out.push_back(toString(name));
1065 }
1066
1067 void transformNum(Num_t* num, std::vector<std::string>& out) {
1068 out.push_back(toString(num));
1069 }
1070
1071 void transformTableLit(TableLit_t* tableLit, std::vector<std::string>& out) {
1072 std::vector<std::string> temp;
1073 ast_node* lastNode = nullptr;
1074 for (auto _tableValue : tableLit->values.objects()) {
1075 auto tableValue = static_cast<TableValue_t*>(_tableValue);
1076 auto value = tableValue->value.get();
1077 switch (value->getId()) {
1078 case "KeyValue"_id:
781 case "Exp"_id: 1079 case "Exp"_id:
782 transformExp(node, out); 1080 if (value->getId() == "Exp"_id) {
783 out.back() = s("["sv) + out.back() + s("]"sv); 1081 transformExp(static_cast<Exp_t*>(value), temp);
1082 } else {
1083 transformKeyValue(static_cast<KeyValue_t*>(value), temp);
1084 }
1085 temp.back() = (lastNode ? s(","sv) + nll(lastNode) : Empty) + indent(1) + temp.back();
1086 lastNode = value;
784 break; 1087 break;
785 default: break; 1088 default: break;
786 } 1089 }
787 }); 1090 }
1091 out.push_back(s("{"sv) + nll(tableLit) + join(temp) + nlr(tableLit) + indent() + s("}"sv));
788 } 1092 }
789 1093
790 void transformInvoke(ast_node* invoke, std::vector<std::string>& out) { 1094 void transformComprehension(Comprehension_t* comp, std::vector<std::string>& out) {
791 invoke->eachChild([&](ast_node* node) { 1095 std::vector<std::string> temp;
792 switch (node->getId()) { 1096 std::string accum = getValidName("_accum_");
793 case "FnArgs"_id: transformFnArgs(node, out); break; 1097 std::string len = getValidName("_len_");
794 case "SingleString"_id: transformSingleString(node, out); break; 1098 addToScope(accum);
795 case "DoubleString"_id: transformDoubleString(node, out); break; 1099 addToScope(len);
796 case "LuaString"_id: transformLuaString(node, out); break; 1100 transformExp(comp->value, temp);
1101 auto compInner = comp->forLoop.get();
1102 switch (compInner->compFor->getId()) {
1103 case "CompForEach"_id:
1104 transformCompForEach(
1105 static_cast<CompForEach_t*>(compInner->compFor.get()), temp);
1106 break;
1107 case "CompFor"_id: transformCompFor(compInner->compFor, temp); break;
1108 default: break;
1109 }
1110 std::vector<std::string> clauseCodes;
1111 for (auto clause : compInner->clauses.objects()) {
1112 pushScope();
1113 auto child = clause->getFirstChild();
1114 switch (child->getId()) {
1115 case "CompForEach"_id:
1116 transformCompForEach(static_cast<CompForEach_t*>(child), clauseCodes);
1117 break;
1118 case "CompFor"_id: transformCompFor(child, clauseCodes); break;
1119 case "Exp"_id:
1120 transformExp(static_cast<Exp_t*>(child), clauseCodes);
1121 clauseCodes.back() = indent() + s("if "sv) + clauseCodes.back() + s(" then"sv) + nll(clause);
1122 break;
797 default: break; 1123 default: break;
798 } 1124 }
799 }); 1125 }
1126 for (size_t i = 0; i < compInner->clauses.objects().size(); ++i) {
1127 popScope();
1128 }
1129 _buf << indent() << "local "sv << accum << " = { }"sv << nll(comp);
1130 _buf << indent() << "local "sv << len << " = 1"sv << nll(comp);
1131 _buf << temp.back();
1132 pushScope();
1133 if (clauseCodes.empty()) {
1134 _buf << indent() << accum << "["sv << len << "] = "sv << temp.front() << nll(comp);
1135 _buf << indent() << len << " = "sv << len << " + 1"sv << nll(comp);
1136 } else {
1137 _buf << join(clauseCodes);
1138 _buf << indent(int(clauseCodes.size())) << accum << "["sv << len << "] = "sv << temp.front() << nll(comp);
1139 _buf << indent(int(clauseCodes.size())) << len << " = "sv << len << " + 1"sv << nll(comp);
1140 for (int ind = int(clauseCodes.size()) - 1; ind > -1 ; --ind) {
1141 _buf << indent(ind) << "end"sv << nll(comp);
1142 }
1143 }
1144 popScope();
1145 _buf << indent() << "end"sv << nll(comp);
1146 out.push_back(accum);
1147 out.push_back(clearBuf());
800 } 1148 }
801 1149
802 void transformFnArgs(ast_node* fnArgs, std::vector<std::string>& out) { 1150 void transformCompInPlace(Comprehension_t* comp, const std::string& expStr, std::vector<std::string>& out) {
803 std::vector<std::string> temp; 1151 std::vector<std::string> temp;
804 fnArgs->eachChild([&](ast_node* node) { 1152 pushScope();
805 switch (node->getId()) { 1153 transformComprehension(comp, temp);
806 case "Exp"_id: transformExp(node, temp); break; 1154 out.push_back(
807 default: break; 1155 s("do"sv) + nll(comp) +
1156 temp.back() +
1157 indent() + expStr + s(" = "sv) + temp.front() + nll(comp));
1158 popScope();
1159 out.back() = out.back() + indent() + s("end"sv) + nlr(comp);
1160 }
1161
1162 void transformCompReturn(Comprehension_t* comp, std::vector<std::string>& out) {
1163 std::vector<std::string> temp;
1164 transformComprehension(comp, temp);
1165 out.push_back(temp.back() + indent() + s("return "sv) + temp.front() + nlr(comp));
1166 }
1167
1168 void transformCompClosure(Comprehension_t* comp, std::vector<std::string>& out) {
1169 std::vector<std::string> temp;
1170 std::string before = s("(function()"sv) + nll(comp);
1171 pushScope();
1172 transformComprehension(comp, temp);
1173 out.push_back(
1174 before +
1175 temp.back() +
1176 indent() + s("return "sv) + temp.front() + nlr(comp));
1177 popScope();
1178 out.back() = out.back() + indent() + s("end)()"sv);
1179 }
1180
1181 void transformForEachHead(AssignableNameList_t* nameList, ast_node* loopTarget, std::vector<std::string>& out) {
1182 std::vector<std::string> temp;
1183 transformAssignableNameList(nameList, temp);
1184 switch (loopTarget->getId()) {
1185 case "star_exp"_id: {
1186 auto star_exp = static_cast<star_exp_t*>(loopTarget);
1187 auto listName = getValidName("_list_");
1188 auto indexName = getValidName("_index_");
1189 addToScope(listName);
1190 addToScope(indexName);
1191 transformExp(star_exp->value, temp);
1192 _buf << indent() << "local "sv << listName << " = "sv << temp.back() << nll(nameList);
1193 _buf << indent() << "for "sv << indexName << " = 1, #"sv << listName << " do"sv << nlr(loopTarget);
1194 _buf << indent(1) << "local "sv << temp.front() << " = "sv << listName << "["sv << indexName << "]"sv << nll(nameList);
1195 out.push_back(clearBuf());
1196 break;
808 } 1197 }
809 }); 1198 case "Exp"_id:
810 std::string args = join(temp, ", "sv); 1199 transformExp(static_cast<Exp_t*>(loopTarget), temp);
811 out.push_back(args.empty() ? s("()"sv) : s("("sv) + args + s(")"sv)); 1200 _buf << indent() << "for "sv << temp.front() << " in "sv << temp.back() << " do"sv << nlr(loopTarget);
1201 out.push_back(clearBuf());
1202 break;
1203 case "ExpList"_id:
1204 transformExpList(static_cast<ExpList_t*>(loopTarget), temp);
1205 _buf << indent() << "for "sv << temp.front() << " in "sv << temp.back() << " do"sv << nlr(loopTarget);
1206 out.push_back(clearBuf());
1207 break;
1208 default: break;
1209 }
812 } 1210 }
813 1211
814 void transformColonChain(ast_node* colonChain, std::vector<std::string>& out) { 1212 void transformCompForEach(CompForEach_t* comp, std::vector<std::string>& out) {
1213 transformForEachHead(comp->nameList, comp->loopValue, out);
1214 }
1215
1216 void transformAssignableNameList(AssignableNameList_t* nameList, std::vector<std::string>& out) {
815 std::vector<std::string> temp; 1217 std::vector<std::string> temp;
816 colonChain->eachChild([&](ast_node* node) { 1218 for (auto node : nameList->items.objects()) {
817 switch (node->getId()) { 1219 switch (node->getId()) {
818 case "ColonChainItem"_id: 1220 case "Name"_id:
819 temp.push_back(s(":"sv) + toString(node->getChild(0))); 1221 transformName(static_cast<Name_t*>(node), temp);
1222 break;
1223 case "TableLit"_id:
1224 transformTableLit(static_cast<TableLit_t*>(node), temp);
820 break; 1225 break;
821 case "invoke_chain"_id: transform_invoke_chain(node, temp); break;
822 default: break; 1226 default: break;
823 } 1227 }
824 }); 1228 }
1229 out.push_back(join(temp, ", "sv));
1230 }
1231
1232 void transformInvokeArgs(InvokeArgs_t* invokeArgs, std::vector<std::string>& out) {
1233 std::vector<std::string> temp;
1234 if (invokeArgs->argsList) {
1235 transformExpList(invokeArgs->argsList, temp);
1236 }
1237 if (invokeArgs->argsTableBlock) {
1238 transform_invoke_args_with_table(invokeArgs->argsTableBlock, temp);
1239 }
1240 if (invokeArgs->tableBlock) {
1241 transformTableBlock(invokeArgs->tableBlock, temp);
1242 }
1243 out.push_back(join(temp, ", "sv));
1244 }
1245
1246 void transformForHead(For_t* forNode, std::vector<std::string>& out) {
1247 std::vector<std::string> temp;
1248 std::string varName = toString(forNode->varName);
1249 transformExp(forNode->startValue, temp);
1250 transformExp(forNode->stopValue, temp);
1251 if (forNode->stepValue) {
1252 transformExp(forNode->stepValue->value, temp);
1253 } else {
1254 temp.emplace_back();
1255 }
1256 _buf << indent() << "for "sv << varName << " = "sv << temp[0] << ", "sv << temp[1] << (temp[2].empty() ? Empty : s(", "sv) + temp[2]) << " do"sv << nll(forNode);
1257 out.push_back(clearBuf());
1258 }
1259
1260 void transformFor(For_t* forNode, std::vector<std::string>& out) {
1261 std::vector<std::string> temp;
1262 transformForHead(forNode, temp);
1263 pushScope();
1264 transformBody(forNode->body, temp);
1265 popScope();
1266 out.push_back(temp[0] + temp[1] + indent() + s("end"sv) + nlr(forNode));
1267 }
1268
1269 void transformForClosure(For_t* forNode, std::vector<std::string>& out) {
1270 std::vector<std::string> temp;
1271 std::string accum = getValidName("_accum_");
1272 std::string len = getValidName("_len_");
1273 addToScope(accum);
1274 addToScope(len);
1275 _buf << "(function()"sv << nll(forNode);
1276 pushScope();
1277 _buf << indent() << "local "sv << accum << " = { }"sv << nll(forNode);
1278 _buf << indent() << "local "sv << len << " = 1"sv << nll(forNode);
1279 temp.push_back(clearBuf());
1280 transformForHead(forNode, temp);
1281 auto last = lastStatementFrom(forNode->body);
1282 bool hasTableItem = ast_is<ExpList_t>(last->content);
1283 if (hasTableItem) {
1284 _buf << accum << "["sv << len << "]"sv;
1285 std::string assignLeft = clearBuf();
1286 auto expList = toAst<ExpList_t>(assignLeft, ExpList);
1287 auto assignment = new_ptr<Assignment_t>();
1288 assignment->assignable.set(expList);
1289 auto expListLow = new_ptr<ExpListLow_t>();
1290 expListLow->exprs = ast_cast<ExpList_t>(last->content)->exprs;
1291 auto assign = new_ptr<Assign_t>();
1292 assign->value.set(expListLow);
1293 assignment->target.set(assign);
1294 last->content.set(assignment);
1295 }
1296 pushScope();
1297 transformBody(forNode->body, temp);
1298 temp.push_back(indent() + len + s(" = "sv) + len + s(" + 1"sv) + nlr(forNode->body));
1299 popScope();
1300 temp.push_back(indent() + s("end"sv) + nlr(forNode) + indent() + s("return "sv) + accum + nlr(forNode));
1301 popScope();
1302 temp.push_back(indent() + s("end)()"sv) + nlr(forNode));
825 out.push_back(join(temp)); 1303 out.push_back(join(temp));
826 } 1304 }
827 1305
828 void transform_invoke_chain(ast_node* invoke_chain, std::vector<std::string>& out) { 1306 void transformForInPlace(For_t* forNode, std::vector<std::string>& out, ExpList_t* assignExpList) {
829 std::vector<std::string> temp; 1307 std::vector<std::string> temp;
830 invoke_chain->eachChild([&](ast_node* node) { 1308 std::string accum = getValidName("_accum_");
831 switch (node->getId()) { 1309 std::string len = getValidName("_len_");
832 case "Invoke"_id: transformInvoke(node, temp); break; 1310 _buf << indent() << "do"sv << nll(forNode);
833 case "ChainItems"_id: transformChainItems(node, temp); break; 1311 pushScope();
1312 addToScope(accum);
1313 addToScope(len);
1314 _buf << indent() << "local "sv << accum << " = { }"sv << nll(forNode);
1315 _buf << indent() << "local "sv << len << " = 1"sv << nll(forNode);
1316 temp.push_back(clearBuf());
1317 transformForHead(forNode, temp);
1318 auto last = lastStatementFrom(forNode->body);
1319 bool hasTableItem = ast_is<ExpList_t>(last->content);
1320 if (hasTableItem) {
1321 _buf << accum << "["sv << len << "]"sv;
1322 std::string assignLeft = clearBuf();
1323 auto expList = toAst<ExpList_t>(assignLeft, ExpList);
1324 auto assignment = new_ptr<Assignment_t>();
1325 assignment->assignable.set(expList);
1326 auto expListLow = new_ptr<ExpListLow_t>();
1327 expListLow->exprs = ast_cast<ExpList_t>(last->content)->exprs;
1328 auto assign = new_ptr<Assign_t>();
1329 assign->value.set(expListLow);
1330 assignment->target.set(assign);
1331 last->content.set(assignment);
1332 }
1333 pushScope();
1334 transformBody(forNode->body, temp);
1335 temp.push_back(indent() + len + s(" = "sv) + len + s(" + 1"sv) + nlr(forNode->body));
1336 popScope();
1337 temp.push_back(indent() + s("end"sv) + nlr(forNode));
1338 transformExpList(assignExpList, temp);
1339 temp.back() = indent() + temp.back() + s(" = "sv) + accum + nlr(forNode);
1340 popScope();
1341 temp.push_back(indent() + s("end"sv) + nlr(forNode));
1342 out.push_back(join(temp));
1343 }
1344
1345 void transformBinaryOperator(BinaryOperator_t* node, std::vector<std::string>& out) {
1346 out.push_back(toString(node));
1347 }
1348
1349 void transformForEach(ForEach_t* forEach, std::vector<std::string>& out) {
1350 std::vector<std::string> temp;
1351 transformForEachHead(forEach->nameList, forEach->loopValue, temp);
1352 pushScope();
1353 transformBody(forEach->body, temp);
1354 popScope();
1355 out.push_back(temp[0] + temp[1] + indent() + s("end"sv) + nlr(forEach));
1356 }
1357
1358 void transformForEachClosure(ForEach_t* forEach, std::vector<std::string>& out) {
1359 std::vector<std::string> temp;
1360 std::string accum = getValidName("_accum_");
1361 std::string len = getValidName("_len_");
1362 addToScope(accum);
1363 addToScope(len);
1364 _buf << "(function()"sv << nll(forEach);
1365 pushScope();
1366 _buf << indent() << "local "sv << accum << " = { }"sv << nll(forEach);
1367 _buf << indent() << "local "sv << len << " = 1"sv << nll(forEach);
1368 temp.push_back(clearBuf());
1369 transformForEachHead(forEach->nameList, forEach->loopValue, temp);
1370 auto last = lastStatementFrom(forEach->body);
1371 bool hasTableItem = ast_is<ExpList_t>(last->content);
1372 if (hasTableItem) {
1373 _buf << accum << "["sv << len << "]"sv;
1374 std::string assignLeft = clearBuf();
1375 auto expList = toAst<ExpList_t>(assignLeft, ExpList);
1376 auto assignment = new_ptr<Assignment_t>();
1377 assignment->assignable.set(expList);
1378 auto expListLow = new_ptr<ExpListLow_t>();
1379 expListLow->exprs = ast_cast<ExpList_t>(last->content)->exprs;
1380 auto assign = new_ptr<Assign_t>();
1381 assign->value.set(expListLow);
1382 assignment->target.set(assign);
1383 last->content.set(assignment);
1384 }
1385 pushScope();
1386 transformBody(forEach->body, temp);
1387 temp.push_back(indent() + len + s(" = "sv) + len + s(" + 1"sv) + nlr(forEach->body));
1388 popScope();
1389 temp.push_back(indent() + s("end"sv) + nlr(forEach) + indent() + s("return "sv) + accum + nlr(forEach));
1390 popScope();
1391 temp.push_back(indent() + s("end)()"sv) + nlr(forEach));
1392 out.push_back(join(temp));
1393 }
1394
1395 void transformForEachInPlace(ForEach_t* forEach, std::vector<std::string>& out, ExpList_t* assignExpList) {
1396 std::vector<std::string> temp;
1397 std::string accum = getValidName("_accum_");
1398 std::string len = getValidName("_len_");
1399 _buf << indent() << "do"sv << nll(forEach);
1400 pushScope();
1401 addToScope(accum);
1402 addToScope(len);
1403 _buf << indent() << "local "sv << accum << " = { }"sv << nll(forEach);
1404 _buf << indent() << "local "sv << len << " = 1"sv << nll(forEach);
1405 temp.push_back(clearBuf());
1406 transformForEachHead(forEach->nameList, forEach->loopValue, temp);
1407 auto last = lastStatementFrom(forEach->body);
1408 bool hasTableItem = ast_is<ExpList_t>(last->content);
1409 if (hasTableItem) {
1410 _buf << accum << "["sv << len << "]"sv;
1411 std::string assignLeft = clearBuf();
1412 auto expList = toAst<ExpList_t>(assignLeft, ExpList);
1413 auto assignment = new_ptr<Assignment_t>();
1414 assignment->assignable.set(expList);
1415 auto expListLow = new_ptr<ExpListLow_t>();
1416 expListLow->exprs = ast_cast<ExpList_t>(last->content)->exprs;
1417 auto assign = new_ptr<Assign_t>();
1418 assign->value.set(expListLow);
1419 assignment->target.set(assign);
1420 last->content.set(assignment);
1421 }
1422 pushScope();
1423 transformBody(forEach->body, temp);
1424 temp.push_back(indent() + len + s(" = "sv) + len + s(" + 1"sv) + nlr(forEach->body));
1425 popScope();
1426 temp.push_back(indent() + s("end"sv) + nlr(forEach));
1427 transformExpList(assignExpList, temp);
1428 temp.back() = indent() + temp.back() + s(" = "sv) + accum + nlr(forEach);
1429 popScope();
1430 temp.push_back(indent() + s("end"sv) + nlr(forEach));
1431 out.push_back(join(temp));
1432 }
1433
1434 void transformKeyValue(KeyValue_t* keyValue, std::vector<std::string>& out) {
1435 auto item = keyValue->item.get();
1436 switch (item->getId()) {
1437 case "variable_pair"_id:
1438 out.push_back(toString(static_cast<variable_pair_t*>(item)->name));
1439 break;
1440 case "normal_pair"_id: {
1441 auto pair = static_cast<normal_pair_t*>(item);
1442 auto key = pair->key.get();
1443 std::vector<std::string> temp;
1444 switch (key->getId()) {
1445 case "KeyName"_id: transformKeyName(static_cast<KeyName_t*>(key), temp); break;
1446 case "Exp"_id:
1447 transformExp(static_cast<Exp_t*>(key), temp);
1448 temp.back() = s("["sv) + temp.back() + s("]"sv);
1449 break;
1450 case "DoubleString"_id: transformDoubleString(static_cast<DoubleString_t*>(key), temp); break;
1451 case "SingleString"_id: transformSingleString(static_cast<SingleString_t*>(key), temp); break;
1452 default: break;
1453 }
1454 auto value = pair->value.get();
1455 switch (value->getId()) {
1456 case "Exp"_id: transformExp(static_cast<Exp_t*>(value), temp); break;
1457 case "TableBlock"_id: transformTableBlock(static_cast<TableBlock_t*>(value), temp); break;
1458 default: break;
1459 }
1460 out.push_back(temp[0] + s(" = "sv) + temp[1]);
1461 break;
1462 }
1463 default: break;
1464 }
1465 }
1466
1467 void transformKeyName(KeyName_t* keyName, std::vector<std::string>& out) {
1468 auto name = keyName->name.get();
1469 switch (name->getId()) {
1470 case "SelfName"_id: transformSelfName(static_cast<SelfName_t*>(name), out, false); break;
1471 case "_Name"_id: out.push_back(toString(name)); break;
1472 default: break;
1473 }
1474 }
1475
1476 void transformLuaString(LuaString_t* luaString, std::vector<std::string>& out) {
1477 out.push_back(toString(luaString));
1478 }
1479
1480 void transformSingleString(SingleString_t* singleString, std::vector<std::string>& out) {
1481 out.push_back(toString(singleString));
1482 }
1483
1484 void transformDoubleString(DoubleString_t* doubleString, std::vector<std::string>& out) {
1485 std::vector<std::string> temp;
1486 for (auto _seg : doubleString->segments.objects()) {
1487 auto seg = static_cast<double_string_content_t*>(_seg);
1488 auto content = seg->content.get();
1489 switch (content->getId()) {
1490 case "double_string_inner"_id:
1491 temp.push_back(s("\""sv) + toString(content) + s("\""sv));
1492 break;
1493 case "Exp"_id:
1494 transformExp(static_cast<Exp_t*>(content), temp);
1495 temp.back() = s("tostring("sv) + temp.back() + s(")"sv);
1496 break;
834 default: break; 1497 default: break;
835 } 1498 }
836 }); 1499 }
837 out.push_back(join(temp)); 1500 out.push_back(join(temp, " .. "sv));
838 } 1501 }
839 1502
840 void transformUpdate(ast_node* node, std::vector<std::string>& out) {noop(node, out);} 1503 void transformString(String_t* string, std::vector<std::string>& out) {
1504 auto str = string->str.get();
1505 switch (str->getId()) {
1506 case "SingleString"_id: transformSingleString(static_cast<SingleString_t*>(str), out); break;
1507 case "DoubleString"_id: transformDoubleString(static_cast<DoubleString_t*>(str), out); break;
1508 case "LuaString"_id: transformLuaString(static_cast<LuaString_t*>(str), out); break;
1509 default: break;
1510 }
1511 }
841 1512
1513 void transformUpdate(ast_node* node, std::vector<std::string>& out) {noop(node, out);}
842 void transformImport(ast_node* node, std::vector<std::string>& out) {noopnl(node, out);} 1514 void transformImport(ast_node* node, std::vector<std::string>& out) {noopnl(node, out);}
843 void transformWhile(ast_node* node, std::vector<std::string>& out) {noopnl(node, out);} 1515 void transformWhile(ast_node* node, std::vector<std::string>& out) {noopnl(node, out);}
844 void transformWith(ast_node* node, std::vector<std::string>& out) {noopnl(node, out);} 1516 void transformWith(ast_node* node, std::vector<std::string>& out) {noopnl(node, out);}
845 void transformFor(ast_node* node, std::vector<std::string>& out) {noopnl(node, out);}
846 void transformIf(ast_node* node, std::vector<std::string>& out) { noopnl(node, out); }
847 void transformForEach(ast_node* node, std::vector<std::string>& out) {noopnl(node, out);}
848 void transformSwitch(ast_node* node, std::vector<std::string>& out) {noopnl(node, out);} 1517 void transformSwitch(ast_node* node, std::vector<std::string>& out) {noopnl(node, out);}
849 void transformReturn(ast_node* node, std::vector<std::string>& out) {noopnl(node, out);}
850 void transformTableBlock(ast_node* node, std::vector<std::string>& out) {noopnl(node, out);} 1518 void transformTableBlock(ast_node* node, std::vector<std::string>& out) {noopnl(node, out);}
851 void transformLocal(ast_node* node, std::vector<std::string>& out) {noopnl(node, out);} 1519 void transformLocal(ast_node* node, std::vector<std::string>& out) {noopnl(node, out);}
852 void transformExport(ast_node* node, std::vector<std::string>& out) {noopnl(node, out);} 1520 void transformExport(ast_node* node, std::vector<std::string>& out) {noopnl(node, out);}
853 void transformBreakLoop(ast_node* node, std::vector<std::string>& out) {noopnl(node, out);} 1521 void transformBreakLoop(ast_node* node, std::vector<std::string>& out) {noopnl(node, out);}
854 void transform_unless_line(ast_node* node, std::vector<std::string>& out) {noop(node, out);} 1522 void transform_unless_line(ast_node* node, std::vector<std::string>& out) {noop(node, out);}
855 void transformCompInner(ast_node* node, std::vector<std::string>& out) {noop(node, out);}
856 void transform_simple_table(ast_node* node, std::vector<std::string>& out) {noop(node, out);} 1523 void transform_simple_table(ast_node* node, std::vector<std::string>& out) {noop(node, out);}
857 void transformString(ast_node* node, std::vector<std::string>& out) {noop(node, out);}
858 void transformInvokeArgs(ast_node* node, std::vector<std::string>& out) {noop(node, out);}
859 void transformName(ast_node* node, std::vector<std::string>& out) {noop(node, out);}
860 void transformSelfName(ast_node* node, std::vector<std::string>& out) {noop(node, out);}
861 void transform_const_value(ast_node* node, std::vector<std::string>& out) {noop(node, out);} 1524 void transform_const_value(ast_node* node, std::vector<std::string>& out) {noop(node, out);}
862 void transformClassDecl(ast_node* node, std::vector<std::string>& out) {noop(node, out);} 1525 void transformClassDecl(ast_node* node, std::vector<std::string>& out) {noop(node, out);}
863 void transformDo(ast_node* node, std::vector<std::string>& out) {noop(node, out);} 1526 void transformDo(ast_node* node, std::vector<std::string>& out) {noop(node, out);}
864 void transform_unary_exp(ast_node* node, std::vector<std::string>& out) {noop(node, out);}
865 void transformTblComprehension(ast_node* node, std::vector<std::string>& out) {noop(node, out);} 1527 void transformTblComprehension(ast_node* node, std::vector<std::string>& out) {noop(node, out);}
866 void transformTableLit(ast_node* node, std::vector<std::string>& out) {noop(node, out);}
867 void transformComprehension(ast_node* node, std::vector<std::string>& out) {noop(node, out);}
868 void transformNum(ast_node* node, std::vector<std::string>& out) {noop(node, out);}
869 void transformVarArg(ast_node* node, std::vector<std::string>& out) {noop(node, out);}
870 void transformBinaryOperator(ast_node* node, std::vector<std::string>& out) {noop(node, out);}
871 void transform_chain_item(ast_node* node, std::vector<std::string>& out) {noop(node, out);}
872 void transform_chain_dot_chain(ast_node* node, std::vector<std::string>& out) {noop(node, out);} 1528 void transform_chain_dot_chain(ast_node* node, std::vector<std::string>& out) {noop(node, out);}
873 void transformSlice(ast_node* node, std::vector<std::string>& out) {noop(node, out);} 1529 void transformSlice(ast_node* node, std::vector<std::string>& out) {noop(node, out);}
874 void transformSingleString(ast_node* node, std::vector<std::string>& out) {noop(node, out);} 1530 void transformCompFor(ast_node* node, std::vector<std::string>& out) {noop(node, out);}
875 void transformDoubleString(ast_node* node, std::vector<std::string>& out) {noop(node, out);} 1531 void transformCompClause(ast_node* node, std::vector<std::string>& out) {noop(node, out);}
876 void transformLuaString(ast_node* node, std::vector<std::string>& out) {noop(node, out);} 1532 void transform_invoke_args_with_table(ast_node* node, std::vector<std::string>& out) {noop(node, out);}
877}; 1533};
878 1534
879const std::string MoonCompliler::Empty; 1535const std::string MoonCompliler::Empty;
880 1536
881int main() 1537int main()
882{ 1538{
883 std::string s = R"TestCodesHere(a = 998 1539 std::string s = R"TestCodesHere(
884f, d = (-> 1540-- vararg bubbling
885 joop = 2302 + 567 1541f = (...) -> #{...}
1542
1543dont_bubble = ->
1544 [x for x in ((...)-> print ...)("hello")]
1545
1546k = [x for x in ((...)-> print ...)("hello")]
1547
1548j = for i=1,10
1549 (...) -> print ...
1550
1551-- bubble me
886 1552
887 (hi, a, b = Vec2(100,200), c, d, ... using nil) -> 1553m = (...) ->
888 d = "中文" 1554 [x for x in *{...} when f(...) > 4]
889 hi = 1021
890 1555
891 a,b,c,d = 1,2,3,4 1556x = for i in *{...} do i
1557y = [x for x in *{...}]
1558z = [x for x in hallo when f(...) > 4]
892 1559
893 hello[232], (5+5)[121], hello, x[99] = 100, 200, 300
894 1560
895 joop = 12), 123 if true else print("a",1,2)\abc(998).x 1561a = for i=1,10 do ...
896 1562
897a, b = if hello 1563b = for i=1,10
898 "hello" 1564 -> print ...
899else
900 "nothing", "yeah"
901 1565
902 1566
903a, b = if hello 1567)TestCodesHere";
904 if yeah then "one", "two" else "mmhh"
905else
906 print "the other"
907 "nothing", "yeah")TestCodesHere";
908 1568
909 MoonCompliler{}.complile(s); 1569 MoonCompliler{}.complile(s);
910 1570