00001
00002 #ifndef _VMETHOD_H_
00003 #define _VMETHOD_H_
00004
00005 #include <string>
00006 #include <map>
00007 #include "Object.h"
00008
00009 namespace FD {
00010
00011 class SymbolSet {
00012 protected:
00013 int currentID;
00014 std::map<std::string,int> translationMap;
00015 public:
00016 SymbolSet()
00017 : currentID(0)
00018 {}
00019 int get(const std::string &str)
00020 {
00021 std::map<std::string,int>::iterator sym = translationMap.find(str);
00022 if (sym == translationMap.end())
00023 {
00024 translationMap.insert(make_pair(str, currentID++));
00025 return currentID-1;
00026 } else {
00027 return sym->second;
00028 }
00029 }
00030
00031 int get (char *str)
00032 {
00033 return get(std::string(str));
00034 }
00035
00036 std::string reverseLookup (int ID)
00037 {
00038 std::map<std::string,int>::iterator it = translationMap.begin();
00039 while (it!=translationMap.end())
00040 {
00041 if (it->second == ID)
00042 return it->first;
00043 ++it;
00044 }
00045 return std::string("");
00046 }
00047 };
00048
00049
00050
00051 class VirtualMethods {
00052 protected:
00053 SymbolSet* symbols;
00054
00055 typedef ObjectRef (*funct_ptr0) (ObjectRef x);
00056 typedef ObjectRef (*funct_ptr1) (ObjectRef x, ObjectRef a);
00057 typedef ObjectRef (*funct_ptr2) (ObjectRef x, ObjectRef a, ObjectRef b);
00058 typedef ObjectRef (*funct_ptr3) (ObjectRef x, ObjectRef a, ObjectRef b, ObjectRef c);
00059
00060 typedef std::map<const std::type_info *, funct_ptr0> vtableType0;
00061 typedef std::map<const std::type_info *, funct_ptr1> vtableType1;
00062 typedef std::map<const std::type_info *, funct_ptr2> vtableType2;
00063 typedef std::map<const std::type_info *, funct_ptr3> vtableType3;
00064
00065 std::vector<vtableType0> tables0;
00066 std::vector<vtableType1> tables1;
00067 std::vector<vtableType2> tables2;
00068 std::vector<vtableType3> tables3;
00069 public:
00070 VirtualMethods()
00071 {
00072 symbols=new SymbolSet;
00073 }
00074
00075 int lookup(const std::string &str)
00076 {
00077 return symbols->get(str);
00078 }
00079
00080 int lookup (char *str)
00081 {
00082 return symbols->get(str);
00083 }
00084
00085 int registerFunct0(funct_ptr0 ptr, const std::type_info *x, std::string name)
00086 {
00087 unsigned int id = symbols->get(name);
00088 if (id >= tables0.size())
00089 tables0.resize(id+1);
00090 tables0[id][x] = ptr;
00091 }
00092
00093 int registerFunct1(funct_ptr1 ptr, const std::type_info *x, std::string name)
00094 {
00095 unsigned int id = symbols->get(name);
00096 if (id >= tables1.size())
00097 tables1.resize(id+1);
00098 tables1[id][x] = ptr;
00099 }
00100
00101 int registerFunct2(funct_ptr2 ptr, const std::type_info *x, std::string name)
00102 {
00103 unsigned int id = symbols->get(name);
00104 if (id >= tables2.size())
00105 tables2.resize(id+1);
00106 tables2[id][x] = ptr;
00107 }
00108
00109 int registerFunct3(funct_ptr3 ptr, const std::type_info *x, std::string name)
00110 {
00111 unsigned int id = symbols->get(name);
00112 if (id >= tables3.size())
00113 tables3.resize(id+1);
00114 tables3[id][x] = ptr;
00115 }
00116
00117 ObjectRef call(int id, ObjectRef x)
00118 {
00119 const std::type_info *t1 = &typeid(*x);
00120 vtableType0 &vtable=tables0[id];
00121 vtableType0::iterator v1 = vtable.find(t1);
00122 if (v1!=vtable.end())
00123 {
00124 return v1->second(x);
00125 } else {
00126 x->doesNotUnderstand(symbols->reverseLookup(id));
00127
00128 }
00129 }
00130
00131 ObjectRef call(int id, ObjectRef x, ObjectRef y)
00132 {
00133 const std::type_info *t1 = &typeid(*x);
00134 vtableType1::iterator v1 = tables1[id].find(t1);
00135 if (v1!=tables1[id].end())
00136 {
00137 return v1->second(x,y);
00138 } else {
00139 x->doesNotUnderstand(symbols->reverseLookup(id));
00140
00141 }
00142 }
00143
00144 };
00145
00146
00147
00148 VirtualMethods* vmethod();
00149
00150 #define REGISTER_VTABLE0(name, type, func, id) \
00151 static int dummy_vtable_init_for ## _ ## name ## id =\
00152 vmethod()->registerFunct0(func, &typeid(type), # name);
00153
00154 }
00155
00156 #endif