given the following class hierarchy
struct Expression {};
struct ExpBinary : Expression {
Expression *left, *right;
ExpBinary(Expression *o1, Expression *o2)
: left(o1)
, right(o2) {}
};
struct ExpArith : ExpBinary {
enum function {
SUB, ADD, MUL, DIV
};
function arithOp;
ExpArith(function f, Expression *l, Expression *r)
: ExpBinary(l, r)
, arithOp(f) {}
};
struct ExpLogical : ExpBinary {
enum function_log {
GT, LT, EQ
};
function_log logicalOp;
ExpLogical(function_log f, Expression *l, Expression *r)
: ExpBinary(l, r)
, logicalOp(f) {}
};
struct ExpInteger : Expression {
int value;
ExpInteger(int v) : value(v) {}
};
The following evaluator somehow does not work:
int evaluate(const Expression& exp){
var<Expression&> left, right;
var<ExpLogical::function_log> lOp;
var<ExpArith::function> aOp;
int val;
Match(exp){
Case(C<ExpBinary>(&left, &right)) {
Match(exp) {
// cout << typeid(exp).name() << endl;
Case(C<ExpArith>(aOp)) {
//cout << "exparith!\n";
Match(aOp) {
Case(ExpArith::ADD) {
return evaluate(left) + evaluate(right);
}
Case(ExpArith::SUB) {
return evaluate(left) - evaluate(right);
}
Case(ExpArith::MUL) {
return evaluate(left) * evaluate(right);
}
Case(ExpArith::DIV) {
return evaluate(left) / evaluate(right);
}
Otherwise() {
return 0;
}
} EndMatch
}
Case(C<ExpLogical>(lOp)) {
cout << "explogical!\n"; //never reached, but it should
Match(lOp) {
Case(ExpLogical::GT) {
return evaluate(left) > evaluate(right);
}
Case(ExpLogical::LT) {
return evaluate(left) < evaluate(right);
}
Case(ExpLogical::EQ) {
return evaluate(left) == evaluate(right);
}
Otherwise() {
return 0;
}
} EndMatch
}
Otherwise() {
cout << "Error in exp arith/logical matching!\n";
return 0;
}
} EndMatch
}
Case(C<ExpInteger>(val)) {
return val;
}
Otherwise() {
cout << "Error in evaluate!\n";
return 0;
}
} EndMatch
}
If I build the expression
Expression *log =
new ExpLogical(ExpLogical::GT,
new ExpInteger(3),
new ExpInteger(4));
and try to evaluate it using the statement,
cout << evaluate(*log) << endl;
the program outputs -1 which is wrong. Somehow the statement Case(C<ExpLogical>(lOp)) is not reached, instead the second Match(exp) chooses Case(C<ExpArith>(aOp)). I don't understand why, since the patterns against which the subjecting values are being matched are clearly different. Do you have any idea? Is it disallowed to nest Match statements?
I also provided the whole (compilable) example as a gist.
Best regards
given the following class hierarchy
The following evaluator somehow does not work:
If I build the expression
Expression *log = new ExpLogical(ExpLogical::GT, new ExpInteger(3), new ExpInteger(4));and try to evaluate it using the statement,
the program outputs
-1which is wrong. Somehow the statementCase(C<ExpLogical>(lOp))is not reached, instead the secondMatch(exp)choosesCase(C<ExpArith>(aOp)). I don't understand why, since the patterns against which the subjecting values are being matched are clearly different. Do you have any idea? Is it disallowed to nestMatchstatements?I also provided the whole (compilable) example as a gist.
Best regards