| 433 | return result; |
| 434 | } |
| 435 | auto evaluatePostfix(const std::vector<Token>& postfix, QiVarMap* local) -> QiVar |
| 436 | { |
| 437 | std::vector<QiVar> stack; |
| 438 | for (const auto& token : postfix) |
| 439 | { |
| 440 | if (token.type == VARIABLE) stack.push_back(value(token.value, local)); |
| 441 | else if (token.type == NULLOPT) stack.push_back(QiVar()); |
| 442 | else if (token.type == NUMBER) |
| 443 | { |
| 444 | if (QiVar::isInteger(token.value, false)) stack.push_back(QiVar(QiVar::toInteger(token.value))); |
| 445 | else stack.push_back(QiVar(QiVar::toNumber(token.value))); |
| 446 | } |
| 447 | else if (token.type == STRING) stack.push_back(QiVar(processInterpolation(token.value, local))); |
| 448 | else if (token.type == TRUE_) stack.push_back(QiVar(true)); |
| 449 | else if (token.type == FALSE_) stack.push_back(QiVar(false)); |
| 450 | else if (token.type == OPERATOR) |
| 451 | { |
| 452 | QiVar result; |
| 453 | try |
| 454 | { |
| 455 | if (token.value == "return") |
| 456 | { |
| 457 | QiVar right; |
| 458 | if (!stack.empty()) |
| 459 | { |
| 460 | right = stack.back(); |
| 461 | stack.pop_back(); |
| 462 | } |
| 463 | throw ReturnException(right); |
| 464 | } |
| 465 | else if (token.value == "!" || token.value == "~" || token.value == "_-") |
| 466 | { |
| 467 | if (stack.size() < 1) throw std::runtime_error(error_not_enough_operands + std::string(": ") + token.value); |
| 468 | QiVar right = stack.back(); |
| 469 | stack.pop_back(); |
| 470 | |
| 471 | if (token.value == "!") result = !right; |
| 472 | else if (token.value == "~") result = ~right; |
| 473 | else if (token.value == "_-") result = (right.type() == QiVar::t_num) ? QiVar(0.0) - right : QiVar(0) - right; |
| 474 | } |
| 475 | else |
| 476 | { |
| 477 | if (stack.size() < 2) throw std::runtime_error(error_not_enough_operands + std::string(": ") + token.value); |
| 478 | QiVar right = stack.back(); |
| 479 | stack.pop_back(); |
| 480 | QiVar left = stack.back(); |
| 481 | stack.pop_back(); |
| 482 | |
| 483 | if (token.value == "^") result = left.merge(right); |
| 484 | else if (token.value == "+") result = left + right; |
| 485 | else if (token.value == "-") result = left - right; |
| 486 | else if (token.value == "*") result = left * right; |
| 487 | else if (token.value == "/") result = left / right; |
| 488 | else if (token.value == "%") result = left % right; |
| 489 | else if (token.value == "&") result = left & right; |
| 490 | else if (token.value == "|") result = left | right; |
| 491 | else if (token.value == "^^") result = left ^ right; |
| 492 | else if (token.value == "<<") result = left << right; |