summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Stellard <tstellar@gmail.com>2010-12-15 18:33:13 -0800
committerTom Stellard <tstellar@gmail.com>2010-12-15 18:33:13 -0800
commitb1d5428ecbbcde94071d642a3c1672f2f74a6ee1 (patch)
tree308796efcd02830c4b7adda434a2a760c746476f
parent5c16dd6f39da486d31e890d068cb7987a1785c5a (diff)
Add hack to emulate overloaded evaluate() functions
-rw-r--r--emulator.cpp4
-rw-r--r--evaluator.cpp52
-rw-r--r--evaluator.h14
-rw-r--r--value.cpp71
-rw-r--r--value.h12
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_
diff --git a/value.cpp b/value.cpp
index f210dd1..291ba34 100644
--- a/value.cpp
+++ b/value.cpp
@@ -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();
+}
diff --git a/value.h b/value.h
index ba1eae1..6a18053 100644
--- a/value.h
+++ b/value.h
@@ -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 {