]> AND Private Git Repository - blast.git/blob - BlockImplementation.cpp
Logo AND Algorithmique Numérique Distribuée

Private GIT Repository
started VHDL generation of GroupBlock
[blast.git] / BlockImplementation.cpp
1 #include "BlockImplementation.h"\r
2 \r
3 #include "FunctionalBlock.h"\r
4 #include "ReferenceBlock.h"\r
5 #include "ReferenceInterface.h"\r
6 #include "FunctionalInterface.h"\r
7 #include "BlockParameter.h"\r
8 #include <QHashIterator>\r
9 \r
10 \r
11 BlockImplementation::BlockImplementation(const QString& _xmlFile) {\r
12   xmlFile = _xmlFile;\r
13   productionCounter = "";\r
14   delta = "";\r
15 \r
16   evaluator = new ArithmeticEvaluator;\r
17   evaluator->setVariableMarkers("@$");\r
18 \r
19   noPatterns = true;\r
20 }\r
21 \r
22 BlockImplementation::BlockImplementation(const QString& _xmlFile, const QString &_referenceXml, const QString &_referenceMd5) {\r
23   xmlFile = _xmlFile;  \r
24   productionCounter = "";\r
25   delta = "";\r
26   referenceXml = _referenceXml;\r
27   referenceMd5 = _referenceMd5;\r
28 \r
29   noPatterns = true;\r
30 }\r
31 \r
32 void BlockImplementation::loadPatterns(QDomElement& root) throw(Exception) {\r
33     \r
34   QDomNodeList patternNode = root.elementsByTagName("patterns");\r
35   \r
36   if (patternNode.isEmpty()) {\r
37     cout << "impl has no patterns" << endl;\r
38     return;\r
39   }\r
40   \r
41   QDomElement patternElt = patternNode.at(0).toElement();\r
42   \r
43   QDomElement eltDelta  = patternElt.firstChildElement("delta");\r
44   delta = eltDelta.attribute("value","none");\r
45   if (delta == "none") throw(Exception(IMPLFILE_CORRUPTED));\r
46 \r
47   QDomElement eltCons  = eltDelta.nextSiblingElement("consumption");\r
48   \r
49   QDomNodeList listNodeInput = eltCons.elementsByTagName("input");\r
50   for(int i=0; i<listNodeInput.size(); i++) {\r
51     QDomNode node = listNodeInput.at(i);    \r
52     QDomElement elt = node.toElement();    \r
53     QString nameStr = elt.attribute("name","none");\r
54     if (nameStr == "none") throw(Exception(IMPLFILE_CORRUPTED));\r
55     QString patternStr = elt.attribute("pattern","none");\r
56     if (patternStr == "none") throw(Exception(IMPLFILE_CORRUPTED));\r
57     consumptionPattern.insert(nameStr,patternStr);\r
58   }\r
59   \r
60   QDomElement eltProd  = eltCons.nextSiblingElement("production");\r
61   \r
62   productionCounter = eltProd.attribute("counter","none");\r
63   QDomNodeList listNodeOutput = eltProd.elementsByTagName("output");\r
64   for(int i=0; i<listNodeOutput.size(); i++) {\r
65     QDomNode node = listNodeOutput.at(i);    \r
66     QDomElement elt = node.toElement();        \r
67     QString nameStr = elt.attribute("name","none");\r
68     if (nameStr == "none") throw(Exception(IMPLFILE_CORRUPTED));\r
69     QString patternStr = elt.attribute("pattern","none");    \r
70     if (patternStr == "none") throw(Exception(IMPLFILE_CORRUPTED));\r
71     productionPattern.insert(nameStr,patternStr);    \r
72   }\r
73   cout << "patterns summary:" << endl;\r
74   QHashIterator<QString,QString> iterP(productionPattern);\r
75   while (iterP.hasNext()) {\r
76     iterP.next();\r
77     cout << qPrintable(iterP.key()) << " -> " << qPrintable(iterP.value()) << endl;\r
78   }\r
79   cout << "impls patterns read correctly" << endl;\r
80   noPatterns = false;\r
81 }\r
82 \r
83 bool BlockImplementation::checkPatterns() {\r
84 \r
85 \r
86   if (reference == NULL) {\r
87     cout << "no ref. while checking patterns of implementation " << endl;\r
88     return false;\r
89   }\r
90   \r
91   AbstractInterface* iface;  \r
92   QHashIterator<QString,QString> iterI(consumptionPattern);\r
93   while (iterI.hasNext()) {\r
94     iterI.next();\r
95     iface = reference->getIfaceFromName(iterI.key());\r
96     if (iface == NULL) {\r
97       cout << "cannot found an input  ref. iface for impl. iface " << qPrintable(iterI.key()) << endl;\r
98       return false;\r
99     }\r
100   }\r
101   QHashIterator<QString,QString> iterO(productionPattern);\r
102   while (iterO.hasNext()) {\r
103     iterO.next();\r
104     iface = reference->getIfaceFromName(iterO.key());\r
105     if (iface == NULL) {\r
106       cout << "cannot found an output  ref. iface for impl. iface " << qPrintable(iterI.key()) << endl;\r
107       return false;\r
108     }\r
109   }  \r
110   return true;  \r
111 }\r
112 \r
113 QString BlockImplementation::eval(QString line, QTextStream& out) {\r
114   QString res, s, begLine, endLine, expr;\r
115   evaluator->setExpression(line);\r
116   QRegExp *rxString = new QRegExp("(.*)@{(.*)}(.*)");\r
117   QRegExp *rxValue = new QRegExp("(.*)@val{(.*)}(.*)");\r
118   QRegExp *rxExpr = new QRegExp(".*@eval{(.*)}.*");\r
119 \r
120   int nbAt = line.count('@');\r
121   while(nbAt != 0) {\r
122     for(int i = 0; i < line.size(); i++) {\r
123       if(rxString->indexIn(line)) {\r
124         begLine = rxString->cap(1);\r
125         s = rxString->cap(2);\r
126         endLine = rxString->cap(3);\r
127         res = begLine + evalString(s) + endLine + '\n';\r
128         nbAt --;\r
129       }\r
130     }\r
131     for(int i = 0; i < line.size(); i++) {\r
132       if(rxValue->indexIn(line)) {\r
133         begLine = rxValue->cap(1);\r
134         s = rxValue->cap(2);\r
135         endLine = rxValue->cap(3);\r
136         res = begLine + evalValue(s) + endLine + '\n';\r
137         nbAt --;\r
138       }\r
139     }\r
140     for(int i = 0; i < line.size(); i++) {\r
141       if(rxExpr->indexIn(line)) {\r
142         expr = rxExpr->cap(1);\r
143         if(expr.count('@') == 0) {\r
144           evaluator->setExpression(expr);\r
145           s = QString::number(evaluator->evaluate());\r
146         }\r
147         res = begLine + s + endLine + '\n';\r
148         nbAt --;\r
149       }\r
150     }\r
151   }\r
152   return res;\r
153 }\r
154 \r
155 QString BlockImplementation::evalComplex(QString line, int id) {\r
156   QString res, s, begLine, endLine, expr;\r
157   QRegExp *rxString = new QRegExp("(.*)@{(.*)}(.*)");\r
158   QRegExp *rxValue = new QRegExp("(.*)@val{(.*)}(.*)");\r
159   QRegExp *rxExpr = new QRegExp(".*@eval{(.*)}.*");\r
160   QRegExp *rxFor = new QRegExp("@foreach{.*}(@{.*})(.*)@endforeach");\r
161   QRegExp *rxCase = new QRegExp("@caseeach{.*,(.*),(.*)}(@{.*})(.*)@endcaseeach");\r
162   QRegExp *rxCaseDown = new QRegExp("@#-:(.*)");\r
163   QRegExp *rxCaseUp = new QRegExp("@#:(.*)");\r
164   evaluator->setExpression(line);\r
165 \r
166   int nbAt = line.count('@') - 2;\r
167   while(nbAt != 0) {\r
168     for(int i = 0; i < line.size(); i++) {\r
169       if(rxString->indexIn(line)) {\r
170         begLine = rxString->cap(1);\r
171         s = rxString->cap(2);\r
172         endLine = rxString->cap(3);\r
173         if(evalStringComplex(s)->size() == 0)\r
174           line = begLine + evalString(s) + endLine;\r
175         nbAt --;\r
176       }\r
177     }\r
178     for(int i = 0; i < line.size(); i++) {\r
179       if(rxValue->indexIn(line)) {\r
180         begLine = rxValue->cap(1);\r
181         s = rxValue->cap(2);\r
182         endLine = rxValue->cap(3);\r
183         line = begLine + evalValue(s) + endLine;\r
184         nbAt --;\r
185       }\r
186     }\r
187     for(int i = 0; i < line.size(); i++) {\r
188       if(rxExpr->indexIn(line)) {\r
189         expr = rxExpr->cap(1);\r
190         if(expr.count('@') == 0) {\r
191           evaluator->setExpression(expr);\r
192           s = QString::number(evaluator->evaluate());\r
193         }\r
194         res = begLine + s + endLine + '\n';\r
195         nbAt --;\r
196       }\r
197     }\r
198   }\r
199 \r
200   if(id == 1) {\r
201     if(rxFor->indexIn(line)) {\r
202       QString intName, instruc;\r
203       intName = rxFor->cap(1);\r
204       instruc = rxFor->cap(2);\r
205       QList<AbstractInterface*> *intList = evalStringComplex(intName);\r
206       if(intList->size() != 0) {\r
207         for(int i = 0; i < intList->size(); i++) {\r
208           res = intList->at(i)->getName() + instruc + '\n';\r
209         }\r
210       }\r
211     }\r
212   }\r
213 \r
214   else if(id == 2) {\r
215     if(rxCase->indexIn(line)) {\r
216       QString intName, sigName, cases, instruc;\r
217       int number;\r
218       sigName = rxCase->cap(1);\r
219       cases = rxCase->cap(2);\r
220       intName = rxCase->cap(3);\r
221       instruc = rxCase->cap(4);\r
222       QList<AbstractInterface*> *intList = evalStringComplex(intName);\r
223       int listSize = intList->count();\r
224       res = "case " + sigName + " is\n";\r
225       if(rxCaseUp->indexIn(cases)) {\r
226         number = rxCaseUp->cap(1).toInt();\r
227         for(int j = number; j < listSize; j++) {\r
228           if(listSize > 0) {\r
229             for(int i = 0; i < listSize; i++) {\r
230               res += "\twhen " + QString::number(number) + " " + intList->at(i)->getName() + instruc + "\n";\r
231             }\r
232           }\r
233           else\r
234             res += "\twhen " + number + ' ' + intName + instruc + "\n";\r
235           number++;\r
236         }\r
237       }\r
238       if(rxCaseDown->indexIn(cases)) {\r
239         number = rxCaseDown->cap(1).toInt();\r
240         for(int j = number; j < listSize; j++) {\r
241           if(listSize > 0) {\r
242             for(int i = 0; i < listSize; i++) {\r
243               res += "\twhen " + QString::number(number) + " " + intList->at(i)->getName() + instruc + "\n";\r
244             }\r
245           }\r
246           else\r
247             res += "\twhen " + number + ' ' + intName + instruc + "\n";\r
248           number--;\r
249         }\r
250         res += "end case ;\n";\r
251       }\r
252     }\r
253   }\r
254   return res;\r
255 }\r
256 \r
257 QString BlockImplementation::evalString(QString s) {\r
258 \r
259   QString name = getIfaceUserName(block->AbstractBlock::getIfaceFromName(s));\r
260   return name;\r
261 }\r
262 \r
263 QList<AbstractInterface*>* BlockImplementation::evalStringComplex(QString s) {\r
264 \r
265   int j = 0;\r
266   QList<AbstractInterface*> *listInterfaces = new QList<AbstractInterface*>();\r
267   AbstractInterface *inter = block->AbstractBlock::getIfaceFromName(s);\r
268   QList<AbstractInterface*> listIntBlock = block->getInterfaces();\r
269   for(int i = 0; i < listIntBlock.size(); i++) {\r
270     if(inter->getName().compare(listIntBlock.at(i)->getName()) < -1) {\r
271       listInterfaces->insert(j, inter);\r
272       j ++;\r
273     }\r
274   }\r
275   return listInterfaces;\r
276 }\r
277 \r
278 QString BlockImplementation::evalValue(QString s) {\r
279 \r
280   QString val = "";\r
281   if(paramMap.contains(s))\r
282     val = paramMap.value(s);\r
283   return val;\r
284 }\r
285 \r
286 QString BlockImplementation::getIfaceUserName(AbstractInterface* refIface) {\r
287 \r
288   if (! refIface->isReferenceInterface()) return "";\r
289 \r
290   AbstractInterface* funcIface = NULL;\r
291 \r
292   if (refIface->getDirection() == AbstractInterface::Input) {\r
293     foreach(AbstractInterface* iface, block->getInputs()) {\r
294       FunctionalInterface* fi = (FunctionalInterface*)iface;\r
295       if (fi->getReference() == refIface) {\r
296         funcIface = iface;\r
297         break;\r
298       }\r
299     }\r
300   }\r
301   else if (refIface->getDirection() == AbstractInterface::Output) {\r
302     foreach(AbstractInterface* iface, block->getOutputs()) {\r
303       FunctionalInterface* fi = (FunctionalInterface*)iface;\r
304       if (fi->getReference() == refIface) {\r
305         funcIface = iface;\r
306         break;\r
307       }\r
308     }\r
309   }\r
310   else if (refIface->getDirection() == AbstractInterface::InOut) {\r
311     foreach(AbstractInterface* iface, block->getBidirs()) {\r
312       FunctionalInterface* fi = (FunctionalInterface*)iface;\r
313       if (fi->getReference() == refIface) {\r
314         funcIface = iface;\r
315         break;\r
316       }\r
317     }\r
318   }\r
319   if (funcIface == NULL) return "";\r
320 \r
321   return funcIface->getName();\r
322 }\r
323 \r
324 QDataStream& operator<<(QDataStream &out, const BlockImplementation &impl) {\r
325 \r
326   out.setVersion(QDataStream::Qt_5_0);\r
327 \r
328   QByteArray blockData;\r
329   QDataStream toWrite(&blockData, QIODevice::WriteOnly);\r
330 \r
331   toWrite << impl.xmlFile;\r
332   toWrite << impl.referenceXml;\r
333   toWrite << impl.referenceMd5;\r
334   // saving patterns\r
335   toWrite << impl.noPatterns;\r
336   toWrite << impl.delta;\r
337   toWrite << impl.consumptionPattern;\r
338   toWrite << impl.productionPattern;\r
339   toWrite << impl.productionCounter;\r
340   \r
341   out << blockData;\r
342 \r
343   return out;\r
344 }\r
345 \r
346 QDataStream& operator>>(QDataStream &in, BlockImplementation &impl) {\r
347 \r
348   quint32 blockSize;\r
349 \r
350   in.setVersion(QDataStream::Qt_5_0);\r
351 \r
352   in >> blockSize;\r
353 \r
354   in >> impl.xmlFile;\r
355   in >> impl.referenceXml;\r
356   in >> impl.referenceMd5;\r
357   // loading patterns\r
358   in >> impl.noPatterns;\r
359   in >> impl.delta;\r
360   in >> impl.consumptionPattern;\r
361   in >> impl.productionPattern;\r
362   in >> impl.productionCounter;\r
363 \r
364   return in;\r
365 }\r
366 \r
367 QString BlockImplementation::calculateWidth(QString s){\r
368   QRegExp *rxWidth = new QRegExp("$*([a-zA-Z0-9_-]*)");\r
369   QStringList matchList = s.split(" ");\r
370   int pos = 0;\r
371   QString res, line;\r
372   QList<BlockParameter*> listParams = reference->getParameters();\r
373 \r
374   while ((pos = rxWidth->indexIn(s, pos)) != -1) {\r
375     matchList << rxWidth->cap(1);\r
376     pos += rxWidth->matchedLength();\r
377   }\r
378 \r
379   for (int i = 0; i < matchList.size(); i++) {\r
380     QString match = matchList.at(i);\r
381     if(rxWidth->indexIn(match)) {\r
382       for(int j = 0; j < listParams.size(); j++) {\r
383         if(match.compare(listParams.at(j)->getName())) {\r
384           BlockParameter *param = listParams.at(i);\r
385           if(param->getContext() == "generic") {\r
386             match = match.remove('$');\r
387           }\r
388           else {\r
389             match = param->getValue().toString();\r
390           }\r
391         }\r
392       }\r
393     }\r
394   }\r
395   line = matchList.join(' ');\r
396   evaluator->setExpression(line);\r
397   res = evaluator->evaluate();\r
398   return res;\r
399 }\r
400 \r