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

brysonda at myxo.css.msu.edu brysonda at myxo.css.msu.edu
Wed Feb 27 19:27:40 PST 2008


Author: brysonda
Date: 2008-02-27 22:27:40 -0500 (Wed, 27 Feb 2008)
New Revision: 2388

Modified:
   development/source/script/ASTree.h
   development/source/script/AvidaScript.h
   development/source/script/cDumpASTVisitor.cc
   development/source/script/cSemanticASTVisitor.cc
   development/source/script/cSemanticASTVisitor.h
Log:
AS array unpack and variable reference semantics.

Modified: development/source/script/ASTree.h
===================================================================
--- development/source/script/ASTree.h	2008-02-28 02:28:36 UTC (rev 2387)
+++ development/source/script/ASTree.h	2008-02-28 03:27:40 UTC (rev 2388)
@@ -125,9 +125,12 @@
 private:
   cString m_var;
   cASTNode* m_expr;
+  int m_id;
+  bool m_global;
   
 public:
-  cASTAssignment(const cASFilePosition& fp, const cString& var) : cASTNode(fp), m_var(var), m_expr(NULL) { ; }
+  cASTAssignment(const cASFilePosition& fp, const cString& var)
+    : cASTNode(fp), m_var(var), m_expr(NULL), m_id(-1), m_global(false) { ; }
   ~cASTAssignment() { delete m_expr; }
   
   inline const cString& GetVariable() { return m_var; }
@@ -135,6 +138,10 @@
   inline void SetExpression(cASTNode* expr) { delete m_expr; m_expr = expr; }
   inline cASTNode* GetExpression() { return m_expr; }
   
+  inline int GetVarID() const { return m_id; }
+  inline bool IsVarGlobal() const { return m_global; }
+  inline void SetVar(int in_id, bool global) { m_id = in_id; m_global = global; }
+  
   void Accept(cASTVisitor& visitor);
 };
 
@@ -474,16 +481,22 @@
 private:
   cString m_name;
   ASType_t m_type;
+  int m_id;
+  bool m_global;
   
 public:
   cASTVariableReference(const cASFilePosition& fp, const cString& name)
-    : cASTNode(fp), m_name(name), m_type(AS_TYPE_INVALID) { ; }
+    : cASTNode(fp), m_name(name), m_type(AS_TYPE_INVALID), m_id(-1), m_global(false) { ; }
   
   inline const cString& GetName() { return m_name; }
   
   ASType_t GetType() const { return m_type; }
   inline void SetType(ASType_t type) { m_type = type; }
   
+  inline int GetVarID() const { return m_id; }
+  inline bool IsVarGlobal() const { return m_global; }
+  inline void SetVar(int in_id, bool global) { m_id = in_id; m_global = global; }
+  
   void Accept(cASTVisitor& visitor);
 };
 
@@ -491,7 +504,19 @@
 class cASTUnpackTarget : public cASTNode
 {
 private:
-  tManagedPointerArray<cString> m_nodes;
+  struct sUnpackNode {
+    cString name;
+    int var_id;
+    bool global;
+    ASType_t type;
+    
+    inline sUnpackNode() : name(""), var_id(-1), global(false), type(AS_TYPE_INVALID) { ; }
+    inline sUnpackNode(const cString& in_name) : name(in_name), var_id(-1), global(false), type(AS_TYPE_INVALID) { ; }
+    inline sUnpackNode(const sUnpackNode& un) : name(un.name), var_id(un.var_id), global(un.global), type(un.type) { ; }
+    
+    inline void SetVar(int in_vi, bool in_g, ASType_t in_t) { var_id = in_vi; global = in_g; type = in_t; }
+  };
+  tManagedPointerArray<sUnpackNode> m_nodes;
   bool m_last_wild;
   bool m_last_named;
   cASTNode* m_expr;
@@ -500,9 +525,13 @@
   cASTUnpackTarget(const cASFilePosition& fp) : cASTNode(fp), m_last_wild(false), m_last_named(false), m_expr(NULL) { ; }
   ~cASTUnpackTarget() { delete m_expr; }
   
-  inline void AddVar(const cString& name) { m_nodes.Push(name); }
+  inline void AddVar(const cString& name) { m_nodes.Push(sUnpackNode(name)); }
   inline int GetSize() const { return m_nodes.GetSize(); }
-  inline const cString& GetVar(int idx) const { return m_nodes[idx]; }
+  inline const cString& GetVarName(int idx) const { return m_nodes[idx].name; }
+  inline int GetVarID(int idx) const { return m_nodes[idx].var_id; }
+  inline bool IsVarGlobal(int idx) const { return m_nodes[idx].global; }
+  inline ASType_t GetVarType(int idx) const { return m_nodes[idx].type; }
+  inline void SetVar(int idx, int var_id, bool global, ASType_t type) { m_nodes[idx].SetVar(var_id, global, type); }
   
   inline bool IsLastNamed() const { return m_last_named; }
   inline bool IsLastWild() const { return m_last_wild; }

Modified: development/source/script/AvidaScript.h
===================================================================
--- development/source/script/AvidaScript.h	2008-02-28 02:28:36 UTC (rev 2387)
+++ development/source/script/AvidaScript.h	2008-02-28 03:27:40 UTC (rev 2388)
@@ -117,6 +117,7 @@
   
   AS_SEMANTIC_ERR_CANNOT_CAST,
   AS_SEMANTIC_ERR_UNDEFINED_TYPE_OP,
+  AS_SEMANTIC_ERR_UNPACK_WILD_NONARRAY,
   AS_SEMANTIC_ERR_VARIABLE_UNDEFINED,
   AS_SEMANTIC_ERR_VARIABLE_REDEFINITION,
   AS_SEMANTIC_ERR_INTERNAL,

Modified: development/source/script/cDumpASTVisitor.cc
===================================================================
--- development/source/script/cDumpASTVisitor.cc	2008-02-28 02:28:36 UTC (rev 2387)
+++ development/source/script/cDumpASTVisitor.cc	2008-02-28 03:27:40 UTC (rev 2388)
@@ -352,7 +352,7 @@
   for (int i = 0; i < node.GetSize(); i++) {
     cout << endl;
     indent();
-    cout << node.GetVar(i);
+    cout << node.GetVarName(i);
   }
   if (node.IsLastNamed()) {
     cout << "..";

Modified: development/source/script/cSemanticASTVisitor.cc
===================================================================
--- development/source/script/cSemanticASTVisitor.cc	2008-02-28 02:28:36 UTC (rev 2387)
+++ development/source/script/cSemanticASTVisitor.cc	2008-02-28 03:27:40 UTC (rev 2388)
@@ -78,10 +78,9 @@
 {
   node.GetExpression()->Accept(*this);
   int var_id = -1;
-  if (m_cur_symtbl->LookupVariable(node.GetVariable(), var_id)) {
-    checkCast(node.GetExpression()->GetType(), m_cur_symtbl->GetVariableType(var_id));
-  } else if (m_cur_symtbl != m_global_symtbl && m_global_symtbl->LookupVariable(node.GetVariable(), var_id)) {
-    checkCast(node.GetExpression()->GetType(), m_global_symtbl->GetVariableType(var_id));    
+  bool global = false;
+  if (lookupVariable(node.GetVariable(), var_id, global)) {
+    checkCast(node.GetExpression()->GetType(), (global ? m_global_symtbl : m_cur_symtbl)->GetVariableType(var_id));
   } else {
     SEMANTIC_ERROR(VARIABLE_UNDEFINED, (const char*)node.GetVariable());
   }
@@ -289,6 +288,7 @@
 
 void cSemanticASTVisitor::visitLiteral(cASTLiteral& node)
 {
+  // Nothing to do here...   type already determined by the parser
 }
 
 
@@ -299,11 +299,41 @@
 
 void cSemanticASTVisitor::visitVariableReference(cASTVariableReference& node)
 {
+  int var_id = -1;
+  bool global = false;
+  if (lookupVariable(node.GetName(), var_id, global)) {
+    node.SetVar(var_id, global);
+    node.SetType(m_cur_symtbl->GetVariableType(var_id));
+  } else {
+    SEMANTIC_ERROR(VARIABLE_UNDEFINED, (const char*)node.GetName());
+  }
 }
 
 
 void cSemanticASTVisitor::visitUnpackTarget(cASTUnpackTarget& node)
 {
+  node.GetExpression()->Accept(*this);
+  
+  // Make sure that the expression can be used as an array
+  checkCast(node.GetExpression()->GetType(), TYPE(ARRAY));
+  
+  // Check each named variable and determine if it exists
+  for (int var = 0; var < node.GetSize(); var++) {
+    int var_id = -1;
+    bool global = false;
+    if (lookupVariable(node.GetVarName(var), var_id, global)) {
+      node.SetVar(var, var_id, global, (global ? m_global_symtbl : m_cur_symtbl)->GetVariableType(var_id));
+    } else {
+      SEMANTIC_ERROR(VARIABLE_UNDEFINED, (const char*)node.GetVarName(var));
+    }
+  }
+  
+  // Check if last named is of array type
+  const int last = node.GetSize() - 1;
+  if (node.IsLastNamed() && node.GetVarID(last) != -1 && node.GetVarType(last) != TYPE(ARRAY))
+    SEMANTIC_ERROR(UNPACK_WILD_NONARRAY, (const char*)node.GetVarName(last));
+  
+  // Rest of variable type checking must be done at runtime
 }
 
 ASType_t cSemanticASTVisitor::getConsensusType(ASType_t left, ASType_t right)
@@ -413,8 +443,22 @@
       return false;
   }
 }
+        
+inline bool cSemanticASTVisitor::lookupVariable(const cString& name, int& var_id, bool& global) const
+{
+  if (m_cur_symtbl->LookupVariable(name, var_id)) {
+    global = false;
+    return true;
+  } else if (m_cur_symtbl != m_global_symtbl && m_global_symtbl->LookupVariable(name, var_id)) {
+    global = true;
+    return true;
+  } 
+  
+  return false;
+}
 
 
+
 void cSemanticASTVisitor::reportError(bool fail, ASSemanticError_t err, const cASFilePosition& fp, const int line, ...)
 {
 #define ERR_ENDL "  (cSemanticASTVisitor.cc:" << line << ")" << std::endl
@@ -451,6 +495,8 @@
       std::cerr << "'" << va_arg(vargs, const char*) << "' operation undefined for type '"
                 << va_arg(vargs, const char*) << "'" << ERR_ENDL;
       break;
+    case AS_SEMANTIC_ERR_UNPACK_WILD_NONARRAY:
+      std::cerr << "cannot unpack ... items into '" << va_arg(vargs, const char*) << "', variable must be an array" << ERR_ENDL;
     case AS_SEMANTIC_ERR_VARIABLE_REDEFINITION:
       std::cerr << "redefining variable '" << va_arg(vargs, const char*) << "'" << ERR_ENDL;
       break;

Modified: development/source/script/cSemanticASTVisitor.h
===================================================================
--- development/source/script/cSemanticASTVisitor.h	2008-02-28 02:28:36 UTC (rev 2387)
+++ development/source/script/cSemanticASTVisitor.h	2008-02-28 03:27:40 UTC (rev 2388)
@@ -93,6 +93,9 @@
   ASType_t getConsensusType(ASType_t t1, ASType_t t2);
   inline bool validArithmeticType(ASType_t type, bool allow_matrix = false) const;
   inline bool validBitwiseType(ASType_t type) const;
+  
+  inline bool lookupVariable(const cString& name, int& var_id, bool& global) const;
+  
   void reportError(bool fail, ASSemanticError_t err, const cASFilePosition& fp, const int line, ...);
 };
 #endif




More information about the Avida-cvs mailing list