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

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