Skip to content

Commit

Permalink
fix: Cleanup interpreter::evaluate function
Browse files Browse the repository at this point in the history
  • Loading branch information
Asger Gitz-Johansen committed Sep 10, 2022
1 parent 2ccc3e6 commit 137fdad
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 63 deletions.
38 changes: 19 additions & 19 deletions include/drivers/interpreter.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,33 +38,33 @@ namespace expr {
void add_tree(const syntax_tree_t& tree) override;
void add_tree(const std::string& identifier, const syntax_tree_t& tree) override;

auto add(const symbol_value_t &a, const symbol_value_t &b) -> symbol_value_t override { return ::operator+(a,b); };
auto sub(const symbol_value_t &a, const symbol_value_t &b) -> symbol_value_t override { return a - b; };
auto mul(const symbol_value_t &a, const symbol_value_t &b) -> symbol_value_t override { return a * b; };
auto div(const symbol_value_t &a, const symbol_value_t &b) -> symbol_value_t override { return a / b; };
auto mod(const symbol_value_t &a, const symbol_value_t &b) -> symbol_value_t override { return a % b; };
auto pow(const symbol_value_t &a, const symbol_value_t &b) -> symbol_value_t override { return a ^ b; };
auto add(const symbol_value_t &a, const symbol_value_t &b) const -> symbol_value_t override { return ::operator+(a,b); };
auto sub(const symbol_value_t &a, const symbol_value_t &b) const -> symbol_value_t override { return a - b; };
auto mul(const symbol_value_t &a, const symbol_value_t &b) const -> symbol_value_t override { return a * b; };
auto div(const symbol_value_t &a, const symbol_value_t &b) const -> symbol_value_t override { return a / b; };
auto mod(const symbol_value_t &a, const symbol_value_t &b) const -> symbol_value_t override { return a % b; };
auto pow(const symbol_value_t &a, const symbol_value_t &b) const -> symbol_value_t override { return a ^ b; };

auto _not(const symbol_value_t &a) -> symbol_value_t override { return not_(a); }
auto _and(const symbol_value_t &a, const symbol_value_t &b) -> symbol_value_t override { return and_(a,b); }
auto _or(const symbol_value_t &a, const symbol_value_t &b) -> symbol_value_t override { return or_(a,b); }
auto _xor(const symbol_value_t &a, const symbol_value_t &b) -> symbol_value_t override { return xor_(a,b); }
auto _implies(const symbol_value_t &a, const symbol_value_t &b) -> symbol_value_t override { return implies_(a,b); }
auto _not(const symbol_value_t &a) const -> symbol_value_t override { return not_(a); }
auto _and(const symbol_value_t &a, const symbol_value_t &b) const -> symbol_value_t override { return and_(a,b); }
auto _or(const symbol_value_t &a, const symbol_value_t &b) const -> symbol_value_t override { return or_(a,b); }
auto _xor(const symbol_value_t &a, const symbol_value_t &b) const -> symbol_value_t override { return xor_(a,b); }
auto _implies(const symbol_value_t &a, const symbol_value_t &b) const -> symbol_value_t override { return implies_(a,b); }

auto gt(const symbol_value_t &a, const symbol_value_t &b) -> symbol_value_t override { return gt_(a,b); }
auto ge(const symbol_value_t &a, const symbol_value_t &b) -> symbol_value_t override { return ge_(a,b); }
auto ee(const symbol_value_t &a, const symbol_value_t &b) -> symbol_value_t override { return ee_(a,b); }
auto ne(const symbol_value_t &a, const symbol_value_t &b) -> symbol_value_t override { return ne_(a,b); }
auto le(const symbol_value_t &a, const symbol_value_t &b) -> symbol_value_t override { return le_(a,b); }
auto lt(const symbol_value_t &a, const symbol_value_t &b) -> symbol_value_t override { return lt_(a,b); }
auto gt(const symbol_value_t &a, const symbol_value_t &b) const -> symbol_value_t override { return gt_(a,b); }
auto ge(const symbol_value_t &a, const symbol_value_t &b) const -> symbol_value_t override { return ge_(a,b); }
auto ee(const symbol_value_t &a, const symbol_value_t &b) const -> symbol_value_t override { return ee_(a,b); }
auto ne(const symbol_value_t &a, const symbol_value_t &b) const -> symbol_value_t override { return ne_(a,b); }
auto le(const symbol_value_t &a, const symbol_value_t &b) const -> symbol_value_t override { return le_(a,b); }
auto lt(const symbol_value_t &a, const symbol_value_t &b) const -> symbol_value_t override { return lt_(a,b); }

symbol_table_t result{};
symbol_value_t expression_result{};

auto evaluate(const syntax_tree_t& tree) -> symbol_value_t;
auto evaluate(const compiler::compiled_expr_collection_t& tree) -> symbol_table_t;
static auto evaluate(const syntax_tree_t& tree, expr::arithmetic_operator& arith, expr::boolean_operator& boolean, expr::compare_operator& comparator, const symbol_table_t& symbols) -> symbol_value_t;
static auto evaluate(const compiler::compiled_expr_collection_t& symbol_tree_map, expr::arithmetic_operator& arith, expr::boolean_operator& boolean, expr::compare_operator& comparator, const symbol_table_t& symbols) -> symbol_table_t;
static auto evaluate(const syntax_tree_t& tree, const interpreter& op, const symbol_table_t& symbols) -> symbol_value_t;
static auto evaluate(const compiler::compiled_expr_collection_t& symbol_tree_map, const interpreter& op, const symbol_table_t& symbols) -> symbol_table_t;

protected:
const symbol_table_t &environment{};
Expand Down
49 changes: 24 additions & 25 deletions src/drivers/interpreter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,55 +83,54 @@ namespace expr {
}

auto interpreter::evaluate(const syntax_tree_t& tree) -> symbol_value_t {
return evaluate(tree, *this, *this, *this, environment);
return evaluate(tree, *this, environment);
}

auto interpreter::evaluate(const compiler::compiled_expr_collection_t& trees) -> symbol_table_t {
return evaluate(trees, *this, *this, *this, environment);
return evaluate(trees, *this, environment);
}

auto interpreter::evaluate(const syntax_tree_t& tree, arithmetic_operator& arith, boolean_operator& boolean, compare_operator& comparator, const symbol_table_t& symbols) -> symbol_value_t {
auto interpreter::evaluate(const syntax_tree_t& tree, const interpreter& op, const symbol_table_t& symbols) -> symbol_value_t {
symbol_value_t v{};
auto eval_wrapper = [&](const syntax_tree_t& t) { return evaluate(t, arith, boolean, comparator, symbols); };
std::visit(ya::overload(
[&](const symbol_reference_t& r){ v = symbols.at(r->first); }, // TODO: Should we look up every time? If so, what is the point of storing an iterator in the ast?
[&](const c_symbol_reference_t& r){ v = symbols.at(r->first); }, // TODO: Should we look up every time? If so, what is the point of storing an iterator in the ast?
[&](const operator_t& o) {
switch (o.operator_type) {
case operator_type_t::minus: v = arith.sub(eval_wrapper(tree.children[0]), eval_wrapper(tree.children[1])); break;
case operator_type_t::plus: v = arith.add(eval_wrapper(tree.children[0]), eval_wrapper(tree.children[1])); break;
case operator_type_t::star: v = arith.mul(eval_wrapper(tree.children[0]), eval_wrapper(tree.children[1])); break;
case operator_type_t::slash: v = arith.div(eval_wrapper(tree.children[0]), eval_wrapper(tree.children[1])); break;
case operator_type_t::percent: v = arith.mod(eval_wrapper(tree.children[0]), eval_wrapper(tree.children[1])); break;
case operator_type_t::hat: v = arith.pow(eval_wrapper(tree.children[0]), eval_wrapper(tree.children[1])); break;
case operator_type_t::_and: v = boolean._and(eval_wrapper(tree.children[0]), eval_wrapper(tree.children[1])); break;
case operator_type_t::_or: v = boolean._or(eval_wrapper(tree.children[0]), eval_wrapper(tree.children[1])); break;
case operator_type_t::_xor: v = boolean._xor(eval_wrapper(tree.children[0]), eval_wrapper(tree.children[1])); break;
case operator_type_t::_not: v = boolean._not(eval_wrapper(tree.children[0])); break;
case operator_type_t::_implies: v = boolean._implies(eval_wrapper(tree.children[0]), eval_wrapper(tree.children[1])); break;
case operator_type_t::gt: v = comparator.gt(eval_wrapper(tree.children[0]), eval_wrapper(tree.children[1])); break;
case operator_type_t::ge: v = comparator.ge(eval_wrapper(tree.children[0]), eval_wrapper(tree.children[1])); break;
case operator_type_t::ne: v = comparator.ne(eval_wrapper(tree.children[0]), eval_wrapper(tree.children[1])); break;
case operator_type_t::ee: v = comparator.ee(eval_wrapper(tree.children[0]), eval_wrapper(tree.children[1])); break;
case operator_type_t::le: v = comparator.le(eval_wrapper(tree.children[0]), eval_wrapper(tree.children[1])); break;
case operator_type_t::lt: v = comparator.lt(eval_wrapper(tree.children[0]), eval_wrapper(tree.children[1])); break;
case operator_type_t::parentheses: v = eval_wrapper(tree.children[0]); break;
case operator_type_t::minus: v = op.sub(evaluate(tree.children[0], op, symbols), evaluate(tree.children[1], op, symbols)); break;
case operator_type_t::plus: v = op.add(evaluate(tree.children[0], op, symbols), evaluate(tree.children[1], op, symbols)); break;
case operator_type_t::star: v = op.mul(evaluate(tree.children[0], op, symbols), evaluate(tree.children[1], op, symbols)); break;
case operator_type_t::slash: v = op.div(evaluate(tree.children[0], op, symbols), evaluate(tree.children[1], op, symbols)); break;
case operator_type_t::percent: v = op.mod(evaluate(tree.children[0], op, symbols), evaluate(tree.children[1], op, symbols)); break;
case operator_type_t::hat: v = op.pow(evaluate(tree.children[0], op, symbols), evaluate(tree.children[1], op, symbols)); break;
case operator_type_t::_and: v = op._and(evaluate(tree.children[0], op, symbols), evaluate(tree.children[1], op, symbols)); break;
case operator_type_t::_or: v = op._or(evaluate(tree.children[0], op, symbols), evaluate(tree.children[1], op, symbols)); break;
case operator_type_t::_xor: v = op._xor(evaluate(tree.children[0], op, symbols), evaluate(tree.children[1], op, symbols)); break;
case operator_type_t::_not: v = op._not(evaluate(tree.children[0], op, symbols)); break;
case operator_type_t::_implies: v = op._implies(evaluate(tree.children[0], op, symbols), evaluate(tree.children[1], op, symbols)); break;
case operator_type_t::gt: v = op.gt(evaluate(tree.children[0], op, symbols), evaluate(tree.children[1], op, symbols)); break;
case operator_type_t::ge: v = op.ge(evaluate(tree.children[0], op, symbols), evaluate(tree.children[1], op, symbols)); break;
case operator_type_t::ne: v = op.ne(evaluate(tree.children[0], op, symbols), evaluate(tree.children[1], op, symbols)); break;
case operator_type_t::ee: v = op.ee(evaluate(tree.children[0], op, symbols), evaluate(tree.children[1], op, symbols)); break;
case operator_type_t::le: v = op.le(evaluate(tree.children[0], op, symbols), evaluate(tree.children[1], op, symbols)); break;
case operator_type_t::lt: v = op.lt(evaluate(tree.children[0], op, symbols), evaluate(tree.children[1], op, symbols)); break;
case operator_type_t::parentheses: v = evaluate(tree.children[0], op, symbols); break;
}
},
[&v](const symbol_value_t& o){ v = o; },
[&](const root_t& r){
if(!tree.children.empty())
v = eval_wrapper(tree.children[0]);
v = evaluate(tree.children[0], op, symbols);
},
[](auto&&){ throw std::logic_error("operator type not recognized"); }
), static_cast<const underlying_syntax_node_t&>(tree.node));
return v;
}

auto interpreter::evaluate(const compiler::compiled_expr_collection_t& symbol_tree_map, expr::arithmetic_operator &arith, expr::boolean_operator &boolean, expr::compare_operator &comparator, const symbol_table_t& symbols) -> symbol_table_t {
auto interpreter::evaluate(const compiler::compiled_expr_collection_t& symbol_tree_map, const interpreter& op, const symbol_table_t& symbols) -> symbol_table_t {
symbol_table_t result{};
for(auto& tree : symbol_tree_map)
result[tree.first] = evaluate(tree.second, arith, boolean, comparator, symbols);
result[tree.first] = evaluate(tree.second, op, symbols);
return result;
}
}
3 changes: 1 addition & 2 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -117,8 +117,7 @@ int main (int argc, char *argv[]) {
std::cout << tree.first << ": " << tree.second << "\n";
std::cout << "\n";
interpreter i{drv_c->get_environment()};
auto eval = [&i](const compiler::compiled_expr_collection_t& t){return interpreter::evaluate(t,i,i,i);};
std::cout << eval(drv_c->trees) << "\n";
std::cout << i.evaluate(drv_c->trees) << "\n";
}
if(cli_arguments["driver"].as_string() == "interpreter") {
auto drv_i = std::dynamic_pointer_cast<interpreter>(drv);
Expand Down
34 changes: 17 additions & 17 deletions src/operations.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,27 +32,27 @@

namespace expr {
struct arithmetic_operator {
virtual auto add(const symbol_value_t &a, const symbol_value_t &b) -> symbol_value_t = 0;
virtual auto sub(const symbol_value_t &a, const symbol_value_t &b) -> symbol_value_t = 0;
virtual auto mul(const symbol_value_t &a, const symbol_value_t &b) -> symbol_value_t = 0;
virtual auto div(const symbol_value_t &a, const symbol_value_t &b) -> symbol_value_t = 0;
virtual auto mod(const symbol_value_t &a, const symbol_value_t &b) -> symbol_value_t = 0;
virtual auto pow(const symbol_value_t &a, const symbol_value_t &b) -> symbol_value_t = 0;
virtual auto add(const symbol_value_t &a, const symbol_value_t &b) const -> symbol_value_t = 0;
virtual auto sub(const symbol_value_t &a, const symbol_value_t &b) const -> symbol_value_t = 0;
virtual auto mul(const symbol_value_t &a, const symbol_value_t &b) const -> symbol_value_t = 0;
virtual auto div(const symbol_value_t &a, const symbol_value_t &b) const -> symbol_value_t = 0;
virtual auto mod(const symbol_value_t &a, const symbol_value_t &b) const -> symbol_value_t = 0;
virtual auto pow(const symbol_value_t &a, const symbol_value_t &b) const -> symbol_value_t = 0;
};
struct boolean_operator {
virtual auto _not(const symbol_value_t &a) -> symbol_value_t = 0;
virtual auto _and(const symbol_value_t &a, const symbol_value_t &b) -> symbol_value_t = 0;
virtual auto _or(const symbol_value_t &a, const symbol_value_t &b) -> symbol_value_t = 0;
virtual auto _xor(const symbol_value_t &a, const symbol_value_t &b) -> symbol_value_t = 0;
virtual auto _implies(const symbol_value_t& a, const symbol_value_t& b) -> symbol_value_t = 0;
virtual auto _not(const symbol_value_t &a) const -> symbol_value_t = 0;
virtual auto _and(const symbol_value_t &a, const symbol_value_t &b) const -> symbol_value_t = 0;
virtual auto _or(const symbol_value_t &a, const symbol_value_t &b) const -> symbol_value_t = 0;
virtual auto _xor(const symbol_value_t &a, const symbol_value_t &b) const -> symbol_value_t = 0;
virtual auto _implies(const symbol_value_t& a, const symbol_value_t& b) const -> symbol_value_t = 0;
};
struct compare_operator {
virtual auto gt(const symbol_value_t &a, const symbol_value_t &b) -> symbol_value_t = 0;
virtual auto ge(const symbol_value_t &a, const symbol_value_t &b) -> symbol_value_t = 0;
virtual auto ee(const symbol_value_t &a, const symbol_value_t &b) -> symbol_value_t = 0;
virtual auto ne(const symbol_value_t &a, const symbol_value_t &b) -> symbol_value_t = 0;
virtual auto le(const symbol_value_t &a, const symbol_value_t &b) -> symbol_value_t = 0;
virtual auto lt(const symbol_value_t &a, const symbol_value_t &b) -> symbol_value_t = 0;
virtual auto gt(const symbol_value_t &a, const symbol_value_t &b) const -> symbol_value_t = 0;
virtual auto ge(const symbol_value_t &a, const symbol_value_t &b) const -> symbol_value_t = 0;
virtual auto ee(const symbol_value_t &a, const symbol_value_t &b) const -> symbol_value_t = 0;
virtual auto ne(const symbol_value_t &a, const symbol_value_t &b) const -> symbol_value_t = 0;
virtual auto le(const symbol_value_t &a, const symbol_value_t &b) const -> symbol_value_t = 0;
virtual auto lt(const symbol_value_t &a, const symbol_value_t &b) const -> symbol_value_t = 0;
};
}

Expand Down

0 comments on commit 137fdad

Please sign in to comment.