[Avida-SVN] r2385 - development/source/script
brysonda at myxo.css.msu.edu
brysonda at myxo.css.msu.edu
Tue Feb 26 20:39:27 PST 2008
Author: brysonda
Date: 2008-02-26 23:39:27 -0500 (Tue, 26 Feb 2008)
New Revision: 2385
Modified:
development/source/script/ASTree.h
development/source/script/AvidaScript.h
development/source/script/cSemanticASTVisitor.cc
development/source/script/cSemanticASTVisitor.h
Log:
Begin AS binary expression semantics. Implement AS semantic checkCast.
Modified: development/source/script/ASTree.h
===================================================================
--- development/source/script/ASTree.h 2008-02-26 22:50:24 UTC (rev 2384)
+++ development/source/script/ASTree.h 2008-02-27 04:39:27 UTC (rev 2385)
@@ -363,10 +363,11 @@
ASToken_t m_op;
cASTNode* m_left;
cASTNode* m_right;
+ ASType_t m_type;
public:
cASTExpressionBinary(const cASFilePosition& fp, ASToken_t op, cASTNode* l, cASTNode* r)
- : cASTNode(fp), m_op(op), m_left(l), m_right(r) { ; }
+ : cASTNode(fp), m_op(op), m_left(l), m_right(r), m_type(AS_TYPE_INVALID) { ; }
~cASTExpressionBinary() { delete m_left; delete m_right; }
inline ASToken_t GetOperator() { return m_op; }
@@ -374,7 +375,10 @@
inline cASTNode* GetLeft() { return m_left; }
inline void SetRight(cASTNode* right) { m_right = right; }
inline cASTNode* GetRight() { return m_right; }
-
+
+ ASType_t GetType() const { return m_type; }
+ inline void SetType(ASType_t type) { m_type = type; }
+
void Accept(cASTVisitor& visitor);
};
@@ -410,15 +414,20 @@
private:
cASTNode* m_target;
cASTArgumentList* m_args;
+ ASType_t m_type;
public:
- cASTFunctionCall(const cASFilePosition& fp, cASTNode* target) : cASTNode(fp), m_target(target), m_args(NULL) { ; }
+ cASTFunctionCall(const cASFilePosition& fp, cASTNode* target)
+ : cASTNode(fp), m_target(target), m_args(NULL), m_type(AS_TYPE_INVALID) { ; }
~cASTFunctionCall() { delete m_args; }
cASTNode* GetTarget() { return m_target; }
void SetArguments(cASTArgumentList* args) { delete m_args; m_args = args; }
cASTArgumentList* GetArguments() { return m_args; }
+ ASType_t GetType() const { return m_type; }
+ inline void SetType(ASType_t type) { m_type = type; }
+
bool HasArguments() const { return (m_args); }
void Accept(cASTVisitor& visitor);
@@ -434,7 +443,7 @@
public:
cASTLiteral(const cASFilePosition& fp, ASType_t t, const cString& v) : cASTNode(fp), m_type(t), m_value(v) { ; }
- inline ASType_t GetType() { return m_type; }
+ ASType_t GetType() const { return m_type; }
inline const cString& GetValue() { return m_value; }
void Accept(cASTVisitor& visitor);
@@ -454,6 +463,8 @@
inline cASTNode* 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; }
+
void Accept(cASTVisitor& visitor);
};
@@ -462,12 +473,17 @@
{
private:
cString m_name;
+ ASType_t m_type;
public:
- cASTVariableReference(const cASFilePosition& fp, const cString& name) : cASTNode(fp), m_name(name) { ; }
+ cASTVariableReference(const cASFilePosition& fp, const cString& name)
+ : cASTNode(fp), m_name(name), m_type(AS_TYPE_INVALID) { ; }
inline const cString& GetName() { return m_name; }
+ ASType_t GetType() const { return m_type; }
+ inline void SetType(ASType_t type) { m_type = type; }
+
void Accept(cASTVisitor& visitor);
};
Modified: development/source/script/AvidaScript.h
===================================================================
--- development/source/script/AvidaScript.h 2008-02-26 22:50:24 UTC (rev 2384)
+++ development/source/script/AvidaScript.h 2008-02-27 04:39:27 UTC (rev 2385)
@@ -111,9 +111,11 @@
typedef enum eASSemanticErrors {
+ AS_SEMANTIC_WARN_LOSS_OF_PRECISION,
AS_SEMANTIC_WARN_UNREACHABLE,
AS_SEMANTIC_WARN__LAST,
+ AS_SEMANTIC_ERR_CANNOT_CAST,
AS_SEMANTIC_ERR_UNDEFINED_TYPE_OP,
AS_SEMANTIC_ERR_VARIABLE_UNDEFINED,
AS_SEMANTIC_ERR_VARIABLE_REDEFINITION,
@@ -125,13 +127,14 @@
typedef enum eASTypes {
AS_TYPE_ARRAY = 0,
+ AS_TYPE_BOOL,
AS_TYPE_CHAR,
AS_TYPE_FLOAT,
AS_TYPE_INT,
+ AS_TYPE_OBJECT_REF,
AS_TYPE_MATRIX,
AS_TYPE_STRING,
AS_TYPE_VOID,
- AS_TYPE_OBJECT_REF,
AS_TYPE_INVALID
} ASType_t;
Modified: development/source/script/cSemanticASTVisitor.cc
===================================================================
--- development/source/script/cSemanticASTVisitor.cc 2008-02-26 22:50:24 UTC (rev 2384)
+++ development/source/script/cSemanticASTVisitor.cc 2008-02-27 04:39:27 UTC (rev 2385)
@@ -38,7 +38,31 @@
#define TOKEN(x) AS_TOKEN_ ## x
#define TYPE(x) AS_TYPE_ ## x
+namespace AvidaScript {
+ static const bool valid_cast[8][8] = {
+ // ARRAY, BOOL , CHAR , FLOAT, INT , @OBJ , MATRX, STRNG
+ {true , true , false, false, false, false, false, true }, // TYPE(ARRAY)
+ {true , true , true , true , true , false, true , true }, // TYPE(BOOL)
+ {true , true , true , true , true , false, true , true }, // TYPE(CHAR)
+ {true , true , false, true , true , false, true , true }, // TYPE(FLOAT)
+ {true , true , true , true , true , false, true , true }, // TYPE(INT)
+ {true , true , false, false, false, true , false, true }, // TYPE(OBJECT_REF)
+ {true , true , false, false, false, false, true , true }, // TYPE(MATRIX)
+ {true , true , false, true , true , false, false, true } // TYPE(STRNG)
+ };
+}
+
+#define checkCast(in_type, out_type) { \
+ if (valid_cast[in_type][out_type]) { \
+ if ((in_type == TYPE(FLOAT) && out_type == TYPE(INT)) || (in_type == TYPE(INT) && out_type == TYPE(CHAR))) \
+ SEMANTIC_WARNING(LOSS_OF_PRECISION, mapType(in_type), mapType(out_type)); \
+ } else { \
+ SEMANTIC_ERROR(CANNOT_CAST, mapType(in_type), mapType(out_type)); \
+ } \
+}
+
+
cSemanticASTVisitor::cSemanticASTVisitor(cASLibrary* lib, cSymbolTable* global_symtbl)
: m_library(lib), m_global_symtbl(global_symtbl), m_parent_scope(global_symtbl), m_fun_id(0), m_cur_symtbl(global_symtbl)
{
@@ -46,6 +70,7 @@
m_global_symtbl->AddFunction("__asmain", TYPE(INT));
}
+
void cSemanticASTVisitor::visitAssignment(cASTAssignment& node)
{
node.GetExpression()->Accept(*this);
@@ -117,6 +142,60 @@
void cSemanticASTVisitor::visitExpressionBinary(cASTExpressionBinary& node)
{
+ node.GetLeft()->Accept(*this);
+ node.GetRight()->Accept(*this);
+
+ switch (node.GetOperator()) {
+ case TOKEN(DOT):
+ break;
+ case TOKEN(IDX_OPEN):
+ break;
+ case TOKEN(ARR_RANGE):
+ break;
+ case TOKEN(ARR_EXPAN):
+ break;
+ case TOKEN(OP_BIT_AND):
+ case TOKEN(OP_BIT_OR):
+ {
+ bool valid_types = true;
+ if (!validBitwiseType(node.GetLeft()->GetType())) {
+ valid_types = false;
+ SEMANTIC_ERROR(UNDEFINED_TYPE_OP, mapToken(node.GetOperator()), mapType(node.GetLeft()->GetType()));
+ }
+ if (!validBitwiseType(node.GetRight()->GetType())) {
+ valid_types = false;
+ SEMANTIC_ERROR(UNDEFINED_TYPE_OP, mapToken(node.GetOperator()), mapType(node.GetRight()->GetType()));
+ }
+
+ if (valid_types) {
+ // @TODO - get consensus type
+ // Set node return type
+ }
+ }
+ break;
+ case TOKEN(OP_LOGIC_AND):
+ case TOKEN(OP_LOGIC_OR):
+ case TOKEN(OP_EQ):
+ case TOKEN(OP_LE):
+ case TOKEN(OP_GE):
+ case TOKEN(OP_LT):
+ case TOKEN(OP_GT):
+ case TOKEN(OP_NEQ):
+ checkCast(node.GetLeft()->GetType(), TYPE(BOOL));
+ checkCast(node.GetRight()->GetType(), TYPE(BOOL));
+ node.SetType(TYPE(BOOL));
+ break;
+ case TOKEN(OP_ADD):
+ case TOKEN(OP_SUB):
+ case TOKEN(OP_MUL):
+ case TOKEN(OP_DIV):
+ case TOKEN(OP_MOD):
+ break;
+
+ default:
+ SEMANTIC_ERROR(INTERNAL);
+ break;
+ }
}
@@ -126,24 +205,15 @@
switch (node.GetOperator()) {
case TOKEN(OP_BIT_NOT):
- switch (node.GetExpression()->GetType()) {
- case TYPE(ARRAY):
- case TYPE(MATRIX):
- // Array and Matrix meta-op, validity must be determined at runtime
- case TYPE(INT):
- case TYPE(CHAR):
- // Char and Int Okay
-
- node.SetType(node.GetExpression()->GetType());
- break;
-
- default:
- SEMANTIC_ERROR(UNDEFINED_TYPE_OP, mapToken(TOKEN(OP_BIT_NOT)), mapType(node.GetExpression()->GetType()));
- break;
+ if (validBitwiseType(node.GetExpression()->GetType())) {
+ node.SetType(node.GetExpression()->GetType());
+ } else {
+ SEMANTIC_ERROR(UNDEFINED_TYPE_OP, mapToken(TOKEN(OP_BIT_NOT)), mapType(node.GetExpression()->GetType()));
}
break;
case TOKEN(OP_LOGIC_NOT):
- // All types support boolean usage
+ checkCast(node.GetExpression()->GetType(), TYPE(BOOL));
+ node.SetType(TYPE(BOOL));
break;
case TOKEN(OP_SUB):
switch (node.GetExpression()->GetType()) {
@@ -199,10 +269,19 @@
}
-
-void cSemanticASTVisitor::checkCast(ASType_t in_type, ASType_t out_type)
-{
-
+inline bool cSemanticASTVisitor::validBitwiseType(ASType_t type) const {
+ switch (type) {
+ case TYPE(ARRAY):
+ case TYPE(MATRIX):
+ // Array and Matrix meta-op, validity must be determined at runtime
+ case TYPE(INT):
+ case TYPE(CHAR):
+ // Char and Int Okay
+ return true;
+
+ default:
+ return false;
+ }
}
@@ -219,9 +298,16 @@
va_list vargs;
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;
+ 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;
+ break;
case AS_SEMANTIC_ERR_VARIABLE_UNDEFINED:
{
cString varname = va_arg(vargs, const char*);
Modified: development/source/script/cSemanticASTVisitor.h
===================================================================
--- development/source/script/cSemanticASTVisitor.h 2008-02-26 22:50:24 UTC (rev 2384)
+++ development/source/script/cSemanticASTVisitor.h 2008-02-27 04:39:27 UTC (rev 2385)
@@ -90,7 +90,8 @@
void visitUnpackTarget(cASTUnpackTarget&);
private:
- void checkCast(ASType_t in_type, ASType_t out_type);
+
+ inline bool validBitwiseType(ASType_t type) const;
void reportError(bool fail, ASSemanticError_t err, const cASFilePosition& fp, const int line, ...);
};
#endif
More information about the Avida-cvs
mailing list