tree-typecheck.cpp
Go to the documentation of this file.
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 


aseba
Author(s): Stéphane Magnenat
autogenerated on Thu Jan 2 2014 11:17:17