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

brysonda at myxo.css.msu.edu brysonda at myxo.css.msu.edu
Fri Feb 29 07:43:42 PST 2008


Author: brysonda
Date: 2008-02-29 10:43:42 -0500 (Fri, 29 Feb 2008)
New Revision: 2399

Modified:
   development/source/script/ASTree.h
   development/source/script/AvidaScript.h
   development/source/script/cDumpASTVisitor.cc
   development/source/script/cParser.cc
   development/source/script/cSemanticASTVisitor.cc
   development/source/script/cSymbolTable.cc
   development/source/script/cSymbolTable.h
Log:
AS: add additional checking to variable definition to handle dimensions and assignments.

Modified: development/source/script/ASTree.h
===================================================================
--- development/source/script/ASTree.h	2008-02-29 15:36:03 UTC (rev 2398)
+++ development/source/script/ASTree.h	2008-02-29 15:43:42 UTC (rev 2399)
@@ -155,9 +155,10 @@
   
 public:
   cASTArgumentList(const cASFilePosition& fp) : cASTNode(fp) { ; }
-  ~cASTArgumentList() { ; }
+  ~cASTArgumentList() { while (m_nodes.GetSize()) delete m_nodes.Pop(); }
   
   inline void AddNode(cASTNode* n) { m_nodes.PushRear(n); }
+  inline int GetSize() const { return m_nodes.GetSize(); }
   inline tListIterator<cASTNode> Iterator() { return tListIterator<cASTNode>(m_nodes); }
   
   void Accept(cASTVisitor& visitor);
@@ -323,22 +324,26 @@
 {
 private:
   ASType_t m_type;
-  cString m_var;
+  cString m_name;
   cASTNode* m_assign;
   cASTArgumentList* m_dims;
+  int m_id;
   
 public:
-  cASTVariableDefinition(const cASFilePosition& fp, ASType_t type, const cString& var)
-    : cASTNode(fp), m_type(type), m_var(var), m_assign(NULL), m_dims(NULL) { ; }
+  cASTVariableDefinition(const cASFilePosition& fp, ASType_t type, const cString& name)
+    : cASTNode(fp), m_type(type), m_name(name), m_assign(NULL), m_dims(NULL), m_id(-1) { ; }
   ~cASTVariableDefinition() { delete m_assign; delete m_dims; }
   
   inline ASType_t GetType() { return m_type; }
-  inline const cString& GetVariable() { return m_var; }
+  inline const cString& GetName() { return m_name; }
   inline void SetAssignmentExpression(cASTNode* assign) { delete m_assign; m_assign = assign; }
   inline cASTNode* GetAssignmentExpression() { return m_assign; }
   inline void SetDimensions(cASTArgumentList* dims) { delete m_dims; m_dims = dims; }
   inline cASTArgumentList* GetDimensions() { return m_dims; }
   
+  inline int GetVarID() const { return m_id; }
+  inline void SetVar(int in_id) { m_id = in_id; }
+  
   void Accept(cASTVisitor& visitor);
 };
 
@@ -469,14 +474,15 @@
 class cASTLiteralArray : public cASTNode
 {
 private:
-  cASTNode* m_value;
+  cASTArgumentList* m_value;
   bool m_is_matrix;
   
 public:
-  cASTLiteralArray(const cASFilePosition& fp, cASTNode* v, bool is_mat) : cASTNode(fp), m_value(v), m_is_matrix(is_mat) { ; }
+  cASTLiteralArray(const cASFilePosition& fp, cASTArgumentList* v, bool is_mat)
+    : cASTNode(fp), m_value(v), m_is_matrix(is_mat) { ; }
   ~cASTLiteralArray() { delete m_value; }  
   
-  inline cASTNode* GetValue() { return m_value; }
+  inline cASTArgumentList* GetValue() { return m_value; }
   inline bool IsMatrix() const { return m_is_matrix; }
   
   ASType_t GetType() const { return m_is_matrix ? AS_TYPE_MATRIX : AS_TYPE_ARRAY; }

Modified: development/source/script/AvidaScript.h
===================================================================
--- development/source/script/AvidaScript.h	2008-02-29 15:36:03 UTC (rev 2398)
+++ development/source/script/AvidaScript.h	2008-02-29 15:43:42 UTC (rev 2399)
@@ -112,12 +112,15 @@
 
 typedef enum eASSemanticErrors {
   AS_SEMANTIC_WARN_LOSS_OF_PRECISION,
+  AS_SEMANTIC_WARN_NO_DIMENSIONS,
   AS_SEMANTIC_WARN_UNREACHABLE,
   AS_SEMANTIC_WARN__LAST,
   
   AS_SEMANTIC_ERR_CANNOT_CAST,
+  AS_SEMANTIC_ERR_TOO_MANY_ARGUMENTS,
   AS_SEMANTIC_ERR_UNDEFINED_TYPE_OP,
   AS_SEMANTIC_ERR_UNPACK_WILD_NONARRAY,
+  AS_SEMANTIC_ERR_VARIABLE_DIMENSIONS_INVALID,
   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-29 15:36:03 UTC (rev 2398)
+++ development/source/script/cDumpASTVisitor.cc	2008-02-29 15:43:42 UTC (rev 2399)
@@ -218,8 +218,19 @@
 void cDumpASTVisitor::visitVariableDefinition(cASTVariableDefinition& node)
 {
   indent();
-  cout << mapType(node.GetType()) << " " << node.GetVariable() << endl;
+  cout << mapType(node.GetType()) << " " << node.GetName() << endl;
   
+  if (node.GetDimensions()) {
+    m_depth++;
+    indent();
+    cout << "dimensions:" << endl;
+    
+    m_depth++;
+    node.GetDimensions()->Accept(*this);
+
+    m_depth -= 2;
+  }
+  
   if (node.GetAssignmentExpression()) {
     m_depth++;
     indent();

Modified: development/source/script/cParser.cc
===================================================================
--- development/source/script/cParser.cc	2008-02-29 15:36:03 UTC (rev 2398)
+++ development/source/script/cParser.cc	2008-02-29 15:43:42 UTC (rev 2399)
@@ -595,9 +595,12 @@
       if (nextToken() != TOKEN(ARR_OPEN)) PARSE_UNEXPECT();
       is_matrix = true;
     case TOKEN(ARR_OPEN):
-      if (nextToken() != TOKEN(ARR_CLOSE)) expr.Set(parseArgumentList());
-      if (currentToken() != TOKEN(ARR_CLOSE)) PARSE_UNEXPECT();
-      expr.Set(new cASTLiteralArray(FILEPOS, expr.Release(), is_matrix));
+      {
+        tAutoRelease<cASTArgumentList> al;
+        if (nextToken() != TOKEN(ARR_CLOSE)) al.Set(parseArgumentList());
+        if (currentToken() != TOKEN(ARR_CLOSE)) PARSE_UNEXPECT();
+        expr.Set(new cASTLiteralArray(FILEPOS, al.Release(), is_matrix));
+      }
       break;
       
     case TOKEN(OP_BIT_NOT):

Modified: development/source/script/cSemanticASTVisitor.cc
===================================================================
--- development/source/script/cSemanticASTVisitor.cc	2008-02-29 15:36:03 UTC (rev 2398)
+++ development/source/script/cSemanticASTVisitor.cc	2008-02-29 15:43:42 UTC (rev 2399)
@@ -70,7 +70,8 @@
   : m_library(lib), m_global_symtbl(global_symtbl), m_parent_scope(global_symtbl), m_fun_id(0), m_cur_symtbl(global_symtbl)
 {
   // Add internal definition of the global function
-  m_global_symtbl->AddFunction("__asmain", TYPE(INT));
+  int fun_id = -1;
+  m_global_symtbl->AddFunction("__asmain", TYPE(INT), fun_id);
 }
 
 
@@ -130,9 +131,41 @@
 
 void cSemanticASTVisitor::visitVariableDefinition(cASTVariableDefinition& node)
 {
-  if (!m_cur_symtbl->AddVariable(node.GetVariable(), node.GetType())) {
-    SEMANTIC_ERROR(VARIABLE_REDEFINITION, (const char*)node.GetVariable());
+  int var_id = -1;
+  if (m_cur_symtbl->AddVariable(node.GetName(), node.GetType(), var_id)) node.SetVar(var_id);
+  else SEMANTIC_ERROR(VARIABLE_REDEFINITION, (const char*)node.GetName());
+  
+  // Process matrix/array dimensions
+  cASTArgumentList* al = node.GetDimensions();
+  if (al) {
+    if (node.GetType() == TYPE(MATRIX) || node.GetType() == TYPE(ARRAY)) {
+      // Check individual arguments for validity
+      tListIterator<cASTNode> it = al->Iterator();
+      cASTNode* alnode = NULL;
+      while ((alnode = it.Next())) {
+        alnode->Accept(*this);
+        checkCast(alnode->GetType(), TYPE(INT));
+      }
+      
+      // If empty, warn...
+      if (al->GetSize() == 0) SEMANTIC_WARNING(NO_DIMENSIONS);
+      
+      // Arrays can only have one dimension specifier
+      if (node.GetType() == TYPE(ARRAY) && al->GetSize() > 1) {
+        SEMANTIC_ERROR(TOO_MANY_ARGUMENTS);
+        SEMANTIC_ERROR(VARIABLE_DIMENSIONS_INVALID, (const char*)node.GetName(), mapType(node.GetType()));
+      }
+    } else {
+      SEMANTIC_ERROR(VARIABLE_DIMENSIONS_INVALID, (const char*)node.GetName(), mapType(node.GetType()));
+    }
   }
+  
+  // Process assignment
+  cASTNode* ae = node.GetAssignmentExpression();
+  if (ae) {
+    ae->Accept(*this);
+    checkCast(ae->GetType(), node.GetType());
+  }
 }
 
 
@@ -277,6 +310,8 @@
 
 void cSemanticASTVisitor::visitArgumentList(cASTArgumentList& node)
 {
+  // Should never recurse into here.  Argument lists are processed by their owners as needed.
+  SEMANTIC_ERROR(INTERNAL);
 }
 
 void cSemanticASTVisitor::visitFunctionCall(cASTFunctionCall& node)
@@ -470,6 +505,7 @@
 void cSemanticASTVisitor::reportError(bool fail, ASSemanticError_t err, const cASFilePosition& fp, const int line, ...)
 {
 #define ERR_ENDL "  (cSemanticASTVisitor.cc:" << line << ")" << std::endl
+#define VA_ARG_STR va_arg(vargs, const char*)
   
   if (fail) m_success = false;
   
@@ -481,18 +517,17 @@
   va_start(vargs, line);
   switch (err) {
     case AS_SEMANTIC_WARN_LOSS_OF_PRECISION:
-      std::cerr << "loss of precision occuring in cast of " << va_arg(vargs, const char*) << " to " 
-                << va_arg(vargs, const char*) << ERR_ENDL;
+      std::cerr << "loss of precision occuring in cast of " << VA_ARG_STR << " to " << VA_ARG_STR << ERR_ENDL;
       break;
     case AS_SEMANTIC_WARN_UNREACHABLE:
       std::cerr << "unreachable statement(s)" << ERR_ENDL;
       break;
     case AS_SEMANTIC_ERR_CANNOT_CAST:
-      std::cerr << "cannot cast " << va_arg(vargs, const char*) << " to " << va_arg(vargs, const char*) << ERR_ENDL;
+      std::cerr << "cannot cast " << VA_ARG_STR << " to " << VA_ARG_STR << ERR_ENDL;
       break;
     case AS_SEMANTIC_ERR_VARIABLE_UNDEFINED:
       {
-        cString varname = va_arg(vargs, const char*);
+        cString varname = VA_ARG_STR;
         std::cerr << "'" << varname << "' undefined";
         cString nearmatch = m_cur_symtbl->VariableNearMatch(varname);
         if (nearmatch != "") std::cerr << " - possible match '" << nearmatch << "'";
@@ -500,13 +535,12 @@
       }
       break;
     case AS_SEMANTIC_ERR_UNDEFINED_TYPE_OP:
-      std::cerr << "'" << va_arg(vargs, const char*) << "' operation undefined for type '"
-                << va_arg(vargs, const char*) << "'" << ERR_ENDL;
+      std::cerr << "'" << VA_ARG_STR << "' operation undefined for type '" << VA_ARG_STR << "'" << 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;
+      std::cerr << "cannot unpack ... items into '" << VA_ARG_STR << "', variable must be an array" << ERR_ENDL;
     case AS_SEMANTIC_ERR_VARIABLE_REDEFINITION:
-      std::cerr << "redefining variable '" << va_arg(vargs, const char*) << "'" << ERR_ENDL;
+      std::cerr << "redefining variable '" << VA_ARG_STR << "'" << ERR_ENDL;
       break;
     case AS_SEMANTIC_ERR_INTERNAL:
       std::cerr << "internal semantic analysis error at cSemanticASTVisitor.cc:" << line << std::endl;
@@ -518,6 +552,7 @@
   va_end(vargs);
   
 #undef ERR_ENDL
+#undef VA_ARG_STR
 }
                 
 #undef SEMANTIC_ERROR()

Modified: development/source/script/cSymbolTable.cc
===================================================================
--- development/source/script/cSymbolTable.cc	2008-02-29 15:36:03 UTC (rev 2398)
+++ development/source/script/cSymbolTable.cc	2008-02-29 15:43:42 UTC (rev 2399)
@@ -31,22 +31,24 @@
   for (int i = 0; i < m_fun_tbl.GetSize(); i++) delete m_fun_tbl[i];
 }
 
-bool cSymbolTable::AddVariable(const cString& name, ASType_t type)
+bool cSymbolTable::AddVariable(const cString& name, ASType_t type, int& var_id)
 {
-  if (HasSymbol(name)) return false;
+  if (LookupVariable(name, var_id)) return false;
 
+  var_id = m_sym_tbl.GetSize();
   m_sym_tbl.Push(new sSymbolEntry(name, type));
-  m_sym_dict.Add(name, m_sym_tbl.GetSize() - 1);
+  m_sym_dict.Add(name, var_id);
   
   return true;
 }
 
-bool cSymbolTable::AddFunction(const cString& name, ASType_t type)
+bool cSymbolTable::AddFunction(const cString& name, ASType_t type, int& fun_id)
 {
-  if (HasSymbol(name)) return false;
+  if (LookupFunction(name, fun_id)) return false;
   
+  fun_id = m_fun_tbl.GetSize();
   m_fun_tbl.Push(new sFunctionEntry(name, type));
-  m_fun_dict.Add(name, m_fun_tbl.GetSize() - 1);
+  m_fun_dict.Add(name, fun_id);
   
   return true;
 }

Modified: development/source/script/cSymbolTable.h
===================================================================
--- development/source/script/cSymbolTable.h	2008-02-29 15:36:03 UTC (rev 2398)
+++ development/source/script/cSymbolTable.h	2008-02-29 15:43:42 UTC (rev 2399)
@@ -70,8 +70,8 @@
   ~cSymbolTable();
 
   
-  bool AddVariable(const cString& name, ASType_t type);
-  bool AddFunction(const cString& name, ASType_t type);
+  bool AddVariable(const cString& name, ASType_t type, int& var_id);
+  bool AddFunction(const cString& name, ASType_t type, int& fun_id);
   
   ASType_t GetVariableType(int var_id) const { return m_sym_tbl[var_id]->type; }
   ASType_t GetFunctionRType(int fun_id) const { return m_fun_tbl[fun_id]->type; }




More information about the Avida-cvs mailing list