diff options
author | Li Jin <dragon-fly@qq.com> | 2023-10-23 10:19:42 +0800 |
---|---|---|
committer | Li Jin <dragon-fly@qq.com> | 2023-10-23 10:19:42 +0800 |
commit | 08fef1c7698cff09689e9965d993931ca6081257 (patch) | |
tree | 2d206d3b3b6cca927881a46873b53be3d0319221 | |
parent | 0ecd527e2b9e441c169bc66ecbac12d202b9d1f8 (diff) | |
download | yuescript-08fef1c7698cff09689e9965d993931ca6081257.tar.gz yuescript-08fef1c7698cff09689e9965d993931ca6081257.tar.bz2 yuescript-08fef1c7698cff09689e9965d993931ca6081257.zip |
fix chaining condition evaluation rules.v0.20.1
-rw-r--r-- | spec/inputs/cond.yue | 22 | ||||
-rw-r--r-- | spec/outputs/cond.lua | 155 | ||||
-rw-r--r-- | spec/outputs/unicode/cond.lua | 12 | ||||
-rw-r--r-- | src/yuescript/yue_compiler.cpp | 265 |
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 | ||
240 | do | ||
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 | |||
240 | nil | 262 | nil |
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 |
372 | end | ||
373 | do | ||
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 | ||
364 | end | 515 | end |
365 | return nil | 516 | return 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 |
370 | end | 378 | end |
371 | return nil | 379 | return 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 | ||
78 | const std::string_view version = "0.20.0"sv; | 78 | const std::string_view version = "0.20.1"sv; |
79 | const std::string_view extension = "yue"sv; | 79 | const std::string_view extension = "yue"sv; |
80 | 80 | ||
81 | class CompileError : public std::logic_error { | 81 | class 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 | ||