diff --git a/core/evaluator.cpp b/core/evaluator.cpp index 333d8885..cb70b205 100644 --- a/core/evaluator.cpp +++ b/core/evaluator.cpp @@ -1314,10 +1314,9 @@ void Evaluator::compile(const Tokens& tokens) m_codes.append(Opcode(Opcode::Fact)); break; case Token::Percent: - syntaxStack.pop(); - m_constants.append(HNumber("0.01")); - m_codes.append(Opcode(Opcode::Load, m_constants.count() - 1)); - m_codes.append(Opcode(Opcode::Mul)); + ruleFound = true; + syntaxStack.reduce(2); + m_codes.append(Opcode(Opcode::Pct)); break; default:; } @@ -1924,6 +1923,27 @@ Quantity Evaluator::exec(const QVector& opcodes, stack.push(val2); break; + case Opcode::Pct: + if (stack.count() < 1) { + m_error = tr("invalid expression"); + return CMath::nan(); + } + val1 = stack.pop(); + + switch ((pc + 1) < opcodes.count() ? + opcodes.at(pc + 1).type : Opcode::Nop) { + case Opcode::Add: + case Opcode::Sub: + val2 = stack.pop(); + stack.push(val2); + break; + default: + val2 = 1; + } + val1 = checkOperatorResult(val2 * (val1 * HNumber("0.01"))); + stack.push(val1); + break; + case Opcode::Conv: if (stack.count() < 2) { m_error = tr("invalid expression"); @@ -2470,6 +2490,9 @@ QString Evaluator::dump() case Opcode::BOr: code = "BOr"; break; + case Opcode::Pct: + code = "Pct"; + break; default: code = "Unknown"; break; diff --git a/core/opcode.h b/core/opcode.h index 1a47eca0..40a73f18 100644 --- a/core/opcode.h +++ b/core/opcode.h @@ -28,7 +28,7 @@ class Opcode { public: enum Type { Nop, Load, Ref, Function, Add, Sub, Neg, Mul, Div, Pow, - Fact, Modulo, IntDiv, LSh, RSh, BAnd, BOr, Conv }; + Fact, Modulo, IntDiv, LSh, RSh, BAnd, BOr, Conv, Pct }; Type type; unsigned index;