InOutRulesConditionSwitch.xtend 14 KB

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