aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLi Jin <dragon-fly@qq.com>2023-10-23 10:19:42 +0800
committerLi Jin <dragon-fly@qq.com>2023-10-23 10:19:42 +0800
commit08fef1c7698cff09689e9965d993931ca6081257 (patch)
tree2d206d3b3b6cca927881a46873b53be3d0319221
parent0ecd527e2b9e441c169bc66ecbac12d202b9d1f8 (diff)
downloadyuescript-08fef1c7698cff09689e9965d993931ca6081257.tar.gz
yuescript-08fef1c7698cff09689e9965d993931ca6081257.tar.bz2
yuescript-08fef1c7698cff09689e9965d993931ca6081257.zip
fix chaining condition evaluation rules.v0.20.1
-rw-r--r--spec/inputs/cond.yue22
-rw-r--r--spec/outputs/cond.lua155
-rw-r--r--spec/outputs/unicode/cond.lua12
-rw-r--r--src/yuescript/yue_compiler.cpp265
4 files changed, 349 insertions, 105 deletions
diff --git a/spec/inputs/cond.yue b/spec/inputs/cond.yue
index df7d78e..f5f42a8 100644
--- a/spec/inputs/cond.yue
+++ b/spec/inputs/cond.yue
@@ -237,6 +237,28 @@ do
237 237
238 evaluation = v(1) > v(2) <= v(3) 238 evaluation = v(1) > v(2) <= v(3)
239 239
240do
241 a = v(1) < v(2) < v(3) < v(4)
242 a = x and y or v(1) < v(2) < v(3) < v(4)
243 a = v(1) < v(2) < v(3) < v(4) or x and y
244 a = x and y or v(1) < v(2) < v(3) < v(4) or w and z
245
246 a = v(1) < v(2) < v(3) and b < v(4) < v(5) < v(6)
247 a = x and y or v(1) < v(2) < v(3) and b < v(4) < v(5) < v(6)
248 a = v(1) < v(2) < v(3) and b < v(4) < v(5) < v(6) or x and y
249 a = x and y or v(1) < v(2) < v(3) and b < v(4) < v(5) < v(6) or w and z
250
251 local v1, v2, v3, v4, v5, v6
252 a = v1 < v2 < v3 < v4
253 a = x and y or v1 < v2 < v3 < v4
254 a = v1 < v2 < v3 < v4 or x and y
255 a = x and y or v1 < v2 < v3 < v4 or w and z
256
257 a = v1 < v2 < v3 and b < v4 < v5 < v6
258 a = x and y or v1 < v2 < v3 and b < v4 < v5 < v6
259 a = v1 < v2 < v3 and b < v4 < v5 < v6 or x and y
260 a = x and y or v1 < v2 < v3 and b < v4 < v5 < v6 or w and z
261
240nil 262nil
241 263
242 264
diff --git a/spec/outputs/cond.lua b/spec/outputs/cond.lua
index 651c14a..d7aae02 100644
--- a/spec/outputs/cond.lua
+++ b/spec/outputs/cond.lua
@@ -355,11 +355,162 @@ do
355 local evaluation 355 local evaluation
356 do 356 do
357 local _cond_0 = v(2) 357 local _cond_0 = v(2)
358 evaluation = v(1) < _cond_0 and _cond_0 <= v(3) 358 if not (v(1) < _cond_0) then
359 evaluation = false
360 else
361 evaluation = _cond_0 <= v(3)
362 end
363 end
364 do
365 local _cond_0 = v(2)
366 if not (v(1) > _cond_0) then
367 evaluation = false
368 else
369 evaluation = _cond_0 <= v(3)
370 end
359 end 371 end
372end
373do
360 do 374 do
361 local _cond_0 = v(2) 375 local _cond_0 = v(2)
362 evaluation = v(1) > _cond_0 and _cond_0 <= v(3) 376 if not (v(1) < _cond_0) then
377 a = false
378 else
379 local _cond_1 = v(3)
380 if not (_cond_0 < _cond_1) then
381 a = false
382 else
383 a = _cond_1 < v(4)
384 end
385 end
363 end 386 end
387 a = x and y or (function()
388 local _cond_0 = v(2)
389 if not (v(1) < _cond_0) then
390 return false
391 else
392 local _cond_1 = v(3)
393 if not (_cond_0 < _cond_1) then
394 return false
395 else
396 return _cond_1 < v(4)
397 end
398 end
399 end)()
400 a = (function()
401 local _cond_0 = v(2)
402 if not (v(1) < _cond_0) then
403 return false
404 else
405 local _cond_1 = v(3)
406 if not (_cond_0 < _cond_1) then
407 return false
408 else
409 return _cond_1 < v(4)
410 end
411 end
412 end)() or x and y
413 a = x and y or (function()
414 local _cond_0 = v(2)
415 if not (v(1) < _cond_0) then
416 return false
417 else
418 local _cond_1 = v(3)
419 if not (_cond_0 < _cond_1) then
420 return false
421 else
422 return _cond_1 < v(4)
423 end
424 end
425 end)() or w and z
426 a = (function()
427 local _cond_0 = v(2)
428 if not (v(1) < _cond_0) then
429 return false
430 else
431 return _cond_0 < v(3)
432 end
433 end)() and (function()
434 local _cond_0 = v(4)
435 if not (b < _cond_0) then
436 return false
437 else
438 local _cond_1 = v(5)
439 if not (_cond_0 < _cond_1) then
440 return false
441 else
442 return _cond_1 < v(6)
443 end
444 end
445 end)()
446 a = x and y or (function()
447 local _cond_0 = v(2)
448 if not (v(1) < _cond_0) then
449 return false
450 else
451 return _cond_0 < v(3)
452 end
453 end)() and (function()
454 local _cond_0 = v(4)
455 if not (b < _cond_0) then
456 return false
457 else
458 local _cond_1 = v(5)
459 if not (_cond_0 < _cond_1) then
460 return false
461 else
462 return _cond_1 < v(6)
463 end
464 end
465 end)()
466 a = (function()
467 local _cond_0 = v(2)
468 if not (v(1) < _cond_0) then
469 return false
470 else
471 return _cond_0 < v(3)
472 end
473 end)() and (function()
474 local _cond_0 = v(4)
475 if not (b < _cond_0) then
476 return false
477 else
478 local _cond_1 = v(5)
479 if not (_cond_0 < _cond_1) then
480 return false
481 else
482 return _cond_1 < v(6)
483 end
484 end
485 end)() or x and y
486 a = x and y or (function()
487 local _cond_0 = v(2)
488 if not (v(1) < _cond_0) then
489 return false
490 else
491 return _cond_0 < v(3)
492 end
493 end)() and (function()
494 local _cond_0 = v(4)
495 if not (b < _cond_0) then
496 return false
497 else
498 local _cond_1 = v(5)
499 if not (_cond_0 < _cond_1) then
500 return false
501 else
502 return _cond_1 < v(6)
503 end
504 end
505 end)() or w and z
506 local v1, v2, v3, v4, v5, v6
507 a = v1 < v2 and v2 < v3 and v3 < v4
508 a = x and y or v1 < v2 and v2 < v3 and v3 < v4
509 a = v1 < v2 and v2 < v3 and v3 < v4 or x and y
510 a = x and y or v1 < v2 and v2 < v3 and v3 < v4 or w and z
511 a = v1 < v2 and v2 < v3 and b < v4 and v4 < v5 and v5 < v6
512 a = x and y or v1 < v2 and v2 < v3 and b < v4 and v4 < v5 and v5 < v6
513 a = v1 < v2 and v2 < v3 and b < v4 and v4 < v5 and v5 < v6 or x and y
514 a = x and y or v1 < v2 and v2 < v3 and b < v4 and v4 < v5 and v5 < v6 or w and z
364end 515end
365return nil 516return nil
diff --git a/spec/outputs/unicode/cond.lua b/spec/outputs/unicode/cond.lua
index 9a4ccb9..ed5d274 100644
--- a/spec/outputs/unicode/cond.lua
+++ b/spec/outputs/unicode/cond.lua
@@ -361,11 +361,19 @@ do
361 local _u6c42_u503c 361 local _u6c42_u503c
362 do 362 do
363 local _cond_0 = _u503c(2) 363 local _cond_0 = _u503c(2)
364 _u6c42_u503c = _u503c(1) < _cond_0 and _cond_0 <= _u503c(3) 364 if not (_u503c(1) < _cond_0) then
365 _u6c42_u503c = false
366 else
367 _u6c42_u503c = _cond_0 <= _u503c(3)
368 end
365 end 369 end
366 do 370 do
367 local _cond_0 = _u503c(2) 371 local _cond_0 = _u503c(2)
368 _u6c42_u503c = _u503c(1) > _cond_0 and _cond_0 <= _u503c(3) 372 if not (_u503c(1) > _cond_0) then
373 _u6c42_u503c = false
374 else
375 _u6c42_u503c = _cond_0 <= _u503c(3)
376 end
369 end 377 end
370end 378end
371return nil 379return nil
diff --git a/src/yuescript/yue_compiler.cpp b/src/yuescript/yue_compiler.cpp
index d32d9c1..7ec3b3a 100644
--- a/src/yuescript/yue_compiler.cpp
+++ b/src/yuescript/yue_compiler.cpp
@@ -75,7 +75,7 @@ static std::unordered_set<std::string> Metamethods = {
75 "close"s // Lua 5.4 75 "close"s // Lua 5.4
76}; 76};
77 77
78const std::string_view version = "0.20.0"sv; 78const std::string_view version = "0.20.1"sv;
79const std::string_view extension = "yue"sv; 79const std::string_view extension = "yue"sv;
80 80
81class CompileError : public std::logic_error { 81class CompileError : public std::logic_error {
@@ -1207,19 +1207,16 @@ private:
1207 1207
1208 bool isConditionChaining(Exp_t* exp) { 1208 bool isConditionChaining(Exp_t* exp) {
1209 int conditionChaining = 0; 1209 int conditionChaining = 0;
1210 for (const auto& opValue_ : exp->opValues.objects()) { 1210 for (auto opValue_ : exp->opValues.objects()) {
1211 auto opValue = static_cast<ExpOpValue_t*>(opValue_); 1211 auto opValue = static_cast<ExpOpValue_t*>(opValue_);
1212 auto op = _parser.toString(opValue->op); 1212 auto op = _parser.toString(opValue->op);
1213 if (isConditionChainingOperator(op)) { 1213 if (isConditionChainingOperator(op)) {
1214 conditionChaining++; 1214 conditionChaining++;
1215 if (conditionChaining > 1) { 1215 } else if (conditionChaining > 0) {
1216 return true; 1216 return false;
1217 }
1218 } else {
1219 conditionChaining = 0;
1220 } 1217 }
1221 } 1218 }
1222 return false; 1219 return conditionChaining > 1 && conditionChaining == static_cast<int>(exp->opValues.size());
1223 } 1220 }
1224 1221
1225 UnaryExp_t* unaryGeneratingAnonFunc(Exp_t* exp) { 1222 UnaryExp_t* unaryGeneratingAnonFunc(Exp_t* exp) {
@@ -3369,14 +3366,14 @@ private:
3369 std::list<std::pair<std::string, ast_list<true, UnaryExp_t>*>> chains; 3366 std::list<std::pair<std::string, ast_list<true, UnaryExp_t>*>> chains;
3370 chains.emplace_back(std::string(), &exp->pipeExprs); 3367 chains.emplace_back(std::string(), &exp->pipeExprs);
3371 int conditionChainCount = 0; 3368 int conditionChainCount = 0;
3372 str_list evalLines; 3369 auto checkChains = [&]()-> ast_ptr<false, Exp_t> {
3373 auto checkChains = [&]() {
3374 std::optional<str_list> result; 3370 std::optional<str_list> result;
3375 if (conditionChainCount > 1) { 3371 if (conditionChainCount > 1) {
3376 bool needWrapping = false; 3372 ast_ptr<false, Exp_t> newCondExp;
3377 str_list conds; 3373 ast_ptr<false, ExpListAssign_t> preDefine;
3378 str_list preDefines; 3374 ast_sel_list<true, IfCond_t, Block_t, Statement_t>* nodes = nullptr;
3379 std::list<std::variant<std::string, ast_ptr<false, Exp_t>>> stack; 3375 std::list<std::variant<std::string, ast_list<true, UnaryExp_t>>> stack;
3376 pushScope();
3380 for (const auto& item : chains) { 3377 for (const auto& item : chains) {
3381 if (!item.first.empty()) { 3378 if (!item.first.empty()) {
3382 stack.push_back(item.first); 3379 stack.push_back(item.first);
@@ -3393,9 +3390,7 @@ private:
3393 if (varName.empty()) { 3390 if (varName.empty()) {
3394 if (auto sval = static_cast<Value_t*>(unary->expos.front())->item.as<SimpleValue_t>()) { 3391 if (auto sval = static_cast<Value_t*>(unary->expos.front())->item.as<SimpleValue_t>()) {
3395 if (ast_is<ConstValue_t, Num_t>(sval->value)) { 3392 if (ast_is<ConstValue_t, Num_t>(sval->value)) {
3396 auto condExp = unary->new_ptr<Exp_t>(); 3393 stack.push_back(*item.second);
3397 condExp->pipeExprs.dup(*item.second);
3398 stack.push_back(condExp);
3399 goto reduce; 3394 goto reduce;
3400 } 3395 }
3401 } 3396 }
@@ -3404,77 +3399,125 @@ private:
3404 } 3399 }
3405 if (varName.empty() || !isLocal(varName)) { 3400 if (varName.empty() || !isLocal(varName)) {
3406 varName = getUnusedName("_cond_"sv); 3401 varName = getUnusedName("_cond_"sv);
3402 addToScope(varName);
3407 auto condExp = node->new_ptr<Exp_t>(); 3403 auto condExp = node->new_ptr<Exp_t>();
3408 condExp->pipeExprs.dup(*item.second); 3404 condExp->pipeExprs.dup(*item.second);
3409 auto varExp = toAst<Exp_t>(varName, node); 3405 auto varExp = toAst<Exp_t>(varName, node);
3410 auto assignment = assignmentFrom(varExp, condExp, node); 3406 auto assignment = assignmentFrom(varExp, condExp, node);
3411 if (!needWrapping) { 3407 preDefine = assignment;
3412 needWrapping = true; 3408 stack.push_back(varExp->pipeExprs);
3413 if (usage == ExpUsage::Closure) {
3414 pushFunctionScope();
3415 pushAnonVarArg();
3416 pushScope();
3417 } else if (usage == ExpUsage::Assignment) {
3418 pushScope();
3419 }
3420 }
3421 transformAssignment(assignment, preDefines);
3422 stack.push_back(varExp);
3423 goto reduce; 3409 goto reduce;
3424 } 3410 }
3425 } 3411 }
3426 { 3412 {
3427 auto condExp = node->new_ptr<Exp_t>(); 3413 stack.push_back(*item.second);
3428 condExp->pipeExprs.dup(*item.second);
3429 stack.push_back(condExp);
3430 } 3414 }
3431 reduce: 3415 reduce: {
3432 if (stack.size() == 3) { 3416 if (stack.size() == 3) {
3433 str_list tmp; 3417 auto condExp = exp->new_ptr<Exp_t>();
3434 auto one = std::get<ast_ptr<false, Exp_t>>(stack.front()).get(); 3418 const auto& one = std::get<ast_list<true, UnaryExp_t>>(stack.front());
3435 transformExp(one, tmp, ExpUsage::Closure); 3419 condExp->pipeExprs.dup(one);
3436 stack.pop_front(); 3420 stack.pop_front();
3437 auto two = std::get<std::string>(stack.front()); 3421 auto opValue = exp->new_ptr<ExpOpValue_t>();
3438 tmp.push_back(two); 3422 const auto& two = std::get<std::string>(stack.front());
3423 auto op = toAst<BinaryOperator_t>(two, exp);
3424 opValue->op.set(op);
3439 stack.pop_front(); 3425 stack.pop_front();
3440 auto three = std::get<ast_ptr<false, Exp_t>>(stack.front()).get(); 3426 const auto& three = std::get<ast_list<true, UnaryExp_t>>(stack.front());
3441 transformExp(three, tmp, ExpUsage::Closure); 3427 opValue->pipeExprs.dup(three);
3442 conds.push_back(join(tmp, " "sv)); 3428 condExp->opValues.push_back(opValue);
3443 } 3429 if (preDefine) {
3444 } 3430 auto ifNode = exp->new_ptr<If_t>();
3445 auto condStr = join(conds, " and "sv); 3431 ifNode->type.set(toAst<IfType_t>("unless"sv, exp));
3446 if (needWrapping && usage == ExpUsage::Closure) { 3432 auto ifCond = exp->new_ptr<IfCond_t>();
3447 str_list closureLines{anonFuncStart() + nll(exp)}; 3433 ifCond->condition.set(condExp);
3448 closureLines.insert(closureLines.end(), preDefines.begin(), preDefines.end()); 3434 ifNode->nodes.push_back(ifCond);
3449 closureLines.push_back(indent() + "return "s + condStr + nll(exp)); 3435 ifNode->nodes.push_back(toAst<Statement_t>("false"sv, exp));
3450 popScope(); 3436 if (newCondExp) {
3451 closureLines.push_back(indent() + anonFuncEnd()); 3437 if (nodes) {
3452 temp.push_back(join(closureLines)); 3438 auto block = exp->new_ptr<Block_t>();
3453 popAnonVarArg(); 3439 auto stmt = exp->new_ptr<Statement_t>();
3454 popFunctionScope(); 3440 stmt->content.set(preDefine);
3455 } else { 3441 preDefine.set(nullptr);
3456 temp.push_back(condStr); 3442 block->statements.push_back(stmt);
3457 if (!preDefines.empty()) { 3443 auto simpleValue = exp->new_ptr<SimpleValue_t>();
3458 evalLines.insert(evalLines.end(), preDefines.begin(), preDefines.end()); 3444 simpleValue->value.set(ifNode);
3459 if (usage == ExpUsage::Assignment) { 3445 auto explist = exp->new_ptr<ExpList_t>();
3460 popScope(); 3446 explist->exprs.push_back(newExp(simpleValue, exp));
3447 auto expListAssign = exp->new_ptr<ExpListAssign_t>();
3448 expListAssign->expList.set(explist);
3449 stmt = exp->new_ptr<Statement_t>();
3450 stmt->content.set(expListAssign);
3451 block->statements.push_back(stmt);
3452 nodes->push_back(block);
3453 nodes = &ifNode->nodes;
3454 } else {
3455 auto ifNodePrev = exp->new_ptr<If_t>();
3456 ifNodePrev->type.set(toAst<IfType_t>("unless"sv, exp));
3457 auto ifCondPrev = exp->new_ptr<IfCond_t>();
3458 ifCondPrev->condition.set(newCondExp);
3459 ifNodePrev->nodes.push_back(ifCondPrev);
3460 ifNodePrev->nodes.push_back(toAst<Statement_t>("false", exp));
3461 auto simpleValue = exp->new_ptr<SimpleValue_t>();
3462 simpleValue->value.set(ifNodePrev);
3463 newCondExp.set(newExp(simpleValue, exp));
3464 nodes = &ifNodePrev->nodes;
3465 }
3466 } else {
3467 auto block = exp->new_ptr<Block_t>();
3468 auto stmt = exp->new_ptr<Statement_t>();
3469 stmt->content.set(preDefine);
3470 preDefine.set(nullptr);
3471 block->statements.push_back(stmt);
3472 auto simpleValue = exp->new_ptr<SimpleValue_t>();
3473 simpleValue->value.set(ifNode);
3474 auto explist = exp->new_ptr<ExpList_t>();
3475 explist->exprs.push_back(newExp(simpleValue, exp));
3476 auto expListAssign = exp->new_ptr<ExpListAssign_t>();
3477 expListAssign->expList.set(explist);
3478 stmt = exp->new_ptr<Statement_t>();
3479 stmt->content.set(expListAssign);
3480 block->statements.push_back(stmt);
3481 auto body = exp->new_ptr<Body_t>();
3482 body->content.set(block);
3483 auto doNode = exp->new_ptr<Do_t>();
3484 doNode->body.set(body);
3485 simpleValue = exp->new_ptr<SimpleValue_t>();
3486 simpleValue->value.set(doNode);
3487 newCondExp.set(newExp(simpleValue, exp));
3488 nodes = &ifNode->nodes;
3489 }
3490 } else {
3491 if (newCondExp) {
3492 if (nodes) {
3493 auto explist = exp->new_ptr<ExpList_t>();
3494 explist->exprs.push_back(condExp);
3495 auto expListAssign = exp->new_ptr<ExpListAssign_t>();
3496 expListAssign->expList.set(explist);
3497 auto stmt = exp->new_ptr<Statement_t>();
3498 stmt->content.set(expListAssign);
3499 nodes->push_back(stmt);
3500 } else {
3501 auto opValue = exp->new_ptr<ExpOpValue_t>();
3502 opValue->op.set(toAst<BinaryOperator_t>("and"sv, exp));
3503 opValue->pipeExprs.dup(condExp->pipeExprs);
3504 newCondExp->opValues.push_back(opValue);
3505 newCondExp->opValues.dup(condExp->opValues);
3506 }
3507 } else {
3508 newCondExp.set(condExp);
3509 }
3510 }
3461 } 3511 }
3462 } 3512 }
3463 } 3513 }
3464 } else { 3514 popScope();
3465 for (const auto& item : chains) { 3515 return newCondExp;
3466 if (!item.first.empty()) {
3467 temp.push_back(item.first);
3468 }
3469 transform_pipe_exp(item.second->objects(), temp, ExpUsage::Closure);
3470 }
3471 } 3516 }
3472 conditionChainCount = 0; 3517 return nullptr;
3473 chains.clear();
3474 }; 3518 };
3475 str_list preDefines; 3519 for (auto opValue_ : exp->opValues.objects()) {
3476 for (auto _opValue : exp->opValues.objects()) { 3520 auto opValue = static_cast<ExpOpValue_t*>(opValue_);
3477 auto opValue = static_cast<ExpOpValue_t*>(_opValue);
3478 transformBinaryOperator(opValue->op, temp); 3521 transformBinaryOperator(opValue->op, temp);
3479 auto op = temp.back(); 3522 auto op = temp.back();
3480 temp.pop_back(); 3523 temp.pop_back();
@@ -3482,43 +3525,63 @@ private:
3482 conditionChainCount++; 3525 conditionChainCount++;
3483 chains.emplace_back(op, &opValue->pipeExprs); 3526 chains.emplace_back(op, &opValue->pipeExprs);
3484 } else { 3527 } else {
3485 checkChains(); 3528 if (auto e = checkChains()) {
3529 transformExp(e, temp, ExpUsage::Closure);
3530 } else {
3531 for (const auto& item : chains) {
3532 if (!item.first.empty()) {
3533 temp.push_back(item.first);
3534 }
3535 transform_pipe_exp(item.second->objects(), temp, ExpUsage::Closure);
3536 }
3537 }
3538 chains.clear();
3539 conditionChainCount = 0;
3486 temp.push_back(op); 3540 temp.push_back(op);
3487 transform_pipe_exp(opValue->pipeExprs.objects(), temp, ExpUsage::Closure); 3541 chains.emplace_back(Empty, &opValue->pipeExprs);
3488 } 3542 }
3489 } 3543 }
3490 checkChains(); 3544 if (auto e = checkChains()) {
3491 auto condStr = join(temp, " "sv); 3545 if (!temp.empty()) {
3492 switch (usage) { 3546 transformExp(e, temp, ExpUsage::Closure);
3493 case ExpUsage::Closure: { 3547 auto condStr = join(temp, " "sv);
3494 out.push_back(condStr); 3548 out.push_back(condStr);
3495 break; 3549 } else {
3496 } 3550 switch (usage) {
3497 case ExpUsage::Assignment: { 3551 case ExpUsage::Closure:
3498 auto assignment = exp->new_ptr<ExpListAssign_t>(); 3552 transformExp(e, out, ExpUsage::Closure);
3499 assignment->expList.set(assignList); 3553 break;
3500 auto assign = exp->new_ptr<Assign_t>(); 3554 case ExpUsage::Assignment: {
3501 assign->values.push_back(toAst<Exp_t>(condStr, exp)); 3555 auto assignment = exp->new_ptr<ExpListAssign_t>();
3502 assignment->action.set(assign); 3556 assignment->expList.set(assignList);
3503 if (evalLines.empty()) { 3557 auto assign = exp->new_ptr<Assign_t>();
3504 transformAssignment(assignment, out); 3558 assign->values.push_back(e);
3505 } else { 3559 assignment->action.set(assign);
3506 evalLines.push_front(indent() + "do"s + nll(exp)); 3560 transformAssignment(assignment, out);
3507 evalLines.push_front(getPreDefineLine(assignment)); 3561 break;
3508 pushScope(); 3562 }
3509 transformAssignment(assignment, evalLines); 3563 case ExpUsage::Return: {
3510 popScope(); 3564 auto expListLow = exp->new_ptr<ExpListLow_t>();
3511 evalLines.push_back(indent() + "end"s + nlr(exp)); 3565 expListLow->exprs.push_back(e);
3512 out.push_back(join(evalLines)); 3566 auto returnNode = exp->new_ptr<Return_t>();
3567 returnNode->valueList.set(expListLow);
3568 transformReturn(returnNode, out);
3569 break;
3570 }
3571 default:
3572 YUEE("invalid expression usage", exp);
3573 break;
3513 } 3574 }
3514 break;
3515 } 3575 }
3516 case ExpUsage::Return: { 3576 } else {
3517 evalLines.push_back(indent() + "return "s + condStr + nll(exp)); 3577 for (const auto& item : chains) {
3518 out.push_back(join(evalLines)); 3578 if (!item.first.empty()) {
3519 break; 3579 temp.push_back(item.first);
3580 }
3581 transform_pipe_exp(item.second->objects(), temp, ExpUsage::Closure);
3520 } 3582 }
3521 default: YUEE("invalid expression usage", exp); break; 3583 auto condStr = join(temp, " "sv);
3584 out.push_back(condStr);
3522 } 3585 }
3523 } 3586 }
3524 3587