|
1 | 1 | #include "form/expression_util.hpp" |
2 | 2 |
|
| 3 | +#include "lang/semantics.hpp" |
| 4 | + |
3 | 5 | Expression ExpressionUtil::newConstant(int64_t value) { |
4 | 6 | return Expression(Expression::Type::CONSTANT, "", Number(value)); |
5 | 7 | } |
@@ -314,3 +316,55 @@ void ExpressionUtil::collectNames(const Expression& e, Expression::Type type, |
314 | 316 | collectNames(*c, type, target); |
315 | 317 | } |
316 | 318 | } |
| 319 | + |
| 320 | +void assertNumChildren(const Expression& e, size_t num) { |
| 321 | + if (e.children.size() != num) { |
| 322 | + throw std::runtime_error("unexpected number of terms in " + e.toString()); |
| 323 | + } |
| 324 | +} |
| 325 | + |
| 326 | +Number ExpressionUtil::eval(const Expression& e, |
| 327 | + const std::map<std::string, Number> params) { |
| 328 | + switch (e.type) { |
| 329 | + case Expression::Type::CONSTANT: { |
| 330 | + return e.value; |
| 331 | + } |
| 332 | + case Expression::Type::PARAMETER: { |
| 333 | + return params.at(e.name); |
| 334 | + } |
| 335 | + case Expression::Type::SUM: { |
| 336 | + auto result = Number::ZERO; |
| 337 | + for (auto c : e.children) { |
| 338 | + result = Semantics::add(result, eval(*c, params)); |
| 339 | + } |
| 340 | + return result; |
| 341 | + } |
| 342 | + case Expression::Type::PRODUCT: { |
| 343 | + auto result = Number::ONE; |
| 344 | + for (auto c : e.children) { |
| 345 | + result = Semantics::mul(result, eval(*c, params)); |
| 346 | + } |
| 347 | + return result; |
| 348 | + } |
| 349 | + case Expression::Type::FRACTION: { |
| 350 | + assertNumChildren(e, 2); |
| 351 | + auto a = eval(*e.children[0], params); |
| 352 | + auto b = eval(*e.children[1], params); |
| 353 | + return Semantics::div(a, b); |
| 354 | + } |
| 355 | + case Expression::Type::POWER: { |
| 356 | + assertNumChildren(e, 2); |
| 357 | + auto a = eval(*e.children[0], params); |
| 358 | + auto b = eval(*e.children[1], params); |
| 359 | + return Semantics::pow(a, b); |
| 360 | + } |
| 361 | + case Expression::Type::MODULUS: { |
| 362 | + assertNumChildren(e, 2); |
| 363 | + auto a = eval(*e.children[0], params); |
| 364 | + auto b = eval(*e.children[1], params); |
| 365 | + return Semantics::mod(a, b); |
| 366 | + } |
| 367 | + default: |
| 368 | + throw std::runtime_error("cannot evaluate " + e.toString()); |
| 369 | + } |
| 370 | +} |
0 commit comments