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.cpp822
1 files changed, 766 insertions, 56 deletions
diff --git a/MoonParser/moon_ast.cpp b/MoonParser/moon_ast.cpp
index 2a6ca61..4fb0212 100644
--- a/MoonParser/moon_ast.cpp
+++ b/MoonParser/moon_ast.cpp
@@ -2,23 +2,15 @@
2#include <unordered_set> 2#include <unordered_set>
3#include <stack> 3#include <stack>
4#include <algorithm> 4#include <algorithm>
5#include <sstream>
6#include <vector> 5#include <vector>
6#include <numeric>
7#include <memory>
8#include <array>
9#include <sstream>
10#include <string_view>
11using namespace std::string_view_literals;
7#include "moon_ast.h" 12#include "moon_ast.h"
8 13
9input& trim(input& s)
10{
11 s.erase(s.begin(), std::find_if(s.begin(), s.end(), [](input::value_type ch)
12 {
13 return !std::isspace(ch);
14 }));
15 s.erase(std::find_if(s.rbegin(), s.rend(), [](input::value_type ch)
16 {
17 return !std::isspace(ch);
18 }).base(), s.end());
19 return s;
20}
21
22const input& AstLeaf::getValue() 14const input& AstLeaf::getValue()
23{ 15{
24 if (_value.empty()) 16 if (_value.empty())
@@ -144,50 +136,768 @@ AST_IMPL(BlockEnd)
144 136
145#include <iostream> 137#include <iostream>
146 138
147int main() 139template<class T, class... Args>
140inline std::unique_ptr<T> MakeUnique(Args&&... args) {
141 return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
142}
143
144inline std::string s(std::string_view sv) {
145 return std::string(sv);
146}
147
148class MoonCompliler
148{ 149{
149 std::string s = R"TestCodesHere( 150public:
150thing = { var: 10, hello: "world", func: => @var } 151 void complile(const std::string& codes) {
151import hello, \func from thing 152 input input = _converter.from_bytes(codes);
152)TestCodesHere"; 153 error_list el;
153 input i = Converter{}.from_bytes(s); 154 BlockEnd_t* root = nullptr;
154 155 State st;
155 error_list el; 156 if (parse(input, BlockEnd, el, root, &st)) {
156 BlockEnd_t* root = nullptr; 157 std::cout << "matched!\n";
157 State st; 158 std::vector<std::string> out;
158 if (parse(i, BlockEnd, el, root, &st)) 159 root->eachChild([&](ast_node* node) {
159 { 160 switch (node->getId()) {
160 std::cout << "matched!\n"; 161 case "Block"_id:
161 int indent = 0; 162 pushScope();
162 root->visit([&](ast_node* node) 163 transformBlock(node, out);
163 { 164 popScope();
164 if (std::string("Seperator") != node->getName()) 165 break;
165 { 166 default: break;
166 indent++; 167 }
167 for (int i = 0; i < indent; i++) std::cout << " "; 168 });
168 std::cout << "{" << node->getName() << "\n"; 169 std::string result;
169 } 170 if (out.size() == 1) {
170 return false; 171 result = std::move(out.front());
171 }, [&](ast_node* node) 172 } else if (out.size() > 1) {
172 { 173 result = join(out, "\n");
173 if (std::string("Seperator") != node->getName()) 174 }
174 { 175 std::cout << result << '\n';
175 for (int i = 0; i < indent; i++) std::cout << " "; 176 } else {
176 std::cout << "}\n" ; 177 std::cout << "not matched!\n";
177 indent--; 178 for (error_list::iterator it = el.begin(); it != el.end(); ++it) {
178 } 179 const error& err = *it;
179 return false; 180 std::cout << "line " << err.m_begin.m_line << ", col " << err.m_begin.m_col << ": syntax error\n";
180 }); 181 }
181 } 182 }
182 else 183 }
183 { 184
184 std::cout << "not matched!\n"; 185private:
185 for (error_list::iterator it = el.begin(); it != el.end(); ++it) 186 Converter _converter;
186 { 187 std::ostringstream _buf;
187 const error& err = *it; 188 std::string _newLine = "\n";
188 std::cout << "line " << err.m_begin.m_line << ", col " << err.m_begin.m_col << ": syntax error\n"; 189 std::vector<int> _lineTable;
190 struct Scope {
191 std::unique_ptr<std::unordered_set<std::string>> vars;
192 std::unique_ptr<std::unordered_set<std::string>> allows;
193 };
194 std::vector<Scope> _scopes;
195 static const std::string Empty;
196
197 void pushScope() {
198 _scopes.emplace_back();
199 _scopes.back().vars = MakeUnique<std::unordered_set<std::string>>();
200 }
201
202 bool isDefined(const std::string& name, bool checkShadowScope = false) {
203 bool isDefined = false;
204 for (auto it = _scopes.rbegin(); it != _scopes.rend(); ++it) {
205 auto vars = it->vars.get();
206 if (vars->find(name) != vars->end()) {
207 isDefined = true;
208 break;
209 }
210 if (checkShadowScope && it->allows) break;
211 }
212 return isDefined;
213 }
214
215 void markVarShadowed() {
216 auto& scope = _scopes.back();
217 scope.allows = MakeUnique<std::unordered_set<std::string>>();
218 }
219
220 void addToAllowList(const std::string& name) {
221 auto& scope = _scopes.back();
222 scope.allows->insert(name);
223 }
224
225 void forceAddToScope(const std::string& name) {
226 auto& scope = _scopes.back();
227 scope.vars->insert(name);
228 }
229
230 bool addToScope(const std::string& name) {
231 bool defined = false;
232 auto& scope = _scopes.back();
233 decltype(scope.allows.get()) allows = nullptr;
234 for (auto it = _scopes.rbegin(); it != _scopes.rend(); ++it) {
235 if (it->allows) allows = it->allows.get();
236 }
237 if (allows) {
238 bool shadowed = allows->find(name) == allows->end();
239 defined = isDefined(name, shadowed);
240 } else {
241 defined = isDefined(name);
242 }
243 if (!defined) scope.vars->insert(name);
244 return !defined;
245 }
246
247 void popScope() {
248 _scopes.pop_back();
249 }
250
251 const std::string nll(ast_node* node) {
252 _lineTable.push_back(node->m_begin.m_line);
253 return _newLine;
254 }
255
256 const std::string nlr(ast_node* node) {
257 _lineTable.push_back(node->m_end.m_line);
258 return _newLine;
259 }
260
261 std::string indent() {
262 return std::string(_scopes.size() - 1, '\t');
263 }
264
265 std::string clearBuf() {
266 std::string str = _buf.str();
267 _buf.str("");
268 _buf.clear();
269 return str;
270 }
271
272 std::string join(const std::vector<std::string>& items) {
273 if (items.empty()) return Empty;
274 else if (items.size() == 1) return items.front();
275 return std::accumulate(items.begin()+1, items.end(), items.front(),
276 [&](const std::string& a, const std::string& b) { return a + b; });
277 }
278
279 std::string join(const std::vector<std::string>& items, std::string_view sep) {
280 if (items.empty()) return Empty;
281 else if (items.size() == 1) return items.front();
282 std::string sepStr = s(sep);
283 return std::accumulate(items.begin()+1, items.end(), items.front(),
284 [&](const std::string& a, const std::string& b) { return a + sepStr + b; });
285 }
286
287 std::string toString(ast_node* node) {
288 auto str = _converter.to_bytes(std::u32string(node->m_begin.m_it, node->m_end.m_it));
289 return trim(str);
290 }
291
292 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));
294 out.push_back(s("<"sv) + node->getName() + s(">"sv) + trim(str));
295 // out.push_back(trim(str));
296 }
297
298 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));
300 out.push_back(s("<"sv) + node->getName() + s(">"sv) + trim(str) + nll(node));
301 // out.push_back(trim(str) + nll(node));
302 }
303
304 void transformBlock(ast_node* block, std::vector<std::string>& out) {
305 std::vector<std::string> temp;
306 block->eachChild([&](ast_node* node) {
307 switch (node->getId()) {
308 case "Line"_id: transformLine(node, temp); break;
309 default: break;
310 }
311 });
312 out.push_back(join(temp));
313 }
314
315 void transformLine(ast_node* line, std::vector<std::string>& out) {
316 line->eachChild([&](ast_node* node) {
317 switch (node->getId()) {
318 case "Statement"_id: transformStatement(node, out); break;
319 default: break;
320 }
321 });
322 }
323
324 void transformStatement(ast_node* statement, std::vector<std::string>& out) {
325 std::vector<std::string> temp;
326 auto transformContent = [&](ast_node* node, std::vector<std::string>& out) {
327 switch (node->getId()) {
328 case "Import"_id: transformImport(node, temp); break;
329 case "While"_id: transformWhile(node, temp); break;
330 case "With"_id: transformWith(node, temp); break;
331 case "For"_id: transformFor(node, temp); break;
332 case "ForEach"_id: transformForEach(node, temp); break;
333 case "Switch"_id: transformSwitch(node, temp); break;
334 case "Return"_id: transformReturn(node, temp); break;
335 case "Local"_id: transformLocal(node, temp); break;
336 case "Export"_id: transformExport(node, temp); break;
337 case "BreakLoop"_id: transformBreakLoop(node, temp); break;
338 case "Assignment"_id: transformAssignment(node, temp); break;
339 case "ExpList"_id:
340 transformExpList(node, temp);
341 temp.back() = indent() + temp.back() + nll(node);
342 break;
343 default: break;
344 }
345 };
346 if (statement->getChildCount() > 1) {
347 pushScope();
348 transformContent(statement->getChild(0), out);
349 popScope();
350 transform_statement_appendix(statement->getChild(1), temp);
351 } else {
352 transformContent(statement->getChild(0), out);
353 }
354 switch (temp.size()) {
355 case 1: // body
356 out.push_back(std::move(temp.front()));
357 break;
358 case 2: // body, if
359 out.push_back(join({std::move(temp[1]), std::move(temp[0]), s("end"sv) + nlr(statement)}));
360 break;
361 case 3: // body, if, else
362 out.push_back(join({std::move(temp[1]), std::move(temp[0]), std::move(temp[2]), s("end"sv) + nlr(statement)}));
363 break;
364 }
365 }
366
367 void transform_statement_appendix(ast_node* appendix, std::vector<std::string>& out) {
368 appendix->eachChild([&](ast_node* node) {
369 switch (node->getId()) {
370 case "if_else_line"_id: transform_if_else_line(node, out); break;
371 case "unless_line"_id: transform_unless_line(node, out); break;
372 case "CompInner"_id: transformCompInner(node, out); break;
373 default: break;
374 }
375 });
376 }
377
378 void transform_if_else_line(ast_node* if_else_line, std::vector<std::string>& out) {
379 std::vector<std::string> temp;
380 if_else_line->eachChild([&](ast_node* node) {
381 switch (node->getId()) {
382 case "Exp"_id:
383 pushScope();
384 transformExp(node, temp);
385 popScope();
386 break;
387 default: break;
388 }
389 });
390 out.push_back(indent() + s("if "sv) + temp[0] + s(" then"sv) + nll(if_else_line));
391 out.push_back(indent() + s("else "sv) + nll(if_else_line) + indent() + '\t' + temp[1] + nll(if_else_line));
392 }
393
394 void transformAssignment(ast_node* assignment, std::vector<std::string>& out) {
395 std::vector<std::string> temp;
396 std::string preDefined;
397 assignment->eachChild([&](ast_node* node) {
398 switch (node->getId()) {
399 case "ExpList"_id: {
400 std::vector<std::string> preDefs;
401 std::vector<ast_node*> values;
402 node->traverse([&](ast_node* child) {
403 if (child->getId() == "Value"_id) {
404 auto target = child->getByPath({"ChainValue"_id, "Callable"_id, "Name"_id});
405 if (target) {
406 auto name = toString(target);
407 if (addToScope(name)) {
408 preDefs.push_back(name);
409 }
410 }
411 return traversal::Return;
412 }
413 return traversal::Continue;
414 });
415 if (!preDefs.empty()) {
416 preDefined = indent() + s("local "sv) + join(preDefs, ", "sv) + nll(node);
417 }
418 transformExpList(node, temp);
419 break;
420 }
421 case "Update"_id: transformUpdate(node, temp); break;
422 case "Assign"_id: transformAssign(node, temp); break;
423 default: break;
424 }
425 });
426 out.push_back(preDefined + indent() + temp[0] + s(" = "sv) + temp[1] + nll(assignment));
427 }
428
429 void transformExpList(ast_node* expList, std::vector<std::string>& out) {
430 std::vector<std::string> temp;
431 expList->eachChild([&](ast_node* node) {
432 switch (node->getId()) {
433 case "Exp"_id: transformExp(node, temp); break;
434 default: break;
435 }
436 });
437 out.push_back(join(temp, ", "sv));
438 }
439
440 void transformExpListLow(ast_node* expListLow, std::vector<std::string>& out) {
441 std::vector<std::string> temp;
442 expListLow->eachChild([&](ast_node* node) {
443 switch (node->getId()) {
444 case "Exp"_id: transformExp(node, temp); break;
445 default: break;
446 }
447 });
448 out.push_back(join(temp, ", "sv));
449 }
450
451 void transformAssign(ast_node* assign, std::vector<std::string>& out) {
452 assign->eachChild([&](ast_node* node) {
453 switch (node->getId()) {
454 case "With"_id: transformWith(node, out); break;
455 case "If"_id: transformIf(node, out); break;
456 case "Switch"_id: transformSwitch(node, out); break;
457 case "TableBlock"_id: transformTableBlock(node, out); break;
458 case "ExpListLow"_id: transformExpListLow(node, out); break;
459 default: break;
460 }
461 });
462 }
463
464 void transformExp(ast_node* exp, std::vector<std::string>& out) {
465 std::vector<std::string> temp;
466 exp->eachChild([&](ast_node* node) {
467 switch (node->getId()) {
468 case "Value"_id: transformValue(node, temp); break;
469 case "exp_op_value"_id: transform_exp_op_value(node, temp); break;
470 default: break;
471 }
472 });
473 out.push_back(join(temp, " "sv));
474 }
475
476 void transform_exp_op_value(ast_node* exp_op_value, std::vector<std::string>& out) {
477 exp_op_value->eachChild([&](ast_node* node) {
478 switch (node->getId()) {
479 case "BinaryOperator"_id: transformBinaryOperator(node, out); break;
480 case "Value"_id: transformValue(node, out); break;
481 default: break;
482 }
483 });
484 }
485
486 void transformValue(ast_node* value, std::vector<std::string>& out) {
487 value->eachChild([&](ast_node* node) {
488 switch (node->getId()) {
489 case "SimpleValue"_id: transformSimpleValue(node, out); break;
490 case "simple_table"_id: transform_simple_table(node, out); break;
491 case "ChainValue"_id: transformChainValue(node, out); break;
492 case "String"_id: transformString(node, out); break;
493 default: break;
494 }
495 });
496 }
497
498 void transformChainValue(ast_node* chainValue, std::vector<std::string>& out) {
499 std::vector<std::string> temp;
500 bool hasInvokeArgs = false;
501 chainValue->eachChild([&](ast_node* node) {
502 switch (node->getId()) {
503 case "Chain"_id: transformChain(node, temp); break;
504 case "Callable"_id: transformCallable(node, temp); break;
505 case "InvokeArgs"_id:
506 hasInvokeArgs = true;
507 transformInvokeArgs(node, temp);
508 break;
509 default: break;
510 }
511 });
512 out.push_back(hasInvokeArgs ? (temp[0] + s("("sv) + temp[1] + s(")"sv)) : temp[0]);
513 }
514
515 void transformCallable(ast_node* callable, std::vector<std::string>& out) {
516 callable->eachChild([&](ast_node* node) {
517 switch (node->getId()) {
518 case "Name"_id: transformName(node, out); break;
519 case "SelfName"_id: transformSelfName(node, out); break;
520 case "VarArg"_id: transformVarArg(node, out); break;
521 case "Parens"_id: transformParens(node, out); break;
522 default: break;
523 }
524 });
525 }
526
527 void transformParens(ast_node* parans, std::vector<std::string>& out) {
528 std::vector<std::string> temp;
529 parans->eachChild([&](ast_node* node) {
530 switch (node->getId()) {
531 case "Exp"_id: transformExp(node, temp); break;
532 default: break;
533 }
534 });
535 out.push_back(s("("sv) + temp.front() + s(")"sv));
536 }
537
538 void transformSimpleValue(ast_node* simpleValue, std::vector<std::string>& out) {
539 simpleValue->eachChild([&](ast_node* node) {
540 switch (node->getId()) {
541 case "const_value"_id: transform_const_value(node, out); break;
542 case "If"_id: transformIf(node, out); break;
543 case "Switch"_id: transformSwitch(node, out); break;
544 case "With"_id: transformWith(node, out); break;
545 case "ClassDecl"_id: transformClassDecl(node, out); break;
546 case "ForEach"_id: transformForEach(node, out); break;
547 case "For"_id: transformFor(node, out); break;
548 case "While"_id: transformWhile(node, out); break;
549 case "Do"_id: transformDo(node, out); break;
550 case "unary_exp"_id: transform_unary_exp(node, out); break;
551 case "TblComprehension"_id: transformTblComprehension(node, out); break;
552 case "TableLit"_id: transformTableLit(node, out); break;
553 case "Comprehension"_id: transformComprehension(node, out); break;
554 case "FunLit"_id: transformFunLit(node, out); break;
555 case "Num"_id: transformNum(node, out); break;
556 default: break;
557 }
558 });
559 }
560
561 void transformFunLit(ast_node* funLit, std::vector<std::string>& out) {
562 std::vector<std::string> temp;
563 bool isFatArrow = false;
564 bool hasArgsDef = false;
565 ast_node* body = nullptr;
566 pushScope();
567 funLit->eachChild([&](ast_node* node) {
568 switch (node->getId()) {
569 case "FnArgsDef"_id:
570 hasArgsDef = true;
571 transformFnArgsDef(node, temp);
572 break;
573 case "fn_arrow"_id:
574 isFatArrow = toString(node) == "=>"sv;
575 break;
576 case "Body"_id:
577 transformBody(node, temp);
578 body = node;
579 break;
580 default: break;
581 }
582 });
583 popScope();
584 if (hasArgsDef) {
585 auto& args = temp[0];
586 auto& initArgs = temp[1];
587 auto& bodyCodes = temp[2];
588 _buf << "function("sv <<
589 (isFatArrow ? s("self"sv) + s(args.empty() ? ""sv : ", "sv) : Empty) <<
590 args << ')' << nll(funLit) <<
591 (initArgs.empty() ? Empty : initArgs) <<
592 (body ? bodyCodes : Empty) <<
593 indent() << "end"sv;
594 out.push_back(clearBuf());
595 } else {
596 auto& bodyCodes = temp[0];
597 out.push_back(
598 s("function()"sv) + nll(funLit) +
599 (body ? bodyCodes : Empty) +
600 indent() + s("end"sv)
601 );
189 } 602 }
190 } 603 }
191 system("pause"); 604
605 void transformBody(ast_node* body, std::vector<std::string>& out) {
606 body->eachChild([&](ast_node* node) {
607 switch (node->getId()) {
608 case "Block"_id: transformBlock(node, out); break;
609 case "Statement"_id: transformStatement(node, out); break;
610 default: break;
611 }
612 });
613 }
614
615 void transformFnArgsDef(ast_node* argsDef, std::vector<std::string>& out) {
616 argsDef->eachChild([&](ast_node* node) {
617 switch (node->getId()) {
618 case "FnArgDefList"_id: transformFnArgDefList(node, out); break;
619 case "outer_var_shadow"_id: transform_outer_var_shadow(node, out); break;
620 default: break;
621 }
622 });
623 }
624
625 void transform_outer_var_shadow(ast_node* shadow, std::vector<std::string>& out) {
626 markVarShadowed();
627 shadow->eachChild([&](ast_node* node) {
628 switch (node->getId()) {
629 case "NameList"_id:
630 node->eachChild([&](ast_node* child) {
631 if (child->getId() == "Name"_id) {
632 this->addToAllowList(toString(child));
633 }
634 });
635 break;
636 default: break;
637 }
638 });
639 }
640
641 void transformFnArgDefList(ast_node* argDefList, std::vector<std::string>& out) {
642 std::vector<std::vector<std::string>> argItems;
643 const int Name = 0;
644 const int AssignSelf = 1;
645 const int DefaultVal = 2;
646 argDefList->eachChild([&](ast_node* node) {
647 switch (node->getId()) {
648 case "FnArgDef"_id: {
649 argItems.emplace_back(2);
650 auto& arg = argItems.back();
651 node->eachChild([&](ast_node* child) {
652 switch (child->getId()) {
653 case "Name"_id: arg[Name] = toString(child); break;
654 case "SelfName"_id:
655 child->eachChild([&](ast_node* inner) {
656 switch (inner->getId()) {
657 case "self_class_name"_id:
658 arg[Name] = toString(inner->getChild(0));
659 arg[AssignSelf] = s("self.__class."sv) + arg.front();
660 break;
661 case "self_class"_id:
662 arg[Name] = "self.__class"sv;
663 break;
664 case "self_name"_id:
665 arg[Name] = toString(inner->getChild(0));
666 arg[AssignSelf] = s("self."sv) + arg.front();
667 break;
668 case "self"_id:
669 arg[Name] = "self"sv;
670 break;
671 }
672 });
673 break;
674 case "Exp"_id: transformExp(child, arg); break;
675 default: break;
676 }
677 });
678 break;
679 }
680 case "VarArg"_id:
681 argItems.emplace_back(2);
682 argItems.back()[Name] = "..."sv;
683 break;
684 default: break;
685 }
686 });
687 std::string varNames;
688 for (const auto& item : argItems) {
689 if (varNames.empty()) {
690 varNames = item[Name];
691 } else {
692 varNames.append(s(", "sv) + item[Name]);
693 }
694 forceAddToScope(item[Name]);
695 }
696 for (const auto& item : argItems) {
697 if (item.size() == 3 && !item[DefaultVal].empty()) {
698 _buf << indent() << "if "sv << item[Name] << " == nil then"sv << nll(argDefList) <<
699 indent() << '\t' << item[Name] << " = "sv << item[DefaultVal] << nll(argDefList) <<
700 indent() << "end"sv << nll(argDefList);
701 }
702 }
703 std::string initCodes = clearBuf();
704 std::vector<std::array<const std::string*, 2>> assignSelfVars;
705 for (const auto& item : argItems) {
706 if (!item[AssignSelf].empty()) {
707 assignSelfVars.push_back({&item[AssignSelf], &item[Name]});
708 }
709 }
710 auto sjoin = [](const decltype(assignSelfVars)& items, int index) {
711 std::string result;
712 for (auto it = items.begin(); it != items.end(); ++it) {
713 if (result.empty()) result = *((*it)[index]);
714 else result.append(s(", "sv) + *((*it)[index]));
715 }
716 return result;
717 };
718 std::string sleft = sjoin(assignSelfVars, 0);
719 std::string sright = sjoin(assignSelfVars, 1);
720 if (!assignSelfVars.empty()) {
721 initCodes.append(sleft + s(" = "sv) + sright + nll(argDefList));
722 }
723 out.push_back(varNames);
724 out.push_back(initCodes);
725 }
726
727 void transformChain(ast_node* chain, std::vector<std::string>& out) {
728 chain->eachChild([&](ast_node* node) {
729 switch (node->getId()) {
730 case "chain_call"_id: transform_chain_call(node, out); break;
731 case "chain_item"_id: transform_chain_item(node, out); break;
732 case "chain_dot_chain"_id: transform_chain_dot_chain(node, out); break;
733 case "ColonChain"_id: transformColonChain(node, out); break;
734 default: break;
735 }
736 });
737 }
738
739 void transform_chain_call(ast_node* chain_call, std::vector<std::string>& out) {
740 std::vector<std::string> temp;
741 chain_call->eachChild([&](ast_node* node) {
742 switch (node->getId()) {
743 case "Callable"_id: transformCallable(node, temp); break;
744 case "String"_id: transformString(node, temp); break;
745 case "ChainItems"_id: transformChainItems(node, temp); break;
746 default: break;
747 }
748 });
749 out.push_back(join(temp));
750 }
751
752 void transformChainItems(ast_node* chainItems, std::vector<std::string>& out) {
753 std::vector<std::string> temp;
754 chainItems->eachChild([&](ast_node* node) {
755 switch (node->getId()) {
756 case "ChainItem"_id: transformChainItem(node, temp); break;
757 case "ColonChain"_id: transformColonChain(node, temp); break;
758 default: break;
759 }
760 });
761 out.push_back(join(temp));
762 }
763
764 void transformChainItem(ast_node* chainItem, std::vector<std::string>& out) {
765 chainItem->eachChild([&](ast_node* node) {
766 switch (node->getId()) {
767 case "Invoke"_id: transformInvoke(node, out); break;
768 case "DotChainItem"_id:
769 out.push_back(s("."sv) + toString(node->getChild(0)));
770 break;
771 case "Slice"_id: transformSlice(node, out); break;
772 case "Exp"_id:
773 transformExp(node, out);
774 out.back() = s("["sv) + out.back() + s("]"sv);
775 break;
776 default: break;
777 }
778 });
779 }
780
781 void transformInvoke(ast_node* invoke, std::vector<std::string>& out) {
782 invoke->eachChild([&](ast_node* node) {
783 switch (node->getId()) {
784 case "FnArgs"_id: transformFnArgs(node, out); break;
785 case "SingleString"_id: transformSingleString(node, out); break;
786 case "DoubleString"_id: transformDoubleString(node, out); break;
787 case "LuaString"_id: transformLuaString(node, out); break;
788 default: break;
789 }
790 });
791 }
792
793 void transformFnArgs(ast_node* fnArgs, std::vector<std::string>& out) {
794 std::vector<std::string> temp;
795 fnArgs->eachChild([&](ast_node* node) {
796 switch (node->getId()) {
797 case "Exp"_id: transformExp(node, temp); break;
798 default: break;
799 }
800 });
801 std::string args = join(temp, ", ");
802 out.push_back(args.empty() ? "()" : s("(") + args + ")");
803 }
804
805 void transformColonChain(ast_node* colonChain, std::vector<std::string>& out) {
806 std::vector<std::string> temp;
807 colonChain->eachChild([&](ast_node* node) {
808 switch (node->getId()) {
809 case "ColonChainItem"_id:
810 temp.push_back(s(":"sv) + toString(node->getChild(0)));
811 break;
812 case "invoke_chain"_id: transform_invoke_chain(node, temp); break;
813 default: break;
814 }
815 });
816 out.push_back(join(temp));
817 }
818
819 void transform_invoke_chain(ast_node* invoke_chain, std::vector<std::string>& out) {
820 std::vector<std::string> temp;
821 invoke_chain->eachChild([&](ast_node* node) {
822 switch (node->getId()) {
823 case "Invoke"_id: transformInvoke(node, temp); break;
824 case "ChainItems"_id: transformChainItems(node, temp); break;
825 default: break;
826 }
827 });
828 out.push_back(join(temp));
829 }
830
831 void transformUpdate(ast_node* node, std::vector<std::string>& out) {noop(node, out);}
832
833 void transformImport(ast_node* node, std::vector<std::string>& out) {noopnl(node, out);}
834 void transformWhile(ast_node* node, std::vector<std::string>& out) {noopnl(node, out);}
835 void transformWith(ast_node* node, std::vector<std::string>& out) {noopnl(node, out);}
836 void transformIf(ast_node* node, std::vector<std::string>& out) {noopnl(node, out);}
837 void transformFor(ast_node* node, std::vector<std::string>& out) {noopnl(node, out);}
838 void transformForEach(ast_node* node, std::vector<std::string>& out) {noopnl(node, out);}
839 void transformSwitch(ast_node* node, std::vector<std::string>& out) {noopnl(node, out);}
840 void transformReturn(ast_node* node, std::vector<std::string>& out) {noopnl(node, out);}
841 void transformTableBlock(ast_node* node, std::vector<std::string>& out) {noopnl(node, out);}
842 void transformLocal(ast_node* node, std::vector<std::string>& out) {noopnl(node, out);}
843 void transformExport(ast_node* node, std::vector<std::string>& out) {noopnl(node, out);}
844 void transformBreakLoop(ast_node* node, std::vector<std::string>& out) {noopnl(node, out);}
845 void transform_unless_line(ast_node* node, std::vector<std::string>& out) {noop(node, out);}
846 void transformCompInner(ast_node* node, std::vector<std::string>& out) {noop(node, out);}
847 void transform_simple_table(ast_node* node, std::vector<std::string>& out) {noop(node, out);}
848 void transformString(ast_node* node, std::vector<std::string>& out) {noop(node, out);}
849 void transformInvokeArgs(ast_node* node, std::vector<std::string>& out) {noop(node, out);}
850 void transformName(ast_node* node, std::vector<std::string>& out) {noop(node, out);}
851 void transformSelfName(ast_node* node, std::vector<std::string>& out) {noop(node, out);}
852 void transform_const_value(ast_node* node, std::vector<std::string>& out) {noop(node, out);}
853 void transformClassDecl(ast_node* node, std::vector<std::string>& out) {noop(node, out);}
854 void transformDo(ast_node* node, std::vector<std::string>& out) {noop(node, out);}
855 void transform_unary_exp(ast_node* node, std::vector<std::string>& out) {noop(node, out);}
856 void transformTblComprehension(ast_node* node, std::vector<std::string>& out) {noop(node, out);}
857 void transformTableLit(ast_node* node, std::vector<std::string>& out) {noop(node, out);}
858 void transformComprehension(ast_node* node, std::vector<std::string>& out) {noop(node, out);}
859 void transformNum(ast_node* node, std::vector<std::string>& out) {noop(node, out);}
860 void transformVarArg(ast_node* node, std::vector<std::string>& out) {noop(node, out);}
861 void transformBinaryOperator(ast_node* node, std::vector<std::string>& out) {noop(node, out);}
862 void transform_chain_item(ast_node* node, std::vector<std::string>& out) {noop(node, out);}
863 void transform_chain_dot_chain(ast_node* node, std::vector<std::string>& out) {noop(node, out);}
864 void transformSlice(ast_node* node, std::vector<std::string>& out) {noop(node, out);}
865 void transformSingleString(ast_node* node, std::vector<std::string>& out) {noop(node, out);}
866 void transformDoubleString(ast_node* node, std::vector<std::string>& out) {noop(node, out);}
867 void transformLuaString(ast_node* node, std::vector<std::string>& out) {noop(node, out);}
868};
869
870const std::string MoonCompliler::Empty;
871
872int main()
873{
874 std::string s = R"TestCodesHere(a = 998
875f, d = (->
876 joop = 2302 + 567
877
878 (hi, a, b = Vec2(100,200), c, d, ... using nil) ->
879 d = "中文"
880 hi = 1021
881
882 a,b,c,d = 1,2,3,4
883
884 hello[232], (5+5)[121], hello, x[99] = 100, 200, 300
885
886 joop = 12), 123 if true else print("a",1,2)\abc(998).x
887
888a, b = if hello
889 "hello"
890else
891 "nothing", "yeah"
892
893
894a, b = if hello
895 if yeah then "one", "two" else "mmhh"
896else
897 print "the other"
898 "nothing", "yeah")TestCodesHere";
899
900 MoonCompliler{}.complile(s);
901
192 return 0; 902 return 0;
193} 903}