InOutRulesConditionSwitch.xtend 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470
  1. package be.uantwerpen.ansymo.semanticadaptation.cg.cpp
  2. import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.Assignment
  3. import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.BoolLiteral
  4. import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.CompositeOutputFunction
  5. import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.DataRule
  6. import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.Declaration
  7. import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.If
  8. import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.InRulesBlock
  9. import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.IntLiteral
  10. import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.IsSet
  11. import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.LValueDeclaration
  12. import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.Literal
  13. import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.Multi
  14. import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.Neg
  15. import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.OutRulesBlock
  16. import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.RealLiteral
  17. import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.RuleCondition
  18. import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.SingleVarDeclaration
  19. import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.StateTransitionFunction
  20. import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.Variable
  21. import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.util.SemanticAdaptationSwitch
  22. import java.util.LinkedHashMap
  23. import java.util.List
  24. import org.eclipse.emf.ecore.EObject
  25. import java.util.ArrayList
  26. import java.util.Optional
  27. abstract class InOutRulesConditionSwitch extends SemanticAdaptationSwitch<ReturnInformation> {
  28. protected var LinkedHashMap<String, Pair<SVType, Object>> globalVars = newLinkedHashMap();
  29. protected var LinkedHashMap<String, GlobalInOutVariable> globalVars2 = newLinkedHashMap();
  30. private var Pair<SVType, Object> lastVal;
  31. protected final String adaptationName;
  32. protected final String adaptationClassName;
  33. private Integer count = 0;
  34. private final String functionPrefix;
  35. protected List<String> functionSignatures = newArrayList();
  36. protected String externalVariableOwner;
  37. protected final LinkedHashMap<String, LinkedHashMap<String, MappedScalarVariable>> mSVars;
  38. protected ArrayList<ConnectedVariable> conVars = newArrayList();
  39. protected final LinkedHashMap<String, SAScalarVariable> SASVs;
  40. protected boolean inRuleCondition;
  41. protected boolean inRuleTransition;
  42. protected boolean inRuleOutput;
  43. new(
  44. String adaptationClassName,
  45. String adaptationName,
  46. String functionPrefix,
  47. LinkedHashMap<String, LinkedHashMap<String, MappedScalarVariable>> mSVars,
  48. LinkedHashMap<String, SAScalarVariable> SASVs
  49. ) {
  50. this.SASVs = SASVs;
  51. this.adaptationName = adaptationName;
  52. this.adaptationClassName = adaptationClassName;
  53. this.functionPrefix = functionPrefix;
  54. this.mSVars = mSVars;
  55. }
  56. /*
  57. * UTILITY FUNCTIONS
  58. */
  59. private def Object convertTypeToObject(SVType type, Literal object) {
  60. switch (type) {
  61. case Real: {
  62. return (object as RealLiteral).value.doubleValue;
  63. }
  64. case Integer: {
  65. return (object as IntLiteral).value;
  66. }
  67. case Boolean: {
  68. return Boolean.parseBoolean((object as BoolLiteral).value);
  69. }
  70. default: {
  71. }
  72. }
  73. }
  74. public def getVars() { return this.globalVars; }
  75. /**
  76. * This function adds a header style function signature to the list <i>functionsignatures</i>
  77. * and returns the source style function signature
  78. */
  79. protected def String createFunctionSignature(String functionName, String type) {
  80. val functionSignature = this.functionPrefix + functionName + this.count + "()";
  81. this.functionSignatures.add(type + " " + functionSignature + ";");
  82. return type + " " + this.adaptationClassName + "::" + functionSignature;
  83. }
  84. def void incrementCount() {
  85. this.count++;
  86. }
  87. /*
  88. * COMPILATION FUNCTIONS
  89. */
  90. override ReturnInformation caseOutRulesBlock(OutRulesBlock object) {
  91. var retVal = new ReturnInformation();
  92. // Get the global variables added to globalVars
  93. for (gVar : object.globalOutVars) {
  94. doSwitch(gVar)
  95. }
  96. for (dataRule : object.eAllContents.toIterable.filter(DataRule)) {
  97. this.incrementCount;
  98. retVal.appendCode(doSwitch(dataRule).code);
  99. }
  100. return retVal;
  101. // var cpp = ""
  102. // for (gVar : object.globalOutVars) {
  103. // doSwitch(gVar)
  104. // }
  105. // for (dataRule : object.eAllContents.toIterable.filter(DataRule)) {
  106. // this.incrementCount;
  107. // cpp += doSwitch(dataRule);
  108. // }
  109. // return cpp;
  110. }
  111. override ReturnInformation caseInRulesBlock(InRulesBlock object) {
  112. var retVal = new ReturnInformation();
  113. // Get the global variables added to globalVars
  114. for (gVar : object.globalInVars) {
  115. doSwitch(gVar)
  116. }
  117. for (DataRule dataRule : object.eAllContents.toIterable.filter(DataRule)) {
  118. // This is used for naming each datarule
  119. this.incrementCount;
  120. retVal.appendCode(doSwitch(dataRule).code);
  121. }
  122. return retVal;
  123. // var cpp = ""
  124. // for (gVar : object.globalInVars) {
  125. // doSwitch(gVar)
  126. // }
  127. // for (DataRule dataRule : object.eAllContents.toIterable.filter(DataRule)) {
  128. // this.incrementCount;
  129. // cpp += doSwitch(dataRule);
  130. // }
  131. // return cpp;
  132. }
  133. override ReturnInformation caseDataRule(DataRule object) {
  134. var retVal = new ReturnInformation();
  135. retVal.code = '''«inRuleCondition = true»
  136. «doSwitch(object.condition).code»
  137. «inRuleCondition = false»
  138. «inRuleTransition = true»
  139. «doSwitch(object.statetransitionfunction).code»
  140. «inRuleTransition = false»
  141. «inRuleOutput = true»
  142. «doSwitch(object.outputfunction).code»
  143. «inRuleOutput = false»
  144. '''
  145. return retVal;
  146. // return '''
  147. // «doSwitch(object.condition)»
  148. // «doSwitch(object.statetransitionfunction)»
  149. // «doSwitch(object.outputfunction)»
  150. // '''
  151. }
  152. override ReturnInformation caseRuleCondition(RuleCondition object) {
  153. var retVal = new ReturnInformation();
  154. val functionSignature = createFunctionSignature("condition", "bool");
  155. retVal.code = '''
  156. «functionSignature»{
  157. return «doSwitch(object.condition).code»;
  158. }
  159. ''';
  160. return retVal;
  161. // val functionSignature = createFunctionSignature("condition", "bool");
  162. // '''
  163. // «functionSignature»{
  164. // return «doSwitch(object.condition)»;
  165. // }
  166. // ''';
  167. }
  168. override ReturnInformation caseStateTransitionFunction(StateTransitionFunction object) {
  169. var retVal = new ReturnInformation();
  170. val functionSig = createFunctionSignature("body", "void");
  171. retVal.code = '''
  172. «functionSig»{
  173. «IF object.expression !== null»
  174. «doSwitch(object.expression).code»
  175. «ENDIF»
  176. «IF object.statements !== null»
  177. «FOR stm : object.statements»
  178. «doSwitch(stm).code»
  179. «ENDFOR»
  180. «ENDIF»
  181. «IF object.assignment !== null»
  182. «doSwitch(object.assignment).code»
  183. «ENDIF»
  184. }
  185. ''';
  186. return retVal;
  187. // val functionSig = createFunctionSignature("body", "void");
  188. // '''
  189. // «functionSig»{
  190. // «IF object.expression !== null»
  191. // «doSwitch(object.expression)»
  192. // «ENDIF»
  193. // «IF object.statements !== null»
  194. // «FOR stm : object.statements»
  195. // «doSwitch(stm)»
  196. // «ENDFOR»
  197. // «ENDIF»
  198. // «IF object.assignment !== null»
  199. // «doSwitch(object.assignment)»
  200. // «ENDIF»
  201. // }
  202. // ''';
  203. }
  204. override ReturnInformation defaultCase(EObject object) {
  205. var retVal = new ReturnInformation();
  206. retVal.code = '''[«object.class»]''';
  207. return retVal;
  208. // return '''[«object.class»]''';
  209. }
  210. override ReturnInformation caseIf(If object) {
  211. var retVal = new ReturnInformation();
  212. retVal.code = '''
  213. if(«doSwitch(object.ifcondition)»){
  214. «FOR stm : object.ifstatements»
  215. «doSwitch(stm).code»
  216. «ENDFOR»
  217. }
  218. ''';
  219. return retVal;
  220. // return '''
  221. // if(«doSwitch(object.ifcondition)»){
  222. // «FOR stm : object.ifstatements»
  223. // «doSwitch(stm)»
  224. // «ENDFOR»
  225. // }
  226. // ''';
  227. }
  228. private def calcConSaSvData(SAScalarVariable SASV, ReturnInformation rI) {
  229. if (SASV !== null) {
  230. if (rI.typeIsSet) {
  231. SASV.type = rI.type;
  232. SASV.variability = Optional.of(Conversions.fmiTypeToVariability(rI.type));
  233. return;
  234. } else if (rI.conGlobVar !== null) {
  235. SASV.type = rI.conGlobVar.type;
  236. SASV.variability = Optional.of(Conversions.fmiTypeToVariability(rI.conGlobVar.type));
  237. return;
  238. }
  239. }
  240. throw new Exception("Not enough information to determine content of the SASV: " + SASV.name);
  241. }
  242. override ReturnInformation caseAssignment(Assignment object) {
  243. var retVal = new ReturnInformation();
  244. var lValSwitch = doSwitch(object.lvalue);
  245. var rValSwitch = doSwitch(object.expr);
  246. // Here we set the information necessary to create a scalar variables in the model description for the SA.
  247. if (inRuleTransition) {
  248. if (rValSwitch.conSaSv !== null) {
  249. calcConSaSvData(rValSwitch.conSaSv, lValSwitch);
  250. }
  251. } else if (inRuleOutput) {
  252. calcConSaSvData(lValSwitch.conSaSv, rValSwitch);
  253. }
  254. retVal.code = '''«lValSwitch.code» = «rValSwitch.code»;''';
  255. return retVal;
  256. // return '''«doSwitch(object.lvalue)» = «doSwitch(object.expr)»;'''
  257. }
  258. override ReturnInformation caseMulti(Multi object) {
  259. val doSwitchLeft = doSwitch(object.left);
  260. val doSwitchRight = doSwitch(object.right);
  261. var retVal = new ReturnInformation(doSwitchLeft, doSwitchRight);
  262. retVal.code = '''«doSwitch(object.left).code» * «doSwitch(object.right).code»''';
  263. return retVal;
  264. // return '''«doSwitch(object.left)» * «doSwitch(object.right)»''';
  265. }
  266. override ReturnInformation caseNeg(Neg object) {
  267. var doSwitch = doSwitch(object.right);
  268. var retVal = new ReturnInformation(doSwitch);
  269. retVal.code = doSwitch.code;
  270. return retVal;
  271. // return '''-«doSwitch(object.right)»'''
  272. }
  273. override ReturnInformation caseSingleVarDeclaration(SingleVarDeclaration object) {
  274. var retVal = new ReturnInformation();
  275. retVal.code = '''«object.name»''';
  276. return retVal;
  277. // var returnVal = '''«object.name»'''
  278. // return returnVal;
  279. }
  280. override ReturnInformation caseCompositeOutputFunction(CompositeOutputFunction object) {
  281. var retVal = new ReturnInformation();
  282. val functionSig = createFunctionSignature("flush", "void");
  283. retVal.code = '''
  284. «functionSig»{
  285. «FOR stm : object.statements»
  286. «doSwitch(stm).code»
  287. «ENDFOR»
  288. }
  289. ''';
  290. return retVal;
  291. // val functionSig = createFunctionSignature("flush", "void");
  292. // val returnVal = '''
  293. // «functionSig»{
  294. // «FOR stm : object.statements»
  295. // «doSwitch(stm)»
  296. // «ENDFOR»
  297. // }
  298. // ''';
  299. // return returnVal;
  300. }
  301. override ReturnInformation caseVariable(Variable object) {
  302. var retVal = new ReturnInformation();
  303. if (object.owner === null || object.owner.name == this.adaptationName) {
  304. retVal.code = '''this->«object.ref.name»''';
  305. if (SASVs.containsKey(object.ref.name)) {
  306. retVal.conSaSv = SASVs.get(object.ref.name);
  307. } else if (globalVars2.containsKey(object.ref.name)) {
  308. retVal.conGlobVar = globalVars2.get(object.ref.name);
  309. }
  310. } else {
  311. // TODO: Extract the correct variable here
  312. this.externalVariableOwner = object.owner.name;
  313. retVal.code = '''«doSwitch(object.ref).code»''';
  314. }
  315. return retVal;
  316. // if (object.owner === null || object.owner.name == this.adaptationName) {
  317. // return '''this->«object.ref.name»''';
  318. // } else {
  319. // this.externalVariableOwner = object.owner.name;
  320. // return '''«doSwitch(object.ref)»''';
  321. // }
  322. }
  323. override ReturnInformation caseLValueDeclaration(LValueDeclaration object) {
  324. var retVal = new ReturnInformation();
  325. retVal.code = '''«object.name»''';
  326. return retVal;
  327. // return '''«object.name»'''
  328. }
  329. /*
  330. * This is out var and in var declarations.
  331. */
  332. override ReturnInformation caseDeclaration(Declaration object) {
  333. var retVal2 = new ReturnInformation();
  334. for (decl : object.declarations) {
  335. var doSwitchRes = doSwitch(decl.expr);
  336. retVal2.appendCode(doSwitchRes.code);
  337. var globVar = new GlobalInOutVariable();
  338. globVar.name = decl.name;
  339. globVar.value = doSwitchRes.value;
  340. globVar.type = doSwitchRes.type;
  341. globalVars2.put(decl.name, globVar);
  342. }
  343. return retVal2;
  344. // var returnVal = "";
  345. //
  346. // for (decl : object.declarations) {
  347. // returnVal += doSwitch(decl.expr);
  348. // globalVars.put(decl.name, lastVal);
  349. // }
  350. // return returnVal;
  351. }
  352. override ReturnInformation caseIsSet(IsSet object) {
  353. var retInfo = new ReturnInformation();
  354. // retInfo.type = SVType.Real;
  355. // retInfo.value = convertTypeToObject(retInfo.type, object);
  356. retInfo.code = '''this->isSet«(object.args as Variable).ref.name»''';
  357. return retInfo;
  358. // return '''this->isSet«(object.args as Variable).ref.name»'''
  359. }
  360. override ReturnInformation caseRealLiteral(RealLiteral object) {
  361. var retInfo = new ReturnInformation();
  362. retInfo.type = SVType.Real;
  363. retInfo.value = convertTypeToObject(retInfo.type, object);
  364. retInfo.code = '''«object.value»''';
  365. return retInfo;
  366. // lastVal = convertType(SVType.Real, object);
  367. // return '''«object.value»''';
  368. }
  369. override ReturnInformation caseIntLiteral(IntLiteral object) {
  370. var retInfo = new ReturnInformation();
  371. retInfo.type = SVType.Integer;
  372. retInfo.value = convertTypeToObject(retInfo.type, object);
  373. retInfo.code = '''«object.value»''';
  374. return retInfo;
  375. // return '''«object.value»''';
  376. }
  377. override ReturnInformation caseBoolLiteral(BoolLiteral object) {
  378. var retInfo = new ReturnInformation();
  379. retInfo.type = SVType.Boolean;
  380. retInfo.value = convertTypeToObject(retInfo.type, object);
  381. retInfo.code = '''«object.value»''';
  382. return retInfo;
  383. // return '''«object.value»''';
  384. }
  385. // private def Pair<SVType, Object> convertType(SVType type, Literal object) {
  386. // switch (type) {
  387. // case Real: {
  388. // return type -> (object as RealLiteral).value.doubleValue;
  389. // }
  390. // default: {
  391. // }
  392. // }
  393. // }
  394. }