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

brysonda at myxo.css.msu.edu brysonda at myxo.css.msu.edu
Fri Feb 29 19:31:14 PST 2008


Author: brysonda
Date: 2008-02-29 22:31:14 -0500 (Fri, 29 Feb 2008)
New Revision: 2404

Modified:
   development/source/script/ASTree.cc
   development/source/script/AvidaScript.h
   development/source/script/cSemanticASTVisitor.cc
   development/source/script/cSymbolTable.cc
   development/source/script/cSymbolTable.h
Log:
AS: Scope push and pop.  Function definition checking.

Modified: development/source/script/ASTree.cc
===================================================================
--- development/source/script/ASTree.cc	2008-02-29 22:46:06 UTC (rev 2403)
+++ development/source/script/ASTree.cc	2008-03-01 03:31:14 UTC (rev 2404)
@@ -64,4 +64,4 @@
 {
   delete m_args;
   delete m_code;
-}
\ No newline at end of file
+}

Modified: development/source/script/AvidaScript.h
===================================================================
--- development/source/script/AvidaScript.h	2008-02-29 22:46:06 UTC (rev 2403)
+++ development/source/script/AvidaScript.h	2008-03-01 03:31:14 UTC (rev 2404)
@@ -121,6 +121,7 @@
   AS_SEMANTIC_ERR_FUNCTION_REDEFINITION,
   AS_SEMANTIC_ERR_FUNCTION_RTYPE_MISMATCH,
   AS_SEMANTIC_ERR_FUNCTION_SIGNATURE_MISMATCH,
+  AS_SEMANTIC_ERR_FUNCTION_UNDEFINED,
   AS_SEMANTIC_ERR_TOO_MANY_ARGUMENTS,
   AS_SEMANTIC_ERR_UNDEFINED_TYPE_OP,
   AS_SEMANTIC_ERR_UNPACK_WILD_NONARRAY,

Modified: development/source/script/cSemanticASTVisitor.cc
===================================================================
--- development/source/script/cSemanticASTVisitor.cc	2008-02-29 22:46:06 UTC (rev 2403)
+++ development/source/script/cSemanticASTVisitor.cc	2008-03-01 03:31:14 UTC (rev 2404)
@@ -114,7 +114,7 @@
   node.GetValues()->Accept(*this);
   checkCast(node.GetValues()->GetType(), TYPE(ARRAY));
   
-  // @TODO - push scope
+  m_cur_symtbl->PushScope();
   
   // Check and define the variable in this scope
   node.GetVariable()->Accept(*this);
@@ -122,7 +122,10 @@
   // Check the code
   node.GetCode()->Accept(*this);
   
-  // @TODO - pop scope
+  // Check all functions in the current scope level and make sure they have been defined
+  cSymbolTable::cFunctionIterator fit = m_cur_symtbl->ActiveFunctionIterator();
+  while (fit.Next()) if (!fit.HasCode()) SEMANTIC_ERROR(FUNCTION_UNDEFINED, (const char*)fit.GetName());
+  m_cur_symtbl->PopScope();
 }
 
 
@@ -131,9 +134,15 @@
   // Check main condition and code
   node.GetCondition()->Accept(*this);
   checkCast(node.GetCondition()->GetType(), TYPE(BOOL));
-  // @TODO - push scope
+  
+  m_cur_symtbl->PushScope();
+  
   node.GetCode()->Accept(*this);
-  // @TODO - pop scope
+
+  // Check all functions in the current scope level and make sure they have been defined
+  cSymbolTable::cFunctionIterator fit = m_cur_symtbl->ActiveFunctionIterator();
+  while (fit.Next()) if (!fit.HasCode()) SEMANTIC_ERROR(FUNCTION_UNDEFINED, (const char*)fit.GetName());
+  m_cur_symtbl->PopScope();
   
   // Check all elseif blocks
   tListIterator<cASTIfBlock::cElseIf> it = node.ElseIfIterator();
@@ -141,16 +150,27 @@
   while ((ei = it.Next())) {
     ei->GetCondition()->Accept(*this);
     checkCast(ei->GetCondition()->GetType(), TYPE(BOOL));
-    // @TODO - push scope
+    
+    m_cur_symtbl->PushScope();
+    
     ei->GetCode()->Accept(*this);
-    // @TODO - pop scope
+
+    // Check all functions in the current scope level and make sure they have been defined
+    cSymbolTable::cFunctionIterator fit = m_cur_symtbl->ActiveFunctionIterator();
+    while (fit.Next()) if (!fit.HasCode()) SEMANTIC_ERROR(FUNCTION_UNDEFINED, (const char*)fit.GetName());
+    m_cur_symtbl->PopScope();
   }
   
   // Check else block if there is one
   if (node.GetElseCode()) {
-    // @TODO - push scope
+    m_cur_symtbl->PushScope();
+    
     node.GetElseCode()->Accept(*this);
-    // @TODO - pop scope
+
+    // Check all functions in the current scope level and make sure they have been defined
+    cSymbolTable::cFunctionIterator fit = m_cur_symtbl->ActiveFunctionIterator();
+    while (fit.Next()) if (!fit.HasCode()) SEMANTIC_ERROR(FUNCTION_UNDEFINED, (const char*)fit.GetName());
+    m_cur_symtbl->PopScope();
   }
 }
 
@@ -159,9 +179,15 @@
 {
   node.GetCondition()->Accept(*this);
   checkCast(node.GetCondition()->GetType(), TYPE(BOOL));
-  // @TODO - push scope
+
+  m_cur_symtbl->PushScope();
+  
   node.GetCode()->Accept(*this);
-  // @TODO - pop scope
+
+  // Check all functions in the current scope level and make sure they have been defined
+  cSymbolTable::cFunctionIterator fit = m_cur_symtbl->ActiveFunctionIterator();
+  while (fit.Next()) if (!fit.HasCode()) SEMANTIC_ERROR(FUNCTION_UNDEFINED, (const char*)fit.GetName());
+  m_cur_symtbl->PopScope();
 }
 
 
@@ -244,6 +270,10 @@
     }
   }
   
+  // Check all functions in the current scope level and make sure they have been defined
+  cSymbolTable::cFunctionIterator fit = m_cur_symtbl->ActiveFunctionIterator();
+  while (fit.Next()) if (!fit.HasCode()) SEMANTIC_ERROR(FUNCTION_UNDEFINED, (const char*)fit.GetName());
+  
   // Pop function stack
   sFunctionEntry prev = m_fun_stack.Pop();
   m_cur_symtbl = m_parent_scope;
@@ -676,6 +706,9 @@
     case AS_SEMANTIC_ERR_FUNCTION_SIGNATURE_MISMATCH:
       std::cerr << "call signature of '" << VA_ARG_STR << "()' does not match declaration" << ERR_ENDL;
       break;
+    case AS_SEMANTIC_ERR_FUNCTION_UNDEFINED:
+      std::cerr << "'" << VA_ARG_STR << "()' declared but not defined" << ERR_ENDL;
+      break;
     case AS_SEMANTIC_ERR_TOO_MANY_ARGUMENTS:
       std::cerr << "too many arguments" << ERR_ENDL;
       break;

Modified: development/source/script/cSymbolTable.cc
===================================================================
--- development/source/script/cSymbolTable.cc	2008-02-29 22:46:06 UTC (rev 2403)
+++ development/source/script/cSymbolTable.cc	2008-03-01 03:31:14 UTC (rev 2404)
@@ -36,7 +36,7 @@
   if (LookupVariable(name, var_id)) return false;
 
   var_id = m_sym_tbl.GetSize();
-  m_sym_tbl.Push(new sSymbolEntry(name, type));
+  m_sym_tbl.Push(new sSymbolEntry(name, type, m_scope));
   m_sym_dict.Add(name, var_id);
   
   return true;
@@ -47,10 +47,32 @@
   if (LookupFunction(name, fun_id)) return false;
   
   fun_id = m_fun_tbl.GetSize();
-  m_fun_tbl.Push(new sFunctionEntry(name, type));
+  m_fun_tbl.Push(new sFunctionEntry(name, type, m_scope));
   m_fun_dict.Add(name, fun_id);
   
   return true;
 }
 
+void cSymbolTable::PopScope()
+{
+  m_deactivate_cycle++;
+  
+  for (int i = 0; i < m_sym_tbl.GetSize(); i++) {
+    sSymbolEntry* se = m_sym_tbl[i];
+    if (se->scope == m_scope && !se->deactivate) {
+      m_sym_dict.Remove(se->name);
+      se->deactivate = m_deactivate_cycle;
+    }
+  }
+  
+  for (int i = 0; i < m_fun_tbl.GetSize(); i++) {
+    sFunctionEntry* fe = m_fun_tbl[i];
+    if (fe->scope == m_scope && !fe->deactivate) {
+      m_fun_dict.Remove(fe->name);
+      fe->deactivate = m_deactivate_cycle;
+    }
+  }
 
+  m_scope--;
+}
+

Modified: development/source/script/cSymbolTable.h
===================================================================
--- development/source/script/cSymbolTable.h	2008-02-29 22:46:06 UTC (rev 2403)
+++ development/source/script/cSymbolTable.h	2008-03-01 03:31:14 UTC (rev 2404)
@@ -43,9 +43,11 @@
     cString name;
     ASType_t type;
 
-    bool active;
+    int scope;
+    bool deactivate;
     
-    sSymbolEntry(const cString& in_name, ASType_t in_type) : name(in_name), type(in_type), active(true) { ; }
+    sSymbolEntry(const cString& in_name, ASType_t in_type, int in_scope)
+      : name(in_name), type(in_type), scope(in_scope), deactivate(0) { ; }
   };
   tArray<sSymbolEntry*> m_sym_tbl;
   tDictionary<int> m_sym_dict;
@@ -58,14 +60,18 @@
     cSymbolTable* symtbl;
     cASTNode* code;
     
-    bool active;
+    int scope;
+    int deactivate;
     
-    sFunctionEntry(const cString& in_name, ASType_t in_type)
-      : name(in_name), type(in_type), signature(NULL), symtbl(NULL), code(NULL), active(true) { ; }
+    sFunctionEntry(const cString& in_name, ASType_t in_type, int in_scope)
+      : name(in_name), type(in_type), signature(NULL), symtbl(NULL), code(NULL), scope(in_scope), deactivate(0) { ; }
     ~sFunctionEntry() { delete signature; delete symtbl; delete code; }
   };
   tArray<sFunctionEntry*> m_fun_tbl;
   tDictionary<int> m_fun_dict;
+
+  int m_scope;
+  int m_deactivate_cycle;
   
   
   cSymbolTable(const cSymbolTable&); // @not_implemented
@@ -73,7 +79,7 @@
   
   
 public:
-  cSymbolTable() { ; }
+  cSymbolTable() : m_scope(0), m_deactivate_cycle(0) { ; }
   ~cSymbolTable();
 
   
@@ -83,21 +89,59 @@
   bool LookupVariable(const cString& name, int& var_id) { return m_sym_dict.Find(name, var_id); }
   bool LookupFunction(const cString& name, int& fun_id) { return m_fun_dict.Find(name, fun_id); }
   
-  ASType_t GetVariableType(int var_id) const { return m_sym_tbl[var_id]->type; }
+  inline int GetNumVariables() const { return m_sym_tbl.GetSize(); }
+  inline int GetNumFunctions() const { return m_fun_tbl.GetSize(); }
   
-  ASType_t GetFunctionRType(int fun_id) const { return m_fun_tbl[fun_id]->type; }
-  cSymbolTable* GetFunctionSymbolTable(int fun_id) { return m_fun_tbl[fun_id]->symtbl; }
-  cASTVariableDefinitionList* GetFunctionSignature(int fun_id) { return m_fun_tbl[fun_id]->signature; }
-  cASTNode* GetFunctionDefinition(int fun_id) { return m_fun_tbl[fun_id]->code; }
+  inline void PushScope() { m_scope++; }
+  void PopScope();
+  inline int GetScope() const { return m_scope; }
   
+  inline ASType_t GetVariableType(int var_id) const { return m_sym_tbl[var_id]->type; }
+
+  inline const cString& GetFunctionName(int fun_id) const { return m_fun_tbl[fun_id]->name; }
+  inline ASType_t GetFunctionRType(int fun_id) const { return m_fun_tbl[fun_id]->type; }
+  inline cSymbolTable* GetFunctionSymbolTable(int fun_id) { return m_fun_tbl[fun_id]->symtbl; }
+  inline cASTVariableDefinitionList* GetFunctionSignature(int fun_id) { return m_fun_tbl[fun_id]->signature; }
+  inline cASTNode* GetFunctionDefinition(int fun_id) { return m_fun_tbl[fun_id]->code; }
+  inline int GetFunctionScope(int fun_id) const { return m_fun_tbl[fun_id]->scope; }
+  inline bool IsFunctionActive(int fun_id) const { return !m_fun_tbl[fun_id]->deactivate; }
+  
   inline void SetFunctionSymbolTable(int fun_id, cSymbolTable* symtbl) { m_fun_tbl[fun_id]->symtbl = symtbl; }
   inline void SetFunctionSignature(int fun_id, cASTVariableDefinitionList* vdl) { m_fun_tbl[fun_id]->signature = vdl; }
   inline void SetFunctionDefinition(int fun_id, cASTNode* code) { m_fun_tbl[fun_id]->code = code; }
   
   inline cString VariableNearMatch(const cString& name) const { return m_sym_dict.NearMatch(name); }
   inline cString FunctionNearMatch(const cString& name) const { return m_fun_dict.NearMatch(name); }
+
+  
+  class cFunctionIterator
+  {
+    friend class cSymbolTable;
+  
+  private:
+    cSymbolTable* m_symtbl;
+    int m_scope;
+    int m_idx;
+    
+    cFunctionIterator(cSymbolTable* symtbl)
+      : m_symtbl(symtbl), m_scope(symtbl->GetScope()), m_idx(symtbl->GetNumFunctions() - 1) { ; }
+
+  public:
+    bool Next()
+    {
+      for (; m_idx >= 0; m_idx--)
+        if (m_symtbl->GetFunctionScope(m_idx) == m_scope && m_symtbl->IsFunctionActive(m_idx)) return true;
+      
+      return false;
+    }
+    
+    inline bool HasCode() const { return m_symtbl->GetFunctionDefinition(m_idx); }
+    inline const cString& GetName() const { return m_symtbl->GetFunctionName(m_idx); }
+  };
+
+
+  inline cFunctionIterator ActiveFunctionIterator() { return cFunctionIterator(this); }  
 };
 
 
-
 #endif




More information about the Avida-cvs mailing list