00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "tree.h"
00025 #include "../utils/FormatableString.h"
00026 #include <cstdlib>
00027
00028 namespace Aseba
00029 {
00032
00033 std::string Node::typeName(const Node::ReturnType& type) const
00034 {
00035 switch (type)
00036 {
00037 case TYPE_UNIT: return "unit";
00038 case TYPE_BOOL: return "bool";
00039 case TYPE_INT: return "integer";
00040 default: abort(); return "unknown";
00041 }
00042 }
00043
00044 void Node::expectType(const Node::ReturnType& expected, const Node::ReturnType& type) const
00045 {
00046 if (type != expected)
00047 throw Error(sourcePos, FormatableString("Expecting %0 type, found %1 type instead").arg(typeName(expected)).arg(typeName(type)));
00048 };
00049
00050 Node::ReturnType Node::typeCheck() const
00051 {
00052 for (NodesVector::const_iterator it = children.begin(); it != children.end(); ++it)
00053 {
00054 (*it)->typeCheck();
00055 }
00056 return TYPE_UNIT;
00057 }
00058
00059 Node::ReturnType IfWhenNode::typeCheck() const
00060 {
00061 BinaryArithmeticNode* operation = dynamic_cast<BinaryArithmeticNode*>(children[0]);
00062 if ((operation == 0) || (operation->op < ASEBA_OP_EQUAL))
00063 throw Error(children[0]->sourcePos, FormatableString("Expecting a condition, found a %0 instead").arg(children[0]->toNodeName()));
00064 return TYPE_UNIT;
00065 }
00066
00067 Node::ReturnType WhileNode::typeCheck() const
00068 {
00069 BinaryArithmeticNode* operation = dynamic_cast<BinaryArithmeticNode*>(children[0]);
00070 if ((operation == 0) || (operation->op < ASEBA_OP_EQUAL))
00071 throw Error(children[0]->sourcePos, FormatableString("Expecting a condition, found a %0 instead").arg(children[0]->toNodeName()));
00072 return TYPE_UNIT;
00073 }
00074
00075 Node::ReturnType BinaryArithmeticNode::typeCheck() const
00076 {
00077 switch (op)
00078 {
00079 case ASEBA_OP_SHIFT_LEFT:
00080 case ASEBA_OP_SHIFT_RIGHT:
00081 case ASEBA_OP_ADD:
00082 case ASEBA_OP_SUB:
00083 case ASEBA_OP_MULT:
00084 case ASEBA_OP_DIV:
00085 case ASEBA_OP_MOD:
00086 case ASEBA_OP_BIT_OR:
00087 case ASEBA_OP_BIT_XOR:
00088 case ASEBA_OP_BIT_AND:
00089 expectType(TYPE_INT, children[0]->typeCheck());
00090 expectType(TYPE_INT, children[1]->typeCheck());
00091 return TYPE_INT;
00092
00093 case ASEBA_OP_EQUAL:
00094 case ASEBA_OP_NOT_EQUAL:
00095 case ASEBA_OP_BIGGER_THAN:
00096 case ASEBA_OP_BIGGER_EQUAL_THAN:
00097 case ASEBA_OP_SMALLER_THAN:
00098 case ASEBA_OP_SMALLER_EQUAL_THAN:
00099 expectType(TYPE_INT, children[0]->typeCheck());
00100 expectType(TYPE_INT, children[1]->typeCheck());
00101 return TYPE_BOOL;
00102
00103 case ASEBA_OP_OR:
00104 case ASEBA_OP_AND:
00105 expectType(TYPE_BOOL, children[0]->typeCheck());
00106 expectType(TYPE_BOOL, children[1]->typeCheck());
00107 return TYPE_BOOL;
00108
00109 default:
00110 abort();
00111 return TYPE_UNIT;
00112 }
00113 }
00114
00115 Node::ReturnType UnaryArithmeticNode::typeCheck() const
00116 {
00117 switch (op)
00118 {
00119 case ASEBA_UNARY_OP_SUB:
00120 case ASEBA_UNARY_OP_ABS:
00121 case ASEBA_UNARY_OP_BIT_NOT:
00122 expectType(TYPE_INT, children[0]->typeCheck());
00123 return TYPE_INT;
00124
00125 case ASEBA_UNARY_OP_NOT:
00126 expectType(TYPE_BOOL, children[0]->typeCheck());
00127 return TYPE_BOOL;
00128
00129 default:
00130 abort();
00131 return TYPE_UNIT;
00132 }
00133 }
00134
00137 };
00138