[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