00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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
00193 implementedEvents.clear();
00194 subroutineTable.clear();
00195 subroutineReverseTable.clear();
00196
00197
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
00207 functionsMap.clear();
00208 for (unsigned i = 0; i < targetDescription->nativeFunctions.size(); i++)
00209 {
00210 functionsMap[targetDescription->nativeFunctions[i].name] = i;
00211 }
00212
00213
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
00222 globalEventsMap.clear();
00223 for (unsigned i = 0; i < commonDefinitions->events.size(); i++)
00224 {
00225 globalEventsMap[commonDefinitions->events[i].name] = i;
00226 }
00227
00228
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 }