[Avida-SVN] r2444 - development/source/script

brysonda at myxo.css.msu.edu brysonda at myxo.css.msu.edu
Sun Mar 9 20:43:44 PDT 2008


Author: brysonda
Date: 2008-03-09 23:43:43 -0400 (Sun, 09 Mar 2008)
New Revision: 2444

Modified:
   development/source/script/AvidaScript.h
   development/source/script/cDirectInterpretASTVisitor.cc
   development/source/script/cDirectInterpretASTVisitor.h
Log:
AS:
Implement basic array assignment support.

Modified: development/source/script/AvidaScript.h
===================================================================
--- development/source/script/AvidaScript.h	2008-03-10 01:59:31 UTC (rev 2443)
+++ development/source/script/AvidaScript.h	2008-03-10 03:43:43 UTC (rev 2444)
@@ -143,7 +143,9 @@
 
 typedef enum eASDirectInterpretErrors {
   AS_DIRECT_INTERPRET_ERR_DIVISION_BY_ZERO,
+  AS_DIRECT_INTERPRET_ERR_INDEX_OUT_OF_BOUNDS,
   AS_DIRECT_INTERPRET_ERR_INVALID_ARRAY_SIZE,
+  AS_DIRECT_INTERPRET_ERR_OBJECT_ASSIGN_FAIL,
   AS_DIRECT_INTERPRET_ERR_TYPE_CAST,
   AS_DIRECT_INTERPRET_ERR_UNDEFINED_TYPE_OP,
   AS_DIRECT_INTERPRET_ERR_UNPACK_VALUE_TOO_LARGE,

Modified: development/source/script/cDirectInterpretASTVisitor.cc
===================================================================
--- development/source/script/cDirectInterpretASTVisitor.cc	2008-03-10 01:59:31 UTC (rev 2443)
+++ development/source/script/cDirectInterpretASTVisitor.cc	2008-03-10 03:43:43 UTC (rev 2444)
@@ -24,6 +24,7 @@
 
 #include "cDirectInterpretASTVisitor.h"
 
+#include <cassert>
 #include <cmath>
 
 #include "avida.h"
@@ -45,7 +46,8 @@
 #define TYPE(x) AS_TYPE_ ## x
 
 cDirectInterpretASTVisitor::cDirectInterpretASTVisitor(cSymbolTable* global_symtbl)
-  : m_global_symtbl(global_symtbl), m_cur_symtbl(global_symtbl), m_call_stack(0, 2048), m_sp(0), m_has_returned(false)
+  : m_global_symtbl(global_symtbl), m_cur_symtbl(global_symtbl), m_call_stack(0, 2048), m_sp(0)
+  , m_has_returned(false), m_obj_assign(false)
 {
   m_call_stack.Resize(m_global_symtbl->GetNumVariables());
   for (int i = 0; i < m_global_symtbl->GetNumVariables(); i++) m_call_stack[i].as_string = NULL;
@@ -105,8 +107,12 @@
 
 void cDirectInterpretASTVisitor::VisitObjectAssignment(cASTObjectAssignment& node)
 {
-  // @TODO - handle object assignment
-  INTERPRET_ERROR(INTERNAL);
+  node.GetTarget()->Accept(*this);
+  cObjectRef* obj = m_rvalue.as_ref;
+  
+  node.GetExpression()->Accept(*this);
+  
+  if (!obj->Set(m_rtype, m_rvalue)) INTERPRET_ERROR(OBJECT_ASSIGN_FAIL);
 }
 
 
@@ -615,7 +621,26 @@
       }
       break;
 
-    case TOKEN(IDX_OPEN): // @TODO - handle indexing
+    case TOKEN(IDX_OPEN):
+      if (m_obj_assign) {
+        cObjectRef* obj = lval.as_ref;
+        int idx = asInt(rtype, rval, node);
+        
+        if (obj->GetType() != TYPE(ARRAY))
+          INTERPRET_ERROR(UNDEFINED_TYPE_OP, mapToken(TOKEN(IDX_OPEN)), mapType(obj->GetType()));
+        
+        m_rvalue.as_ref = new cObjectIndexRef(obj, idx);
+        m_rtype = TYPE(OBJECT_REF);
+      } else {
+        cLocalArray* arr = asArray(ltype, lval, node);
+        int idx = asInt(rtype, rval, node);
+        
+        if (idx < 0 || idx >= arr->GetSize()) INTERPRET_ERROR(INDEX_OUT_OF_BOUNDS);
+        
+        const sAggregateValue val = arr->Get(idx);
+        m_rtype = val.type;
+        m_rvalue = val.value;
+      }
       break;
       
     default:
@@ -823,20 +848,33 @@
   int var_id = node.GetVarID();
   int sp = node.IsVarGlobal() ? 0 : m_sp;
   
-  switch (node.GetType()) {
-    case TYPE(ARRAY):       m_rvalue.as_array = m_call_stack[sp + var_id].as_array->GetReference(); break;
-    case TYPE(BOOL):        m_rvalue.as_bool = m_call_stack[sp + var_id].as_bool; break;
-    case TYPE(CHAR):        m_rvalue.as_char = m_call_stack[sp + var_id].as_char; break;
-    case TYPE(FLOAT):       m_rvalue.as_float = m_call_stack[sp + var_id].as_float; break;
-    case TYPE(INT):         m_rvalue.as_int = m_call_stack[sp + var_id].as_int; break;
-    case TYPE(OBJECT_REF):  INTERPRET_ERROR(INTERNAL); // @TODO - assignment
-    case TYPE(MATRIX):      INTERPRET_ERROR(INTERNAL); // @TODO - assignment
-    case TYPE(STRING):      m_rvalue.as_string = new cString(*m_call_stack[sp + var_id].as_string); break;
-      
-    default:
-      INTERPRET_ERROR(INTERNAL);
+  if (m_obj_assign) {
+    switch (node.GetType()) {
+      case TYPE(ARRAY):       m_rvalue.as_ref = new cArrayVarRef(m_call_stack[sp + var_id]); break;
+      case TYPE(OBJECT_REF):  INTERPRET_ERROR(INTERNAL); // @TODO - assignment
+      case TYPE(MATRIX):      INTERPRET_ERROR(INTERNAL); // @TODO - assignment
+      case TYPE(STRING):      INTERPRET_ERROR(INTERNAL); // @TODO - assignment
+        
+      default:
+        INTERPRET_ERROR(INTERNAL);
+    }
+    m_rtype = TYPE(OBJECT_REF);
+  } else {
+    switch (node.GetType()) {
+      case TYPE(ARRAY):       m_rvalue.as_array = m_call_stack[sp + var_id].as_array->GetReference(); break;
+      case TYPE(BOOL):        m_rvalue.as_bool = m_call_stack[sp + var_id].as_bool; break;
+      case TYPE(CHAR):        m_rvalue.as_char = m_call_stack[sp + var_id].as_char; break;
+      case TYPE(FLOAT):       m_rvalue.as_float = m_call_stack[sp + var_id].as_float; break;
+      case TYPE(INT):         m_rvalue.as_int = m_call_stack[sp + var_id].as_int; break;
+      case TYPE(OBJECT_REF):  INTERPRET_ERROR(INTERNAL); // @TODO - assignment
+      case TYPE(MATRIX):      INTERPRET_ERROR(INTERNAL); // @TODO - assignment
+      case TYPE(STRING):      m_rvalue.as_string = new cString(*m_call_stack[sp + var_id].as_string); break;
+        
+      default:
+        INTERPRET_ERROR(INTERNAL);
+    }
+    m_rtype = node.GetType();
   }
-  m_rtype = node.GetType();
 }
 
 
@@ -1228,7 +1266,67 @@
 }
 
 
+bool cDirectInterpretASTVisitor::cArrayVarRef::Set(int idx, ASType_t type, uAnyType value)
+{
+  cLocalArray* arr = m_var.as_array;
+  if (idx < 0 || idx >= arr->GetSize()) return false;
 
+  if (arr->IsShared()) {
+    arr = new cLocalArray(arr);
+    m_var.as_array->RemoveReference();
+    m_var.as_array = arr;
+  }
+  
+  arr->Set(idx, type, value);
+  
+  return true;
+}
+
+
+ASType_t cDirectInterpretASTVisitor::cObjectIndexRef::GetType(int idx)
+{
+  if (m_obj->GetType(m_idx) != TYPE(ARRAY)) return TYPE(INVALID);
+  
+  cLocalArray* arr = m_obj->Get(m_idx).as_array;
+  if (idx < 0 || idx >= arr->GetSize()) return TYPE(INVALID);
+  
+  return arr->Get(idx).type;
+}
+
+
+cDirectInterpretASTVisitor::uAnyType cDirectInterpretASTVisitor::cObjectIndexRef::Get(int idx)
+{
+  assert(m_obj->GetType(m_idx) == TYPE(ARRAY));
+  
+  cLocalArray* arr = m_obj->Get(m_idx).as_array;
+  assert(idx < 0 || idx >= arr->GetSize());
+  
+  return arr->Get(idx).value;
+}
+
+
+bool cDirectInterpretASTVisitor::cObjectIndexRef::Set(int idx, ASType_t type, uAnyType value)
+{
+  if (m_obj->GetType(m_idx) != TYPE(ARRAY)) return false;
+  
+  cLocalArray* arr = m_obj->Get(m_idx).as_array;
+  if (idx < 0 || idx >= arr->GetSize()) return false;
+  
+  if (arr->IsShared()) {
+    arr = new cLocalArray(arr);
+    arr->Set(idx, type, value);
+    
+    uAnyType val;
+    val.as_array = arr;
+    m_obj->Set(m_idx, TYPE(ARRAY), val);
+  } else {
+    arr->Set(idx, type, value);    
+  }
+  
+  return true;
+}
+
+
 void cDirectInterpretASTVisitor::reportError(ASDirectInterpretError_t err, const cASFilePosition& fp, const int line, ...)
 {
 #if DEBUG_AS_DIRECT_INTERPRET
@@ -1247,9 +1345,15 @@
     case AS_DIRECT_INTERPRET_ERR_DIVISION_BY_ZERO:
       std::cerr << "division by zero" << ERR_ENDL;
       break;
+    case AS_DIRECT_INTERPRET_ERR_INDEX_OUT_OF_BOUNDS:
+      std::cerr << "array index out of bounds" << ERR_ENDL;
+      break;
     case AS_DIRECT_INTERPRET_ERR_INVALID_ARRAY_SIZE:
       std::cerr << "invalid array dimension" << ERR_ENDL;
       break;
+    case AS_DIRECT_INTERPRET_ERR_OBJECT_ASSIGN_FAIL:
+      std::cerr << "aggregate assignment failed" << ERR_ENDL;
+      break;
     case AS_DIRECT_INTERPRET_ERR_TYPE_CAST:
       {
         const char* type1 = VA_ARG_STR;

Modified: development/source/script/cDirectInterpretASTVisitor.h
===================================================================
--- development/source/script/cDirectInterpretASTVisitor.h	2008-03-10 01:59:31 UTC (rev 2443)
+++ development/source/script/cDirectInterpretASTVisitor.h	2008-03-10 03:43:43 UTC (rev 2444)
@@ -38,6 +38,7 @@
   // --------  Internal Type Declarations  --------
   class cLocalArray;
   class cLocalMatrix;
+  class cObjectRef;
   
   typedef union {
     bool as_bool;
@@ -47,6 +48,7 @@
     cString* as_string;
     cLocalArray* as_array;
     cLocalMatrix* as_matrix;
+    cObjectRef* as_ref;
   } uAnyType;
   
 
@@ -60,6 +62,7 @@
   tSmartArray<uAnyType> m_call_stack;
   int m_sp;
   bool m_has_returned;
+  bool m_obj_assign;
   
   
   // --------  Private Constructors  --------
@@ -153,6 +156,61 @@
   {
     
   };
+  
+  class cObjectRef
+  {
+  public:
+    virtual ~cObjectRef() { ; }
+
+    virtual bool IsWritable() = 0;
+    virtual ASType_t GetType() = 0;
+    virtual ASType_t GetType(int idx) = 0;
+    
+    virtual uAnyType Get() = 0;
+    virtual uAnyType Get(int idx) = 0;
+    virtual bool Set(ASType_t type, uAnyType value) = 0;
+    virtual bool Set(int idx, ASType_t type, uAnyType value) = 0;
+  };
+
+  class cArrayVarRef : public cObjectRef
+  {
+  private:
+    uAnyType& m_var;
+    
+  public:
+    cArrayVarRef(uAnyType& var) : m_var(var) { ; }
+    ~cArrayVarRef() { ; }
+
+    bool IsWritable() { return true; }
+    ASType_t GetType() { return AS_TYPE_ARRAY; }
+    ASType_t GetType(int idx)
+    { if (idx < 0 || idx >= m_var.as_array->GetSize()) return AS_TYPE_INVALID; else return m_var.as_array->Get(idx).type; }
+    
+    uAnyType Get() { return m_var; }
+    uAnyType Get(int idx) { assert(idx > 0 && idx < m_var.as_array->GetSize()); return m_var.as_array->Get(idx).value; }
+    bool Set(ASType_t type, uAnyType value) { return false; }
+    bool Set(int idx, ASType_t type, uAnyType value);
+  };
+  
+  class cObjectIndexRef : public cObjectRef
+  {
+  private:
+    cObjectRef* m_obj;
+    int m_idx;
+    
+  public:
+    cObjectIndexRef(cObjectRef* obj, int idx) : m_obj(obj), m_idx(idx) { ; }
+    ~cObjectIndexRef() { delete m_obj; }
+    
+    bool IsWritable() { return m_obj->IsWritable(); }
+    ASType_t GetType() { return m_obj->GetType(m_idx); }
+    ASType_t GetType(int idx);
+    
+    uAnyType Get() { return m_obj->Get(m_idx); }
+    uAnyType Get(int idx);
+    bool Set(ASType_t type, uAnyType value) { return m_obj->Set(m_idx, type, value); }
+    bool Set(int idx, ASType_t type, uAnyType value);
+  };
 };
 
 




More information about the Avida-cvs mailing list