Skip to content

Commit 25906be

Browse files
committed
expression eval function
1 parent e880a44 commit 25906be

File tree

2 files changed

+58
-0
lines changed

2 files changed

+58
-0
lines changed

src/form/expression_util.cpp

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
#include "form/expression_util.hpp"
22

3+
#include "lang/semantics.hpp"
4+
35
Expression ExpressionUtil::newConstant(int64_t value) {
46
return Expression(Expression::Type::CONSTANT, "", Number(value));
57
}
@@ -314,3 +316,55 @@ void ExpressionUtil::collectNames(const Expression& e, Expression::Type type,
314316
collectNames(*c, type, target);
315317
}
316318
}
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+
}

src/form/expression_util.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#pragma once
22

3+
#include <map>
34
#include <set>
45

56
#include "form/expression.hpp"
@@ -20,4 +21,7 @@ class ExpressionUtil {
2021

2122
static void collectNames(const Expression& e, Expression::Type type,
2223
std::set<std::string>& target);
24+
25+
static Number eval(const Expression& e,
26+
const std::map<std::string, Number> params);
2327
};

0 commit comments

Comments
 (0)