identifier-lookup.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 "compiler.h"
00022 #include "../common/consts.h"
00023 #include "tree.h"
00024 #include "../utils/FormatableString.h"
00025 #include <cassert>
00026 #include <cstdlib>
00027 #include <sstream>
00028 #include <iostream>
00029 #include <fstream>
00030 #include <iomanip>
00031 #include <memory>
00032 #include <limits>
00033 #ifndef __APPLE__
00034         #include <malloc.h>
00035 #endif
00036 
00037 namespace Aseba
00038 {
00045 
00047         std::wstring SourcePos::toWString() const
00048         {
00049                 if (valid)
00050                 {
00051                         std::wostringstream oss;
00052                         oss << row + 1 << ':' << column;
00053                         return oss.str();
00054                 }
00055                 else
00056                         return L"";
00057         }
00058         
00060         bool NamedValuesVector::contains(const std::wstring& s, size_t* position) const
00061         {
00062                 for (size_t i = 0; i < size(); i++)
00063                 {
00064                         if ((*this)[i].name == s)
00065                         {
00066                                 if (position)
00067                                         *position = i;
00068                                 return true;
00069                         }
00070                 }
00071                 return false;
00072         }
00073         
00075         template <class T> unsigned int editDistance(const T& s1, const T& s2, const unsigned maxDist)
00076         {
00077                 const size_t len1 = s1.size() + 1, len2 = s2.size() + 1;
00078                 const size_t matSize(len1*len2);
00079                 unsigned *d(reinterpret_cast<unsigned*>(alloca(matSize*sizeof(unsigned))));
00080 
00081                 d[0] = 0;
00082                 for(unsigned i = 1; i < len1; ++i)
00083                         d[i*len2+0] = i;
00084                 for(unsigned i = 1; i < len2; ++i)
00085                         d[i] = i;
00086 
00087                 for(unsigned i = 1; i < len1; ++i)
00088                 {
00089                         bool wasBelowMax(false);
00090                         for(unsigned j = 1; j < len2; ++j)
00091                         {
00092                                 const unsigned cost = std::min(std::min(
00093                                         d[(i - 1)*len2+j] + 1,
00094                                         d[i*len2+(j - 1)] + 1),
00095                                         d[(i - 1)*len2+(j - 1)] + (s1[i - 1] == s2[j - 1] ? 0 : 1)
00096                                 );
00097                                 if (cost < maxDist)
00098                                         wasBelowMax = true;
00099                                 d[i*len2+j] = cost;
00100                         }
00101                         if (!wasBelowMax)
00102                                 return maxDist;
00103                 }
00104                 return d[matSize-1];
00105         }
00106         
00108         template <typename MapType>
00109         typename MapType::const_iterator findInTable(const MapType& map, const std::wstring& name, const SourcePos& pos, const ErrorCode notFoundError, const ErrorCode misspelledError)
00110         {
00111                 typename MapType::const_iterator it(map.find(name));
00112                 if (it == map.end())
00113                 {
00114                         const unsigned maxDist(3);
00115                         std::wstring bestName;
00116                         unsigned bestDist(std::numeric_limits<unsigned>::max());
00117                         for (typename MapType::const_iterator jt(map.begin()); jt != map.end(); ++jt)
00118                         {
00119                                 const std::wstring thatName(jt->first);
00120                                 const unsigned d(editDistance<std::wstring>(name, thatName, maxDist));
00121                                 if (d < bestDist && d < maxDist)
00122                                 {
00123                                         bestDist = d;
00124                                         bestName = thatName;
00125                                 }
00126                         }
00127                         if (bestDist < maxDist)
00128                                 throw TranslatableError(pos, misspelledError).arg(name).arg(bestName);
00129                         else
00130                                 throw TranslatableError(pos, notFoundError).arg(name);
00131                 }
00132                 return it;
00133         }
00134         
00136         Compiler::VariablesMap::const_iterator Compiler::findVariable(const std::wstring& varName, const SourcePos& varPos) const
00137         {
00138                 return findInTable<VariablesMap>(variablesMap, varName, varPos, ERROR_VARIABLE_NOT_DEFINED, ERROR_VARIABLE_NOT_DEFINED_GUESS);
00139         }
00140         
00142         Compiler::FunctionsMap::const_iterator Compiler::findFunction(const std::wstring& funcName, const SourcePos& funcPos) const
00143         {
00144                 return findInTable<FunctionsMap>(functionsMap, funcName, funcPos, ERROR_FUNCTION_NOT_DEFINED, ERROR_FUNCTION_NOT_DEFINED_GUESS);
00145         }
00146         
00148         Compiler::ConstantsMap::const_iterator Compiler::findConstant(const std::wstring& name, const SourcePos& pos) const
00149         {
00150                 return findInTable<ConstantsMap>(constantsMap, name, pos, ERROR_CONSTANT_NOT_DEFINED, ERROR_CONSTANT_NOT_DEFINED_GUESS);
00151         }
00152         
00154         bool Compiler::constantExists(const std::wstring& name) const 
00155         {
00156                 return constantsMap.find(name) != constantsMap.end();
00157         }
00158         
00160         Compiler::EventsMap::const_iterator Compiler::findGlobalEvent(const std::wstring& name, const SourcePos& pos) const
00161         {
00162                 try
00163                 {
00164                         return findInTable<EventsMap>(globalEventsMap, name, pos, ERROR_EVENT_NOT_DEFINED, ERROR_EVENT_NOT_DEFINED_GUESS);
00165                 }
00166                 catch (TranslatableError e)
00167                 {
00168                         if (allEventsMap.find(name) != allEventsMap.end())
00169                                 throw TranslatableError(pos, ERROR_EMIT_LOCAL_EVENT).arg(name);
00170                         else
00171                                 throw e;
00172                 }
00173         }
00174         
00175         Compiler::EventsMap::const_iterator Compiler::findAnyEvent(const std::wstring& name, const SourcePos& pos) const
00176         {
00177                 return findInTable<EventsMap>(allEventsMap, name, pos, ERROR_EVENT_NOT_DEFINED, ERROR_EVENT_NOT_DEFINED_GUESS);
00178         }
00179         
00181         Compiler::SubroutineReverseTable::const_iterator Compiler::findSubroutine(const std::wstring& name, const SourcePos& pos) const
00182         {
00183                 return findInTable<SubroutineReverseTable>(subroutineReverseTable, name, pos, ERROR_SUBROUTINE_NOT_DEFINED, ERROR_SUBROUTINE_NOT_DEFINED_GUESS);
00184         }
00185         
00187         void Compiler::buildMaps()
00188         {
00189                 assert(targetDescription);
00190                 freeVariableIndex = 0;
00191                 
00192                 // erase tables
00193                 implementedEvents.clear();
00194                 subroutineTable.clear();
00195                 subroutineReverseTable.clear();
00196                 
00197                 // fill variables map
00198                 variablesMap.clear();
00199                 for (unsigned i = 0; i < targetDescription->namedVariables.size(); i++)
00200                 {
00201                         variablesMap[targetDescription->namedVariables[i].name] =
00202                                 std::make_pair(freeVariableIndex, targetDescription->namedVariables[i].size);
00203                         freeVariableIndex += targetDescription->namedVariables[i].size;
00204                 }
00205                 
00206                 // fill functions map
00207                 functionsMap.clear();
00208                 for (unsigned i = 0; i < targetDescription->nativeFunctions.size(); i++)
00209                 {
00210                         functionsMap[targetDescription->nativeFunctions[i].name] = i;
00211                 }
00212                 
00213                 // fill contants maps
00214                 constantsMap.clear();
00215                 for (unsigned i = 0; i < commonDefinitions->constants.size(); i++)
00216                 {
00217                         const NamedValue &constant(commonDefinitions->constants[i]);
00218                         constantsMap[constant.name] = constant.value;
00219                 }
00220                 
00221                 // fill global events map
00222                 globalEventsMap.clear();
00223                 for (unsigned i = 0; i < commonDefinitions->events.size(); i++)
00224                 {
00225                         globalEventsMap[commonDefinitions->events[i].name] = i;
00226                 }
00227                 
00228                 // fill global all events map
00229                 allEventsMap = globalEventsMap;
00230                 for (unsigned i = 0; i < targetDescription->localEvents.size(); ++i)
00231                 {
00232                         allEventsMap[targetDescription->localEvents[i].name] = ASEBA_EVENT_LOCAL_EVENTS_START - i;
00233                 }
00234         }
00235         
00238 } // Aseba


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