[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