diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/MoonP/moon_ast.h | 33 | ||||
-rw-r--r-- | src/MoonP/moon_compiler.cpp | 464 | ||||
-rw-r--r-- | src/MoonP/moon_parser.cpp | 37 | ||||
-rw-r--r-- | src/MoonP/moon_parser.h | 13 |
4 files changed, 280 insertions, 267 deletions
diff --git a/src/MoonP/moon_ast.h b/src/MoonP/moon_ast.h index 4918a0a..42522dd 100644 --- a/src/MoonP/moon_ast.h +++ b/src/MoonP/moon_ast.h | |||
@@ -341,8 +341,8 @@ AST_END(Update) | |||
341 | AST_LEAF(BinaryOperator) | 341 | AST_LEAF(BinaryOperator) |
342 | AST_END(BinaryOperator) | 342 | AST_END(BinaryOperator) |
343 | 343 | ||
344 | AST_LEAF(BackcallOperator) | 344 | AST_LEAF(unary_operator) |
345 | AST_END(BackcallOperator) | 345 | AST_END(unary_operator) |
346 | 346 | ||
347 | class AssignableChain_t; | 347 | class AssignableChain_t; |
348 | 348 | ||
@@ -351,18 +351,19 @@ AST_NODE(Assignable) | |||
351 | AST_MEMBER(Assignable, &item) | 351 | AST_MEMBER(Assignable, &item) |
352 | AST_END(Assignable) | 352 | AST_END(Assignable) |
353 | 353 | ||
354 | class Value_t; | 354 | class unary_exp_t; |
355 | 355 | ||
356 | AST_NODE(exp_op_value) | 356 | AST_NODE(exp_op_value) |
357 | ast_sel<true, BinaryOperator_t, BackcallOperator_t> op; | 357 | ast_ptr<true, BinaryOperator_t> op; |
358 | ast_ptr<true, Value_t> value; | 358 | ast_list<true, unary_exp_t> backcalls; |
359 | AST_MEMBER(exp_op_value, &op, &value) | 359 | AST_MEMBER(exp_op_value, &op, &backcalls) |
360 | AST_END(exp_op_value) | 360 | AST_END(exp_op_value) |
361 | 361 | ||
362 | AST_NODE(Exp) | 362 | AST_NODE(Exp) |
363 | ast_ptr<true, Value_t> value; | 363 | ast_ptr<true, Seperator_t> sep; |
364 | ast_list<true, unary_exp_t> backcalls; | ||
364 | ast_list<false, exp_op_value_t> opValues; | 365 | ast_list<false, exp_op_value_t> opValues; |
365 | AST_MEMBER(Exp, &value, &opValues) | 366 | AST_MEMBER(Exp, &sep, &backcalls, &opValues) |
366 | AST_END(Exp) | 367 | AST_END(Exp) |
367 | 368 | ||
368 | class Parens_t; | 369 | class Parens_t; |
@@ -396,14 +397,15 @@ AST_END(simple_table) | |||
396 | class String_t; | 397 | class String_t; |
397 | class const_value_t; | 398 | class const_value_t; |
398 | class ClassDecl_t; | 399 | class ClassDecl_t; |
399 | class unary_exp_t; | 400 | class unary_value_t; |
400 | class TableLit_t; | 401 | class TableLit_t; |
401 | class FunLit_t; | 402 | class FunLit_t; |
402 | 403 | ||
403 | AST_NODE(SimpleValue) | 404 | AST_NODE(SimpleValue) |
404 | ast_sel<true, const_value_t, | 405 | ast_sel<true, const_value_t, |
405 | If_t, Unless_t, Switch_t, With_t, ClassDecl_t, | 406 | If_t, Unless_t, Switch_t, With_t, ClassDecl_t, |
406 | ForEach_t, For_t, While_t, Do_t, unary_exp_t, | 407 | ForEach_t, For_t, While_t, Do_t, |
408 | unary_value_t, | ||
407 | TblComprehension_t, TableLit_t, Comprehension_t, | 409 | TblComprehension_t, TableLit_t, Comprehension_t, |
408 | FunLit_t, Num_t> value; | 410 | FunLit_t, Num_t> value; |
409 | AST_MEMBER(SimpleValue, &value) | 411 | AST_MEMBER(SimpleValue, &value) |
@@ -641,9 +643,16 @@ AST_END(InvokeArgs) | |||
641 | AST_LEAF(const_value) | 643 | AST_LEAF(const_value) |
642 | AST_END(const_value) | 644 | AST_END(const_value) |
643 | 645 | ||
646 | AST_NODE(unary_value) | ||
647 | ast_list<true, unary_operator_t> ops; | ||
648 | ast_ptr<true, Value_t> value; | ||
649 | AST_MEMBER(unary_value, &ops, &value) | ||
650 | AST_END(unary_value) | ||
651 | |||
644 | AST_NODE(unary_exp) | 652 | AST_NODE(unary_exp) |
645 | ast_ptr<true, Exp_t> item; | 653 | ast_list<false, unary_operator_t> ops; |
646 | AST_MEMBER(unary_exp, &item) | 654 | ast_list<true, Value_t> expos; |
655 | AST_MEMBER(unary_exp, &ops, &expos) | ||
647 | AST_END(unary_exp) | 656 | AST_END(unary_exp) |
648 | 657 | ||
649 | AST_NODE(ExpListAssign) | 658 | AST_NODE(ExpListAssign) |
diff --git a/src/MoonP/moon_compiler.cpp b/src/MoonP/moon_compiler.cpp index 189a428..f7462dc 100644 --- a/src/MoonP/moon_compiler.cpp +++ b/src/MoonP/moon_compiler.cpp | |||
@@ -43,7 +43,7 @@ inline std::string s(std::string_view sv) { | |||
43 | } | 43 | } |
44 | 44 | ||
45 | const std::string_view version() { | 45 | const std::string_view version() { |
46 | return "0.3.14"sv; | 46 | return "0.4.0"sv; |
47 | } | 47 | } |
48 | 48 | ||
49 | // name of table stored in lua registry | 49 | // name of table stored in lua registry |
@@ -407,14 +407,57 @@ private: | |||
407 | } | 407 | } |
408 | break; | 408 | break; |
409 | } | 409 | } |
410 | case id<unary_exp_t>(): { | ||
411 | auto unary = static_cast<unary_exp_t*>(item); | ||
412 | if (unary->ops.empty() && unary->expos.size() == 1) { | ||
413 | return static_cast<Value_t*>(unary->expos.back()); | ||
414 | } | ||
415 | return nullptr; | ||
416 | } | ||
417 | default: break; | ||
410 | } | 418 | } |
411 | if (!exp) return nullptr; | 419 | if (!exp) return nullptr; |
412 | if (exp->opValues.empty()) { | 420 | BLOCK_START |
413 | return exp->value.get(); | 421 | BREAK_IF(!exp->opValues.empty()); |
414 | } | 422 | BREAK_IF(exp->backcalls.size() != 1); |
423 | auto unary = static_cast<unary_exp_t*>(exp->backcalls.back()); | ||
424 | BREAK_IF(!unary->ops.empty()); | ||
425 | BREAK_IF(unary->expos.size() != 1); | ||
426 | return static_cast<Value_t*>(unary->expos.back()); | ||
427 | BLOCK_END | ||
415 | return nullptr; | 428 | return nullptr; |
416 | } | 429 | } |
417 | 430 | ||
431 | ast_ptr<false, Exp_t> newExp(Value_t* value, ast_node* x) { | ||
432 | auto unary = x->new_ptr<unary_exp_t>(); | ||
433 | unary->expos.push_back(value); | ||
434 | auto exp = x->new_ptr<Exp_t>(); | ||
435 | exp->backcalls.push_back(unary); | ||
436 | return exp; | ||
437 | } | ||
438 | |||
439 | ast_ptr<false, Exp_t> newExp(Value_t* left, BinaryOperator_t* op, Value_t* right, ast_node* x) { | ||
440 | auto lunary = x->new_ptr<unary_exp_t>(); | ||
441 | lunary->expos.push_back(left); | ||
442 | auto opValue = x->new_ptr<exp_op_value_t>(); | ||
443 | { | ||
444 | auto runary = x->new_ptr<unary_exp_t>(); | ||
445 | runary->expos.push_back(right); | ||
446 | opValue->op.set(op); | ||
447 | opValue->backcalls.push_back(runary); | ||
448 | } | ||
449 | auto exp = x->new_ptr<Exp_t>(); | ||
450 | exp->backcalls.push_back(lunary); | ||
451 | exp->opValues.push_back(opValue); | ||
452 | return exp; | ||
453 | } | ||
454 | |||
455 | ast_ptr<false, Exp_t> newExp(unary_exp_t* unary, ast_node* x) { | ||
456 | auto exp = x->new_ptr<Exp_t>(); | ||
457 | exp->backcalls.push_back(unary); | ||
458 | return exp; | ||
459 | } | ||
460 | |||
418 | SimpleValue_t* simpleSingleValueFrom(ast_node* expList) const { | 461 | SimpleValue_t* simpleSingleValueFrom(ast_node* expList) const { |
419 | auto value = singleValueFrom(expList); | 462 | auto value = singleValueFrom(expList); |
420 | if (value && value->item.is<SimpleValue_t>()) { | 463 | if (value && value->item.is<SimpleValue_t>()) { |
@@ -423,18 +466,6 @@ private: | |||
423 | return nullptr; | 466 | return nullptr; |
424 | } | 467 | } |
425 | 468 | ||
426 | Value_t* firstValueFrom(ast_node* item) const { | ||
427 | Exp_t* exp = nullptr; | ||
428 | if (auto expList = ast_cast<ExpList_t>(item)) { | ||
429 | if (!expList->exprs.empty()) { | ||
430 | exp = static_cast<Exp_t*>(expList->exprs.front()); | ||
431 | } | ||
432 | } else { | ||
433 | exp = ast_cast<Exp_t>(item); | ||
434 | } | ||
435 | return exp->value.get(); | ||
436 | } | ||
437 | |||
438 | Statement_t* lastStatementFrom(Body_t* body) const { | 469 | Statement_t* lastStatementFrom(Body_t* body) const { |
439 | if (auto stmt = body->content.as<Statement_t>()) { | 470 | if (auto stmt = body->content.as<Statement_t>()) { |
440 | return stmt; | 471 | return stmt; |
@@ -526,7 +557,7 @@ private: | |||
526 | BLOCK_START | 557 | BLOCK_START |
527 | auto value = singleValueFrom(expList); | 558 | auto value = singleValueFrom(expList); |
528 | BREAK_IF(!value); | 559 | BREAK_IF(!value); |
529 | auto chainValue = value->getByPath<ChainValue_t>(); | 560 | auto chainValue = value->item.as<ChainValue_t>(); |
530 | BREAK_IF(!chainValue); | 561 | BREAK_IF(!chainValue); |
531 | BREAK_IF(chainValue->items.size() != 1); | 562 | BREAK_IF(chainValue->items.size() != 1); |
532 | auto callable = ast_cast<Callable_t>(chainValue->items.front()); | 563 | auto callable = ast_cast<Callable_t>(chainValue->items.front()); |
@@ -542,7 +573,7 @@ private: | |||
542 | BLOCK_START | 573 | BLOCK_START |
543 | auto value = singleValueFrom(exp); | 574 | auto value = singleValueFrom(exp); |
544 | BREAK_IF(!value); | 575 | BREAK_IF(!value); |
545 | auto chainValue = value->getByPath<ChainValue_t>(); | 576 | auto chainValue = value->item.as<ChainValue_t>(); |
546 | BREAK_IF(!chainValue); | 577 | BREAK_IF(!chainValue); |
547 | BREAK_IF(chainValue->items.size() != 1); | 578 | BREAK_IF(chainValue->items.size() != 1); |
548 | auto callable = ast_cast<Callable_t>(chainValue->items.front()); | 579 | auto callable = ast_cast<Callable_t>(chainValue->items.front()); |
@@ -614,18 +645,7 @@ private: | |||
614 | } | 645 | } |
615 | 646 | ||
616 | bool isPureBackcall(Exp_t* exp) const { | 647 | bool isPureBackcall(Exp_t* exp) const { |
617 | if (exp->opValues.empty()) { | 648 | return exp->opValues.empty() && exp->backcalls.size() > 1; |
618 | return false; | ||
619 | } | ||
620 | bool backcall = true; | ||
621 | for (auto _opValue : exp->opValues.objects()) { | ||
622 | auto opValue = static_cast<exp_op_value_t*>(_opValue); | ||
623 | if (!opValue->op.is<BackcallOperator_t>()) { | ||
624 | backcall = false; | ||
625 | break; | ||
626 | } | ||
627 | } | ||
628 | return backcall; | ||
629 | } | 649 | } |
630 | 650 | ||
631 | bool isMacroChain(ChainValue_t* chainValue) const { | 651 | bool isMacroChain(ChainValue_t* chainValue) const { |
@@ -672,8 +692,7 @@ private: | |||
672 | simpleValue->value.set(ifNode); | 692 | simpleValue->value.set(ifNode); |
673 | auto value = x->new_ptr<Value_t>(); | 693 | auto value = x->new_ptr<Value_t>(); |
674 | value->item.set(simpleValue); | 694 | value->item.set(simpleValue); |
675 | auto exp = x->new_ptr<Exp_t>(); | 695 | auto exp = newExp(value, x); |
676 | exp->value.set(value); | ||
677 | auto expList = x->new_ptr<ExpList_t>(); | 696 | auto expList = x->new_ptr<ExpList_t>(); |
678 | expList->exprs.push_back(exp); | 697 | expList->exprs.push_back(exp); |
679 | auto expListAssign = x->new_ptr<ExpListAssign_t>(); | 698 | auto expListAssign = x->new_ptr<ExpListAssign_t>(); |
@@ -700,8 +719,7 @@ private: | |||
700 | simpleValue->value.set(unless); | 719 | simpleValue->value.set(unless); |
701 | auto value = x->new_ptr<Value_t>(); | 720 | auto value = x->new_ptr<Value_t>(); |
702 | value->item.set(simpleValue); | 721 | value->item.set(simpleValue); |
703 | auto exp = x->new_ptr<Exp_t>(); | 722 | auto exp = newExp(value, x); |
704 | exp->value.set(value); | ||
705 | auto exprList = x->new_ptr<ExpList_t>(); | 723 | auto exprList = x->new_ptr<ExpList_t>(); |
706 | exprList->exprs.push_back(exp); | 724 | exprList->exprs.push_back(exp); |
707 | auto expListAssign = x->new_ptr<ExpListAssign_t>(); | 725 | auto expListAssign = x->new_ptr<ExpListAssign_t>(); |
@@ -720,8 +738,7 @@ private: | |||
720 | simpleValue->value.set(comp); | 738 | simpleValue->value.set(comp); |
721 | auto value = x->new_ptr<Value_t>(); | 739 | auto value = x->new_ptr<Value_t>(); |
722 | value->item.set(simpleValue); | 740 | value->item.set(simpleValue); |
723 | auto exp = x->new_ptr<Exp_t>(); | 741 | auto exp = newExp(value, x); |
724 | exp->value.set(value); | ||
725 | auto expList = x->new_ptr<ExpList_t>(); | 742 | auto expList = x->new_ptr<ExpList_t>(); |
726 | expList->exprs.push_back(exp); | 743 | expList->exprs.push_back(exp); |
727 | auto expListAssign = x->new_ptr<ExpListAssign_t>(); | 744 | auto expListAssign = x->new_ptr<ExpListAssign_t>(); |
@@ -951,8 +968,9 @@ private: | |||
951 | checkAssignable(assignment->expList); | 968 | checkAssignable(assignment->expList); |
952 | BLOCK_START | 969 | BLOCK_START |
953 | auto assign = ast_cast<Assign_t>(assignment->action); | 970 | auto assign = ast_cast<Assign_t>(assignment->action); |
954 | BREAK_IF(!assign || assign->values.objects().size() != 1); | 971 | BREAK_IF(!assign); |
955 | auto value = assign->values.objects().front(); | 972 | BREAK_IF(assign->values.objects().size() != 1); |
973 | auto value = assign->values.objects().back(); | ||
956 | if (ast_is<Exp_t>(value)) { | 974 | if (ast_is<Exp_t>(value)) { |
957 | if (auto val = simpleSingleValueFrom(value)) { | 975 | if (auto val = simpleSingleValueFrom(value)) { |
958 | value = val->value.get(); | 976 | value = val->value.get(); |
@@ -1046,8 +1064,9 @@ private: | |||
1046 | transformExp(exp, out, ExpUsage::Assignment, expList); | 1064 | transformExp(exp, out, ExpUsage::Assignment, expList); |
1047 | return; | 1065 | return; |
1048 | } | 1066 | } |
1049 | BREAK_IF(!exp->opValues.empty()); | 1067 | auto singleVal = singleValueFrom(exp); |
1050 | if (auto chainValue = exp->value->item.as<ChainValue_t>()) { | 1068 | BREAK_IF(!singleVal); |
1069 | if (auto chainValue = singleVal->item.as<ChainValue_t>()) { | ||
1051 | auto type = specialChainValue(chainValue); | 1070 | auto type = specialChainValue(chainValue); |
1052 | auto expList = assignment->expList.get(); | 1071 | auto expList = assignment->expList.get(); |
1053 | switch (type) { | 1072 | switch (type) { |
@@ -1115,7 +1134,7 @@ private: | |||
1115 | if (!defs.empty()) _buf << indent() << "local "sv << join(defs,", "sv) << nll(assignment); | 1134 | if (!defs.empty()) _buf << indent() << "local "sv << join(defs,", "sv) << nll(assignment); |
1116 | _buf << indent() << "do"sv << nll(assignment); | 1135 | _buf << indent() << "do"sv << nll(assignment); |
1117 | pushScope(); | 1136 | pushScope(); |
1118 | auto objVar = getUnusedName("_obj_"); | 1137 | auto objVar = getUnusedName("_obj_"sv); |
1119 | for (auto& v : values) v.insert(0, objVar); | 1138 | for (auto& v : values) v.insert(0, objVar); |
1120 | _buf << indent() << "local "sv << objVar << " = "sv << destruct.value << nll(assignment); | 1139 | _buf << indent() << "local "sv << objVar << " = "sv << destruct.value << nll(assignment); |
1121 | _buf << indent() << join(names, ", "sv) << " = "sv << join(values, ", "sv) << nll(assignment); | 1140 | _buf << indent() << join(names, ", "sv) << " = "sv << join(values, ", "sv) << nll(assignment); |
@@ -1291,8 +1310,9 @@ private: | |||
1291 | str_list temp; | 1310 | str_list temp; |
1292 | for (auto i = exprs.begin(), j = values.begin(); i != exprs.end(); ++i, ++j) { | 1311 | for (auto i = exprs.begin(), j = values.begin(); i != exprs.end(); ++i, ++j) { |
1293 | auto expr = *i; | 1312 | auto expr = *i; |
1294 | ast_node* destructNode = expr->getByPath<Value_t, SimpleValue_t, TableLit_t>(); | 1313 | auto value = singleValueFrom(expr); |
1295 | if (destructNode || (destructNode = expr->getByPath<Value_t, simple_table_t>())) { | 1314 | ast_node* destructNode = value->getByPath<SimpleValue_t, TableLit_t>(); |
1315 | if (destructNode || (destructNode = value->item.as<simple_table_t>())) { | ||
1296 | destructPairs.push_back({i,j}); | 1316 | destructPairs.push_back({i,j}); |
1297 | auto& destruct = destructs.emplace_back(); | 1317 | auto& destruct = destructs.emplace_back(); |
1298 | if (!varDefOnly) { | 1318 | if (!varDefOnly) { |
@@ -1304,6 +1324,10 @@ private: | |||
1304 | } | 1324 | } |
1305 | auto pairs = destructFromExp(expr); | 1325 | auto pairs = destructFromExp(expr); |
1306 | destruct.items = std::move(pairs); | 1326 | destruct.items = std::move(pairs); |
1327 | if (destruct.items.size() == 1 && !singleValueFrom(*j)) { | ||
1328 | destruct.value.insert(0, "("sv); | ||
1329 | destruct.value.append(")"sv); | ||
1330 | } | ||
1307 | } | 1331 | } |
1308 | } | 1332 | } |
1309 | for (const auto& p : destructPairs) { | 1333 | for (const auto& p : destructPairs) { |
@@ -1337,7 +1361,7 @@ private: | |||
1337 | auto leftExp = static_cast<Exp_t*>(expList->exprs.objects().front()); | 1361 | auto leftExp = static_cast<Exp_t*>(expList->exprs.objects().front()); |
1338 | auto leftValue = singleValueFrom(leftExp); | 1362 | auto leftValue = singleValueFrom(leftExp); |
1339 | if (!leftValue) throw std::logic_error(_info.errorMessage("left hand expression is not assignable"sv, leftExp)); | 1363 | if (!leftValue) throw std::logic_error(_info.errorMessage("left hand expression is not assignable"sv, leftExp)); |
1340 | if (auto chain = leftValue->getByPath<ChainValue_t>()) { | 1364 | if (auto chain = leftValue->item.as<ChainValue_t>()) { |
1341 | auto tmpChain = x->new_ptr<ChainValue_t>(); | 1365 | auto tmpChain = x->new_ptr<ChainValue_t>(); |
1342 | for (auto item : chain->items.objects()) { | 1366 | for (auto item : chain->items.objects()) { |
1343 | bool itemAdded = false; | 1367 | bool itemAdded = false; |
@@ -1440,8 +1464,7 @@ private: | |||
1440 | simpleValue->value.set(newIf); | 1464 | simpleValue->value.set(newIf); |
1441 | auto value = x->new_ptr<Value_t>(); | 1465 | auto value = x->new_ptr<Value_t>(); |
1442 | value->item.set(simpleValue); | 1466 | value->item.set(simpleValue); |
1443 | auto exp = x->new_ptr<Exp_t>(); | 1467 | auto exp = newExp(value, x); |
1444 | exp->value.set(value); | ||
1445 | auto expList = x->new_ptr<ExpList_t>(); | 1468 | auto expList = x->new_ptr<ExpList_t>(); |
1446 | expList->exprs.push_back(exp); | 1469 | expList->exprs.push_back(exp); |
1447 | auto expListAssign = x->new_ptr<ExpListAssign_t>(); | 1470 | auto expListAssign = x->new_ptr<ExpListAssign_t>(); |
@@ -1612,14 +1635,18 @@ private: | |||
1612 | out.push_back(join(temp, ", "sv)); | 1635 | out.push_back(join(temp, ", "sv)); |
1613 | } | 1636 | } |
1614 | 1637 | ||
1615 | ast_ptr<false, Exp_t> transformBackcall(Value_t* first, node_container::const_iterator begin, node_container::const_iterator end) { | 1638 | void transform_backcall_exp(const node_container& values, str_list& out, ExpUsage usage, ExpList_t* assignList = nullptr) { |
1616 | auto arg = first->new_ptr<Exp_t>(); | 1639 | if (values.size() == 1 && usage == ExpUsage::Closure) { |
1617 | arg->value.set(first); | 1640 | transform_unary_exp(static_cast<unary_exp_t*>(values.front()), out); |
1618 | for (auto it = begin; it != end; ++it) { | 1641 | } else { |
1619 | auto opValue = static_cast<exp_op_value_t*>(*it); | 1642 | auto x = values.front(); |
1620 | if (auto chainValue = opValue->value->item.as<ChainValue_t>()) { | 1643 | auto arg = newExp(static_cast<unary_exp_t*>(x), x); |
1621 | auto newArg = first->new_ptr<Exp_t>(); | 1644 | auto begin = values.begin(); begin++; |
1622 | { | 1645 | for (auto it = begin; it != values.end(); ++it) { |
1646 | auto unary = static_cast<unary_exp_t*>(*it); | ||
1647 | auto value = singleValueFrom(unary); | ||
1648 | if (!value) throw std::logic_error(_info.errorMessage("backcall operator must be followed by chain value"sv, *it)); | ||
1649 | if (auto chainValue = value->item.as<ChainValue_t>()) { | ||
1623 | if (isChainValueCall(chainValue)) { | 1650 | if (isChainValueCall(chainValue)) { |
1624 | auto last = chainValue->items.back(); | 1651 | auto last = chainValue->items.back(); |
1625 | _ast_list* args = nullptr; | 1652 | _ast_list* args = nullptr; |
@@ -1647,98 +1674,65 @@ private: | |||
1647 | args->push_front(arg); | 1674 | args->push_front(arg); |
1648 | } | 1675 | } |
1649 | } else { | 1676 | } else { |
1650 | auto invoke = first->new_ptr<Invoke_t>(); | 1677 | auto invoke = x->new_ptr<Invoke_t>(); |
1651 | invoke->args.push_front(arg); | 1678 | invoke->args.push_front(arg); |
1652 | chainValue->items.push_back(invoke); | 1679 | chainValue->items.push_back(invoke); |
1653 | } | 1680 | } |
1654 | auto value = first->new_ptr<Value_t>(); | 1681 | arg.set(newExp(unary, x)); |
1655 | value->item.set(chainValue); | 1682 | } else { |
1656 | newArg->value.set(value); | 1683 | throw std::logic_error(_info.errorMessage("backcall operator must be followed by chain value"sv, value)); |
1657 | arg.set(newArg); | ||
1658 | } | 1684 | } |
1659 | } else { | ||
1660 | throw std::logic_error(_info.errorMessage("backcall operator must be followed by chain value"sv, opValue->value)); | ||
1661 | } | 1685 | } |
1662 | } | 1686 | switch (usage) { |
1663 | return arg; | 1687 | case ExpUsage::Assignment: { |
1664 | } | 1688 | auto assignment = x->new_ptr<ExpListAssign_t>(); |
1665 | 1689 | auto assign = x->new_ptr<Assign_t>(); | |
1666 | void transformExp(Exp_t* exp, str_list& out, ExpUsage usage, ExpList_t* assignList = nullptr) { | 1690 | assign->values.push_back(arg); |
1667 | const auto& opValues = exp->opValues.objects(); | 1691 | assignment->action.set(assign); |
1668 | for (auto it = opValues.begin(); it != opValues.end(); ++it) { | 1692 | assignment->expList.set(assignList); |
1669 | auto opValue = static_cast<exp_op_value_t*>(*it); | 1693 | transformAssignment(assignment, out); |
1670 | if (opValue->op.is<BackcallOperator_t>()) { | 1694 | return; |
1671 | auto end = std::find_if_not(it, opValues.end(), [](ast_node* node) { | ||
1672 | return static_cast<exp_op_value_t*>(node)->op.is<BackcallOperator_t>(); | ||
1673 | }); | ||
1674 | ast_ptr<false, Exp_t> backcall; | ||
1675 | if (it == opValues.begin()) { | ||
1676 | auto first = exp->value.get(); | ||
1677 | backcall = transformBackcall(first, it, end); | ||
1678 | for (auto i = end; i != opValues.end(); ++i) { | ||
1679 | backcall->opValues.push_back(*i); | ||
1680 | } | ||
1681 | } else { | ||
1682 | auto prev = it; --prev; | ||
1683 | auto first = static_cast<exp_op_value_t*>(*prev)->value.get(); | ||
1684 | backcall = transformBackcall(first, it, end); | ||
1685 | for (auto i = opValues.begin(); i != it; ++i) { | ||
1686 | backcall->opValues.push_back(*i); | ||
1687 | } | ||
1688 | static_cast<exp_op_value_t*>(backcall->opValues.back())->value.set(backcall->value); | ||
1689 | backcall->value.set(exp->value); | ||
1690 | for (auto i = end; i != opValues.end(); ++i) { | ||
1691 | backcall->opValues.push_back(*i); | ||
1692 | } | ||
1693 | } | 1695 | } |
1694 | auto x = exp; | 1696 | case ExpUsage::Common: { |
1695 | switch (usage) { | 1697 | auto value = singleValueFrom(arg); |
1696 | case ExpUsage::Assignment: { | 1698 | if (value && value->item.is<ChainValue_t>()) { |
1697 | auto assignment = x->new_ptr<ExpListAssign_t>(); | 1699 | transformChainValue(value->item.to<ChainValue_t>(), out, ExpUsage::Common); |
1698 | auto assign = x->new_ptr<Assign_t>(); | 1700 | } else { |
1699 | assign->values.push_back(backcall); | 1701 | transformExp(arg, out, ExpUsage::Closure); |
1700 | assignment->action.set(assign); | 1702 | out.back().insert(0, indent()); |
1701 | assignment->expList.set(assignList); | 1703 | out.back().append(nlr(x)); |
1702 | transformAssignment(assignment, out); | ||
1703 | return; | ||
1704 | } | ||
1705 | case ExpUsage::Common: { | ||
1706 | if (backcall->opValues.empty() && backcall->value->item.is<ChainValue_t>()) { | ||
1707 | transformChainValue(backcall->value->item.to<ChainValue_t>(), out, ExpUsage::Common); | ||
1708 | } else { | ||
1709 | transformExp(backcall, out, ExpUsage::Closure); | ||
1710 | out.back().insert(0, indent()); | ||
1711 | out.back().append(nlr(x)); | ||
1712 | } | ||
1713 | return; | ||
1714 | } | ||
1715 | case ExpUsage::Return: { | ||
1716 | auto ret = x->new_ptr<Return_t>(); | ||
1717 | auto expListLow = x->new_ptr<ExpListLow_t>(); | ||
1718 | expListLow->exprs.push_back(backcall); | ||
1719 | ret->valueList.set(expListLow); | ||
1720 | transformReturn(ret, out); | ||
1721 | return; | ||
1722 | } | ||
1723 | case ExpUsage::Closure: { | ||
1724 | transformExp(backcall, out, ExpUsage::Closure); | ||
1725 | return; | ||
1726 | } | 1704 | } |
1727 | default: assert(false); return; | 1705 | return; |
1728 | } | 1706 | } |
1707 | case ExpUsage::Return: { | ||
1708 | auto ret = x->new_ptr<Return_t>(); | ||
1709 | auto expListLow = x->new_ptr<ExpListLow_t>(); | ||
1710 | expListLow->exprs.push_back(arg); | ||
1711 | ret->valueList.set(expListLow); | ||
1712 | transformReturn(ret, out); | ||
1713 | return; | ||
1714 | } | ||
1715 | case ExpUsage::Closure: { | ||
1716 | transformExp(arg, out, ExpUsage::Closure); | ||
1717 | return; | ||
1718 | } | ||
1719 | default: assert(false); return; | ||
1729 | } | 1720 | } |
1730 | } | 1721 | } |
1722 | } | ||
1723 | |||
1724 | void transformExp(Exp_t* exp, str_list& out, ExpUsage usage, ExpList_t* assignList = nullptr) { | ||
1725 | if (exp->opValues.empty()) { | ||
1726 | transform_backcall_exp(exp->backcalls.objects(), out, usage, assignList); | ||
1727 | return; | ||
1728 | } | ||
1731 | assert(usage == ExpUsage::Closure); | 1729 | assert(usage == ExpUsage::Closure); |
1732 | str_list temp; | 1730 | str_list temp; |
1733 | transformValue(exp->value, temp); | 1731 | transform_backcall_exp(exp->backcalls.objects(), temp, ExpUsage::Closure); |
1734 | for (auto _opValue : exp->opValues.objects()) { | 1732 | for (auto _opValue : exp->opValues.objects()) { |
1735 | auto opValue = static_cast<exp_op_value_t*>(_opValue); | 1733 | auto opValue = static_cast<exp_op_value_t*>(_opValue); |
1736 | if (auto op = opValue->op.as<BinaryOperator_t>()) { | 1734 | transformBinaryOperator(opValue->op, temp); |
1737 | transformBinaryOperator(op, temp); | 1735 | transform_backcall_exp(opValue->backcalls.objects(), temp, ExpUsage::Closure); |
1738 | } else { | ||
1739 | temp.push_back(s("|>"sv)); | ||
1740 | } | ||
1741 | transformValue(opValue->value, temp); | ||
1742 | } | 1736 | } |
1743 | out.push_back(join(temp, " "sv)); | 1737 | out.push_back(join(temp, " "sv)); |
1744 | } | 1738 | } |
@@ -1748,11 +1742,7 @@ private: | |||
1748 | switch (item->getId()) { | 1742 | switch (item->getId()) { |
1749 | case id<SimpleValue_t>(): transformSimpleValue(static_cast<SimpleValue_t*>(item), out); break; | 1743 | case id<SimpleValue_t>(): transformSimpleValue(static_cast<SimpleValue_t*>(item), out); break; |
1750 | case id<simple_table_t>(): transform_simple_table(static_cast<simple_table_t*>(item), out); break; | 1744 | case id<simple_table_t>(): transform_simple_table(static_cast<simple_table_t*>(item), out); break; |
1751 | case id<ChainValue_t>(): { | 1745 | case id<ChainValue_t>(): transformChainValue(static_cast<ChainValue_t*>(item), out, ExpUsage::Closure); break; |
1752 | auto chainValue = static_cast<ChainValue_t*>(item); | ||
1753 | transformChainValue(chainValue, out, ExpUsage::Closure); | ||
1754 | break; | ||
1755 | } | ||
1756 | case id<String_t>(): transformString(static_cast<String_t*>(item), out); break; | 1746 | case id<String_t>(): transformString(static_cast<String_t*>(item), out); break; |
1757 | default: assert(false); break; | 1747 | default: assert(false); break; |
1758 | } | 1748 | } |
@@ -1812,7 +1802,7 @@ private: | |||
1812 | case id<For_t>(): transformForClosure(static_cast<For_t*>(value), out); break; | 1802 | case id<For_t>(): transformForClosure(static_cast<For_t*>(value), out); break; |
1813 | case id<While_t>(): transformWhileClosure(static_cast<While_t*>(value), out); break; | 1803 | case id<While_t>(): transformWhileClosure(static_cast<While_t*>(value), out); break; |
1814 | case id<Do_t>(): transformDo(static_cast<Do_t*>(value), out, ExpUsage::Closure); break; | 1804 | case id<Do_t>(): transformDo(static_cast<Do_t*>(value), out, ExpUsage::Closure); break; |
1815 | case id<unary_exp_t>(): transform_unary_exp(static_cast<unary_exp_t*>(value), out); break; | 1805 | case id<unary_value_t>(): transform_unary_value(static_cast<unary_value_t*>(value), out); break; |
1816 | case id<TblComprehension_t>(): transformTblComprehension(static_cast<TblComprehension_t*>(value), out, ExpUsage::Closure); break; | 1806 | case id<TblComprehension_t>(): transformTblComprehension(static_cast<TblComprehension_t*>(value), out, ExpUsage::Closure); break; |
1817 | case id<TableLit_t>(): transformTableLit(static_cast<TableLit_t*>(value), out); break; | 1807 | case id<TableLit_t>(): transformTableLit(static_cast<TableLit_t*>(value), out); break; |
1818 | case id<Comprehension_t>(): transformComprehension(static_cast<Comprehension_t*>(value), out, ExpUsage::Closure); break; | 1808 | case id<Comprehension_t>(): transformComprehension(static_cast<Comprehension_t*>(value), out, ExpUsage::Closure); break; |
@@ -1904,7 +1894,7 @@ private: | |||
1904 | } | 1894 | } |
1905 | } | 1895 | } |
1906 | x = backcall; | 1896 | x = backcall; |
1907 | auto arg = x->new_ptr<Exp_t>(); | 1897 | ast_ptr<false, Exp_t> arg; |
1908 | { | 1898 | { |
1909 | auto block = x->new_ptr<Block_t>(); | 1899 | auto block = x->new_ptr<Block_t>(); |
1910 | auto next = it; ++next; | 1900 | auto next = it; ++next; |
@@ -1924,7 +1914,7 @@ private: | |||
1924 | simpleValue->value.set(funLit); | 1914 | simpleValue->value.set(funLit); |
1925 | auto value = x->new_ptr<Value_t>(); | 1915 | auto value = x->new_ptr<Value_t>(); |
1926 | value->item.set(simpleValue); | 1916 | value->item.set(simpleValue); |
1927 | arg->value.set(value); | 1917 | arg = newExp(value, x); |
1928 | } | 1918 | } |
1929 | if (isChainValueCall(backcall->value)) { | 1919 | if (isChainValueCall(backcall->value)) { |
1930 | auto last = backcall->value->items.back(); | 1920 | auto last = backcall->value->items.back(); |
@@ -1962,8 +1952,7 @@ private: | |||
1962 | auto chainValue = backcall->value.get(); | 1952 | auto chainValue = backcall->value.get(); |
1963 | auto value = x->new_ptr<Value_t>(); | 1953 | auto value = x->new_ptr<Value_t>(); |
1964 | value->item.set(chainValue); | 1954 | value->item.set(chainValue); |
1965 | auto exp = x->new_ptr<Exp_t>(); | 1955 | auto exp = newExp(value, x); |
1966 | exp->value.set(value); | ||
1967 | auto expList = x->new_ptr<ExpList_t>(); | 1956 | auto expList = x->new_ptr<ExpList_t>(); |
1968 | expList->exprs.push_back(exp); | 1957 | expList->exprs.push_back(exp); |
1969 | auto expListAssign = x->new_ptr<ExpListAssign_t>(); | 1958 | auto expListAssign = x->new_ptr<ExpListAssign_t>(); |
@@ -2103,8 +2092,7 @@ private: | |||
2103 | simpleValue->value.set(last->content); | 2092 | simpleValue->value.set(last->content); |
2104 | auto value = x->new_ptr<Value_t>(); | 2093 | auto value = x->new_ptr<Value_t>(); |
2105 | value->item.set(simpleValue); | 2094 | value->item.set(simpleValue); |
2106 | auto exp = x->new_ptr<Exp_t>(); | 2095 | auto exp = newExp(value, x); |
2107 | exp->value.set(value); | ||
2108 | assign->values.push_back(exp); | 2096 | assign->values.push_back(exp); |
2109 | } | 2097 | } |
2110 | newAssignment->action.set(assign); | 2098 | newAssignment->action.set(assign); |
@@ -2539,12 +2527,7 @@ private: | |||
2539 | chainValue->items.pop_back(); | 2527 | chainValue->items.pop_back(); |
2540 | auto value = x->new_ptr<Value_t>(); | 2528 | auto value = x->new_ptr<Value_t>(); |
2541 | value->item.set(chainValue); | 2529 | value->item.set(chainValue); |
2542 | auto opValue = x->new_ptr<exp_op_value_t>(); | 2530 | auto exp = newExp(value, toAst<BinaryOperator_t>("!="sv, x), toAst<Value_t>("nil"sv, x), x); |
2543 | opValue->op.set(toAst<BinaryOperator_t>("!="sv, x)); | ||
2544 | opValue->value.set(toAst<Value_t>("nil"sv, x)); | ||
2545 | auto exp = x->new_ptr<Exp_t>(); | ||
2546 | exp->value.set(value); | ||
2547 | exp->opValues.push_back(opValue); | ||
2548 | parens->expr.set(exp); | 2531 | parens->expr.set(exp); |
2549 | } | 2532 | } |
2550 | switch (usage) { | 2533 | switch (usage) { |
@@ -2555,8 +2538,7 @@ private: | |||
2555 | chainValue->items.push_back(callable); | 2538 | chainValue->items.push_back(callable); |
2556 | auto value = x->new_ptr<Value_t>(); | 2539 | auto value = x->new_ptr<Value_t>(); |
2557 | value->item.set(chainValue); | 2540 | value->item.set(chainValue); |
2558 | auto exp = x->new_ptr<Exp_t>(); | 2541 | auto exp = newExp(value, x); |
2559 | exp->value.set(value); | ||
2560 | auto assignment = x->new_ptr<ExpListAssign_t>(); | 2542 | auto assignment = x->new_ptr<ExpListAssign_t>(); |
2561 | assignment->expList.set(assignList); | 2543 | assignment->expList.set(assignList); |
2562 | auto assign = x->new_ptr<Assign_t>(); | 2544 | auto assign = x->new_ptr<Assign_t>(); |
@@ -2633,8 +2615,7 @@ private: | |||
2633 | } else { | 2615 | } else { |
2634 | auto value = x->new_ptr<Value_t>(); | 2616 | auto value = x->new_ptr<Value_t>(); |
2635 | value->item.set(chainValue); | 2617 | value->item.set(chainValue); |
2636 | auto exp = x->new_ptr<Exp_t>(); | 2618 | auto exp = newExp(value, x); |
2637 | exp->value.set(value); | ||
2638 | auto assign = x->new_ptr<Assign_t>(); | 2619 | auto assign = x->new_ptr<Assign_t>(); |
2639 | assign->values.push_back(exp); | 2620 | assign->values.push_back(exp); |
2640 | auto expListAssign = x->new_ptr<ExpListAssign_t>(); | 2621 | auto expListAssign = x->new_ptr<ExpListAssign_t>(); |
@@ -2665,8 +2646,7 @@ private: | |||
2665 | } | 2646 | } |
2666 | auto value = x->new_ptr<Value_t>(); | 2647 | auto value = x->new_ptr<Value_t>(); |
2667 | value->item.set(partOne); | 2648 | value->item.set(partOne); |
2668 | auto exp = x->new_ptr<Exp_t>(); | 2649 | auto exp = newExp(value, x); |
2669 | exp->value.set(value); | ||
2670 | auto assign = x->new_ptr<Assign_t>(); | 2650 | auto assign = x->new_ptr<Assign_t>(); |
2671 | assign->values.push_back(exp); | 2651 | assign->values.push_back(exp); |
2672 | auto expListAssign = x->new_ptr<ExpListAssign_t>(); | 2652 | auto expListAssign = x->new_ptr<ExpListAssign_t>(); |
@@ -2689,8 +2669,7 @@ private: | |||
2689 | case ExpUsage::Assignment: { | 2669 | case ExpUsage::Assignment: { |
2690 | auto value = x->new_ptr<Value_t>(); | 2670 | auto value = x->new_ptr<Value_t>(); |
2691 | value->item.set(partTwo); | 2671 | value->item.set(partTwo); |
2692 | auto exp = x->new_ptr<Exp_t>(); | 2672 | auto exp = newExp(value, x); |
2693 | exp->value.set(value); | ||
2694 | auto assign = x->new_ptr<Assign_t>(); | 2673 | auto assign = x->new_ptr<Assign_t>(); |
2695 | assign->values.push_back(exp); | 2674 | assign->values.push_back(exp); |
2696 | auto assignment = x->new_ptr<ExpListAssign_t>(); | 2675 | auto assignment = x->new_ptr<ExpListAssign_t>(); |
@@ -2703,8 +2682,7 @@ private: | |||
2703 | case ExpUsage::Closure: { | 2682 | case ExpUsage::Closure: { |
2704 | auto value = x->new_ptr<Value_t>(); | 2683 | auto value = x->new_ptr<Value_t>(); |
2705 | value->item.set(partTwo); | 2684 | value->item.set(partTwo); |
2706 | auto exp = x->new_ptr<Exp_t>(); | 2685 | auto exp = newExp(value, x); |
2707 | exp->value.set(value); | ||
2708 | auto ret = x->new_ptr<Return_t>(); | 2686 | auto ret = x->new_ptr<Return_t>(); |
2709 | auto expListLow = x->new_ptr<ExpListLow_t>(); | 2687 | auto expListLow = x->new_ptr<ExpListLow_t>(); |
2710 | expListLow->exprs.push_back(exp); | 2688 | expListLow->exprs.push_back(exp); |
@@ -2771,8 +2749,7 @@ private: | |||
2771 | { | 2749 | { |
2772 | auto value = x->new_ptr<Value_t>(); | 2750 | auto value = x->new_ptr<Value_t>(); |
2773 | value->item.set(baseChain); | 2751 | value->item.set(baseChain); |
2774 | auto exp = x->new_ptr<Exp_t>(); | 2752 | auto exp = newExp(value, x); |
2775 | exp->value.set(value); | ||
2776 | auto assign = x->new_ptr<Assign_t>(); | 2753 | auto assign = x->new_ptr<Assign_t>(); |
2777 | assign->values.push_back(exp); | 2754 | assign->values.push_back(exp); |
2778 | auto assignment = x->new_ptr<ExpListAssign_t>(); | 2755 | auto assignment = x->new_ptr<ExpListAssign_t>(); |
@@ -2886,8 +2863,7 @@ private: | |||
2886 | } | 2863 | } |
2887 | auto value = x->new_ptr<Value_t>(); | 2864 | auto value = x->new_ptr<Value_t>(); |
2888 | value->item.set(chainValue); | 2865 | value->item.set(chainValue); |
2889 | auto exp = x->new_ptr<Exp_t>(); | 2866 | auto exp = newExp(value, x); |
2890 | exp->value.set(value); | ||
2891 | callVar = singleVariableFrom(exp); | 2867 | callVar = singleVariableFrom(exp); |
2892 | if (callVar.empty()) { | 2868 | if (callVar.empty()) { |
2893 | callVar = getUnusedName(s("_call_"sv)); | 2869 | callVar = getUnusedName(s("_call_"sv)); |
@@ -2901,6 +2877,7 @@ private: | |||
2901 | block->statements.push_back(stmt); | 2877 | block->statements.push_back(stmt); |
2902 | } | 2878 | } |
2903 | } | 2879 | } |
2880 | ast_ptr<false, Exp_t> nexp; | ||
2904 | { | 2881 | { |
2905 | auto name = _parser.toString(colonItem->name); | 2882 | auto name = _parser.toString(colonItem->name); |
2906 | auto chainValue = x->new_ptr<ChainValue_t>(); | 2883 | auto chainValue = x->new_ptr<ChainValue_t>(); |
@@ -2920,10 +2897,9 @@ private: | |||
2920 | } | 2897 | } |
2921 | auto value = x->new_ptr<Value_t>(); | 2898 | auto value = x->new_ptr<Value_t>(); |
2922 | value->item.set(chainValue); | 2899 | value->item.set(chainValue); |
2923 | auto exp = x->new_ptr<Exp_t>(); | 2900 | nexp = newExp(value, x); |
2924 | exp->value.set(value); | ||
2925 | auto expList = x->new_ptr<ExpList_t>(); | 2901 | auto expList = x->new_ptr<ExpList_t>(); |
2926 | expList->exprs.push_back(exp); | 2902 | expList->exprs.push_back(nexp); |
2927 | auto expListAssign = x->new_ptr<ExpListAssign_t>(); | 2903 | auto expListAssign = x->new_ptr<ExpListAssign_t>(); |
2928 | expListAssign->expList.set(expList); | 2904 | expListAssign->expList.set(expList); |
2929 | auto stmt = x->new_ptr<Statement_t>(); | 2905 | auto stmt = x->new_ptr<Statement_t>(); |
@@ -2942,25 +2918,28 @@ private: | |||
2942 | default: | 2918 | default: |
2943 | break; | 2919 | break; |
2944 | } | 2920 | } |
2945 | auto body = x->new_ptr<Body_t>(); | 2921 | if (block->statements.size() == 1) { |
2946 | body->content.set(block); | 2922 | transformExp(nexp, out, usage, assignList); |
2947 | auto funLit = toAst<FunLit_t>("->"sv, x); | 2923 | } else { |
2948 | funLit->body.set(body); | 2924 | auto body = x->new_ptr<Body_t>(); |
2949 | auto simpleValue = x->new_ptr<SimpleValue_t>(); | 2925 | body->content.set(block); |
2950 | simpleValue->value.set(funLit); | 2926 | auto funLit = toAst<FunLit_t>("->"sv, x); |
2951 | auto value = x->new_ptr<Value_t>(); | 2927 | funLit->body.set(body); |
2952 | value->item.set(simpleValue); | 2928 | auto simpleValue = x->new_ptr<SimpleValue_t>(); |
2953 | auto exp = x->new_ptr<Exp_t>(); | 2929 | simpleValue->value.set(funLit); |
2954 | exp->value.set(value); | 2930 | auto value = x->new_ptr<Value_t>(); |
2955 | auto paren = x->new_ptr<Parens_t>(); | 2931 | value->item.set(simpleValue); |
2956 | paren->expr.set(exp); | 2932 | auto exp = newExp(value, x); |
2957 | auto callable = x->new_ptr<Callable_t>(); | 2933 | auto paren = x->new_ptr<Parens_t>(); |
2958 | callable->item.set(paren); | 2934 | paren->expr.set(exp); |
2959 | auto chainValue = x->new_ptr<ChainValue_t>(); | 2935 | auto callable = x->new_ptr<Callable_t>(); |
2960 | chainValue->items.push_back(callable); | 2936 | callable->item.set(paren); |
2961 | auto invoke = x->new_ptr<Invoke_t>(); | 2937 | auto chainValue = x->new_ptr<ChainValue_t>(); |
2962 | chainValue->items.push_back(invoke); | 2938 | chainValue->items.push_back(callable); |
2963 | transformChainValue(chainValue, out, ExpUsage::Closure); | 2939 | auto invoke = x->new_ptr<Invoke_t>(); |
2940 | chainValue->items.push_back(invoke); | ||
2941 | transformChainValue(chainValue, out, ExpUsage::Closure); | ||
2942 | } | ||
2964 | return; | 2943 | return; |
2965 | } | 2944 | } |
2966 | transformColonChainItem(colonItem, temp); | 2945 | transformColonChainItem(colonItem, temp); |
@@ -3032,13 +3011,13 @@ private: | |||
3032 | } | 3011 | } |
3033 | for (auto arg : *args) { | 3012 | for (auto arg : *args) { |
3034 | std::string str; | 3013 | std::string str; |
3035 | if (auto exp = ast_cast<Exp_t>(arg)) { | 3014 | // check whether arg is reassembled |
3036 | // patch for backcall operator support | 3015 | // do some workaround for backcall expression |
3016 | if (ast_is<Exp_t>(arg) && arg->m_begin.m_it == arg->m_end.m_it) { | ||
3017 | auto exp = static_cast<Exp_t*>(arg); | ||
3037 | BLOCK_START | 3018 | BLOCK_START |
3038 | BREAK_IF(arg->m_begin.m_line != arg->m_end.m_line || | ||
3039 | arg->m_begin.m_col != arg->m_end.m_col); | ||
3040 | BREAK_IF(!exp->opValues.empty()); | 3019 | BREAK_IF(!exp->opValues.empty()); |
3041 | auto chainValue = exp->getByPath<Value_t, ChainValue_t>(); | 3020 | auto chainValue = exp->getByPath<unary_exp_t, Value_t, ChainValue_t>(); |
3042 | BREAK_IF(!chainValue); | 3021 | BREAK_IF(!chainValue); |
3043 | BREAK_IF(!isMacroChain(chainValue)); | 3022 | BREAK_IF(!isMacroChain(chainValue)); |
3044 | BREAK_IF(chainValue->items.size() != 2); | 3023 | BREAK_IF(chainValue->items.size() != 2); |
@@ -3047,26 +3026,27 @@ private: | |||
3047 | str = codes; | 3026 | str = codes; |
3048 | BLOCK_END | 3027 | BLOCK_END |
3049 | if (str.empty()) { | 3028 | if (str.empty()) { |
3050 | bool multiLineStr = false; | 3029 | // exp is reassembled due to backcall expressions |
3051 | BLOCK_START | 3030 | // in transform stage, toString(exp) won't be able |
3052 | auto value = singleValueFrom(exp); | 3031 | // to convert its whole text content |
3053 | BREAK_IF(!value); | 3032 | str = _parser.toString(exp->backcalls.front()); |
3054 | auto lstr = value->getByPath<String_t, LuaString_t>(); | 3033 | } |
3055 | BREAK_IF(!lstr); | 3034 | } else { |
3056 | str = _parser.toString(lstr->content); | 3035 | bool multiLineStr = false; |
3057 | multiLineStr = true; | 3036 | BLOCK_START |
3058 | BLOCK_END | 3037 | auto exp = ast_cast<Exp_t>(arg); |
3059 | if (!multiLineStr) { | 3038 | BREAK_IF(!exp); |
3060 | // convert sub nodes to strings in case exp is assembled | 3039 | auto value = singleValueFrom(exp); |
3061 | // in transform stage, the toString() function won't be able | 3040 | BREAK_IF(!value); |
3062 | // to convert its whole content | 3041 | auto lstr = value->getByPath<String_t, LuaString_t>(); |
3063 | str = _parser.toString(exp->value); | 3042 | BREAK_IF(!lstr); |
3064 | for (auto opVal : exp->opValues.objects()) { | 3043 | str = _parser.toString(lstr->content); |
3065 | str += _parser.toString(opVal); | 3044 | multiLineStr = true; |
3066 | } | 3045 | BLOCK_END |
3067 | } | 3046 | if (!multiLineStr) { |
3047 | str = _parser.toString(arg); | ||
3068 | } | 3048 | } |
3069 | } else str = _parser.toString(arg); | 3049 | } |
3070 | Utils::trim(str); | 3050 | Utils::trim(str); |
3071 | Utils::replace(str, "\r\n"sv, "\n"sv); | 3051 | Utils::replace(str, "\r\n"sv, "\n"sv); |
3072 | lua_pushlstring(L, str.c_str(), str.size()); | 3052 | lua_pushlstring(L, str.c_str(), str.size()); |
@@ -3160,8 +3140,7 @@ private: | |||
3160 | } | 3140 | } |
3161 | auto value = x->new_ptr<Value_t>(); | 3141 | auto value = x->new_ptr<Value_t>(); |
3162 | value->item.set(newChain); | 3142 | value->item.set(newChain); |
3163 | exp = x->new_ptr<Exp_t>(); | 3143 | exp = newExp(value, x); |
3164 | exp->value.set(value); | ||
3165 | } | 3144 | } |
3166 | if (usage == ExpUsage::Common) { | 3145 | if (usage == ExpUsage::Common) { |
3167 | auto expList = x->new_ptr<ExpList_t>(); | 3146 | auto expList = x->new_ptr<ExpList_t>(); |
@@ -3276,13 +3255,34 @@ private: | |||
3276 | out.push_back(s("("sv) + join(temp, ", "sv) + s(")"sv)); | 3255 | out.push_back(s("("sv) + join(temp, ", "sv) + s(")"sv)); |
3277 | } | 3256 | } |
3278 | 3257 | ||
3279 | void transform_unary_exp(unary_exp_t* unary_exp, str_list& out) { | 3258 | void transform_unary_value(unary_value_t* unary_value, str_list& out) { |
3280 | std::string op = _parser.toString(unary_exp->m_begin.m_it, unary_exp->item->m_begin.m_it); | 3259 | str_list temp; |
3281 | str_list temp{op + (op == "not"sv ? s(" "sv) : Empty)}; | 3260 | for (auto _op : unary_value->ops.objects()) { |
3282 | transformExp(unary_exp->item, temp, ExpUsage::Closure); | 3261 | std::string op = _parser.toString(_op); |
3262 | temp.push_back(op + (op == "not"sv ? s(" "sv) : Empty)); | ||
3263 | } | ||
3264 | transformValue(unary_value->value, temp); | ||
3283 | out.push_back(join(temp)); | 3265 | out.push_back(join(temp)); |
3284 | } | 3266 | } |
3285 | 3267 | ||
3268 | void transform_unary_exp(unary_exp_t* unary_exp, str_list& out) { | ||
3269 | if (unary_exp->ops.empty() && unary_exp->expos.size() == 1) { | ||
3270 | transformValue(static_cast<Value_t*>(unary_exp->expos.back()), out); | ||
3271 | return; | ||
3272 | } | ||
3273 | std::string unary_op; | ||
3274 | for (auto _op : unary_exp->ops.objects()) { | ||
3275 | std::string op = _parser.toString(_op); | ||
3276 | unary_op.append(op + (op == "not"sv ? s(" "sv) : Empty)); | ||
3277 | } | ||
3278 | str_list temp; | ||
3279 | for (auto _value : unary_exp->expos.objects()) { | ||
3280 | auto value = static_cast<Value_t*>(_value); | ||
3281 | transformValue(value, temp); | ||
3282 | } | ||
3283 | out.push_back(unary_op + join(temp, " ^ "sv)); | ||
3284 | } | ||
3285 | |||
3286 | void transformVariable(Variable_t* name, str_list& out) { | 3286 | void transformVariable(Variable_t* name, str_list& out) { |
3287 | out.push_back(_parser.toString(name)); | 3287 | out.push_back(_parser.toString(name)); |
3288 | } | 3288 | } |
@@ -3555,8 +3555,7 @@ private: | |||
3555 | sValue->value.set(pair.first); | 3555 | sValue->value.set(pair.first); |
3556 | auto value = x->new_ptr<Value_t>(); | 3556 | auto value = x->new_ptr<Value_t>(); |
3557 | value->item.set(sValue); | 3557 | value->item.set(sValue); |
3558 | auto exp = x->new_ptr<Exp_t>(); | 3558 | auto exp = newExp(value, x); |
3559 | exp->value.set(value); | ||
3560 | auto expList = x->new_ptr<ExpList_t>(); | 3559 | auto expList = x->new_ptr<ExpList_t>(); |
3561 | expList->exprs.push_back(exp); | 3560 | expList->exprs.push_back(exp); |
3562 | auto assign = x->new_ptr<Assign_t>(); | 3561 | auto assign = x->new_ptr<Assign_t>(); |
@@ -3916,7 +3915,7 @@ private: | |||
3916 | if (auto dotChain = ast_cast<DotChainItem_t>(chain->items.back())) { | 3915 | if (auto dotChain = ast_cast<DotChainItem_t>(chain->items.back())) { |
3917 | className = s("\""sv) + _parser.toString(dotChain->name) + s("\""sv); | 3916 | className = s("\""sv) + _parser.toString(dotChain->name) + s("\""sv); |
3918 | } else if (auto index = ast_cast<Exp_t>(chain->items.back())) { | 3917 | } else if (auto index = ast_cast<Exp_t>(chain->items.back())) { |
3919 | if (auto name = index->getByPath<Value_t, String_t>()) { | 3918 | if (auto name = index->getByPath<unary_exp_t, Value_t, String_t>()) { |
3920 | transformString(name, temp); | 3919 | transformString(name, temp); |
3921 | className = temp.back(); | 3920 | className = temp.back(); |
3922 | temp.pop_back(); | 3921 | temp.pop_back(); |
@@ -4441,8 +4440,7 @@ private: | |||
4441 | chainValue->items.push_back(callable); | 4440 | chainValue->items.push_back(callable); |
4442 | auto value = x->new_ptr<Value_t>(); | 4441 | auto value = x->new_ptr<Value_t>(); |
4443 | value->item.set(chainValue); | 4442 | value->item.set(chainValue); |
4444 | auto exp = x->new_ptr<Exp_t>(); | 4443 | auto exp = newExp(value, x); |
4445 | exp->value.set(value); | ||
4446 | expList->exprs.push_back(exp); | 4444 | expList->exprs.push_back(exp); |
4447 | } | 4445 | } |
4448 | auto assignment = x->new_ptr<ExpListAssign_t>(); | 4446 | auto assignment = x->new_ptr<ExpListAssign_t>(); |
@@ -4480,8 +4478,8 @@ private: | |||
4480 | for (auto _exp : expList->exprs.objects()) { | 4478 | for (auto _exp : expList->exprs.objects()) { |
4481 | auto exp = static_cast<Exp_t*>(_exp); | 4479 | auto exp = static_cast<Exp_t*>(_exp); |
4482 | if (!variableFrom(exp) && | 4480 | if (!variableFrom(exp) && |
4483 | !exp->getByPath<Value_t, SimpleValue_t, TableLit_t>() && | 4481 | !exp->getByPath<unary_exp_t, Value_t, SimpleValue_t, TableLit_t>() && |
4484 | !exp->getByPath<Value_t, simple_table_t>()) { | 4482 | !exp->getByPath<unary_exp_t, Value_t, simple_table_t>()) { |
4485 | throw std::logic_error(_info.errorMessage("left hand expressions must be variables in export statement"sv, x)); | 4483 | throw std::logic_error(_info.errorMessage("left hand expressions must be variables in export statement"sv, x)); |
4486 | } | 4484 | } |
4487 | } | 4485 | } |
@@ -4525,7 +4523,7 @@ private: | |||
4525 | auto assignList = toAst<ExpList_t>(_info.moduleName + s("[#"sv) + _info.moduleName + s("+1]"sv), x); | 4523 | auto assignList = toAst<ExpList_t>(_info.moduleName + s("[#"sv) + _info.moduleName + s("+1]"sv), x); |
4526 | assignment->expList.set(assignList); | 4524 | assignment->expList.set(assignList); |
4527 | for (auto exp : expList->exprs.objects()) { | 4525 | for (auto exp : expList->exprs.objects()) { |
4528 | if (auto classDecl = exp->getByPath<Value_t, SimpleValue_t, ClassDecl_t>()) { | 4526 | if (auto classDecl = exp->getByPath<unary_exp_t, Value_t, SimpleValue_t, ClassDecl_t>()) { |
4529 | if (classDecl->name && classDecl->name->item->getId() == id<Variable_t>()) { | 4527 | if (classDecl->name && classDecl->name->item->getId() == id<Variable_t>()) { |
4530 | transformClassDecl(classDecl, temp, ExpUsage::Common); | 4528 | transformClassDecl(classDecl, temp, ExpUsage::Common); |
4531 | auto name = _parser.toString(classDecl->name->item); | 4529 | auto name = _parser.toString(classDecl->name->item); |
@@ -4728,8 +4726,7 @@ private: | |||
4728 | chainValue->items.push_back(dotChainItem); | 4726 | chainValue->items.push_back(dotChainItem); |
4729 | auto value = x->new_ptr<Value_t>(); | 4727 | auto value = x->new_ptr<Value_t>(); |
4730 | value->item.set(chainValue); | 4728 | value->item.set(chainValue); |
4731 | auto exp = x->new_ptr<Exp_t>(); | 4729 | auto exp = newExp(value, x); |
4732 | exp->value.set(value); | ||
4733 | assign->values.push_back(exp); | 4730 | assign->values.push_back(exp); |
4734 | } | 4731 | } |
4735 | auto callable = x->new_ptr<Callable_t>(); | 4732 | auto callable = x->new_ptr<Callable_t>(); |
@@ -4738,8 +4735,7 @@ private: | |||
4738 | chainValue->items.push_back(callable); | 4735 | chainValue->items.push_back(callable); |
4739 | auto value = x->new_ptr<Value_t>(); | 4736 | auto value = x->new_ptr<Value_t>(); |
4740 | value->item.set(chainValue); | 4737 | value->item.set(chainValue); |
4741 | auto exp = x->new_ptr<Exp_t>(); | 4738 | auto exp = newExp(value, x); |
4742 | exp->value.set(value); | ||
4743 | expList->exprs.push_back(exp); | 4739 | expList->exprs.push_back(exp); |
4744 | break; | 4740 | break; |
4745 | } | 4741 | } |
@@ -4755,8 +4751,7 @@ private: | |||
4755 | chainValue->items.push_back(colonChain); | 4751 | chainValue->items.push_back(colonChain); |
4756 | auto value = x->new_ptr<Value_t>(); | 4752 | auto value = x->new_ptr<Value_t>(); |
4757 | value->item.set(chainValue); | 4753 | value->item.set(chainValue); |
4758 | auto exp = x->new_ptr<Exp_t>(); | 4754 | auto exp = newExp(value, x); |
4759 | exp->value.set(value); | ||
4760 | assign->values.push_back(exp); | 4755 | assign->values.push_back(exp); |
4761 | } | 4756 | } |
4762 | auto callable = x->new_ptr<Callable_t>(); | 4757 | auto callable = x->new_ptr<Callable_t>(); |
@@ -4765,8 +4760,7 @@ private: | |||
4765 | chainValue->items.push_back(callable); | 4760 | chainValue->items.push_back(callable); |
4766 | auto value = x->new_ptr<Value_t>(); | 4761 | auto value = x->new_ptr<Value_t>(); |
4767 | value->item.set(chainValue); | 4762 | value->item.set(chainValue); |
4768 | auto exp = x->new_ptr<Exp_t>(); | 4763 | auto exp = newExp(value, x); |
4769 | exp->value.set(value); | ||
4770 | expList->exprs.push_back(exp); | 4764 | expList->exprs.push_back(exp); |
4771 | break; | 4765 | break; |
4772 | } | 4766 | } |
@@ -4898,8 +4892,7 @@ private: | |||
4898 | simpleValue->value.set(tableLit); | 4892 | simpleValue->value.set(tableLit); |
4899 | value->item.set(simpleValue); | 4893 | value->item.set(simpleValue); |
4900 | } | 4894 | } |
4901 | auto exp = x->new_ptr<Exp_t>(); | 4895 | auto exp = newExp(value, x); |
4902 | exp->value.set(value); | ||
4903 | auto assignList = x->new_ptr<ExpList_t>(); | 4896 | auto assignList = x->new_ptr<ExpList_t>(); |
4904 | assignList->exprs.push_back(exp); | 4897 | assignList->exprs.push_back(exp); |
4905 | auto assign = x->new_ptr<Assign_t>(); | 4898 | auto assign = x->new_ptr<Assign_t>(); |
@@ -5087,8 +5080,7 @@ private: | |||
5087 | chainValue->items.push_back(callable); | 5080 | chainValue->items.push_back(callable); |
5088 | auto value = x->new_ptr<Value_t>(); | 5081 | auto value = x->new_ptr<Value_t>(); |
5089 | value->item.set(chainValue); | 5082 | value->item.set(chainValue); |
5090 | auto exp = x->new_ptr<Exp_t>(); | 5083 | auto exp = newExp(value, x); |
5091 | exp->value.set(value); | ||
5092 | expList->exprs.push_back(exp); | 5084 | expList->exprs.push_back(exp); |
5093 | } | 5085 | } |
5094 | auto assignment = x->new_ptr<ExpListAssign_t>(); | 5086 | auto assignment = x->new_ptr<ExpListAssign_t>(); |
diff --git a/src/MoonP/moon_parser.cpp b/src/MoonP/moon_parser.cpp index 2d71567..25e67b3 100644 --- a/src/MoonP/moon_parser.cpp +++ b/src/MoonP/moon_parser.cpp | |||
@@ -292,6 +292,25 @@ MoonParser::MoonParser() { | |||
292 | 292 | ||
293 | Update = Space >> update_op >> expr("=") >> Exp; | 293 | Update = Space >> update_op >> expr("=") >> Exp; |
294 | 294 | ||
295 | Assignable = AssignableChain | Space >> Variable | Space >> SelfName; | ||
296 | |||
297 | unary_value = unary_operator >> *(Space >> unary_operator) >> Value; | ||
298 | |||
299 | ExponentialOperator = expr('^'); | ||
300 | expo_value = Space >> ExponentialOperator >> *SpaceBreak >> Value; | ||
301 | expo_exp = Value >> *expo_value; | ||
302 | |||
303 | unary_operator = | ||
304 | expr('-') >> not_(expr('>') | space_one) | | ||
305 | expr('#') | | ||
306 | expr('~') >> not_(space_one) | | ||
307 | expr("not") >> not_(AlphaNum); | ||
308 | unary_exp = *(Space >> unary_operator) >> expo_exp; | ||
309 | |||
310 | BackcallOperator = expr("|>"); | ||
311 | backcall_value = Space >> BackcallOperator >> *SpaceBreak >> unary_exp; | ||
312 | backcall_exp = unary_exp >> *backcall_value; | ||
313 | |||
295 | BinaryOperator = | 314 | BinaryOperator = |
296 | (expr("or") >> not_(AlphaNum)) | | 315 | (expr("or") >> not_(AlphaNum)) | |
297 | (expr("and") >> not_(AlphaNum)) | | 316 | (expr("and") >> not_(AlphaNum)) | |
@@ -304,14 +323,9 @@ MoonParser::MoonParser() { | |||
304 | expr("<<") | | 323 | expr("<<") | |
305 | expr(">>") | | 324 | expr(">>") | |
306 | expr("//") | | 325 | expr("//") | |
307 | set("+-*/%^><|&~"); | 326 | set("+-*/%><|&~"); |
308 | 327 | exp_op_value = Space >> BinaryOperator >> *SpaceBreak >> backcall_exp; | |
309 | BackcallOperator = expr("|>"); | 328 | Exp = Seperator >> backcall_exp >> *exp_op_value; |
310 | |||
311 | Assignable = AssignableChain | Space >> Variable | Space >> SelfName; | ||
312 | |||
313 | exp_op_value = Space >> (BackcallOperator | BinaryOperator) >> *SpaceBreak >> Value; | ||
314 | Exp = Value >> *exp_op_value; | ||
315 | 329 | ||
316 | ChainValue = Seperator >> (Chain | Callable) >> -existential_op >> -InvokeArgs; | 330 | ChainValue = Seperator >> (Chain | Callable) >> -existential_op >> -InvokeArgs; |
317 | 331 | ||
@@ -520,16 +534,11 @@ MoonParser::MoonParser() { | |||
520 | ); | 534 | ); |
521 | 535 | ||
522 | const_value = (expr("nil") | expr("true") | expr("false")) >> not_(AlphaNum); | 536 | const_value = (expr("nil") | expr("true") | expr("false")) >> not_(AlphaNum); |
523 | minus_exp = expr('-') >> not_(space_one) >> Exp; | ||
524 | sharp_exp = expr('#') >> Exp; | ||
525 | tilde_exp = expr('~') >> not_(space_one) >> Exp; | ||
526 | not_exp = expr("not") >> not_(AlphaNum) >> Exp; | ||
527 | unary_exp = minus_exp | sharp_exp | tilde_exp | not_exp; | ||
528 | 537 | ||
529 | SimpleValue = | 538 | SimpleValue = |
530 | (Space >> const_value) | | 539 | (Space >> const_value) | |
531 | If | Unless | Switch | With | ClassDecl | ForEach | For | While | Do | | 540 | If | Unless | Switch | With | ClassDecl | ForEach | For | While | Do | |
532 | (Space >> unary_exp) | | 541 | (Space >> unary_value) | |
533 | TblComprehension | TableLit | Comprehension | FunLit | | 542 | TblComprehension | TableLit | Comprehension | FunLit | |
534 | (Space >> Num); | 543 | (Space >> Num); |
535 | 544 | ||
diff --git a/src/MoonP/moon_parser.h b/src/MoonP/moon_parser.h index 069fdf1..5787438 100644 --- a/src/MoonP/moon_parser.h +++ b/src/MoonP/moon_parser.h | |||
@@ -172,10 +172,12 @@ private: | |||
172 | rule ArgLine; | 172 | rule ArgLine; |
173 | rule ArgBlock; | 173 | rule ArgBlock; |
174 | rule invoke_args_with_table; | 174 | rule invoke_args_with_table; |
175 | rule minus_exp; | 175 | rule BackcallOperator; |
176 | rule sharp_exp; | 176 | rule ExponentialOperator; |
177 | rule tilde_exp; | 177 | rule backcall_value; |
178 | rule not_exp; | 178 | rule backcall_exp; |
179 | rule expo_value; | ||
180 | rule expo_exp; | ||
179 | rule empty_line_stop; | 181 | rule empty_line_stop; |
180 | rule Line; | 182 | rule Line; |
181 | rule Shebang; | 183 | rule Shebang; |
@@ -233,7 +235,7 @@ private: | |||
233 | AST_RULE(update_op) | 235 | AST_RULE(update_op) |
234 | AST_RULE(Update) | 236 | AST_RULE(Update) |
235 | AST_RULE(BinaryOperator) | 237 | AST_RULE(BinaryOperator) |
236 | AST_RULE(BackcallOperator) | 238 | AST_RULE(unary_operator) |
237 | AST_RULE(Assignable) | 239 | AST_RULE(Assignable) |
238 | AST_RULE(AssignableChain) | 240 | AST_RULE(AssignableChain) |
239 | AST_RULE(exp_op_value) | 241 | AST_RULE(exp_op_value) |
@@ -286,6 +288,7 @@ private: | |||
286 | AST_RULE(AssignableNameList) | 288 | AST_RULE(AssignableNameList) |
287 | AST_RULE(InvokeArgs) | 289 | AST_RULE(InvokeArgs) |
288 | AST_RULE(const_value) | 290 | AST_RULE(const_value) |
291 | AST_RULE(unary_value) | ||
289 | AST_RULE(unary_exp) | 292 | AST_RULE(unary_exp) |
290 | AST_RULE(ExpListAssign) | 293 | AST_RULE(ExpListAssign) |
291 | AST_RULE(if_line) | 294 | AST_RULE(if_line) |