00001
00002
00003
00004
00005
00006
00007
00008 #ifndef _IMPULSE_METHOD_H_
00009 #define _IMPULSE_METHOD_H_
00010
00011 #include "array.h"
00012
00013 namespace impulse {
00014
00015
00016
00017
00018
00023
00024 template <typename T>
00025 class Method : public Frame {
00026
00027 public:
00028
00029
00030
00031 Method(string name, Value (T::*method)(Array&, Value)) : _method( method ) { }
00032 Method(string name, Value (T::*method)(Array&, Value), Frame* arg1proto) : _method( method )
00033 {
00034
00035 _signature.push( arg1proto );
00036 }
00037
00038
00039
00040 Value eval( Array& args, Value self );
00041
00042 string inspect() { return "[Method]"; }
00043
00044
00045
00046 Value invoke( Value proto, Array& args, Value self )
00047 {
00048 T* frame = proto.get<T>();
00049
00050 if (frame)
00051 return ((proto.get<T>())->*_method)( args, self );
00052 else
00053 throw string( "Invalid frame subclass for method" );
00054 }
00055
00056 private:
00057
00058 Value (T::*_method)(Array&, Value);
00059 Array _signature;
00060
00061
00062 };
00063
00064
00065
00066
00067
00068 template <typename T>
00069 Value Method<T>::eval( Array& args, Value self )
00070 {
00071 BEG( "Method::eval( args" << ", self = " << self.inspect() << " )" );
00072
00073 Value proto = args.at(0);
00074
00075 Array& margs = *args.at(1).template get<Array>();
00076
00077
00078
00079
00080
00081
00082 Value result;
00083
00084 for (unsigned int i = 0; i < _signature.size(); i++)
00085 {
00086 if (margs.at(i).getFrame() != _signature.at(i).getFrame())
00087 {
00088 cout << "** Argument types do not match method signature" << endl;
00089
00090 return _nil_;
00091 }
00092 }
00093
00094 result = invoke( proto, margs, self );
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115 END( result.inspect() );
00116
00117 return result;
00118 }
00119
00120 }
00121
00122 #endif