BasicConditionSwitch.xtend 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  1. package be.uantwerpen.ansymo.semanticadaptation.cg.cpp.generation
  2. import be.uantwerpen.ansymo.semanticadaptation.cg.cpp.data.ReturnInformation
  3. import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.util.SemanticAdaptationSwitch
  4. import org.eclipse.emf.ecore.EObject
  5. import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.Multi
  6. import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.Div
  7. import be.uantwerpen.ansymo.semanticadaptation.cg.cpp.data.SVType
  8. import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.Neg
  9. import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.RealLiteral
  10. import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.IntLiteral
  11. import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.Literal
  12. import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.BoolLiteral
  13. import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.Min
  14. import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.Minus
  15. import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.Plus
  16. import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.LessThan
  17. import be.uantwerpen.ansymo.semanticadaptation.cg.cpp.exceptions.TypeException
  18. import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.Or
  19. import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.NotEquals
  20. import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.GreaterThanOrEquals
  21. import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.And
  22. import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.Not
  23. import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.GreaterThan
  24. import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.PassedTime
  25. import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.MinorStepSize
  26. class BasicConditionSwitch extends SemanticAdaptationSwitch<ReturnInformation> {
  27. private def Object convertTypeToObject(SVType type, Literal object) {
  28. switch (type) {
  29. case Real: {
  30. return (object as RealLiteral).value.doubleValue;
  31. }
  32. case Integer: {
  33. return (object as IntLiteral).value;
  34. }
  35. case Boolean: {
  36. return Boolean.parseBoolean((object as BoolLiteral).value);
  37. }
  38. default: {
  39. }
  40. }
  41. }
  42. private def String MathOperationParenthesisHandler(boolean enforceOperationsOrder, String code) {
  43. if (enforceOperationsOrder) {
  44. return '''(«code»)''';
  45. } else {
  46. return code;
  47. }
  48. }
  49. protected def String CreateMathOperationString(String mathOperator, ReturnInformation left,
  50. ReturnInformation right) {
  51. var returnVal = MathOperationParenthesisHandler(left.enforceOperationsOrder, left.code)
  52. returnVal += " " + mathOperator + " ";
  53. returnVal += MathOperationParenthesisHandler(right.enforceOperationsOrder, right.code)
  54. return returnVal;
  55. }
  56. override ReturnInformation caseRealLiteral(RealLiteral object) {
  57. var retInfo = new ReturnInformation();
  58. retInfo.type = SVType.Real;
  59. retInfo.value = convertTypeToObject(retInfo.type, object);
  60. retInfo.code = '''«object.value»''';
  61. return retInfo;
  62. }
  63. override ReturnInformation caseIntLiteral(IntLiteral object) {
  64. var retInfo = new ReturnInformation();
  65. retInfo.type = SVType.Integer;
  66. retInfo.value = convertTypeToObject(retInfo.type, object);
  67. retInfo.code = '''«object.value»''';
  68. return retInfo;
  69. }
  70. override ReturnInformation caseBoolLiteral(BoolLiteral object) {
  71. var retInfo = new ReturnInformation();
  72. retInfo.type = SVType.Boolean;
  73. retInfo.value = convertTypeToObject(retInfo.type, object);
  74. retInfo.code = '''«object.value»''';
  75. return retInfo;
  76. }
  77. override ReturnInformation defaultCase(EObject object) {
  78. var retVal = new ReturnInformation();
  79. retVal.code = '''[«object.class»]''';
  80. return retVal;
  81. }
  82. override ReturnInformation caseMulti(Multi object) {
  83. val doSwitchLeft = doSwitch(object.left);
  84. val doSwitchRight = doSwitch(object.right);
  85. var retVal = new ReturnInformation(doSwitchLeft, doSwitchRight);
  86. retVal.code = CreateMathOperationString("*", doSwitchLeft, doSwitchRight);
  87. // retVal.code = '''«doSwitchLeft.code» * «doSwitchRight.code»''';
  88. retVal.enforceOperationsOrder = true;
  89. return retVal;
  90. }
  91. override ReturnInformation caseDiv(Div object) {
  92. val doSwitchLeft = doSwitch(object.left);
  93. val doSwitchRight = doSwitch(object.right);
  94. var retVal = new ReturnInformation(doSwitchLeft, doSwitchRight);
  95. retVal.code = CreateMathOperationString("/", doSwitchLeft, doSwitchRight);
  96. // retVal.code = '''«doSwitchLeft.code» / «doSwitchRight.code»''';
  97. retVal.type = SVType.Real;
  98. retVal.forceType = true;
  99. retVal.enforceOperationsOrder = true;
  100. return retVal;
  101. }
  102. override ReturnInformation casePassedTime(PassedTime object) {
  103. var retVal = new ReturnInformation();
  104. retVal.code = '''dt''';
  105. retVal.type = SVType.Real;
  106. retVal.forceType = true;
  107. return retVal;
  108. }
  109. override ReturnInformation caseMinorStepSize(MinorStepSize object) {
  110. var retVal = new ReturnInformation();
  111. retVal.code = '''h''';
  112. retVal.type = SVType.Real;
  113. retVal.forceType = true;
  114. return retVal;
  115. }
  116. override ReturnInformation caseNeg(Neg object) {
  117. var doSwitch = doSwitch(object.right);
  118. var retVal = new ReturnInformation(doSwitch);
  119. retVal.code = doSwitch.code;
  120. return retVal;
  121. }
  122. override ReturnInformation caseMin(Min object) {
  123. var retInfo = new ReturnInformation();
  124. var doSwitchResCode = newArrayList();
  125. for (expr : object.args) {
  126. val doSwitchRes_ = this.doSwitch(expr);
  127. doSwitchResCode.add(doSwitchRes_.code);
  128. retInfo = new ReturnInformation(retInfo, doSwitchRes_);
  129. }
  130. retInfo.code = '''min(«doSwitchResCode.join(",")»)'''
  131. return retInfo;
  132. }
  133. override ReturnInformation caseMinus(Minus object) {
  134. val doSwitchLeft = doSwitch(object.left);
  135. val doSwitchRight = doSwitch(object.right);
  136. var retVal = new ReturnInformation(doSwitchLeft, doSwitchRight);
  137. retVal.code = CreateMathOperationString("-", doSwitchLeft, doSwitchRight);
  138. // retVal.code = '''«doSwitchLeft.code» - «doSwitchRight.code»''';
  139. retVal.enforceOperationsOrder = true;
  140. return retVal;
  141. }
  142. override ReturnInformation casePlus(Plus object) {
  143. val doSwitchLeft = doSwitch(object.left);
  144. val doSwitchRight = doSwitch(object.right);
  145. var retVal = new ReturnInformation(doSwitchLeft, doSwitchRight);
  146. retVal.code = CreateMathOperationString("+", doSwitchLeft, doSwitchRight);
  147. // retVal.code = '''«doSwitchLeft.code» + «doSwitchRight.code»''';
  148. retVal.enforceOperationsOrder = true;
  149. return retVal;
  150. }
  151. override ReturnInformation caseGreaterThan(GreaterThan object) {
  152. var ret = new ReturnInformation();
  153. val left = doSwitch(object.left);
  154. val right = doSwitch(object.right);
  155. val code = '''«left.code» > «right.code»'''
  156. if (!Conversions.isTypeANumber(left.type) || !Conversions.isTypeANumber(right.type)) {
  157. throw new TypeException('''Wrong types at: «code»''');
  158. }
  159. ret.type = SVType.Boolean;
  160. ret.code = code;
  161. return ret;
  162. }
  163. override ReturnInformation caseGreaterThanOrEquals(GreaterThanOrEquals object) {
  164. var ret = new ReturnInformation();
  165. val left = doSwitch(object.left);
  166. val right = doSwitch(object.right);
  167. val code = '''«left.code» >= «right.code»'''
  168. if (!Conversions.isTypeANumber(left.type) || !Conversions.isTypeANumber(right.type)) {
  169. throw new TypeException('''Wrong types at: «code»''');
  170. }
  171. ret.type = SVType.Boolean;
  172. ret.code = code;
  173. return ret;
  174. }
  175. override ReturnInformation caseNotEquals(NotEquals object) {
  176. var ret = new ReturnInformation();
  177. val left = doSwitch(object.left);
  178. val right = doSwitch(object.right);
  179. val code = '''«left.code» != «right.code»'''
  180. if (left.type !== right.type) {
  181. throw new TypeException('''Wrong types at: «code»''');
  182. }
  183. ret.type = SVType.Boolean;
  184. ret.code = code;
  185. return ret;
  186. }
  187. override ReturnInformation caseLessThan(LessThan object) {
  188. var ret = new ReturnInformation();
  189. val left = doSwitch(object.left);
  190. val right = doSwitch(object.right);
  191. val code = '''«left.code» < «right.code»'''
  192. if (!Conversions.isTypeANumber(left.type) || !Conversions.isTypeANumber(right.type)) {
  193. throw new TypeException('''Wrong types at: «code»''');
  194. }
  195. ret.type = SVType.Boolean;
  196. ret.code = code;
  197. return ret;
  198. }
  199. override ReturnInformation caseNot(Not object) {
  200. var ret = new ReturnInformation();
  201. val res = doSwitch(object.left);
  202. if (res.type !== SVType.Boolean) {
  203. throw new TypeException('''Wrong types at: «res.code»''');
  204. }
  205. ret.type = SVType.Boolean;
  206. ret.code = res.code;
  207. return ret;
  208. }
  209. override ReturnInformation caseAnd(And object) {
  210. var ret = new ReturnInformation();
  211. val left = doSwitch(object.left);
  212. val right = doSwitch(object.right);
  213. val code = '''«left.code» && «right.code»'''
  214. if (left.type !== SVType.Boolean || right.type !== SVType.Boolean) {
  215. throw new TypeException('''Wrong types at: «code»''');
  216. }
  217. ret.type = SVType.Boolean;
  218. ret.code = code;
  219. return ret;
  220. }
  221. override ReturnInformation caseOr(Or object) {
  222. var ret = new ReturnInformation();
  223. val left = doSwitch(object.left);
  224. val right = doSwitch(object.right);
  225. val code = '''«left.code» || «right.code»'''
  226. if (left.type !== SVType.Boolean || right.type !== SVType.Boolean) {
  227. throw new TypeException('''Wrong types at: «code»''');
  228. }
  229. ret.type = SVType.Boolean;
  230. ret.code = code;
  231. return ret;
  232. }
  233. }