#include <iostream>
#include <string>
#include <memory>
using namespace std;
///////////////////////////////////////
// Expressions
// - eval (interpreter)
class Exp {
public:
virtual int eval() = 0;
};
class IntExp : public Exp {
public:
int x;
IntExp(int x) {
this->x = x;
}
int eval() { return this->x; }
};
class PlusExp : public Exp {
public:
std::shared_ptr<Exp> left, right;
PlusExp(std::shared_ptr<Exp> left, std::shared_ptr<Exp> right) {
this->left = left; this->right = right;
}
int eval() { return left->eval() + right->eval(); }
};
class MultExp : public Exp {
public:
std::shared_ptr<Exp> left, right;
MultExp(std::shared_ptr<Exp> left, std::shared_ptr<Exp>right) {
this->left = left; this->right = right;
}
int eval() { return left->eval() * right->eval(); }
};
// Helper functions
std::shared_ptr<Exp> newInt(int i) {
return std::make_shared<IntExp>(i);
}
std::shared_ptr<Exp> newPlus(std::shared_ptr<Exp> left, std::shared_ptr<Exp> right) {
return std::make_shared<PlusExp>(PlusExp(left,right));
}
std::shared_ptr<Exp> newMult(std::shared_ptr<Exp> left, std::shared_ptr<Exp> right) {
return std::make_shared<MultExp>(MultExp(left,right));
}
void testExp() {
// Automatische Typinferenz.
auto e = newPlus(newMult(newInt(1),newInt(2)), newInt(1)); // (1*2)+1
cout << e->eval();
}
int main()
{
testExp();
return 0;
}