[Avida-SVN] r2380 - development/source/script
brysonda at myxo.css.msu.edu
brysonda at myxo.css.msu.edu
Mon Feb 25 20:25:48 PST 2008
Author: brysonda
Date: 2008-02-25 23:25:48 -0500 (Mon, 25 Feb 2008)
New Revision: 2380
Modified:
development/source/script/ASTree.h
development/source/script/AvidaScript.h
development/source/script/cSemanticASTVisitor.cc
development/source/script/cSemanticASTVisitor.h
development/source/script/cSymbolTable.cc
development/source/script/cSymbolTable.h
Log:
Add support for warnings in cSemanticASTVisitor and implement Assignment handling.
Modified: development/source/script/ASTree.h
===================================================================
--- development/source/script/ASTree.h 2008-02-26 01:59:38 UTC (rev 2379)
+++ development/source/script/ASTree.h 2008-02-26 04:25:48 UTC (rev 2380)
@@ -81,6 +81,8 @@
public:
virtual ~cASTNode() { ; }
+ virtual ASType_t GetType() const { return AS_TYPE_INVALID; }
+
inline const cASFilePosition& GetFilePosition() const { return m_file_pos; }
virtual void Accept(cASTVisitor& visitor) = 0;
@@ -224,7 +226,7 @@
cElseIf(cASTNode* expr, cASTNode* code) : m_expr(expr), m_code(code) { ; }
public:
- cASTNode* GetCondition() { return m_expr; }
+ cASTNode* GetCondition() { return m_expr; }
cASTNode* GetCode() { return m_code; }
};
Modified: development/source/script/AvidaScript.h
===================================================================
--- development/source/script/AvidaScript.h 2008-02-26 01:59:38 UTC (rev 2379)
+++ development/source/script/AvidaScript.h 2008-02-26 04:25:48 UTC (rev 2380)
@@ -111,6 +111,10 @@
typedef enum eASSemanticErrors {
+ AS_SEMANTIC_WARN_UNREACHABLE,
+ AS_SEMANTIC_WARN__LAST,
+
+ AS_SEMANTIC_ERR_VARIABLE_UNDEFINED,
AS_SEMANTIC_ERR_VARIABLE_REDEFINITION,
AS_SEMANTIC_ERR_INTERNAL,
Modified: development/source/script/cSemanticASTVisitor.cc
===================================================================
--- development/source/script/cSemanticASTVisitor.cc 2008-02-26 01:59:38 UTC (rev 2379)
+++ development/source/script/cSemanticASTVisitor.cc 2008-02-26 04:25:48 UTC (rev 2380)
@@ -27,22 +27,39 @@
#include "cASLibrary.h"
#include "cSymbolTable.h"
+#include <cstdarg>
-#define SEMANTIC_ERROR(code, info) reportError(AS_SEMANTIC_ERR_ ## code, node.GetFilePosition(), __LINE__, info)
+#define SEMANTIC_ERROR(code, ...) reportError(true, AS_SEMANTIC_ERR_ ## code, node.GetFilePosition(), __LINE__, __VA_ARGS__)
+#define SEMANTIC_WARNING(code, ...) reportError(false, AS_SEMANTIC_WARN_ ## code, node.GetFilePosition(), __LINE__, __VA_ARGS__)
+
cSemanticASTVisitor::cSemanticASTVisitor(cASLibrary* lib, cSymbolTable* global_symtbl)
- : m_library(lib), m_global_symtbl(global_symtbl), m_cur_symtbl(global_symtbl)
+ : 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", AS_TYPE_INT);
}
void cSemanticASTVisitor::visitAssignment(cASTAssignment& node)
{
+ 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));
+ } else {
+ SEMANTIC_ERROR(VARIABLE_UNDEFINED, (const char*)node.GetVariable());
+ }
}
void cSemanticASTVisitor::visitReturnStatement(cASTReturnStatement& node)
{
+ node.GetExpression()->Accept(*this);
+ checkCast(m_parent_scope->GetFunctionRType(m_fun_id), node.GetExpression()->GetType());
+ // @TODO - mark scope as containing return
}
@@ -53,6 +70,7 @@
cASTNode* stmt = NULL;
while ((stmt = it.Next())) {
stmt->Accept(*this);
+ // @TODO - check for unreachable statements
}
}
@@ -81,7 +99,7 @@
void cSemanticASTVisitor::visitVariableDefinition(cASTVariableDefinition& node)
{
if (!m_cur_symtbl->AddVariable(node.GetVariable(), node.GetType())) {
- SEMANTIC_ERROR(VARIABLE_REDEFINITION, node.GetVariable());
+ SEMANTIC_ERROR(VARIABLE_REDEFINITION, (const char*)node.GetVariable());
}
}
@@ -131,17 +149,40 @@
}
-void cSemanticASTVisitor::reportError(ASSemanticError_t err, const cASFilePosition& fp, const int line, const cString& info)
+
+void cSemanticASTVisitor::checkCast(ASType_t in_type, ASType_t out_type)
{
+
+}
+
+
+void cSemanticASTVisitor::reportError(bool fail, ASSemanticError_t err, const cASFilePosition& fp, const int line, ...)
+{
#define ERR_ENDL " (cSemanticASTVisitor.cc:" << line << ")" << std::endl
- m_success = false;
+ if (fail) m_success = false;
- std::cerr << fp.GetFilename() << ":" << fp.GetLineNumber() << ": error: ";
+ std::cerr << fp.GetFilename() << ":" << fp.GetLineNumber();
+ if (err < AS_SEMANTIC_WARN__LAST) std::cerr << ": warning: ";
+ else std::cerr << ": error: ";
+ va_list info_list;
+ va_start(info_list, line);
switch (err) {
+ case AS_SEMANTIC_WARN_UNREACHABLE:
+ std::cerr << "unreachable statement(s)" << ERR_ENDL;
+ break;
+ case AS_SEMANTIC_ERR_VARIABLE_UNDEFINED:
+ {
+ cString varname = va_arg(info_list, const char*);
+ std::cerr << "'" << varname << "' undefined";
+ cString nearmatch = m_cur_symtbl->VariableNearMatch(varname);
+ if (nearmatch != "") std::cerr << " - possible match '" << nearmatch << "'";
+ std::cerr << ERR_ENDL;
+ }
+ break;
case AS_SEMANTIC_ERR_VARIABLE_REDEFINITION:
- std::cerr << "redefining variable '" << info << "'" << ERR_ENDL;
+ std::cerr << "redefining variable '" << va_arg(info_list, const char*) << "'" << ERR_ENDL;
break;
case AS_SEMANTIC_ERR_INTERNAL:
std::cerr << "internal semantic analysis error at cSemanticASTVisitor.cc:" << line << std::endl;
@@ -150,6 +191,7 @@
default:
std::cerr << "unknown error" << std::endl;
}
+ va_end(info_list);
#undef ERR_ENDL
}
Modified: development/source/script/cSemanticASTVisitor.h
===================================================================
--- development/source/script/cSemanticASTVisitor.h 2008-02-26 01:59:38 UTC (rev 2379)
+++ development/source/script/cSemanticASTVisitor.h 2008-02-26 04:25:48 UTC (rev 2380)
@@ -27,6 +27,7 @@
#include "cASTVisitor.h"
+#include "tArray.h"
#include "tSmartArray.h"
class cASLibrary;
@@ -38,9 +39,22 @@
private:
cASLibrary* m_library;
cSymbolTable* m_global_symtbl;
+ cSymbolTable* m_parent_scope;
+ int m_fun_id;
cSymbolTable* m_cur_symtbl;
- tSmartArray<cSymbolTable*> m_symtbl_stack;
+ struct sFunctionEntry
+ {
+ cSymbolTable* scope;
+ int fun_id;
+
+ cSymbolTable* fun_symtbl;
+
+ sFunctionEntry() : scope(NULL), fun_id(-1) { ; }
+ };
+ tSmartArray<sFunctionEntry> m_fun_stack;
+
+
bool m_success;
@@ -76,6 +90,7 @@
void visitUnpackTarget(cASTUnpackTarget&);
private:
- void reportError(ASSemanticError_t err, const cASFilePosition& fp, const int line, const cString& info);
+ void checkCast(ASType_t in_type, ASType_t out_type);
+ void reportError(bool fail, ASSemanticError_t err, const cASFilePosition& fp, const int line, ...);
};
#endif
Modified: development/source/script/cSymbolTable.cc
===================================================================
--- development/source/script/cSymbolTable.cc 2008-02-26 01:59:38 UTC (rev 2379)
+++ development/source/script/cSymbolTable.cc 2008-02-26 04:25:48 UTC (rev 2380)
@@ -24,6 +24,13 @@
#include "cSymbolTable.h"
+
+cSymbolTable::~cSymbolTable()
+{
+ for (int i = 0; i < m_sym_tbl.GetSize(); i++) delete m_sym_tbl[i];
+ for (int i = 0; i < m_fun_tbl.GetSize(); i++) delete m_fun_tbl[i];
+}
+
bool cSymbolTable::AddVariable(const cString& name, ASType_t type)
{
if (HasSymbol(name)) return false;
@@ -43,3 +50,5 @@
return true;
}
+
+
Modified: development/source/script/cSymbolTable.h
===================================================================
--- development/source/script/cSymbolTable.h 2008-02-26 01:59:38 UTC (rev 2379)
+++ development/source/script/cSymbolTable.h 2008-02-26 04:25:48 UTC (rev 2380)
@@ -67,12 +67,22 @@
public:
cSymbolTable() { ; }
+ ~cSymbolTable();
bool AddVariable(const cString& name, ASType_t type);
bool AddFunction(const cString& name, ASType_t type);
+ 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; }
+
+ 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); }
+
inline bool HasSymbol(const cString& name) const { return m_sym_dict.HasEntry(name) || m_fun_dict.HasEntry(name); }
+
+ 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); }
};
More information about the Avida-cvs
mailing list