[Avida-SVN] r2836 - in development/source: main script
brysonda at myxo.css.msu.edu
brysonda at myxo.css.msu.edu
Sat Oct 11 20:53:59 PDT 2008
Author: brysonda
Date: 2008-10-11 23:53:59 -0400 (Sat, 11 Oct 2008)
New Revision: 2836
Modified:
development/source/main/cAvidaConfig.cc
development/source/main/cAvidaConfig.h
development/source/script/ASAvidaLib.cc
development/source/script/AvidaScript.h
development/source/script/cASNativeObject.h
development/source/script/cDirectInterpretASTVisitor.cc
Log:
AS: Functioning framework for basic argument type native object method calls.
Modified: development/source/main/cAvidaConfig.cc
===================================================================
--- development/source/main/cAvidaConfig.cc 2008-10-11 21:32:31 UTC (rev 2835)
+++ development/source/main/cAvidaConfig.cc 2008-10-12 03:53:59 UTC (rev 2836)
@@ -384,6 +384,14 @@
return false;
}
+cString cAvidaConfig::GetAsString(const cString& entry)
+{
+ // Default to empty string on lookup failure
+ cString rtn("");
+ Get(entry, rtn);
+ return rtn;
+}
+
bool cAvidaConfig::Set(const cString& entry, const cString& val)
{
// Loop through all groups, then all entries, searching for the specified entry.
Modified: development/source/main/cAvidaConfig.h
===================================================================
--- development/source/main/cAvidaConfig.h 2008-10-11 21:32:31 UTC (rev 2835)
+++ development/source/main/cAvidaConfig.h 2008-10-12 03:53:59 UTC (rev 2836)
@@ -574,6 +574,7 @@
bool Get(const cString& entry, cString& ret) const;
+ cString GetAsString(const cString& entry);
bool Set(const cString& entry, const cString& val);
void Set(tDictionary<cString>& sets);
Modified: development/source/script/ASAvidaLib.cc
===================================================================
--- development/source/script/ASAvidaLib.cc 2008-10-11 21:32:31 UTC (rev 2835)
+++ development/source/script/ASAvidaLib.cc 2008-10-12 03:53:59 UTC (rev 2836)
@@ -83,8 +83,17 @@
};
+static void setupNativeObjects()
+{
+ tASNativeObject<cAvidaConfig>::InitializeMethodRegistrar();
+ tASNativeObject<cAvidaConfig>::
+ RegisterMethod(new tASNativeObjectMethod<cAvidaConfig, cString (const cString&)>(&cAvidaConfig::GetAsString), "Get");
+};
+
void RegisterASAvidaLib(cASLibrary* lib)
{
+ setupNativeObjects();
+
lib->RegisterFunction(new tASNativeObjectInstantiate<cAvidaConfig ()>("Config"));
}
Modified: development/source/script/AvidaScript.h
===================================================================
--- development/source/script/AvidaScript.h 2008-10-11 21:32:31 UTC (rev 2835)
+++ development/source/script/AvidaScript.h 2008-10-12 03:53:59 UTC (rev 2836)
@@ -164,7 +164,8 @@
AS_DIRECT_INTERPRET_ERR_KEY_NOT_FOUND,
AS_DIRECT_INTERPRET_ERR_MATRIX_OP_TYPE_MISMATCH,
AS_DIRECT_INTERPRET_ERR_MATRIX_SIZE_MISMATCH,
- AS_DIRECT_INTERPRET_ERR_NATIVE_OBJECT_TYPE_MISMATCH,
+ AS_DIRECT_INTERPRET_ERR_NOBJ_METHOD_LOOKUP_FAILED,
+ AS_DIRECT_INTERPRET_ERR_NOBJ_TYPE_MISMATCH,
AS_DIRECT_INTERPRET_ERR_OBJECT_ASSIGN_FAIL,
AS_DIRECT_INTERPRET_ERR_TYPE_CAST,
AS_DIRECT_INTERPRET_ERR_UNDEFINED_TYPE_OP,
@@ -261,6 +262,7 @@
template<> inline sASTypeInfo TypeOf<int>() { return sASTypeInfo(AS_TYPE_INT); }
template<> inline sASTypeInfo TypeOf<double>() { return sASTypeInfo(AS_TYPE_FLOAT); }
template<> inline sASTypeInfo TypeOf<const cString&>() { return sASTypeInfo(AS_TYPE_STRING); }
+ template<> inline sASTypeInfo TypeOf<cString>() { return sASTypeInfo(AS_TYPE_STRING); }
template<> inline sASTypeInfo TypeOf<void>() { return sASTypeInfo(AS_TYPE_VOID); }
template<> inline sASTypeInfo TypeOf<cASNativeObject>() { return sASTypeInfo(AS_TYPE_OBJECT_REF); }
};
Modified: development/source/script/cASNativeObject.h
===================================================================
--- development/source/script/cASNativeObject.h 2008-10-11 21:32:31 UTC (rev 2835)
+++ development/source/script/cASNativeObject.h 2008-10-12 03:53:59 UTC (rev 2836)
@@ -28,38 +28,98 @@
#include "AvidaScript.h"
#include "cASCPPParameter.h"
+#include "tArray.h"
+#include "tDictionary.h"
#include <typeinfo>
class cString;
+
class cASNativeObject
{
private:
int m_ref_count;
public:
- cASNativeObject() : m_ref_count(1) { ; }
+ cASNativeObject() : m_ref_count(1) { ; }
virtual ~cASNativeObject() { ; }
virtual const char* GetType() = 0;
- virtual bool CallMethod(int mid, int argc, cASCPPParameter args[]) = 0;
+ virtual cASCPPParameter CallMethod(int mid, cASCPPParameter args[]) const = 0;
- int LookupValue(const cString& val_name) { return AS_NOT_FOUND; } // @TODO
- int LookupMethod(const cString& meth_name) { return AS_NOT_FOUND; } // @TODO
+ //virtual bool LookupValue(const cString& val_name, int& vid) = 0;
+ virtual bool LookupMethod(const cString& meth_name, int& mid) = 0;
+ virtual int GetArity(int mid) const = 0;
+ virtual const sASTypeInfo& GetArgumentType(int mid, int arg) const = 0;
+ virtual const sASTypeInfo& GetReturnType(int mid) const = 0;
+
inline cASNativeObject* GetReference() { m_ref_count++; return this; }
inline void RemoveReference() { m_ref_count--; if (m_ref_count == 0) delete this; }
inline bool IsShared() { return (m_ref_count > 1); }
};
+
+template <class NativeClass>
+class cASNativeObjectMethod
+{
+public:
+ virtual ~cASNativeObjectMethod() { ; }
+
+ virtual int GetArity() const = 0;
+ virtual const sASTypeInfo& GetArgumentType(int arg) const = 0;
+ virtual const sASTypeInfo& GetReturnType() const = 0;
+
+ virtual cASCPPParameter Call(NativeClass* object, cASCPPParameter args[]) const = 0;
+};
+
+
+template<class NativeClass, class FunctionType> class tASNativeObjectMethod;
+
+template<class NativeClass, class ReturnType, class Arg1Type>
+class tASNativeObjectMethod<NativeClass, ReturnType (Arg1Type)> : public cASNativeObjectMethod<NativeClass>
+{
+private:
+ sASTypeInfo m_rtype;
+ sASTypeInfo m_signature;
+ ReturnType (NativeClass::*m_method)(Arg1Type);
+
+public:
+ tASNativeObjectMethod(ReturnType (NativeClass::*method)(Arg1Type)) : m_method(method)
+ {
+ m_rtype = AvidaScript::TypeOf<ReturnType>();
+ m_signature = AvidaScript::TypeOf<Arg1Type>();
+ }
+
+ int GetArity() const { return 1; }
+ const sASTypeInfo& GetArgumentType(int arg) const { return m_signature; }
+ const sASTypeInfo& GetReturnType() const { return m_rtype; }
+
+ cASCPPParameter Call(NativeClass* object, cASCPPParameter args[]) const
+ {
+ cASCPPParameter rvalue;
+ rvalue.Set((object->*m_method)(args[0].Get<Arg1Type>()));
+ return rvalue;
+ }
+};
+
+
+
template<class NativeClass>
class tASNativeObject : public cASNativeObject
{
+public:
+
+
private:
+ static tArray<cASNativeObjectMethod<NativeClass>*>* s_methods;
+ static tDictionary<int>* s_method_dict;
+
NativeClass* m_object;
+
public:
tASNativeObject(NativeClass* obj) : m_object(obj) { ; }
@@ -67,8 +127,36 @@
const char* GetType() { return typeid(m_object).name(); }
- bool CallMethod(int mid, int argc, cASCPPParameter args[]) { return false; } // @TODO;
+ cASCPPParameter CallMethod(int mid, cASCPPParameter args[]) const { return (*s_methods)[mid]->Call(m_object, args); }
+
+ bool LookupMethod(const cString& meth_name, int& mid) { return s_method_dict->Find(meth_name, mid); }
+
+ int GetArity(int mid) const { return (*s_methods)[mid]->GetArity(); }
+ const sASTypeInfo& GetArgumentType(int mid, int arg) const { return (*s_methods)[mid]->GetArgumentType(arg); }
+ const sASTypeInfo& GetReturnType(int mid) const { return (*s_methods)[mid]->GetReturnType(); }
+
+ static void InitializeMethodRegistrar()
+ {
+ s_methods = new tArray<cASNativeObjectMethod<NativeClass>*>();
+ s_method_dict = new tDictionary<int>();
+
+ }
+ static void RegisterMethod(cASNativeObjectMethod<NativeClass>* method, const cString& name)
+ {
+ int mid = s_methods->Push(method);
+ s_method_dict->Add(name, mid);
+ }
+
+ static void DestroyMethodRegistrar()
+ {
+ for (int i = 0; i < s_methods->GetSize(); i++) delete *s_methods[i];
+ delete s_methods;
+ delete s_method_dict;
+ }
};
+template<class NativeClass> tArray<cASNativeObjectMethod<NativeClass>*>* tASNativeObject<NativeClass>::s_methods = NULL;
+template<class NativeClass> tDictionary<int>* tASNativeObject<NativeClass>::s_method_dict = NULL;
+
#endif
Modified: development/source/script/cDirectInterpretASTVisitor.cc
===================================================================
--- development/source/script/cDirectInterpretASTVisitor.cc 2008-10-11 21:32:31 UTC (rev 2835)
+++ development/source/script/cDirectInterpretASTVisitor.cc 2008-10-12 03:53:59 UTC (rev 2836)
@@ -1425,9 +1425,74 @@
}
void cDirectInterpretASTVisitor::VisitObjectCall(cASTObjectCall& node)
-{
- // @TODO - handle object call
- INTERPRET_ERROR(INTERNAL);
+{
+ node.GetObject()->Accept(*this);
+
+ if (m_rtype.type != TYPE(OBJECT_REF))
+ INTERPRET_ERROR(TYPE_CAST, mapType(m_rtype.type), mapType(TYPE(OBJECT_REF)));
+
+ cASNativeObject* nobj = m_rvalue.as_nobj;
+
+ int mid = -1;
+ if (!nobj->LookupMethod(node.GetName(), mid))
+ INTERPRET_ERROR(NOBJ_METHOD_LOOKUP_FAILED, *node.GetName(), *m_rtype.info);
+
+ int arity = nobj->GetArity(mid);
+ // Setup arguments
+ cASCPPParameter* args = new cASCPPParameter[arity];
+ if (arity) {
+ tListIterator<cASTNode> cit = node.GetArguments()->Iterator();
+ cASTNode* an = NULL;
+ for (int i = 0; i < arity; i++) {
+ an = cit.Next();
+ an->Accept(*this);
+
+ switch (nobj->GetArgumentType(mid, i).type) {
+ case TYPE(BOOL): args[i].Set(asBool(m_rtype, m_rvalue, node)); break;
+ case TYPE(CHAR): args[i].Set(asChar(m_rtype, m_rvalue, node)); break;
+ case TYPE(FLOAT): args[i].Set(asFloat(m_rtype, m_rvalue, node)); break;
+ case TYPE(INT): args[i].Set(asInt(m_rtype, m_rvalue, node)); break;
+ case TYPE(STRING): args[i].Set(asString(m_rtype, m_rvalue, node)); break;
+
+ default:
+ INTERPRET_ERROR(INTERNAL);
+ }
+ }
+ }
+
+ // Call the function
+ cASCPPParameter rvalue = nobj->CallMethod(mid, args);
+
+ // Handle the return value
+ m_rtype = nobj->GetReturnType(mid);
+ switch (m_rtype.type) {
+ case TYPE(BOOL): m_rvalue.as_bool = rvalue.Get<bool>(); break;
+ case TYPE(CHAR): m_rvalue.as_char = rvalue.Get<char>(); break;
+ case TYPE(FLOAT): m_rvalue.as_float = rvalue.Get<double>(); break;
+ case TYPE(INT): m_rvalue.as_int = rvalue.Get<int>(); break;
+ case TYPE(STRING): m_rvalue.as_string = rvalue.Get<cString*>(); break;
+ case TYPE(OBJECT_REF): m_rvalue.as_nobj = rvalue.Get<cASNativeObject*>(); break;
+ case TYPE(VOID): break;
+
+ default:
+ INTERPRET_ERROR(INTERNAL);
+ }
+
+ // Clean up arguments
+ for (int i = 0; i < arity; i++) {
+ switch (nobj->GetArgumentType(mid, i).type) {
+ case TYPE(BOOL): break;
+ case TYPE(CHAR): break;
+ case TYPE(FLOAT): break;
+ case TYPE(INT): break;
+ case TYPE(STRING): delete args[i].Get<cString*>(); break;
+
+ default:
+ INTERPRET_ERROR(INTERNAL);
+ }
+ }
+ delete [] args;
+
}
void cDirectInterpretASTVisitor::VisitObjectReference(cASTObjectReference& node)
@@ -1776,7 +1841,7 @@
{
switch (type.type) {
case TYPE(OBJECT_REF):
- if (type.info != info) INTERPRET_ERROR(NATIVE_OBJECT_TYPE_MISMATCH, *info, *type.info);
+ if (type.info != info) INTERPRET_ERROR(NOBJ_TYPE_MISMATCH, *info, *type.info);
return value.as_nobj;
default:
@@ -2762,8 +2827,15 @@
case AS_DIRECT_INTERPRET_ERR_MATRIX_SIZE_MISMATCH:
std::cerr << "matrix size mismatch for '" << VA_ARG_STR << "' operation" << ERR_ENDL;
break;
- case AS_DIRECT_INTERPRET_ERR_NATIVE_OBJECT_TYPE_MISMATCH:
+ case AS_DIRECT_INTERPRET_ERR_NOBJ_METHOD_LOOKUP_FAILED:
{
+ const char* meth = VA_ARG_STR;
+ const char* itype = VA_ARG_STR;
+ std::cerr << "method '" << meth << "' not supported by '" << itype << "'" << ERR_ENDL;
+ }
+ break;
+ case AS_DIRECT_INTERPRET_ERR_NOBJ_TYPE_MISMATCH:
+ {
const char* otype = VA_ARG_STR;
const char* itype = VA_ARG_STR;
std::cerr << "expected object of type '" << otype << "', received '" << itype << "'" << ERR_ENDL;
More information about the Avida-cvs
mailing list