diff options
author | Li Jin <dragon-fly@qq.com> | 2019-09-17 00:41:21 +0800 |
---|---|---|
committer | Li Jin <dragon-fly@qq.com> | 2019-09-17 00:41:21 +0800 |
commit | 74c4f6eab47f76b093e17f515204525e00a3b352 (patch) | |
tree | d737b1437f103842f30c96a2787468d474405efb /MoonParser/moon_ast.cpp | |
parent | b65798d7960d797f2b7074c4cc47b8c70a9f5270 (diff) | |
download | yuescript-74c4f6eab47f76b093e17f515204525e00a3b352.tar.gz yuescript-74c4f6eab47f76b093e17f515204525e00a3b352.tar.bz2 yuescript-74c4f6eab47f76b093e17f515204525e00a3b352.zip |
completing spec/class.moon
Diffstat (limited to 'MoonParser/moon_ast.cpp')
-rw-r--r-- | MoonParser/moon_ast.cpp | 557 |
1 files changed, 476 insertions, 81 deletions
diff --git a/MoonParser/moon_ast.cpp b/MoonParser/moon_ast.cpp index fa95097..af34395 100644 --- a/MoonParser/moon_ast.cpp +++ b/MoonParser/moon_ast.cpp | |||
@@ -23,8 +23,8 @@ const input& AstLeaf::getValue() { | |||
23 | ast<type##_t> __##type##_t(type); | 23 | ast<type##_t> __##type##_t(type); |
24 | 24 | ||
25 | AST_IMPL(Num) | 25 | AST_IMPL(Num) |
26 | AST_IMPL(_Name) | ||
27 | AST_IMPL(Name) | 26 | AST_IMPL(Name) |
27 | AST_IMPL(Variable) | ||
28 | AST_IMPL(self) | 28 | AST_IMPL(self) |
29 | AST_IMPL(self_name) | 29 | AST_IMPL(self_name) |
30 | AST_IMPL(self_class) | 30 | AST_IMPL(self_class) |
@@ -235,7 +235,7 @@ private: | |||
235 | return !defined; | 235 | return !defined; |
236 | } | 236 | } |
237 | 237 | ||
238 | std::string getValidName(std::string_view name) { | 238 | std::string getUnusedName(std::string_view name) { |
239 | int index = 0; | 239 | int index = 0; |
240 | std::string newName; | 240 | std::string newName; |
241 | do { | 241 | do { |
@@ -344,6 +344,71 @@ private: | |||
344 | return parse<T>(_codeCache.back(), r, el, &st); | 344 | return parse<T>(_codeCache.back(), r, el, &st); |
345 | } | 345 | } |
346 | 346 | ||
347 | Invoke_t* startWithInvoke(ast_node* chain) { | ||
348 | ast_node* invoke = nullptr; | ||
349 | chain->traverse([&](ast_node* node) { | ||
350 | switch (node->getId()) { | ||
351 | case "Invoke"_id: | ||
352 | invoke = node; | ||
353 | return traversal::Stop; | ||
354 | case "DotChainItem"_id: | ||
355 | case "ColonChainItem"_id: | ||
356 | case "Slice"_id: | ||
357 | case "Index"_id: | ||
358 | case "Callable"_id: | ||
359 | case "String"_id: | ||
360 | return traversal::Stop; | ||
361 | default: | ||
362 | return traversal::Continue; | ||
363 | } | ||
364 | }); | ||
365 | return static_cast<Invoke_t*>(invoke); | ||
366 | } | ||
367 | |||
368 | Invoke_t* endWithInvoke(Chain_t* chain) { | ||
369 | ast_node* last = nullptr; | ||
370 | chain->traverse([&](ast_node* node) { | ||
371 | switch (node->getId()) { | ||
372 | case "Invoke"_id: | ||
373 | case "DotChainItem"_id: | ||
374 | case "ColonChainItem"_id: | ||
375 | case "Slice"_id: | ||
376 | case "Index"_id: | ||
377 | case "Callable"_id: | ||
378 | case "String"_id: | ||
379 | last = node; | ||
380 | return traversal::Return; | ||
381 | default: | ||
382 | return traversal::Continue; | ||
383 | } | ||
384 | }); | ||
385 | if (last && last->getId() == "Invoke"_id) { | ||
386 | return static_cast<Invoke_t*>(last); | ||
387 | } else { | ||
388 | return nullptr; | ||
389 | } | ||
390 | } | ||
391 | |||
392 | std::vector<ast_node*> getChainList(ast_node* chain) { | ||
393 | std::vector<ast_node*> list; | ||
394 | chain->traverse([&](ast_node* node) { | ||
395 | switch (node->getId()) { | ||
396 | case "Invoke"_id: | ||
397 | case "DotChainItem"_id: | ||
398 | case "ColonChainItem"_id: | ||
399 | case "Slice"_id: | ||
400 | case "Index"_id: | ||
401 | case "Callable"_id: | ||
402 | case "String"_id: | ||
403 | list.push_back(node); | ||
404 | return traversal::Return; | ||
405 | default: | ||
406 | return traversal::Continue; | ||
407 | } | ||
408 | }); | ||
409 | return list; | ||
410 | } | ||
411 | |||
347 | void transformStatement(Statement_t* statement, std::vector<std::string>& out) { | 412 | void transformStatement(Statement_t* statement, std::vector<std::string>& out) { |
348 | if (statement->appendix) { | 413 | if (statement->appendix) { |
349 | auto appendix = statement->appendix; | 414 | auto appendix = statement->appendix; |
@@ -354,7 +419,7 @@ private: | |||
354 | ifCond->condition = if_else_line->condition; | 419 | ifCond->condition = if_else_line->condition; |
355 | 420 | ||
356 | auto exprList = new_ptr<ExpList_t>(); | 421 | auto exprList = new_ptr<ExpList_t>(); |
357 | exprList->exprs.add(if_else_line->elseExpr); | 422 | exprList->exprs.push_back(if_else_line->elseExpr); |
358 | auto stmt = new_ptr<Statement_t>(); | 423 | auto stmt = new_ptr<Statement_t>(); |
359 | stmt->content.set(exprList); | 424 | stmt->content.set(exprList); |
360 | auto body = new_ptr<Body_t>(); | 425 | auto body = new_ptr<Body_t>(); |
@@ -369,7 +434,7 @@ private: | |||
369 | auto ifNode = new_ptr<If_t>(); | 434 | auto ifNode = new_ptr<If_t>(); |
370 | ifNode->firstCondition.set(ifCond); | 435 | ifNode->firstCondition.set(ifCond); |
371 | ifNode->firstBody.set(body); | 436 | ifNode->firstBody.set(body); |
372 | ifNode->branches.add(ifElseIf); | 437 | ifNode->branches.push_back(ifElseIf); |
373 | 438 | ||
374 | statement->appendix.set(nullptr); | 439 | statement->appendix.set(nullptr); |
375 | auto simpleValue = new_ptr<SimpleValue_t>(); | 440 | auto simpleValue = new_ptr<SimpleValue_t>(); |
@@ -379,7 +444,7 @@ private: | |||
379 | auto exp = new_ptr<Exp_t>(); | 444 | auto exp = new_ptr<Exp_t>(); |
380 | exp->value.set(value); | 445 | exp->value.set(value); |
381 | exprList = new_ptr<ExpList_t>(); | 446 | exprList = new_ptr<ExpList_t>(); |
382 | exprList->exprs.add(exp); | 447 | exprList->exprs.push_back(exp); |
383 | statement->content.set(exprList); | 448 | statement->content.set(exprList); |
384 | break; | 449 | break; |
385 | } | 450 | } |
@@ -416,14 +481,38 @@ private: | |||
416 | break; | 481 | break; |
417 | } | 482 | } |
418 | if (auto singleValue = singleValueFrom(expList)) { | 483 | if (auto singleValue = singleValueFrom(expList)) { |
419 | if (auto ifNode = static_cast<If_t*>(singleValue->getByPath({"SimpleValue"_id, "If"_id}))) { | 484 | if (auto simpleValue = static_cast<SimpleValue_t*>(singleValue->getByPath({"SimpleValue"_id}))) { |
420 | transformIf(ifNode, out); | 485 | auto value = simpleValue->getFirstChild(); |
421 | break; | 486 | bool specialSingleValue = true; |
487 | switch (value->getId()) { | ||
488 | case "If"_id: transformIf(static_cast<If_t*>(value), out); break; | ||
489 | case "ClassDecl"_id: transformClassDecl(static_cast<ClassDecl_t*>(value), out); break; | ||
490 | case "Unless"_id: transformUnless(static_cast<Unless_t*>(value), out); break; | ||
491 | case "Switch"_id: transformSwitch(static_cast<Switch_t*>(value), out); break; | ||
492 | case "With"_id: transformWith(static_cast<With_t*>(value), out); break; | ||
493 | case "ForEach"_id: transformForEach(static_cast<ForEach_t*>(value), out); break; | ||
494 | case "For"_id: transformFor(static_cast<For_t*>(value), out); break; | ||
495 | case "While"_id: transformWhile(static_cast<While_t*>(value), out); break; | ||
496 | case "Do"_id: transformDo(static_cast<Do_t*>(value), out); break; | ||
497 | default: specialSingleValue = false; break; | ||
498 | } | ||
499 | if (specialSingleValue) { | ||
500 | break; | ||
501 | } | ||
422 | } | 502 | } |
423 | if (singleValue->getByPath({"ChainValue"_id, "InvokeArgs"_id})) { | 503 | if (auto chainValue = static_cast<ChainValue_t*>(singleValue->getByPath({"ChainValue"_id}))) { |
424 | transformValue(singleValue, out); | 504 | if (chainValue->arguments) { |
425 | out.back() = indent() + out.back() + nlr(singleValue); | 505 | transformValue(singleValue, out); |
426 | break; | 506 | out.back() = indent() + out.back() + nlr(singleValue); |
507 | break; | ||
508 | } else { | ||
509 | auto chain = static_cast<Chain_t*>(chainValue->getByPath({"Chain"_id})); | ||
510 | if (chain && endWithInvoke(chain)) { | ||
511 | transformValue(singleValue, out); | ||
512 | out.back() = indent() + out.back() + nlr(singleValue); | ||
513 | break; | ||
514 | } | ||
515 | } | ||
427 | } | 516 | } |
428 | } | 517 | } |
429 | std::string preDefine; | 518 | std::string preDefine; |
@@ -445,7 +534,7 @@ private: | |||
445 | std::vector<ast_node*> values; | 534 | std::vector<ast_node*> values; |
446 | expList->traverse([&](ast_node* child) { | 535 | expList->traverse([&](ast_node* child) { |
447 | if (child->getId() == "Value"_id) { | 536 | if (child->getId() == "Value"_id) { |
448 | auto target = child->getByPath({"ChainValue"_id, "Callable"_id, "Name"_id}); | 537 | auto target = child->getByPath({"ChainValue"_id, "Callable"_id, "Variable"_id}); |
449 | if (target) { | 538 | if (target) { |
450 | auto name = toString(target); | 539 | auto name = toString(target); |
451 | if (addToScope(name)) { | 540 | if (addToScope(name)) { |
@@ -557,6 +646,14 @@ private: | |||
557 | out.push_back(preDefine + nll(statement) + temp.front()); | 646 | out.push_back(preDefine + nll(statement) + temp.front()); |
558 | return; | 647 | return; |
559 | } | 648 | } |
649 | case "ClassDecl"_id: { | ||
650 | std::vector<std::string> temp; | ||
651 | auto expList = assignment->assignable.get(); | ||
652 | std::string preDefine = transformAssignDefs(expList); | ||
653 | transformClassDecl(static_cast<ClassDecl_t*>(valueItem), temp, ClassDeclUsage::Assignment, expList); | ||
654 | out.push_back(preDefine + nll(statement) + temp.front()); | ||
655 | return; | ||
656 | } | ||
560 | } | 657 | } |
561 | } | 658 | } |
562 | } | 659 | } |
@@ -575,7 +672,7 @@ private: | |||
575 | if (auto body = node->getByPath({"Body"_id})) { | 672 | if (auto body = node->getByPath({"Body"_id})) { |
576 | if (traversal::Stop == body->traverse([&](ast_node* n) { | 673 | if (traversal::Stop == body->traverse([&](ast_node* n) { |
577 | if (n->getId() == "Callable"_id) { | 674 | if (n->getId() == "Callable"_id) { |
578 | if (auto name = n->getByPath({"Name"_id})) { | 675 | if (auto name = n->getByPath({"Variable"_id})) { |
579 | if (temp.front() ==toString(name)) { | 676 | if (temp.front() ==toString(name)) { |
580 | return traversal::Stop; | 677 | return traversal::Stop; |
581 | } | 678 | } |
@@ -721,7 +818,7 @@ private: | |||
721 | void transformCallable(Callable_t* callable, std::vector<std::string>& out, bool invoke) { | 818 | void transformCallable(Callable_t* callable, std::vector<std::string>& out, bool invoke) { |
722 | auto item = callable->item.get(); | 819 | auto item = callable->item.get(); |
723 | switch (item->getId()) { | 820 | switch (item->getId()) { |
724 | case "Name"_id: transformName(static_cast<Name_t*>(item), out); break; | 821 | case "Variable"_id: transformVariable(static_cast<Variable_t*>(item), out); break; |
725 | case "SelfName"_id: transformSelfName(static_cast<SelfName_t*>(item), out, invoke); break; | 822 | case "SelfName"_id: transformSelfName(static_cast<SelfName_t*>(item), out, invoke); break; |
726 | case "VarArg"_id: out.push_back(s("..."sv)); break; | 823 | case "VarArg"_id: out.push_back(s("..."sv)); break; |
727 | case "Parens"_id: transformParens(static_cast<Parens_t*>(item), out); break; | 824 | case "Parens"_id: transformParens(static_cast<Parens_t*>(item), out); break; |
@@ -742,7 +839,7 @@ private: | |||
742 | case "If"_id: transformIfClosure(static_cast<If_t*>(value), out); break; | 839 | case "If"_id: transformIfClosure(static_cast<If_t*>(value), out); break; |
743 | case "Switch"_id: transformSwitch(value, out); break; | 840 | case "Switch"_id: transformSwitch(value, out); break; |
744 | case "With"_id: transformWith(value, out); break; | 841 | case "With"_id: transformWith(value, out); break; |
745 | case "ClassDecl"_id: transformClassDecl(static_cast<ClassDecl_t*>(value), out); break; | 842 | case "ClassDecl"_id: transformClassDeclClosure(static_cast<ClassDecl_t*>(value), out); break; |
746 | case "ForEach"_id: transformForEachClosure(static_cast<ForEach_t*>(value), out); break; | 843 | case "ForEach"_id: transformForEachClosure(static_cast<ForEach_t*>(value), out); break; |
747 | case "For"_id: transformForClosure(static_cast<For_t*>(value), out); break; | 844 | case "For"_id: transformForClosure(static_cast<For_t*>(value), out); break; |
748 | case "While"_id: transformWhile(value, out); break; | 845 | case "While"_id: transformWhile(value, out); break; |
@@ -829,6 +926,8 @@ private: | |||
829 | if (auto singleValue = singleValueFrom(valueList)) { | 926 | if (auto singleValue = singleValueFrom(valueList)) { |
830 | if (auto comp = singleValue->getByPath({"SimpleValue"_id, "Comprehension"_id})) { | 927 | if (auto comp = singleValue->getByPath({"SimpleValue"_id, "Comprehension"_id})) { |
831 | transformCompReturn(static_cast<Comprehension_t*>(comp), out); | 928 | transformCompReturn(static_cast<Comprehension_t*>(comp), out); |
929 | } else if (auto classDecl = singleValue->getByPath({"SimpleValue"_id, "ClassDecl"_id})) { | ||
930 | transformClassDecl(static_cast<ClassDecl_t*>(classDecl), out, ClassDeclUsage::Return); | ||
832 | } else { | 931 | } else { |
833 | transformValue(singleValue, out); | 932 | transformValue(singleValue, out); |
834 | out.back() = indent() + s("return "sv) + out.back() + nlr(returnNode); | 933 | out.back() = indent() + s("return "sv) + out.back() + nlr(returnNode); |
@@ -877,7 +976,7 @@ private: | |||
877 | auto def = static_cast<FnArgDef_t*>(_def); | 976 | auto def = static_cast<FnArgDef_t*>(_def); |
878 | auto& arg = argItems.emplace_back(); | 977 | auto& arg = argItems.emplace_back(); |
879 | switch (def->name->getId()) { | 978 | switch (def->name->getId()) { |
880 | case "Name"_id: arg.name = toString(def->name); break; | 979 | case "Variable"_id: arg.name = toString(def->name); break; |
881 | case "SelfName"_id: { | 980 | case "SelfName"_id: { |
882 | assignSelf = true; | 981 | assignSelf = true; |
883 | auto selfName = static_cast<SelfName_t*>(def->name.get()); | 982 | auto selfName = static_cast<SelfName_t*>(def->name.get()); |
@@ -971,7 +1070,10 @@ private: | |||
971 | std::vector<std::string> temp; | 1070 | std::vector<std::string> temp; |
972 | auto caller = chain_call->caller.get(); | 1071 | auto caller = chain_call->caller.get(); |
973 | switch (caller->getId()) { | 1072 | switch (caller->getId()) { |
974 | case "Callable"_id: transformCallable(static_cast<Callable_t*>(caller), temp, true); break; | 1073 | case "Callable"_id: { |
1074 | transformCallable(static_cast<Callable_t*>(caller), temp, startWithInvoke(chain_call->chain)); | ||
1075 | break; | ||
1076 | } | ||
975 | case "String"_id: transformString(static_cast<String_t*>(caller), temp); break; | 1077 | case "String"_id: transformString(static_cast<String_t*>(caller), temp); break; |
976 | default: break; | 1078 | default: break; |
977 | } | 1079 | } |
@@ -1030,7 +1132,9 @@ private: | |||
1030 | 1132 | ||
1031 | void transformColonChain(ColonChain_t* colonChain, std::vector<std::string>& out) { | 1133 | void transformColonChain(ColonChain_t* colonChain, std::vector<std::string>& out) { |
1032 | std::vector<std::string> temp; | 1134 | std::vector<std::string> temp; |
1033 | temp.push_back(s(":"sv) + toString(colonChain->colonChain->name)); | 1135 | temp.push_back( |
1136 | s(colonChain->colonChain->switchToDot ? "."sv : ":"sv) + | ||
1137 | toString(colonChain->colonChain->name)); | ||
1034 | if (colonChain->invokeChain) { | 1138 | if (colonChain->invokeChain) { |
1035 | transform_invoke_chain(colonChain->invokeChain, temp); | 1139 | transform_invoke_chain(colonChain->invokeChain, temp); |
1036 | } | 1140 | } |
@@ -1053,7 +1157,7 @@ private: | |||
1053 | out.push_back(join(temp)); | 1157 | out.push_back(join(temp)); |
1054 | } | 1158 | } |
1055 | 1159 | ||
1056 | void transformName(Name_t* name, std::vector<std::string>& out) { | 1160 | void transformVariable(Variable_t* name, std::vector<std::string>& out) { |
1057 | out.push_back(toString(name)); | 1161 | out.push_back(toString(name)); |
1058 | } | 1162 | } |
1059 | 1163 | ||
@@ -1086,8 +1190,8 @@ private: | |||
1086 | 1190 | ||
1087 | void transformComprehension(Comprehension_t* comp, std::vector<std::string>& out) { | 1191 | void transformComprehension(Comprehension_t* comp, std::vector<std::string>& out) { |
1088 | std::vector<std::string> temp; | 1192 | std::vector<std::string> temp; |
1089 | std::string accum = getValidName("_accum_"); | 1193 | std::string accum = getUnusedName("_accum_"); |
1090 | std::string len = getValidName("_len_"); | 1194 | std::string len = getUnusedName("_len_"); |
1091 | addToScope(accum); | 1195 | addToScope(accum); |
1092 | addToScope(len); | 1196 | addToScope(len); |
1093 | transformExp(comp->value, temp); | 1197 | transformExp(comp->value, temp); |
@@ -1177,8 +1281,8 @@ private: | |||
1177 | switch (loopTarget->getId()) { | 1281 | switch (loopTarget->getId()) { |
1178 | case "star_exp"_id: { | 1282 | case "star_exp"_id: { |
1179 | auto star_exp = static_cast<star_exp_t*>(loopTarget); | 1283 | auto star_exp = static_cast<star_exp_t*>(loopTarget); |
1180 | auto listName = getValidName("_list_"); | 1284 | auto listName = getUnusedName("_list_"); |
1181 | auto indexName = getValidName("_index_"); | 1285 | auto indexName = getUnusedName("_index_"); |
1182 | addToScope(listName); | 1286 | addToScope(listName); |
1183 | addToScope(indexName); | 1287 | addToScope(indexName); |
1184 | transformExp(star_exp->value, temp); | 1288 | transformExp(star_exp->value, temp); |
@@ -1211,8 +1315,8 @@ private: | |||
1211 | for (auto _item : nameList->items.objects()) { | 1315 | for (auto _item : nameList->items.objects()) { |
1212 | auto item = static_cast<NameOrDestructure_t*>(_item)->item.get(); | 1316 | auto item = static_cast<NameOrDestructure_t*>(_item)->item.get(); |
1213 | switch (item->getId()) { | 1317 | switch (item->getId()) { |
1214 | case "Name"_id: | 1318 | case "Variable"_id: |
1215 | transformName(static_cast<Name_t*>(item), temp); | 1319 | transformVariable(static_cast<Variable_t*>(item), temp); |
1216 | break; | 1320 | break; |
1217 | case "TableLit"_id: | 1321 | case "TableLit"_id: |
1218 | transformTableLit(static_cast<TableLit_t*>(item), temp); | 1322 | transformTableLit(static_cast<TableLit_t*>(item), temp); |
@@ -1262,8 +1366,8 @@ private: | |||
1262 | 1366 | ||
1263 | void transformForClosure(For_t* forNode, std::vector<std::string>& out) { | 1367 | void transformForClosure(For_t* forNode, std::vector<std::string>& out) { |
1264 | std::vector<std::string> temp; | 1368 | std::vector<std::string> temp; |
1265 | std::string accum = getValidName("_accum_"); | 1369 | std::string accum = getUnusedName("_accum_"); |
1266 | std::string len = getValidName("_len_"); | 1370 | std::string len = getUnusedName("_len_"); |
1267 | addToScope(accum); | 1371 | addToScope(accum); |
1268 | addToScope(len); | 1372 | addToScope(len); |
1269 | _buf << "(function()"sv << nll(forNode); | 1373 | _buf << "(function()"sv << nll(forNode); |
@@ -1299,8 +1403,8 @@ private: | |||
1299 | 1403 | ||
1300 | void transformForInPlace(For_t* forNode, std::vector<std::string>& out, ExpList_t* assignExpList) { | 1404 | void transformForInPlace(For_t* forNode, std::vector<std::string>& out, ExpList_t* assignExpList) { |
1301 | std::vector<std::string> temp; | 1405 | std::vector<std::string> temp; |
1302 | std::string accum = getValidName("_accum_"); | 1406 | std::string accum = getUnusedName("_accum_"); |
1303 | std::string len = getValidName("_len_"); | 1407 | std::string len = getUnusedName("_len_"); |
1304 | _buf << indent() << "do"sv << nll(forNode); | 1408 | _buf << indent() << "do"sv << nll(forNode); |
1305 | pushScope(); | 1409 | pushScope(); |
1306 | addToScope(accum); | 1410 | addToScope(accum); |
@@ -1351,8 +1455,8 @@ private: | |||
1351 | 1455 | ||
1352 | void transformForEachClosure(ForEach_t* forEach, std::vector<std::string>& out) { | 1456 | void transformForEachClosure(ForEach_t* forEach, std::vector<std::string>& out) { |
1353 | std::vector<std::string> temp; | 1457 | std::vector<std::string> temp; |
1354 | std::string accum = getValidName("_accum_"); | 1458 | std::string accum = getUnusedName("_accum_"); |
1355 | std::string len = getValidName("_len_"); | 1459 | std::string len = getUnusedName("_len_"); |
1356 | addToScope(accum); | 1460 | addToScope(accum); |
1357 | addToScope(len); | 1461 | addToScope(len); |
1358 | _buf << "(function()"sv << nll(forEach); | 1462 | _buf << "(function()"sv << nll(forEach); |
@@ -1388,8 +1492,8 @@ private: | |||
1388 | 1492 | ||
1389 | void transformForEachInPlace(ForEach_t* forEach, std::vector<std::string>& out, ExpList_t* assignExpList) { | 1493 | void transformForEachInPlace(ForEach_t* forEach, std::vector<std::string>& out, ExpList_t* assignExpList) { |
1390 | std::vector<std::string> temp; | 1494 | std::vector<std::string> temp; |
1391 | std::string accum = getValidName("_accum_"); | 1495 | std::string accum = getUnusedName("_accum_"); |
1392 | std::string len = getValidName("_len_"); | 1496 | std::string len = getUnusedName("_len_"); |
1393 | _buf << indent() << "do"sv << nll(forEach); | 1497 | _buf << indent() << "do"sv << nll(forEach); |
1394 | pushScope(); | 1498 | pushScope(); |
1395 | addToScope(accum); | 1499 | addToScope(accum); |
@@ -1462,7 +1566,7 @@ private: | |||
1462 | auto name = keyName->name.get(); | 1566 | auto name = keyName->name.get(); |
1463 | switch (name->getId()) { | 1567 | switch (name->getId()) { |
1464 | case "SelfName"_id: transformSelfName(static_cast<SelfName_t*>(name), out, false); break; | 1568 | case "SelfName"_id: transformSelfName(static_cast<SelfName_t*>(name), out, false); break; |
1465 | case "_Name"_id: out.push_back(toString(name)); break; | 1569 | case "Name"_id: out.push_back(toString(name)); break; |
1466 | default: break; | 1570 | default: break; |
1467 | } | 1571 | } |
1468 | } | 1572 | } |
@@ -1504,47 +1608,309 @@ private: | |||
1504 | } | 1608 | } |
1505 | } | 1609 | } |
1506 | 1610 | ||
1507 | void transformClassDecl(ClassDecl_t* classDecl, std::vector<std::string>& out) { | 1611 | std::pair<std::string,bool> defineClassVariable(Assignable_t* assignable) { |
1508 | std::vector<std::string> temp; | 1612 | if (assignable->item->getId() == "Variable"_id) { |
1509 | if (classDecl->name) { | 1613 | auto variable = static_cast<Variable_t*>(assignable->item.get()); |
1510 | transformAssignable(classDecl->name, temp); | 1614 | auto name = toString(variable); |
1511 | } | 1615 | if (addToScope(name)) { |
1512 | if (classDecl->extend) { | 1616 | return {name, true}; |
1513 | transformExp(classDecl->extend, temp); | 1617 | } else { |
1514 | } | 1618 | return {name, false}; |
1515 | if (classDecl->body) { | 1619 | } |
1516 | transformClassBlock(classDecl->body, temp); | ||
1517 | } | 1620 | } |
1518 | out.push_back(join(temp, "\n"sv)); | 1621 | return {Empty, false}; |
1519 | } | 1622 | } |
1520 | 1623 | ||
1521 | void transformClassBlock(ClassBlock_t* classBlock, std::vector<std::string>& out) { | 1624 | enum class ClassDeclUsage { |
1625 | Return, | ||
1626 | Assignment, | ||
1627 | Common | ||
1628 | }; | ||
1629 | |||
1630 | void transformClassDeclClosure(ClassDecl_t* classDecl, std::vector<std::string>& out) { | ||
1522 | std::vector<std::string> temp; | 1631 | std::vector<std::string> temp; |
1523 | for (auto _line : classBlock->lines.objects()) { | 1632 | temp.push_back(s("(function()"sv) + nll(classDecl)); |
1524 | auto line = static_cast<ClassLine_t*>(_line); | 1633 | pushScope(); |
1525 | transformClassLine(line, temp); | 1634 | transformClassDecl(classDecl, temp, ClassDeclUsage::Return); |
1526 | } | 1635 | popScope(); |
1527 | out.push_back(join(temp,"\n"sv)); | 1636 | temp.push_back(s("end)()"sv)); |
1637 | out.push_back(join(temp)); | ||
1528 | } | 1638 | } |
1529 | 1639 | ||
1530 | void transformClassLine(ClassLine_t* classLine, std::vector<std::string>& out) { | 1640 | struct ClassMember { |
1531 | auto content = classLine->content.get(); | 1641 | std::string key; |
1532 | switch (content->getId()) { | 1642 | bool isBuiltin; |
1533 | case "class_member_list"_id: | 1643 | ast_node* node; |
1534 | transform_class_member_list(static_cast<class_member_list_t*>(content), out); | 1644 | }; |
1535 | break; | 1645 | |
1536 | case "Statement"_id: | 1646 | void transformClassDecl(ClassDecl_t* classDecl, std::vector<std::string>& out, ClassDeclUsage usage = ClassDeclUsage::Common, ExpList_t* expList = nullptr) { |
1537 | transformStatement(static_cast<Statement_t*>(content), out); | 1647 | std::vector<std::string> temp; |
1648 | auto body = classDecl->body.get(); | ||
1649 | auto assignable = classDecl->name.get(); | ||
1650 | auto extend = classDecl->extend.get(); | ||
1651 | std::string className; | ||
1652 | if (assignable) { | ||
1653 | bool newDefined = false; | ||
1654 | std::tie(className, newDefined) = defineClassVariable(assignable); | ||
1655 | if (newDefined) { | ||
1656 | temp.push_back(indent() + s("local "sv) + className + nll(classDecl)); | ||
1657 | } | ||
1658 | } | ||
1659 | temp.push_back(indent() + s("do"sv) + nll(classDecl)); | ||
1660 | pushScope(); | ||
1661 | auto classVar = getUnusedName("_class_"sv); | ||
1662 | addToScope(classVar); | ||
1663 | temp.push_back(indent() + s("local "sv) + classVar + nll(classDecl)); | ||
1664 | if (body) { | ||
1665 | body->traverse([&](ast_node* node) { | ||
1666 | if (node->getId() == "Statement"_id) { | ||
1667 | if (auto assignment = static_cast<Assignment_t*>(node->getByPath({"Assignment"_id}))) { | ||
1668 | std::string preDefine = transformAssignDefs(assignment->assignable.get()); | ||
1669 | if (!preDefine.empty()) temp.push_back(preDefine + nll(assignment)); | ||
1670 | } | ||
1671 | return traversal::Return; | ||
1672 | } | ||
1673 | return traversal::Continue; | ||
1674 | }); | ||
1675 | } | ||
1676 | std::string parent, parentVar; | ||
1677 | if (extend) { | ||
1678 | parentVar = getUnusedName("_parent_"sv); | ||
1679 | addToScope(parentVar); | ||
1680 | transformExp(extend, temp); | ||
1681 | parent = temp.back(); | ||
1682 | temp.pop_back(); | ||
1683 | temp.push_back(indent() + s("local "sv) + parentVar + s(" = "sv) + parent + nll(classDecl)); | ||
1684 | } | ||
1685 | auto baseVar = getUnusedName("_base_"sv); | ||
1686 | auto selfVar = getUnusedName("_self_"sv); | ||
1687 | addToScope(baseVar); | ||
1688 | addToScope(selfVar); | ||
1689 | temp.push_back(indent() + s("local "sv) + baseVar + s(" = "sv)); | ||
1690 | std::vector<std::string> builtins; | ||
1691 | std::vector<std::string> customs; | ||
1692 | std::vector<std::string> statements; | ||
1693 | if (body) { | ||
1694 | std::list<ClassMember> members; | ||
1695 | for (auto _classLine : classDecl->body->lines.objects()) { | ||
1696 | auto classLine = static_cast<ClassLine_t*>(_classLine); | ||
1697 | auto content = classLine->content.get(); | ||
1698 | switch (content->getId()) { | ||
1699 | case "class_member_list"_id: | ||
1700 | pushScope(); | ||
1701 | transform_class_member_list(static_cast<class_member_list_t*>(content), members, classVar); | ||
1702 | popScope(); | ||
1703 | members.back().key = indent(1) + members.back().key; | ||
1704 | break; | ||
1705 | case "Statement"_id: | ||
1706 | transformStatement(static_cast<Statement_t*>(content), statements); | ||
1707 | break; | ||
1708 | default: break; | ||
1709 | } | ||
1710 | } | ||
1711 | for (auto& member : members) { | ||
1712 | if (member.isBuiltin) { | ||
1713 | builtins.push_back((builtins.empty() ? Empty : s(","sv) + nll(member.node)) + member.key); | ||
1714 | } else { | ||
1715 | customs.push_back((customs.empty() ? Empty : s(","sv) + nll(member.node)) + member.key); | ||
1716 | } | ||
1717 | } | ||
1718 | if (!customs.empty()) { | ||
1719 | temp.back() += s("{"sv) + nll(body); | ||
1720 | temp.push_back(join(customs) + nll(body)); | ||
1721 | temp.push_back(indent() + s("}"sv) + nll(body)); | ||
1722 | } else { | ||
1723 | temp.back() += s("{ }"sv) + nll(body); | ||
1724 | } | ||
1725 | temp.push_back(indent() + baseVar + s(".__index = "sv) + baseVar + nll(classDecl)); | ||
1726 | } else { | ||
1727 | temp.back() += s("{ }"sv) + nll(classDecl); | ||
1728 | } | ||
1729 | if (extend) { | ||
1730 | _buf << indent() << "setmetatable("sv << baseVar << ", "sv << parentVar << ".__base)"sv << nll(classDecl); | ||
1731 | } | ||
1732 | _buf << indent() << classVar << " = setmetatable({" << nll(classDecl); | ||
1733 | if (!builtins.empty()) { | ||
1734 | _buf << join(builtins) << ","sv << nll(classDecl); | ||
1735 | } else { | ||
1736 | if (extend) { | ||
1737 | _buf << indent(1) << "__init = function(self, ...)"sv << nll(classDecl); | ||
1738 | _buf << indent(2) << "return _class_0.__parent.__init(self, ...)"sv << nll(classDecl); | ||
1739 | _buf << indent(1) << "end,"sv << nll(classDecl); | ||
1740 | } else { | ||
1741 | _buf << indent(1) << "__init = function() end,"sv << nll(classDecl); | ||
1742 | } | ||
1743 | } | ||
1744 | _buf << indent(1) << "__base = "sv << baseVar; | ||
1745 | if (!className.empty()) { | ||
1746 | _buf << ","sv << nll(classDecl) << indent(1) << "__name = \""sv << className << "\""sv << (extend ? s(","sv) : Empty) << nll(classDecl); | ||
1747 | } else { | ||
1748 | _buf << nll(classDecl); | ||
1749 | } | ||
1750 | if (extend) { | ||
1751 | _buf << indent(1) << "__parent = "sv << parentVar << nll(classDecl); | ||
1752 | } | ||
1753 | _buf << indent() << "}, {"sv << nll(classDecl); | ||
1754 | if (extend) { | ||
1755 | _buf << indent(1) << "__index = function(cls, name)"sv << nll(classDecl); | ||
1756 | _buf << indent(2) << "local val = rawget("sv << baseVar << ", name)"sv << nll(classDecl); | ||
1757 | _buf << indent(2) << "if val == nil then"sv << nll(classDecl); | ||
1758 | _buf << indent(3) << "local parent = rawget(cls, \"__parent\")"sv << nll(classDecl); | ||
1759 | _buf << indent(3) << "if parent then"sv << nll(classDecl); | ||
1760 | _buf << indent(4) << "return parent[name]"sv << nll(classDecl); | ||
1761 | _buf << indent(3) << "end"sv << nll(classDecl); | ||
1762 | _buf << indent(2) << "else"sv << nll(classDecl); | ||
1763 | _buf << indent(3) << "return val"sv << nll(classDecl); | ||
1764 | _buf << indent(2) << "end"sv << nll(classDecl); | ||
1765 | _buf << indent(1) << "end,"sv << nll(classDecl); | ||
1766 | } else { | ||
1767 | _buf << indent(1) << "__index = "sv << baseVar << ","sv << nll(classDecl); | ||
1768 | } | ||
1769 | _buf << indent(1) << "__call = function(cls, ...)"sv << nll(classDecl); | ||
1770 | _buf << indent(2) << "local " << selfVar << " = setmetatable({}, "sv << baseVar << ")"sv << nll(classDecl); | ||
1771 | _buf << indent(2) << "cls.__init("sv << selfVar << ", ...)"sv << nll(classDecl); | ||
1772 | _buf << indent(2) << "return "sv << selfVar << nll(classDecl); | ||
1773 | _buf << indent(1) << "end"sv << nll(classDecl); | ||
1774 | _buf << indent() << "})"sv << nll(classDecl); | ||
1775 | _buf << indent() << baseVar << ".__class = "sv << classVar << nll(classDecl); | ||
1776 | if (extend) { | ||
1777 | _buf << indent() << "if "sv << parentVar << ".__inherited then"sv << nll(classDecl); | ||
1778 | _buf << indent(1) << parentVar << ".__inherited("sv << parentVar << ", "sv << classVar << ")"sv << nll(classDecl); | ||
1779 | _buf << indent() << "end"sv << nll(classDecl); | ||
1780 | } | ||
1781 | if (!statements.empty()) _buf << indent() << "local self = "sv << classVar << nll(classDecl); | ||
1782 | _buf << join(statements); | ||
1783 | if (!className.empty()) _buf << indent() << className << " = "sv << classVar << nll(classDecl); | ||
1784 | switch (usage) { | ||
1785 | case ClassDeclUsage::Return: { | ||
1786 | _buf << indent() << "return "sv << classVar << nlr(classDecl); | ||
1538 | break; | 1787 | break; |
1539 | case "Exp"_id: | 1788 | } |
1540 | transformExp(static_cast<Exp_t*>(content), out); | 1789 | case ClassDeclUsage::Assignment: { |
1790 | std::vector<std::string> tmp; | ||
1791 | transformExpList(expList, tmp); | ||
1792 | _buf << indent() << tmp.back() << " = "sv << classVar << nlr(classDecl); | ||
1541 | break; | 1793 | break; |
1794 | } | ||
1795 | default: break; | ||
1542 | } | 1796 | } |
1797 | temp.push_back(clearBuf()); | ||
1798 | popScope(); | ||
1799 | temp.push_back(indent() + s("end"sv) + nlr(classDecl)); | ||
1800 | out.push_back(join(temp)); | ||
1543 | } | 1801 | } |
1544 | 1802 | ||
1545 | void transform_class_member_list(class_member_list_t* class_member_list, std::vector<std::string>& out) {noop(class_member_list, out);} | 1803 | void transform_class_member_list(class_member_list_t* class_member_list, std::list<ClassMember>& out, const std::string& classVar) { |
1804 | std::vector<std::string> temp; | ||
1805 | for (auto _keyValue : class_member_list->values.objects()) { | ||
1806 | auto keyValue = static_cast<KeyValue_t*>(_keyValue); | ||
1807 | bool isBuiltin = false; | ||
1808 | do { | ||
1809 | auto keyName = static_cast<KeyName_t*>( | ||
1810 | keyValue->getByPath({"normal_pair"_id, "KeyName"_id}) | ||
1811 | ); | ||
1812 | if (!keyName) break; | ||
1813 | auto normal_pair = static_cast<normal_pair_t*>(keyValue->getFirstChild()); | ||
1814 | auto nameNode = keyName->getByPath({"Name"_id}); | ||
1815 | if (!nameNode) break; | ||
1816 | auto name = toString(nameNode); | ||
1817 | input newSuperCall; | ||
1818 | isBuiltin = name == "new"sv; | ||
1819 | if (isBuiltin) { | ||
1820 | keyName->name.set(toAst<Name_t>("__init"sv, Name)); | ||
1821 | newSuperCall = _converter.from_bytes(classVar) + L".__parent.__init"; | ||
1822 | } else { | ||
1823 | newSuperCall = _converter.from_bytes(classVar) + L".__parent.__base." + _converter.from_bytes(name); | ||
1824 | } | ||
1825 | normal_pair->value->traverse([&](ast_node* node) { | ||
1826 | if (node->getId() == "ClassDecl"_id) return traversal::Return; | ||
1827 | if (auto chainValue = ast_cast<ChainValue_t>(node)) { | ||
1828 | if (auto var = chainValue->caller->getByPath({"Variable"_id})) { | ||
1829 | if (toString(var) == "super"sv) { | ||
1830 | if (chainValue->arguments && chainValue->arguments->argsList) { | ||
1831 | chainValue->arguments->argsList->exprs.push_front(toAst<Exp_t>("self"sv, Exp)); | ||
1832 | _codeCache.push_back(newSuperCall); | ||
1833 | var->m_begin.m_it = _codeCache.back().begin(); | ||
1834 | var->m_end.m_it = _codeCache.back().end(); | ||
1835 | } else { | ||
1836 | _codeCache.push_back(_converter.from_bytes(classVar) + L".__parent"); | ||
1837 | var->m_begin.m_it = _codeCache.back().begin(); | ||
1838 | var->m_end.m_it = _codeCache.back().end(); | ||
1839 | } | ||
1840 | } | ||
1841 | } else if (auto var = chainValue->caller->getByPath({"chain_call"_id, "Callable"_id, "Variable"_id})) { | ||
1842 | if (toString(var) == "super"sv) { | ||
1843 | auto chainList = getChainList(chainValue->caller); | ||
1844 | if (auto args = chainValue->getByPath({"InvokeArgs"_id, "ExpList"_id})) { | ||
1845 | chainList.push_back(args); | ||
1846 | } | ||
1847 | auto insertSelfToArguments = [&](ast_node* item) { | ||
1848 | switch (item->getId()) { | ||
1849 | case "ExpList"_id: | ||
1850 | static_cast<ExpList_t*>(item)->exprs.push_front(toAst<Exp_t>("self"sv, Exp)); | ||
1851 | break; | ||
1852 | case "Invoke"_id: { | ||
1853 | auto invoke = static_cast<Invoke_t*>(item); | ||
1854 | if (auto fnArgs = invoke->argument.as<FnArgs_t>()) { | ||
1855 | fnArgs->args.push_front(toAst<Exp_t>("self"sv, Exp)); | ||
1856 | } else { | ||
1857 | auto string = new_ptr<String_t>(); | ||
1858 | string->str.set(invoke->argument); | ||
1859 | auto value = new_ptr<Value_t>(); | ||
1860 | value->item.set(string); | ||
1861 | auto exp = new_ptr<Exp_t>(); | ||
1862 | exp->value.set(value); | ||
1863 | auto newFnArgs = new_ptr<FnArgs_t>(); | ||
1864 | fnArgs->args.push_back(toAst<Exp_t>("self"sv, Exp)); | ||
1865 | newFnArgs->args.push_back(exp); | ||
1866 | invoke->argument.set(newFnArgs); | ||
1867 | } | ||
1868 | break; | ||
1869 | } | ||
1870 | default: break; | ||
1871 | } | ||
1872 | }; | ||
1873 | if (chainList.size() == 2) { | ||
1874 | _codeCache.push_back(newSuperCall); | ||
1875 | var->m_begin.m_it = _codeCache.back().begin(); | ||
1876 | var->m_end.m_it = _codeCache.back().end(); | ||
1877 | auto item = chainList.back(); | ||
1878 | insertSelfToArguments(item); | ||
1879 | } else if (chainList.size() > 2) { | ||
1880 | _codeCache.push_back(_converter.from_bytes(classVar) + L".__parent"); | ||
1881 | var->m_begin.m_it = _codeCache.back().begin(); | ||
1882 | var->m_end.m_it = _codeCache.back().end(); | ||
1883 | if (auto colonChainItem = ast_cast<ColonChainItem_t>(chainList[1])) { | ||
1884 | colonChainItem->switchToDot = true; | ||
1885 | auto item = chainList[2]; | ||
1886 | insertSelfToArguments(item); | ||
1887 | } | ||
1888 | } else { | ||
1889 | _codeCache.push_back(_converter.from_bytes(classVar) + L".__parent"); | ||
1890 | var->m_begin.m_it = _codeCache.back().begin(); | ||
1891 | var->m_end.m_it = _codeCache.back().end(); | ||
1892 | } | ||
1893 | } | ||
1894 | } | ||
1895 | } | ||
1896 | return traversal::Continue; | ||
1897 | }); | ||
1898 | } while (false); | ||
1899 | transformKeyValue(keyValue, temp); | ||
1900 | out.push_back({temp.back(), isBuiltin, keyValue}); | ||
1901 | temp.clear(); | ||
1902 | } | ||
1903 | } | ||
1546 | 1904 | ||
1547 | void transformAssignable(ast_node* node, std::vector<std::string>& out) {noop(node, out);} | 1905 | void transformAssignable(Assignable_t* assignable, std::vector<std::string>& out) { |
1906 | auto item = assignable->item.get(); | ||
1907 | switch (item->getId()) { | ||
1908 | case "Chain"_id: transformChain(static_cast<Chain_t*>(item), out); break; | ||
1909 | case "Variable"_id: transformVariable(static_cast<Variable_t*>(item), out); break; | ||
1910 | case "SelfName"_id: transformSelfName(static_cast<SelfName_t*>(item), out, false); break; | ||
1911 | default: break; | ||
1912 | } | ||
1913 | } | ||
1548 | 1914 | ||
1549 | void transformUpdate(ast_node* node, std::vector<std::string>& out) {noop(node, out);} | 1915 | void transformUpdate(ast_node* node, std::vector<std::string>& out) {noop(node, out);} |
1550 | void transformImport(ast_node* node, std::vector<std::string>& out) {noopnl(node, out);} | 1916 | void transformImport(ast_node* node, std::vector<std::string>& out) {noopnl(node, out);} |
@@ -1565,40 +1931,69 @@ private: | |||
1565 | void transformCompFor(ast_node* node, std::vector<std::string>& out) {noop(node, out);} | 1931 | void transformCompFor(ast_node* node, std::vector<std::string>& out) {noop(node, out);} |
1566 | void transformCompClause(ast_node* node, std::vector<std::string>& out) {noop(node, out);} | 1932 | void transformCompClause(ast_node* node, std::vector<std::string>& out) {noop(node, out);} |
1567 | void transform_invoke_args_with_table(ast_node* node, std::vector<std::string>& out) {noop(node, out);} | 1933 | void transform_invoke_args_with_table(ast_node* node, std::vector<std::string>& out) {noop(node, out);} |
1934 | void transformUnless(Unless_t* node, std::vector<std::string>& out) {noop(node, out);} | ||
1568 | }; | 1935 | }; |
1569 | 1936 | ||
1570 | const std::string MoonCompliler::Empty; | 1937 | const std::string MoonCompliler::Empty; |
1571 | 1938 | ||
1572 | int main() | 1939 | int main() |
1573 | { | 1940 | { |
1574 | std::string s = R"TestCodesHere( | 1941 | std::string s = R"TestCodesHere(class Hello |
1575 | -- vararg bubbling | 1942 | new: (@test, @world) => |
1576 | f = (...) -> #{...} | 1943 | print "creating object.." |
1944 | hello: => | ||
1945 | print @test, @world | ||
1946 | __tostring: => "hello world" | ||
1947 | |||
1948 | x = Hello 1,2 | ||
1949 | x\hello() | ||
1950 | |||
1951 | print x | ||
1952 | |||
1953 | class Simple | ||
1954 | cool: => print "cool" | ||
1955 | |||
1956 | class Yikes extends Simple | ||
1957 | new: => print "created hello" | ||
1958 | |||
1959 | x = Yikes() | ||
1960 | x\cool() | ||
1961 | |||
1962 | |||
1963 | class Hi | ||
1964 | new: (arg) => | ||
1965 | print "init arg", arg | ||
1577 | 1966 | ||
1578 | dont_bubble = -> | 1967 | cool: (num) => |
1579 | [x for x in ((...)-> print ...)("hello")] | 1968 | print "num", num |
1580 | 1969 | ||
1581 | k = [x for x in ((...)-> print ...)("hello")] | ||
1582 | 1970 | ||
1583 | j = for i=1,10 | 1971 | class Simple extends Hi |
1584 | (...) -> print ... | 1972 | new: => super "man" |
1973 | cool: => super 120302 | ||
1585 | 1974 | ||
1586 | -- bubble me | 1975 | x = Simple() |
1976 | x\cool() | ||
1587 | 1977 | ||
1588 | m = (...) -> | 1978 | print x.__class == Simple |
1589 | [x for x in *{...} when f(...) > 4] | ||
1590 | 1979 | ||
1591 | x = for i in *{...} do i | ||
1592 | y = [x for x in *{...}] | ||
1593 | z = [x for x in hallo when f(...) > 4] | ||
1594 | 1980 | ||
1981 | class Okay | ||
1982 | -- what is going on | ||
1983 | something: 20323 | ||
1984 | -- yeaha | ||
1595 | 1985 | ||
1596 | a = for i=1,10 do ... | ||
1597 | 1986 | ||
1598 | b = for i=1,10 | 1987 | class Biggie extends Okay |
1599 | -> print ... | 1988 | something: => |
1989 | super 1,2,3,4 | ||
1990 | super.something another_self, 1,2,3,4 | ||
1991 | assert super == Okay | ||
1600 | 1992 | ||
1601 | 1993 | ||
1994 | class Yeah | ||
1995 | okay: => | ||
1996 | super\something 1,2,3,4 | ||
1602 | )TestCodesHere"; | 1997 | )TestCodesHere"; |
1603 | 1998 | ||
1604 | MoonCompliler{}.complile(s); | 1999 | MoonCompliler{}.complile(s); |