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

brysonda at myxo.css.msu.edu brysonda at myxo.css.msu.edu
Sun Mar 23 10:49:07 PDT 2008


Author: brysonda
Date: 2008-03-23 13:49:07 -0400 (Sun, 23 Mar 2008)
New Revision: 2490

Modified:
   development/source/script/AvidaScript.h
   development/source/script/cDirectInterpretASTVisitor.cc
   development/source/script/cDirectInterpretASTVisitor.h
   development/source/script/cSemanticASTVisitor.cc
Log:
AS:
Implement interpreter support for the matrix type.
Basic index operations on matrices.
Fix nested array indexing.

Modified: development/source/script/AvidaScript.h
===================================================================
--- development/source/script/AvidaScript.h	2008-03-23 17:00:29 UTC (rev 2489)
+++ development/source/script/AvidaScript.h	2008-03-23 17:49:07 UTC (rev 2490)
@@ -155,6 +155,7 @@
 } ASSemanticError_t;
 
 typedef enum eASDirectInterpretErrors {
+  AS_DIRECT_INTERPRET_ERR_CANNOT_RESIZE_MATRIX_ROW,
   AS_DIRECT_INTERPRET_ERR_DIVISION_BY_ZERO,
   AS_DIRECT_INTERPRET_ERR_INDEX_OUT_OF_BOUNDS,
   AS_DIRECT_INTERPRET_ERR_INDEX_ERROR,

Modified: development/source/script/cDirectInterpretASTVisitor.cc
===================================================================
--- development/source/script/cDirectInterpretASTVisitor.cc	2008-03-23 17:00:29 UTC (rev 2489)
+++ development/source/script/cDirectInterpretASTVisitor.cc	2008-03-23 17:49:07 UTC (rev 2490)
@@ -81,7 +81,7 @@
       case TYPE(DICT):        m_call_stack[i].value.as_dict->RemoveReference(); break;
       case TYPE(INT):         break;
       case TYPE(FLOAT):       break;
-      case TYPE(MATRIX):      break; // @TODO - cleanup scope
+      case TYPE(MATRIX):      m_call_stack[i].value.as_matrix->RemoveReference(); break;
       case TYPE(OBJECT_REF):  delete m_call_stack[i].value.as_ref; break;
       case TYPE(STRING):      delete m_call_stack[i].value.as_string; break;
       default: break;
@@ -133,8 +133,11 @@
       break;
       
       
-    case TYPE(MATRIX):      INTERPRET_ERROR(INTERNAL); // @TODO - assignment
-
+    case TYPE(MATRIX):
+      m_call_stack[sp + var_id].value.as_matrix->RemoveReference();
+      m_call_stack[sp + var_id].value.as_matrix = asMatrix(m_rtype, m_rvalue, node);
+      break;
+      
     case TYPE(STRING):
       delete m_call_stack[sp + var_id].value.as_string;
       m_call_stack[sp + var_id].value.as_string = asString(m_rtype, m_rvalue, node);
@@ -224,7 +227,10 @@
         m_call_stack[var_idx].type = val.type;
         break;
         
-      case TYPE(MATRIX):      INTERPRET_ERROR(INTERNAL); // @TODO - foreach assignment
+      case TYPE(MATRIX):
+        m_call_stack[var_idx].value.as_matrix->RemoveReference();
+        m_call_stack[var_idx].value.as_matrix = asMatrix(val.type, val.value, node);
+        break;
         
       case TYPE(STRING):
         delete m_call_stack[var_idx].value.as_string;
@@ -299,7 +305,7 @@
       case TYPE(FLOAT):       m_call_stack[m_sp + var_id].value.as_float = asFloat(m_rtype, m_rvalue, node); break;
       case TYPE(INT):         m_call_stack[m_sp + var_id].value.as_int = asInt(m_rtype, m_rvalue, node); break;
       case TYPE(OBJECT_REF):  INTERPRET_ERROR(INTERNAL); // @TODO - var def assignment
-      case TYPE(MATRIX):      INTERPRET_ERROR(INTERNAL); // @TODO - var def assignment
+      case TYPE(MATRIX):      m_call_stack[m_sp + var_id].value.as_matrix = asMatrix(m_rtype, m_rvalue, node); break;
       case TYPE(STRING):
         delete m_call_stack[m_sp + var_id].value.as_string;
         m_call_stack[m_sp + var_id].value.as_string = asString(m_rtype, m_rvalue, node);
@@ -321,8 +327,16 @@
       cLocalArray* arr = new cLocalArray();
       arr->Resize(asInt(m_rtype, m_rvalue, node));
       m_call_stack[m_sp + node.GetVarID()].value.as_array = arr;
-    } else if (node.GetType() == TYPE(MATRIX)) { // @TODO - variable def dimensions
+    } else if (node.GetType() == TYPE(MATRIX)) {
+      tListIterator<cASTNode> it = node.GetDimensions()->Iterator();
+      it.Next()->Accept(*this);
+      int sz_x = asInt(m_rtype, m_rvalue, node);
+      it.Next()->Accept(*this);
+      int sz_y = asInt(m_rtype, m_rvalue, node);
       
+      cLocalMatrix* mat = new cLocalMatrix();
+      mat->Resize(sz_x, sz_y);
+      m_call_stack[m_sp + node.GetVarID()].value.as_matrix = mat;      
     } else {
       INTERPRET_ERROR(INTERNAL);
     }
@@ -726,6 +740,8 @@
               const sAggregateValue val = arr->Get(idx);
               m_rtype = val.type;
               m_rvalue = val.value;
+              
+              arr->RemoveReference();
             }
             break;
             
@@ -744,22 +760,36 @@
 
               m_rtype = val.type;
               m_rvalue = val.value;
+              
+              dict->RemoveReference();
             }
             break;
             
-          case TYPE(MATRIX): // @TODO - indexing 
-            INTERPRET_ERROR(INTERNAL);
+          case TYPE(MATRIX):
+            {
+              cLocalMatrix* mat = lval.as_matrix;
+              int idx = asInt(rtype, rval, node);
+              
+              if (idx < 0 || idx >= mat->GetNumRows()) INTERPRET_ERROR(INDEX_OUT_OF_BOUNDS);
+              
+              m_rtype = TYPE(ARRAY);
+              m_rvalue.as_array = mat->GetRow(idx);
+              
+              mat->RemoveReference();
+            }
+            break;
             
           case TYPE(STRING):
-          {
-            cString* str = lval.as_string;
-            int idx = asInt(rtype, rval, node);
-            if (idx < 0 || idx >= str->GetSize()) INTERPRET_ERROR(INDEX_OUT_OF_BOUNDS);
+            {
+              cString* str = lval.as_string;
+              int idx = asInt(rtype, rval, node);
+              if (idx < 0 || idx >= str->GetSize()) INTERPRET_ERROR(INDEX_OUT_OF_BOUNDS);
 
-            m_rtype = TYPE(CHAR);
-            m_rvalue.as_char = (*str)[idx];
-            delete str;
-          }
+              m_rtype = TYPE(CHAR);
+              m_rvalue.as_char = (*str)[idx];
+              delete str;
+            }
+            break;
             
           default:
             INTERPRET_ERROR(TYPE_CAST, mapType(ltype.type), mapType(TYPE(ARRAY)));
@@ -946,8 +976,9 @@
       if (m_rtype.type == TYPE(DICT)) {
         m_rvalue.as_dict->Clear();
         m_rvalue.as_dict->RemoveReference();
-      } else if (m_rtype.type == TYPE(MATRIX)) { // @TODO - builtin clear
-        INTERPRET_ERROR(INTERNAL);
+      } else if (m_rtype.type == TYPE(MATRIX)) {
+        m_rvalue.as_matrix->Resize(0, 0);
+        m_rvalue.as_matrix->RemoveReference();
       } else if (m_rtype.type == TYPE(ARRAY)) {
         m_rvalue.as_array->Resize(0);
         m_rvalue.as_array->RemoveReference();
@@ -998,7 +1029,7 @@
       }
       break;
       
-    case AS_BUILTIN_VALUES: // @TODO
+    case AS_BUILTIN_VALUES:
       trgt->Accept(*this);
       if (m_rtype.type == TYPE(DICT)) {
         cLocalArray* arr = new cLocalArray();
@@ -1063,11 +1094,31 @@
       
     case AS_BUILTIN_RESIZE:
       trgt->Accept(*this);
-      if (m_rtype.type == TYPE(MATRIX)) { // @TODO - builtin resize
-        INTERPRET_ERROR(INTERNAL);
+      if (m_rtype.type == TYPE(MATRIX)) {
+        cLocalMatrix* mat = m_rvalue.as_matrix;
+        
+        if (args->GetSize() != 2) INTERPRET_ERROR(INVALID_ARRAY_SIZE);
+        
+        if (!mat->IsShared()) {
+          mat->RemoveReference();
+          break;
+        }
+        
+        tListIterator<cASTNode> it = args->Iterator();
+        it.Next()->Accept(*this);
+        int sz_x = asInt(m_rtype, m_rvalue, node);
+        it.Next()->Accept(*this);
+        int sz_y = asInt(m_rtype, m_rvalue, node);
+        
+        mat->Resize(sz_x, sz_y);
+        mat->RemoveReference();
       } else if (m_rtype.type == TYPE(ARRAY)) {
         cLocalArray* arr = m_rvalue.as_array;
+        
+        if (!arr->IsResizable()) INTERPRET_ERROR(CANNOT_RESIZE_MATRIX_ROW);
 
+        if (args->GetSize() != 1) INTERPRET_ERROR(INVALID_ARRAY_SIZE);
+        
         if (!arr->IsShared()) {
           arr->RemoveReference();
           break;
@@ -1196,7 +1247,7 @@
         case TYPE(FLOAT):       m_call_stack[sp + var_id].value.as_float = asFloat(m_rtype, m_rvalue, node); break;
         case TYPE(INT):         m_call_stack[sp + var_id].value.as_int = asInt(m_rtype, m_rvalue, node); break;
         case TYPE(OBJECT_REF):  INTERPRET_ERROR(INTERNAL); // @TODO - func call arg assignment
-        case TYPE(MATRIX):      INTERPRET_ERROR(INTERNAL); // @TODO - func call arg assignment
+        case TYPE(MATRIX):      m_call_stack[sp + var_id].value.as_matrix = asMatrix(m_rtype, m_rvalue, node); break;
         case TYPE(STRING):
           {
             m_call_stack[sp + var_id].value.as_string = asString(m_rtype, m_rvalue, node);
@@ -1228,7 +1279,7 @@
       case TYPE(FLOAT):       m_rvalue.as_float = asFloat(m_rtype, m_rvalue, node); break;
       case TYPE(INT):         m_rvalue.as_int = asInt(m_rtype, m_rvalue, node); break;
       case TYPE(OBJECT_REF):  INTERPRET_ERROR(INTERNAL); // @TODO - return
-      case TYPE(MATRIX):      INTERPRET_ERROR(INTERNAL); // @TODO - return
+      case TYPE(MATRIX):      m_rvalue.as_matrix = asMatrix(m_rtype, m_rvalue, node); break;
       case TYPE(STRING):      m_rvalue.as_string = asString(m_rtype, m_rvalue, node); break;
       case TYPE(VAR):         break;
       case TYPE(VOID):        break;
@@ -1246,7 +1297,7 @@
       switch (type) {
         case TYPE(ARRAY):       m_call_stack[sp + i].value.as_array->RemoveReference(); break;
         case TYPE(DICT):        m_call_stack[sp + i].value.as_dict->RemoveReference(); break;
-        case TYPE(MATRIX):      break; // @TODO - cleanup scope
+        case TYPE(MATRIX):      m_call_stack[sp + i].value.as_matrix->RemoveReference(); break;
         case TYPE(OBJECT_REF):  delete m_call_stack[sp + i].value.as_ref; break;
         case TYPE(STRING):      delete m_call_stack[sp + i].value.as_string; break;
         default: break;
@@ -1297,7 +1348,37 @@
   cASTArgumentList* vals = node.GetValues();
   
   if (node.IsMatrix()) {
-    // @TODO - literal matrix
+    cLocalMatrix* mat = new cLocalMatrix();
+    
+    int sz_y = 1;
+    bool first = true;
+    
+    tListIterator<cASTNode> it = vals->Iterator();
+    cASTNode* val = NULL;
+    int i = 0;
+    while ((val = it.Next())) {
+      val->Accept(*this);
+      if (first && m_rtype.type == TYPE(ARRAY)) {
+        sz_y = m_rvalue.as_array->GetSize();
+      }
+      
+      mat->Resize(i + 1, sz_y);
+      
+      if (sz_y > 1) {
+        if (m_rtype.type != TYPE(ARRAY)) INTERPRET_ERROR(INVALID_ARRAY_SIZE);
+        mat->Set(i, m_rvalue.as_array);
+      } else {
+        mat->GetRow(i)->Set(0, m_rtype, m_rvalue);
+      }
+
+      sAggregateValue val(m_rtype, m_rvalue);
+      val.Cleanup();
+      first = false;
+      i++;
+    }
+    
+    m_rvalue.as_matrix = mat;
+    m_rtype = TYPE(MATRIX);
   } else {
     cLocalArray* arr = new cLocalArray(vals->GetSize());
     
@@ -1357,7 +1438,7 @@
       case TYPE(ARRAY):       m_rvalue.as_ref = new cArrayVarRef(m_call_stack[sp + var_id].value); break;
       case TYPE(DICT):        m_rvalue.as_ref = new cDictVarRef(m_call_stack[sp + var_id].value); break;
       case TYPE(OBJECT_REF):  INTERPRET_ERROR(INTERNAL); // @TODO - var ref object assignment
-      case TYPE(MATRIX):      INTERPRET_ERROR(INTERNAL); // @TODO - var ref object assignment
+      case TYPE(MATRIX):      m_rvalue.as_ref = new cMatrixVarRef(m_call_stack[sp + var_id].value); break;
       case TYPE(STRING):      INTERPRET_ERROR(INTERNAL); // @TODO - var ref object assignment
         
       default:
@@ -1377,7 +1458,7 @@
       case TYPE(DICT):        m_rvalue.as_dict = m_call_stack[sp + var_id].value.as_dict->GetReference(); break;
       case TYPE(FLOAT):       m_rvalue.as_float = m_call_stack[sp + var_id].value.as_float; break;
       case TYPE(INT):         m_rvalue.as_int = m_call_stack[sp + var_id].value.as_int; break;
-      case TYPE(MATRIX):      INTERPRET_ERROR(INTERNAL); // @TODO - var ref assignment
+      case TYPE(MATRIX):      m_rvalue.as_matrix = m_call_stack[sp + var_id].value.as_matrix->GetReference(); break;
       case TYPE(STRING):      m_rvalue.as_string = new cString(*m_call_stack[sp + var_id].value.as_string); break;
 
       
@@ -1428,10 +1509,12 @@
         m_call_stack[var_idx].value.as_dict->RemoveReference();
         m_call_stack[var_idx].value.as_dict = asDict(val.type, val.value, node);
         break;
+                
+      case TYPE(MATRIX):
+        m_call_stack[var_idx].value.as_matrix->RemoveReference();
+        m_call_stack[var_idx].value.as_matrix = asMatrix(val.type, val.value, node);
+        break;
         
-        
-      case TYPE(MATRIX):      INTERPRET_ERROR(INTERNAL); // @TODO - assignment
-        
       case TYPE(STRING):
         delete m_call_stack[var_idx].value.as_string;
         m_call_stack[var_idx].value.as_string = asString(val.type, val.value, node);
@@ -1466,9 +1549,19 @@
     case TYPE(ARRAY):
       return value.as_array;
 
-    case TYPE(MATRIX): // @TODO - asArray 
-      INTERPRET_ERROR(INTERNAL);
-    
+    case TYPE(MATRIX):
+      {
+        cLocalMatrix* mat = value.as_matrix;
+        cLocalArray* arr = new cLocalArray(mat->GetNumRows());
+        uAnyType val;
+        for (int i = 0; i < mat->GetNumRows(); i++) {
+          val.as_array = new cLocalArray(mat->GetRow(i));
+          arr->Set(i, TYPE(ARRAY), val);
+        }
+        mat->RemoveReference();
+        return arr;
+      }
+      
     case TYPE(STRING):
       {
         cString* str = value.as_string;
@@ -1506,8 +1599,12 @@
       return rval;
     }
       
-    case TYPE(MATRIX): // @TODO - implement asBool
-      INTERPRET_ERROR(INTERNAL);
+    case TYPE(MATRIX):
+      {
+        bool rval = (value.as_matrix->GetNumRows() && value.as_matrix->GetNumCols());
+        value.as_matrix->RemoveReference();
+        return rval;
+      }
       
     case TYPE(BOOL):
       return value.as_bool;
@@ -1554,14 +1651,28 @@
 }
 
 
-cDirectInterpretASTVisitor::cLocalDict* cDirectInterpretASTVisitor::asDict(const sASTypeInfo& type, uAnyType value, cASTNode& node)
+cDirectInterpretASTVisitor::cLocalDict* cDirectInterpretASTVisitor::asDict(const sASTypeInfo& type, uAnyType value,
+                                                                           cASTNode& node)
 {
   switch (type.type) {
     case TYPE(DICT):
       return value.as_dict;
       
-    case TYPE(ARRAY): // @TODO - asDict
-      INTERPRET_ERROR(INTERNAL);
+    case TYPE(ARRAY):
+      {
+        cLocalDict* dict = new cLocalDict();
+        cLocalArray* arr = value.as_array;
+        
+        sAggregateValue idx;
+        idx.type.type = TYPE(INT);
+        
+        for (idx.value.as_int = 0; idx.value.as_int < arr->GetSize(); idx.value.as_int++) {
+          dict->Set(idx, arr->Get(idx.value.as_int));
+        }
+        
+        arr->RemoveReference();
+        return dict;
+      }
       
     default:
       INTERPRET_ERROR(TYPE_CAST, mapType(type), mapType(TYPE(CHAR)));
@@ -1615,13 +1726,39 @@
       }
       
     default:
-      INTERPRET_ERROR(TYPE_CAST, mapType(type), mapType(TYPE(INT)));
+      INTERPRET_ERROR(TYPE_CAST, mapType(type), mapType(TYPE(FLOAT)));
   }
   
   return 0.0;
 }
 
 
+cDirectInterpretASTVisitor::cLocalMatrix* cDirectInterpretASTVisitor::asMatrix(const sASTypeInfo& type, uAnyType value,
+                                                                               cASTNode& node)
+{
+  switch (type.type) {
+    case TYPE(BOOL):
+    case TYPE(CHAR):
+    case TYPE(FLOAT):
+    case TYPE(INT):
+      {
+        sAggregateValue val(type, value);
+        cLocalMatrix* mat = new cLocalMatrix();
+        mat->Resize(1, 1);
+        mat->GetRow(0)->Set(0, val);
+      }
+      
+    case TYPE(MATRIX):
+      return value.as_matrix;
+     
+    default:
+      INTERPRET_ERROR(TYPE_CAST, mapType(type), mapType(TYPE(MATRIX)));
+  }
+  
+  return NULL;
+}
+
+
 cString* cDirectInterpretASTVisitor::asString(const sASTypeInfo& type, uAnyType value, cASTNode& node)
 {
   switch (type.type) {
@@ -1645,9 +1782,9 @@
       return str;
     }
       
-    case TYPE(MATRIX): // @TODO - as string
+    case TYPE(MATRIX):
       {
-        cString* str = new cString(cStringUtil::Stringf("< matrix(,) >"));
+        cString* str = new cString(cStringUtil::Stringf("< matrix(%d, %d) >", value.as_matrix->GetNumRows(), value.as_matrix->GetNumCols()));
         return str;
       }
 
@@ -1658,7 +1795,7 @@
     }
       
     default:
-      INTERPRET_ERROR(TYPE_CAST, mapType(type), mapType(TYPE(INT)));
+      INTERPRET_ERROR(TYPE_CAST, mapType(type), mapType(TYPE(STRING)));
   }
   
   return NULL;
@@ -1741,7 +1878,7 @@
   switch (type.type) {
     case TYPE(ARRAY):       value.as_array->RemoveReference(); break;
     case TYPE(DICT):        value.as_dict->RemoveReference(); break;
-    case TYPE(MATRIX):      break; // @TODO - aggregate value cleanup
+    case TYPE(MATRIX):      value.as_matrix->RemoveReference(); break;
     case TYPE(OBJECT_REF):  delete value.as_ref; break;
     case TYPE(STRING):      delete value.as_string; break;
     default: break;
@@ -1759,8 +1896,8 @@
       case TYPE(STRING):  return *value.as_string == *lval.value.as_string;
       case TYPE(ARRAY):   return value.as_array == lval.value.as_array;
       case TYPE(DICT):    return value.as_dict == lval.value.as_dict;
+      case TYPE(MATRIX):  return value.as_matrix == lval.value.as_matrix;
         
-      case TYPE(MATRIX): // @TODO - aggregate value compare
       case TYPE(OBJECT_REF): // @TODO - aggregate value compare
         return value.as_void == lval.value.as_void;
       
@@ -1798,7 +1935,8 @@
       m_storage[i].value.as_dict = value.as_dict->GetReference();
       break;
       
-    case TYPE(MATRIX): // @TODO - array set
+    case TYPE(MATRIX):
+      m_storage[i].value.as_matrix = value.as_matrix->GetReference();
       break;
       
     default: break;
@@ -1818,8 +1956,7 @@
       case TYPE(STRING):  m_storage[i + offset].value.as_string = new cString(*in_storage[i].value.as_string); break;
       case TYPE(ARRAY):   m_storage[i + offset].value.as_array = in_storage[i].value.as_array->GetReference(); break;
       case TYPE(DICT):    m_storage[i + offset].value.as_dict = in_storage[i].value.as_dict->GetReference(); break;
-      case TYPE(MATRIX):  // @TODO - array copy
-        break;
+      case TYPE(MATRIX):  m_storage[i + offset].value.as_matrix = in_storage[i].value.as_matrix->GetReference(); break;
         
       default: break;
     }
@@ -1843,6 +1980,12 @@
   }  
 }
 
+void cDirectInterpretASTVisitor::cLocalArray::SetWithArray(cLocalArray* arr)
+{
+  Resize(arr->GetSize());
+  
+  for (int i = 0; i < arr->GetSize(); i++) Set(i, arr->Get(i));
+}
 
 void cDirectInterpretASTVisitor::cLocalArray::SetWithKeys(cLocalDict* dict)
 {
@@ -1855,8 +1998,7 @@
       case TYPE(STRING):  m_storage[i].value.as_string = new cString(*m_storage[i].value.as_string); break;
       case TYPE(ARRAY):   m_storage[i].value.as_array->GetReference(); break;
       case TYPE(DICT):    m_storage[i].value.as_dict->GetReference(); break;
-      case TYPE(MATRIX):  // @TODO - array copy
-        break;
+      case TYPE(MATRIX):  m_storage[i].value.as_matrix->GetReference(); break;
         
       default: break;
     }
@@ -1875,8 +2017,7 @@
       case TYPE(STRING):  m_storage[i].value.as_string = new cString(*m_storage[i].value.as_string); break;
       case TYPE(ARRAY):   m_storage[i].value.as_array->GetReference(); break;
       case TYPE(DICT):    m_storage[i].value.as_dict->GetReference(); break;
-      case TYPE(MATRIX):  // @TODO - array copy
-        break;
+      case TYPE(MATRIX):  m_storage[i].value.as_matrix->GetReference(); break;
         
       default: break;
     }
@@ -1893,6 +2034,23 @@
 }
 
 
+void cDirectInterpretASTVisitor::cLocalMatrix::Resize(int sz_x, int sz_y)
+{
+  int o_sz = m_storage.GetSize();
+  m_storage.Resize(sz_x);
+  
+  // Resize the columns
+  for (int i = (m_sz_y == sz_y) ? o_sz : 0; i < sz_x; i++) {
+    m_storage[i].SetNonResizable();
+    m_storage[i].Resize(sz_y);
+  }
+
+  m_sz_y = sz_y;
+}
+
+
+
+
 void cDirectInterpretASTVisitor::cLocalDict::Set(const sAggregateValue& idx, const sAggregateValue& val)
 {
   sAggregateValue o_val;
@@ -1969,7 +2127,7 @@
     case TYPE(STRING):      idxi = idx.value.as_string->AsInt(); delete idx.value.as_string; break;
     case TYPE(ARRAY):       idx.value.as_array->RemoveReference(); break;
     case TYPE(DICT):        idx.value.as_dict->RemoveReference(); break;
-    case TYPE(MATRIX):      // @TODO - array ref get
+    case TYPE(MATRIX):      idx.value.as_matrix->RemoveReference(); break;
     case TYPE(OBJECT_REF):  delete idx.value.as_ref; break;
     default: break;
   } 
@@ -1982,8 +2140,58 @@
 }
 
 
+bool cDirectInterpretASTVisitor::cMatrixVarRef::Get(const sAggregateValue& idx, sAggregateValue& val)
+{
+  int idxi = -1;
+  switch (idx.type.type) {
+    case TYPE(BOOL):        idxi = (idx.value.as_bool) ? 1 : 0; break;
+    case TYPE(CHAR):        idxi = (int)idx.value.as_char; break;
+    case TYPE(INT):         idxi = idx.value.as_int; break;
+    case TYPE(FLOAT):       idxi = (int)idx.value.as_float; break;
+    case TYPE(STRING):      idxi = idx.value.as_string->AsInt(); break;
+    default: break;
+  } 
+  
+  if (idxi < 0 || idxi >= m_var.as_matrix->GetNumRows()) return false;
+  
+  val.value.as_array = m_var.as_matrix->GetRow(idxi);
+  val.type = TYPE(ARRAY);
+  return true;
+}
 
+bool cDirectInterpretASTVisitor::cMatrixVarRef::Set(sAggregateValue& idx, sAggregateValue& val)
+{
+  int idxi = -1;
+  switch (idx.type.type) {
+    case TYPE(BOOL):        idxi = (idx.value.as_bool) ? 1 : 0; break;
+    case TYPE(CHAR):        idxi = (int)idx.value.as_char; break;
+    case TYPE(INT):         idxi = idx.value.as_int; break;
+    case TYPE(FLOAT):       idxi = (int)idx.value.as_float; break;
+    case TYPE(STRING):      idxi = idx.value.as_string->AsInt(); delete idx.value.as_string; break;
+    case TYPE(ARRAY):       idx.value.as_array->RemoveReference(); break;
+    case TYPE(DICT):        idx.value.as_dict->RemoveReference(); break;
+    case TYPE(MATRIX):      idx.value.as_matrix->RemoveReference(); break;
+    case TYPE(OBJECT_REF):  delete idx.value.as_ref; break;
+    default: break;
+  } 
+  
+  if (idxi < 0 || idxi >= m_var.as_matrix->GetNumRows()) return false;
+  
+  if (m_var.as_matrix->GetNumCols() > 1) {
+    if (val.type.type != TYPE(ARRAY)) return false;
+    m_var.as_matrix->Set(idxi, val.value.as_array);
+  } else if (m_var.as_matrix->GetNumCols() == 0) {
+    m_var.as_matrix->GetRow(idxi)->Set(0, val);    
+  } else {
+    return false;
+  }
+  
+  return true;
+}
 
+
+
+
 bool cDirectInterpretASTVisitor::cDictVarRef::Get(const sAggregateValue& idx, sAggregateValue& val)
 {
   return m_var.as_dict->Get(idx, val);
@@ -2024,8 +2232,24 @@
     case TYPE(DICT):
       return o_val.value.as_dict->Get(idx, val);
       
-    case TYPE(MATRIX): // @TODO - object index ref get
-      break;
+    case TYPE(MATRIX):
+      {
+        cLocalMatrix* mat = o_val.value.as_matrix;
+        
+        int idxi = -1;
+        switch (idx.type.type) {
+          case TYPE(BOOL):        idxi = (idx.value.as_bool) ? 1 : 0; break;
+          case TYPE(CHAR):        idxi = (int)idx.value.as_char; break;
+          case TYPE(INT):         idxi = idx.value.as_int; break;
+          case TYPE(FLOAT):       idxi = (int)idx.value.as_float; break;
+          case TYPE(STRING):      idxi = idx.value.as_string->AsInt(); break;
+          default: break;
+        }      
+        if (idxi < 0 || idxi >= mat->GetNumRows()) return false;
+        val.value.as_array = mat->GetRow(idxi);
+        val.type = TYPE(ARRAY);
+        return true;
+      }
       
     default:
       break;
@@ -2040,7 +2264,7 @@
 {
   sAggregateValue o_val;
   
-  if (!m_obj->Get(m_idx)) {
+  if (!m_obj->Get(m_idx, o_val)) {
     idx.Cleanup();
     return false;
   }
@@ -2059,7 +2283,7 @@
           case TYPE(STRING):      idxi = idx.value.as_string->AsInt(); delete idx.value.as_string; break;
           case TYPE(ARRAY):       idx.value.as_array->RemoveReference(); break;
           case TYPE(DICT):        idx.value.as_dict->RemoveReference(); break;
-          case TYPE(MATRIX):      // @TODO - array ref get
+          case TYPE(MATRIX):      idx.value.as_matrix->RemoveReference(); break;
           case TYPE(OBJECT_REF):  delete idx.value.as_ref; break;
           default: break;
         }      
@@ -2073,8 +2297,35 @@
       o_val.value.as_dict->Set(idx, val);
       return true;
       
-    case TYPE(MATRIX): // @TODO - object index ref set
-      break;
+    case TYPE(MATRIX):
+      {
+        cLocalMatrix* mat = o_val.value.as_matrix;
+        
+        int idxi = -1;
+        switch (idx.type.type) {
+          case TYPE(BOOL):        idxi = (idx.value.as_bool) ? 1 : 0; break;
+          case TYPE(CHAR):        idxi = (int)idx.value.as_char; break;
+          case TYPE(INT):         idxi = idx.value.as_int; break;
+          case TYPE(FLOAT):       idxi = (int)idx.value.as_float; break;
+          case TYPE(STRING):      idxi = idx.value.as_string->AsInt(); delete idx.value.as_string; break;
+          case TYPE(ARRAY):       idx.value.as_array->RemoveReference(); break;
+          case TYPE(DICT):        idx.value.as_dict->RemoveReference(); break;
+          case TYPE(MATRIX):      idx.value.as_matrix->RemoveReference(); break;
+          case TYPE(OBJECT_REF):  delete idx.value.as_ref; break;
+          default: break;
+        }      
+        if (idxi < 0 || idxi >= mat->GetNumRows()) return false;
+        
+        if (mat->GetNumCols() > 1) {
+          if (val.type.type != TYPE(ARRAY)) return false;
+          mat->Set(idxi, val.value.as_array);
+        } else if (mat->GetNumCols() == 0) {
+          mat->GetRow(idxi)->Set(0, val);    
+        } else {
+          return false;
+        }
+      }
+      return true;
       
     default:
       break;
@@ -2100,6 +2351,9 @@
   va_list vargs;
   va_start(vargs, line);
   switch (err) {
+    case AS_DIRECT_INTERPRET_ERR_CANNOT_RESIZE_MATRIX_ROW:
+      std::cerr << "cannot directly resize matrix row" << ERR_ENDL;
+      break;
     case AS_DIRECT_INTERPRET_ERR_DIVISION_BY_ZERO:
       std::cerr << "division by zero" << ERR_ENDL;
       break;

Modified: development/source/script/cDirectInterpretASTVisitor.h
===================================================================
--- development/source/script/cDirectInterpretASTVisitor.h	2008-03-23 17:00:29 UTC (rev 2489)
+++ development/source/script/cDirectInterpretASTVisitor.h	2008-03-23 17:49:07 UTC (rev 2490)
@@ -28,6 +28,7 @@
 #include "cASTVisitor.h"
 
 #include "tHashTable.h"
+#include "tManagedPointerArray.h"
 #include "tSmartArray.h"
 
 class cSymbolTable;
@@ -130,6 +131,7 @@
   cLocalDict* asDict(const sASTypeInfo& type, uAnyType value, cASTNode& node);
   int asInt(const sASTypeInfo& type, uAnyType value, cASTNode& node);
   double asFloat(const sASTypeInfo& type, uAnyType value, cASTNode& node);
+  cLocalMatrix* asMatrix(const sASTypeInfo& type, uAnyType value, cASTNode& node);
   cString* asString(const sASTypeInfo& type, uAnyType value, cASTNode& node);
 
   ASType_t getRuntimeType(ASType_t ltype, ASType_t rtype, bool allow_str = false);
@@ -143,11 +145,12 @@
   private:
     tArray<sAggregateValue> m_storage;
     int m_ref_count;
+    bool m_resizable;
     
     
   public:
-    inline cLocalArray() : m_ref_count(1) { ; }
-    inline explicit cLocalArray(int sz) : m_storage(sz), m_ref_count(1) { ; }
+    inline cLocalArray() : m_ref_count(1), m_resizable(true) { ; }
+    inline explicit cLocalArray(int sz) : m_storage(sz), m_ref_count(1), m_resizable(true) { ; }
     inline explicit cLocalArray(cLocalArray* in_array); // Create a copy
     inline cLocalArray(cLocalArray* arr1, cLocalArray* arr2); // Concat two arrays
     ~cLocalArray();
@@ -157,12 +160,15 @@
     inline bool IsShared() const { return (m_ref_count > 1); }
     
     inline int GetSize() const { return m_storage.GetSize(); }
+    inline bool IsResizable() const { return m_resizable; }
+    inline void SetNonResizable() { m_resizable = false; }
     void Resize(int sz);
     
     inline const sAggregateValue& Get(int i) const { return m_storage[i]; }    
     void Set(int i, const sASTypeInfo& type, uAnyType value);
     inline void Set(int i, const sAggregateValue& val) { Set(i, val.type, val.value); }
     
+    void SetWithArray(cLocalArray* arr);    
     void SetWithKeys(cLocalDict* dict);
     void SetWithValues(cLocalDict* dict);
     
@@ -203,9 +209,30 @@
   
   class cLocalMatrix
   {
+  private:
+    tManagedPointerArray<cLocalArray> m_storage;
+    int m_sz_y;
+    int m_ref_count;
     
+    
+  public:
+    inline cLocalMatrix() : m_sz_y(0), m_ref_count(1) { ; }
+    explicit cLocalMatrix(cLocalMatrix* in_matrix); // Create a copy
+    ~cLocalMatrix() { ; }
+    
+    inline cLocalMatrix* GetReference() { m_ref_count++; return this; }
+    inline void RemoveReference() { m_ref_count--;  if (m_ref_count == 0) delete this; }
+    inline bool IsShared() const { return (m_ref_count > 1); }
+    
+    inline int GetNumRows() const { return m_storage.GetSize(); }
+    inline int GetNumCols() const { return m_sz_y; }
+    void Resize(int sz_x, int sz_y);
+    
+    inline cLocalArray* GetRow(int i) { return &m_storage[i]; }
+    void Set(int i, cLocalArray* arr) { m_storage[i].SetWithArray(arr); }
   };
   
+
   class cObjectRef
   {
   public:
@@ -236,6 +263,23 @@
     bool Set(sAggregateValue& idx, sAggregateValue& val);
   };
   
+  class cMatrixVarRef : public cObjectRef
+  {
+  private:
+    uAnyType& m_var;
+    
+  public:
+    cMatrixVarRef(uAnyType& var) : m_var(var) { ; }
+    ~cMatrixVarRef() { ; }
+    
+    bool IsWritable() { return true; }
+    
+    bool Get(sAggregateValue& val) { val.value = m_var; val.type = AS_TYPE_MATRIX; return true; }
+    bool Get(const sAggregateValue& idx, sAggregateValue& val);
+    bool Set(sAggregateValue& val) { return false; }
+    bool Set(sAggregateValue& idx, sAggregateValue& val);
+  };
+  
   class cDictVarRef : public cObjectRef
   {
   private:
@@ -288,13 +332,13 @@
 
 
 inline cDirectInterpretASTVisitor::cLocalArray::cLocalArray(cLocalArray* in_array)
-  : m_storage(in_array->m_storage.GetSize()), m_ref_count(1)
+  : m_storage(in_array->m_storage.GetSize()), m_ref_count(1), m_resizable(true)
 {
   copy(0, in_array->m_storage);
 }
 
 inline cDirectInterpretASTVisitor::cLocalArray::cLocalArray(cLocalArray* arr1, cLocalArray* arr2)
-  : m_storage(arr1->m_storage.GetSize() + arr2->m_storage.GetSize()), m_ref_count(1)
+  : m_storage(arr1->m_storage.GetSize() + arr2->m_storage.GetSize()), m_ref_count(1), m_resizable(true)
 {
   copy(0, arr1->m_storage);
   copy(arr1->m_storage.GetSize(), arr2->m_storage);

Modified: development/source/script/cSemanticASTVisitor.cc
===================================================================
--- development/source/script/cSemanticASTVisitor.cc	2008-03-23 17:00:29 UTC (rev 2489)
+++ development/source/script/cSemanticASTVisitor.cc	2008-03-23 17:49:07 UTC (rev 2490)
@@ -33,7 +33,7 @@
 
 
 #ifndef DEBUG_AS_SEMANTIC
-#define DEBUG_AS_SEMANTIC 0
+#define DEBUG_AS_SEMANTIC 1
 #endif
 
 #define SEMANTIC_ERROR(code, ...) reportError(AS_SEMANTIC_ERR_ ## code, node.GetFilePosition(),  __LINE__, ##__VA_ARGS__)
@@ -386,6 +386,9 @@
         case TYPE(RUNTIME):
           break;
           
+        case TYPE(OBJECT_REF):
+          if (m_obj_assign) break;
+          
         default:
           SEMANTIC_ERROR(UNDEFINED_TYPE_OP, mapToken(node.GetOperator()), mapType(node.GetLeft()->GetType()));
           break;




More information about the Avida-cvs mailing list