$search
00001 /* 00002 Aseba - an event-based framework for distributed robot control 00003 Copyright (C) 2007--2012: 00004 Stephane Magnenat <stephane at magnenat dot net> 00005 (http://stephane.magnenat.net) 00006 and other contributors, see authors.txt for details 00007 00008 This program is free software: you can redistribute it and/or modify 00009 it under the terms of the GNU Lesser General Public License as published 00010 by the Free Software Foundation, version 3 of the License. 00011 00012 This program is distributed in the hope that it will be useful, 00013 but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 GNU Lesser General Public License for more details. 00016 00017 You should have received a copy of the GNU Lesser General Public License 00018 along with this program. If not, see <http://www.gnu.org/licenses/>. 00019 */ 00020 00021 #include "tree.h" 00022 #include "../utils/FormatableString.h" 00023 #include <cstdlib> 00024 00025 namespace Aseba 00026 { 00029 00030 std::wstring Node::typeName(const Node::ReturnType& type) const 00031 { 00032 switch (type) 00033 { 00034 case TYPE_UNIT: return L"unit"; 00035 case TYPE_BOOL: return L"bool"; 00036 case TYPE_INT: return L"integer"; 00037 default: abort(); return L"unknown"; 00038 } 00039 } 00040 00041 void Node::expectType(const Node::ReturnType& expected, const Node::ReturnType& type) const 00042 { 00043 if (type != expected) 00044 throw TranslatableError(sourcePos, ERROR_EXPECTING_TYPE).arg(typeName(expected)).arg(typeName(type)); 00045 }; 00046 00047 Node::ReturnType Node::typeCheck() const 00048 { 00049 for (NodesVector::const_iterator it = children.begin(); it != children.end(); ++it) 00050 { 00051 (*it)->typeCheck(); 00052 } 00053 return TYPE_UNIT; 00054 } 00055 00056 Node::ReturnType AssignmentNode::typeCheck() const 00057 { 00058 expectType(TYPE_UNIT, children[0]->typeCheck()); 00059 expectType(TYPE_INT, children[1]->typeCheck()); 00060 return TYPE_UNIT; 00061 } 00062 00063 Node::ReturnType IfWhenNode::typeCheck() const 00064 { 00065 expectType(TYPE_BOOL, children[0]->typeCheck()); 00066 expectType(TYPE_UNIT, children[1]->typeCheck()); 00067 if (children.size() > 2) 00068 expectType(TYPE_UNIT, children[2]->typeCheck()); 00069 00070 BinaryArithmeticNode* binaryOp = dynamic_cast<BinaryArithmeticNode*>(children[0]); 00071 UnaryArithmeticNode* unaryOp = dynamic_cast<UnaryArithmeticNode*>(children[0]); 00072 bool ok(false); 00073 if (binaryOp && binaryOp->op >= ASEBA_OP_EQUAL && binaryOp->op <= ASEBA_OP_AND) 00074 ok = true; 00075 if (unaryOp && unaryOp->op == ASEBA_UNARY_OP_NOT) 00076 ok = true; 00077 00078 if (!ok) 00079 throw TranslatableError(children[0]->sourcePos, ERROR_EXPECTING_CONDITION).arg(children[0]->toNodeName()); 00080 return TYPE_UNIT; 00081 } 00082 00083 Node::ReturnType WhileNode::typeCheck() const 00084 { 00085 expectType(TYPE_BOOL, children[0]->typeCheck()); 00086 expectType(TYPE_UNIT, children[1]->typeCheck()); 00087 00088 BinaryArithmeticNode* binaryOp = dynamic_cast<BinaryArithmeticNode*>(children[0]); 00089 UnaryArithmeticNode* unaryOp = dynamic_cast<UnaryArithmeticNode*>(children[0]); 00090 bool ok(false); 00091 if (binaryOp && binaryOp->op >= ASEBA_OP_EQUAL && binaryOp->op <= ASEBA_OP_AND) 00092 ok = true; 00093 if (unaryOp && unaryOp->op == ASEBA_UNARY_OP_NOT) 00094 ok = true; 00095 00096 if (!ok) 00097 throw TranslatableError(children[0]->sourcePos, ERROR_EXPECTING_CONDITION).arg(children[0]->toNodeName()); 00098 return TYPE_UNIT; 00099 } 00100 00101 Node::ReturnType BinaryArithmeticNode::typeCheck() const 00102 { 00103 switch (op) 00104 { 00105 case ASEBA_OP_SHIFT_LEFT: 00106 case ASEBA_OP_SHIFT_RIGHT: 00107 case ASEBA_OP_ADD: 00108 case ASEBA_OP_SUB: 00109 case ASEBA_OP_MULT: 00110 case ASEBA_OP_DIV: 00111 case ASEBA_OP_MOD: 00112 case ASEBA_OP_BIT_OR: 00113 case ASEBA_OP_BIT_XOR: 00114 case ASEBA_OP_BIT_AND: 00115 expectType(TYPE_INT, children[0]->typeCheck()); 00116 expectType(TYPE_INT, children[1]->typeCheck()); 00117 return TYPE_INT; 00118 00119 case ASEBA_OP_EQUAL: 00120 case ASEBA_OP_NOT_EQUAL: 00121 case ASEBA_OP_BIGGER_THAN: 00122 case ASEBA_OP_BIGGER_EQUAL_THAN: 00123 case ASEBA_OP_SMALLER_THAN: 00124 case ASEBA_OP_SMALLER_EQUAL_THAN: 00125 expectType(TYPE_INT, children[0]->typeCheck()); 00126 expectType(TYPE_INT, children[1]->typeCheck()); 00127 return TYPE_BOOL; 00128 00129 case ASEBA_OP_OR: 00130 case ASEBA_OP_AND: 00131 expectType(TYPE_BOOL, children[0]->typeCheck()); 00132 expectType(TYPE_BOOL, children[1]->typeCheck()); 00133 return TYPE_BOOL; 00134 00135 default: 00136 abort(); 00137 return TYPE_UNIT; 00138 } 00139 } 00140 00141 Node::ReturnType UnaryArithmeticNode::typeCheck() const 00142 { 00143 switch (op) 00144 { 00145 case ASEBA_UNARY_OP_SUB: 00146 case ASEBA_UNARY_OP_ABS: 00147 case ASEBA_UNARY_OP_BIT_NOT: 00148 expectType(TYPE_INT, children[0]->typeCheck()); 00149 return TYPE_INT; 00150 00151 case ASEBA_UNARY_OP_NOT: 00152 expectType(TYPE_BOOL, children[0]->typeCheck()); 00153 return TYPE_BOOL; 00154 00155 default: 00156 abort(); 00157 return TYPE_UNIT; 00158 } 00159 } 00160 00163 }; // Aseba 00164