#include "expression.h" #include // SEE HEADER FILE FOR EXPLANATION // MOST ARE REAL ONE LINERS expression::expression() { } expression::~expression() { } bool expression::simple() const { return true; } constant::constant(double d):value(d) { } constant::constant(const constant& c):value(c.value) { } expression* constant::clone() const { return new constant(*this); } double constant::evaluate(double*) const { return value; } void constant::print(ostream& os) const { os << value; } bool constant::simple() const { return true; } expression* constant::simplify() const { return clone(); } variable::variable(int i):index(i) { } variable::variable(const variable& v):index(v.index) { } bool variable::simple() const { return false; } expression* variable::simplify() const { return clone(); } expression* variable::clone() const { return new variable(*this); } double variable::evaluate(double* L) const { return L[index]; } void variable::print(ostream& os) const { os << '_' << '{' << index << '}'; } sub_expression::sub_expression(expression* e):expr(e) { } sub_expression::~sub_expression() { delete expr; } sub_expression::sub_expression(const sub_expression& se): expr(se.expr->clone()) { } expression* sub_expression::clone() const { return new sub_expression(*this); } double sub_expression::evaluate(double* L) const { return expr->evaluate(L); } bool sub_expression::simple() const { return expr->simple(); } expression* sub_expression::simplify() const { expression* nexpr = expr->simplify(); if (nexpr->simple()) return nexpr; else return new sub_expression(nexpr); } void sub_expression::print(ostream& os) const { os << '('; expr->print(os); os << ')'; } binary_operator_expression::binary_operator_expression(expression* l, expression* r, int p):lhs(l),rhs(r), precedence(p) { } binary_operator_expression::binary_operator_expression( const binary_operator_expression& be): lhs(be.lhs->clone()),rhs(be.rhs->clone()) { } // FIXING PRECEDENCE // IF THE RIGHT HAND SIDE IS ALSO A BINARY OPERATOR // AND ITS PRECEDENCE IS LOWER THAN IT SHOULD MOVE UP // THE TREE: // // * + // / \ / \ // 2 + ===> * 4 // / \ / \ // 3 4 2 3 // void binary_operator_adaptor::fix_right() { // ran IS USED TO "RANDOMIZE", IE TO CORRECT CONSISTENTLY LEFT // OR RIGHT BRANCHING TREES, THE SHALLOWER THE BETTER static bool ran = false; // CHECK TYPE OF RHS binary_operator_adaptor* rhs = dynamic_cast(binary_expression->rhs); if (rhs != (binary_operator_adaptor*)0) { ran = !ran; rhs->fix_left(); // FIX RIGHT'S LEFT RECURSIVELLY rhs->fix_right(); // FIX RIGHT's RIGHT RECURSIVELLY int this_prec = binary_expression->precedence, rhs_prec = rhs->binary_expression->precedence; if ((this_prec > rhs_prec) || (this_prec == rhs_prec && ran)) { // SWING, SEE DIAGRAM ABOVE binary_operator_expression* move_up = rhs->binary_expression; rhs->binary_expression = binary_expression; binary_expression->rhs = move_up->lhs; move_up->lhs = rhs; binary_expression = move_up; } } } // FIXING PRECEDENCE // IF THE LEFT HAND SIDE IS ALSO A BINARY OPERATOR // AND ITS PRECEDENCE IS LOWER THAN IT SHOULD MOVE UP // THE TREE: // // * + // / \ / \ // + 4 ===> 2 * // / \ / \ // 2 3 3 4 // void binary_operator_adaptor::fix_left() { // ran IS USED TO "RANDOMIZE", IE TO CORRECT CONSISTENTLY LEFT // OR RIGHT BRANCHING TREES, THE SHALLOWER THE BETTER static bool ran = false; binary_operator_adaptor* lhs = dynamic_cast(binary_expression->lhs); if (lhs != (binary_operator_adaptor*)0) { lhs->fix_left(); // FIX LEFT'S LEFT RECURSIVELLY lhs->fix_right(); // FIX LEFT's RIGHT RECURSIVELLY int this_prec = binary_expression->precedence, lhs_prec = lhs->binary_expression->precedence; if ((this_prec > lhs_prec) || (this_prec == lhs_prec && ran)) { // SWING, SEE DIAGRAM binary_operator_expression* move_up = lhs->binary_expression; lhs->binary_expression = binary_expression; binary_expression->lhs = move_up->rhs; move_up->rhs = lhs; binary_expression = move_up; } } } // ANY TIME A NEW binary_operator_adaptor IS CONSTRUCTED // FIX ITS PRECEDENCE binary_operator_adaptor::binary_operator_adaptor(binary_operator_expression* e) :binary_expression(e) { fix_right(); fix_left(); } binary_operator_adaptor::binary_operator_adaptor( const binary_operator_adaptor& ba):binary_expression( dynamic_cast(ba.binary_expression->clone())) { } bool binary_operator_adaptor::simple() const { return binary_expression->simple(); } expression* binary_operator_adaptor::clone() const { return new binary_operator_adaptor(*this); } expression* binary_operator_adaptor::simplify() const { return binary_expression->simplify(); } binary_operator_adaptor::~binary_operator_adaptor() { delete binary_expression; } double binary_operator_adaptor::evaluate(double* L) const { return binary_expression->evaluate(L); } void binary_operator_adaptor::print(ostream& os) const { os << '('; binary_expression->print(os); os << ')'; } binary_operator_expression::~binary_operator_expression() { delete lhs; delete rhs; } bool binary_operator_expression::simple() const { return lhs->simple() && rhs->simple(); } int binary_operator_expression::get_precedence() const { return precedence; } unary_operator_expression::unary_operator_expression(expression* e): operand(e) { } unary_operator_expression::unary_operator_expression( const unary_operator_expression& ue):operand(ue.operand->clone()) { } unary_operator_expression::~unary_operator_expression() { delete operand; } bool unary_operator_expression::simple() const { return operand->simple(); } function_call::function_call() { } function_call::function_call(const function_call& fc): argv(new expression*[fc.argc]),argc(fc.argc) { for(int i=0; iclone(); } } function_call::~function_call() { for(int i=0; isimple()) return false; } return true; } ostream& operator<<(ostream& os, const expression& e) { e.print(os); return os; }