[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