diff options
author | Tom Stellard <tstellar@gmail.com> | 2010-12-15 18:33:13 -0800 |
---|---|---|
committer | Tom Stellard <tstellar@gmail.com> | 2010-12-15 18:33:13 -0800 |
commit | b1d5428ecbbcde94071d642a3c1672f2f74a6ee1 (patch) | |
tree | 308796efcd02830c4b7adda434a2a760c746476f | |
parent | 5c16dd6f39da486d31e890d068cb7987a1785c5a (diff) |
Add hack to emulate overloaded evaluate() functions
-rw-r--r-- | emulator.cpp | 4 | ||||
-rw-r--r-- | evaluator.cpp | 52 | ||||
-rw-r--r-- | evaluator.h | 14 | ||||
-rw-r--r-- | value.cpp | 71 | ||||
-rw-r--r-- | value.h | 12 |
5 files changed, 121 insertions, 32 deletions
diff --git a/emulator.cpp b/emulator.cpp index f2cef7f..18cec8a 100644 --- a/emulator.cpp +++ b/emulator.cpp @@ -45,11 +45,11 @@ emulator::get_value(register_address addr) unsigned int index = calc_reg_index(addr.m_index, addr.m_swizzle); switch(addr.m_type) { - case REGISTER_TYPE_TEMP: std::cout << m_temp_regs[index]->to_string() << "\n"; return m_temp_regs[index]->clone(); + case REGISTER_TYPE_TEMP: return m_temp_regs[index]->clone(); case REGISTER_TYPE_CONST: { float_value * val = m_const_regs[index]; - std::cout << val->to_string() << "\n"; + if (val->m_has_value) { return new float_value(*val); } else { diff --git a/evaluator.cpp b/evaluator.cpp index 1356258..c5721ae 100644 --- a/evaluator.cpp +++ b/evaluator.cpp @@ -6,11 +6,61 @@ evaluator::evaluator(const char * display_name) : m_display_name(display_name) { } +/* XXX: This is really ugly. I'm sure there is a way to do this with function + * overloads, but I can't figure out how. */ value * evaluator::evaluate( value * l, value * r) { + enum value_type l_type = l->get_type(); + enum value_type r_type = r->get_type(); + switch(l_type) { + case VALUE_TYPE_FLOAT: + return evaluate((float_value*)l, r); + default: + switch(r_type) { + case VALUE_TYPE_FLOAT: + return evaluate(l, (float_value*)r); + default: + return default_evaluate(l, r); + } + } +} + +value * +evaluator::evaluate( + float_value * l, + value * r) +{ + enum value_type r_type = r->get_type(); + switch(r_type) { + case VALUE_TYPE_FLOAT: + return evaluate(l, (float_value*)r); + default: + return default_evaluate(l, r); + } +} + +value * +evaluator::evaluate( + value * l, + float_value * r) +{ + enum value_type l_type = l->get_type(); + switch(l_type) { + case VALUE_TYPE_FLOAT: + return evaluate((float_value*)l, r); + default: + return default_evaluate(l, r); + } +} + +value * +evaluator::default_evaluate( + value * l, + value * r) +{ return new tree_value(this, l, r); } @@ -31,7 +81,7 @@ add_evaluator::evaluate( { float_value * new_val; if (!l->m_has_value || !r->m_has_value) { - return this->evaluator::evaluate(l, r); + return default_evaluate(l, r); } new_val = new float_value(); diff --git a/evaluator.h b/evaluator.h index e64f27b..26594f0 100644 --- a/evaluator.h +++ b/evaluator.h @@ -12,8 +12,21 @@ public: virtual value * evaluate( value * l, value * r); + virtual value * evaluate( + float_value * l, + value * r); + virtual value * evaluate( + value * r, + float_value * l); + virtual value * evaluate( + float_value * l, + float_value * r) = 0; virtual std::string to_string(); +protected: + value * default_evaluate( + value * l, + value * r); private: const char * m_display_name; }; @@ -24,5 +37,6 @@ public: value * evaluate( float_value * l, float_value * r); + }; #endif //EVALUATOR_H_ @@ -4,11 +4,22 @@ #include "evaluator.h" +value::value(enum value_type type) : + m_type(type) + { } + +enum value_type +value::get_type() +{ + return m_type; +} + tree_value::tree_value( evaluator * evaluator, value * lchild, value * rchild) : + value(VALUE_TYPE_TREE), m_evaluator(evaluator), m_lchild(lchild), m_rchild(rchild) @@ -39,36 +50,8 @@ tree_value::to_string() + (m_rchild ? m_rchild->to_string() : "?") + ")"; } -const_value::const_value( - register_address address, - float_value * value_ptr) : - value(), - m_reg_address(address), - m_value(value_ptr) - { } - -value * -const_value::simplify() -{ - if (m_value->m_has_value) { - return m_value->clone(); - } else { - return this->clone(); - } -} - -value * -const_value::clone() -{ - return new const_value(m_reg_address, m_value); -} - -std::string -const_value::to_string() -{ - return m_reg_address.to_string(); -} float_value::float_value() : + value(VALUE_TYPE_FLOAT), m_has_value(false) { } @@ -102,3 +85,33 @@ float_value::set_value(float value) m_has_value = true; m_value = value; } + +const_value::const_value( + register_address address, + float_value * value_ptr) : + value(VALUE_TYPE_CONST), + m_reg_address(address), + m_value(value_ptr) + { } + +value * +const_value::simplify() +{ + if (m_value->m_has_value) { + return m_value->clone(); + } else { + return this->clone(); + } +} + +value * +const_value::clone() +{ + return new const_value(m_reg_address, m_value); +} + +std::string +const_value::to_string() +{ + return m_reg_address.to_string(); +} @@ -8,12 +8,24 @@ class evaluator; +enum value_type { + VALUE_TYPE_GENERIC, + VALUE_TYPE_TREE, + VALUE_TYPE_CONST, + VALUE_TYPE_FLOAT +}; + class value { public: + value(enum value_type type); + virtual value * simplify() = 0; virtual value * clone() = 0; virtual std::string to_string() = 0; + enum value_type get_type(); +private: + enum value_type m_type; }; class tree_value : public value { |