[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