CppGenerator.xtend 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607
  1. package be.uantwerpen.ansymo.semanticadaptation.cg.cpp.generation
  2. import be.uantwerpen.ansymo.semanticadaptation.cg.cpp.data.GlobalInOutVariable
  3. import be.uantwerpen.ansymo.semanticadaptation.cg.cpp.data.InOutRulesBlockResult
  4. import be.uantwerpen.ansymo.semanticadaptation.cg.cpp.data.InputOutputRuleType
  5. import be.uantwerpen.ansymo.semanticadaptation.cg.cpp.data.MappedScalarVariable
  6. import be.uantwerpen.ansymo.semanticadaptation.cg.cpp.data.SAScalarVariable
  7. import be.uantwerpen.ansymo.semanticadaptation.cg.cpp.data.SVCausality
  8. import be.uantwerpen.ansymo.semanticadaptation.cg.cpp.data.SVType
  9. import be.uantwerpen.ansymo.semanticadaptation.cg.cpp.data.ScalarVariable
  10. import be.uantwerpen.ansymo.semanticadaptation.cg.cpp.exceptions.IncorrectAmountOfElementsException
  11. import be.uantwerpen.ansymo.semanticadaptation.log.Log
  12. import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.Adaptation
  13. import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.ControlRuleBlock
  14. import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.InOutRules
  15. import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.InRulesBlock
  16. import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.InnerFMU
  17. import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.OutRulesBlock
  18. import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.ParamDeclarations
  19. import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.Port
  20. import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.SemanticAdaptation
  21. import java.io.File
  22. import java.util.ArrayList
  23. import java.util.Collection
  24. import java.util.LinkedHashMap
  25. import java.util.List
  26. import org.eclipse.emf.common.util.EList
  27. import org.eclipse.emf.ecore.resource.Resource
  28. import org.eclipse.xtext.generator.IFileSystemAccess2
  29. import org.eclipse.emf.common.CommonPlugin
  30. import org.eclipse.emf.common.util.URI
  31. class CppGenerator {
  32. private var IFileSystemAccess2 fsa;
  33. private List<File> resourcePaths = newArrayList();
  34. def void doGenerate(Resource resource, IFileSystemAccess2 fsa) {
  35. Log.push("CppGenerator.doGenerate")
  36. val adaptationFolderURI = resource.URI.trimSegments(1)
  37. Log.println("Adaptation folder URI: " + adaptationFolderURI)
  38. doGenerate(resource, fsa, adaptationFolderURI)
  39. Log.pop("CppGenerator.doGenerate")
  40. }
  41. def void doGenerate(Resource resource, IFileSystemAccess2 fsa, URI adaptationFolderURI) {
  42. Log.push("CppGenerator.doGenerate " + adaptationFolderURI)
  43. this.fsa = fsa;
  44. for (SemanticAdaptation type : resource.allContents.toIterable.filter(SemanticAdaptation)) {
  45. type.compile(adaptationFolderURI);
  46. }
  47. Log.pop("CppGenerator.doGenerate" + adaptationFolderURI)
  48. }
  49. // TODO: Verify adaptation.name is not a C++ keyword
  50. def void compile(SemanticAdaptation adaptation, URI adaptationFolderURI) {
  51. Log.push("CppGenerator.compile")
  52. for (Adaptation adap : adaptation.elements.filter(Adaptation)) {
  53. // Value used for scoping variables in the .sa file
  54. val adapInteralRefName = adap.name;
  55. // The CPP class name
  56. val adapClassName = adap.name.toFirstUpper;
  57. // This is the external name used in the model description file for the semantic adaptation FMU.
  58. val adapExternalName = adap.type.name;
  59. // List of FMUs with a pairing between its name and its type.name.
  60. var ArrayList<Pair<String, String>> fmus = newArrayList();
  61. // TODO: Currently only 1 inner fmu is supported
  62. val innerFmus = adap.inner.eAllContents.toList.filter(InnerFMU);
  63. if (innerFmus.size > 1) {
  64. throw new IncorrectAmountOfElementsException("Only one InnerFmu is supported.")
  65. }
  66. if (innerFmus.isEmpty) {
  67. throw new IncorrectAmountOfElementsException("The adaptation does not contain any InnerFMUs.")
  68. }
  69. /*
  70. * This map will contain scalar variables from the FMUs defined in InnerFMU.
  71. * The structure is fmuName -> (SVName -> mappedSV) where SVName = mappedSV.name for easy lookup.
  72. * The mappedSV contains the original scalar variable and extra data such as define name.
  73. */
  74. var LinkedHashMap<String, LinkedHashMap<String, MappedScalarVariable>> mappedScalarVariables = newLinkedHashMap();
  75. /*
  76. * Loading the FMU defined in InnerFMU, the related model description file and its scalar variables.
  77. */
  78. // TODO: Add support for multiple inner fmus
  79. var ModelDescription md;
  80. for (fmu : adap.inner.eAllContents.toList.filter(InnerFMU)) {
  81. Log.push("Loading fmu " + fmu.path)
  82. val fmuFile = getFMUFile(fmu.path, adaptationFolderURI)
  83. this.resourcePaths.add(fmuFile);
  84. md = new ModelDescription(fmu.name, fmu.type.name, fmuFile);
  85. fmus.add(fmu.name -> fmu.type.name);
  86. val LinkedHashMap<String, MappedScalarVariable> mSV = newLinkedHashMap();
  87. for (sv : md.sv.values) {
  88. var mappedSv = new MappedScalarVariable(sv);
  89. mappedSv.define = (mappedSv.mappedSv.owner + mappedSv.mappedSv.name).toUpperCase;
  90. mSV.put(mappedSv.mappedSv.name, mappedSv);
  91. }
  92. mappedScalarVariables.put(fmu.name, mSV);
  93. Log.pop("Loading fmu " + fmu.path)
  94. }
  95. // C++ Defines for accessing FMU scalar variables.
  96. val String fmusDefines = calcDefines(mappedScalarVariables);
  97. // Compile Params
  98. var LinkedHashMap<String, GlobalInOutVariable> params = newLinkedHashMap;
  99. val String paramsConstructorSource = compileParams(params, adap.params);
  100. /*
  101. * This map contains all the ScalarVariables for the semantic adaptation.
  102. * The are not populated yet, but they will be during the compilation of the in and out rule blocks.
  103. */
  104. var LinkedHashMap<String, SAScalarVariable> SASVs = calcSASVsFromInportsOutports(adapInteralRefName,
  105. adap.inports, adap.outports)
  106. // C++ defines for accessing semantic adaptation scalar variables
  107. val String SADefines = calcSADefines(SASVs.values);
  108. // Compile the transparent in mappings
  109. // Compile the in rules
  110. val inRuleResult = compileInOutRuleBlocks(InputOutputRuleType.Input, adaptation.eAllContents.toIterable.filter(
  111. InRulesBlock).map[x|x as InOutRules], adapClassName, adapInteralRefName, mappedScalarVariables, SASVs,
  112. params);
  113. // Compile the out rules
  114. val outRuleResult = compileInOutRuleBlocks(InputOutputRuleType.Output, adaptation.eAllContents.toIterable.
  115. filter(OutRulesBlock).map[x|x as InOutRules], adapClassName, adapInteralRefName, mappedScalarVariables,
  116. SASVs, params);
  117. // Compile the Control Rules
  118. val crtlRuleResult = compileControlRuleBlock(adaptation.eAllContents.toIterable.filter(ControlRuleBlock),
  119. adapClassName, adapInteralRefName, SASVs, params);
  120. /*
  121. * Compile the constructor, destructor and initialize functions
  122. */
  123. val String deAndConstructorAndInitializeSource = compileDeAndConstructorAndInitialize(
  124. adapClassName,
  125. fmus.head.key,
  126. fmus.head.value,
  127. md.guid,
  128. paramsConstructorSource,
  129. inRuleResult.constructorInitialization,
  130. outRuleResult.constructorInitialization,
  131. crtlRuleResult.constructorInitialization
  132. );
  133. /*
  134. * Compile getRuleThis function
  135. */
  136. val String getRuleThisSource = compileGetRuleThis(adapClassName);
  137. /*
  138. * The in and out rules have populated the semantic adaptation scalar variables we can generate the getFmiValue* and setFmiValue functions.
  139. */
  140. val String getFuncsSource = compileGetFmiValueFunctions(adapClassName, SASVs);
  141. val String setFuncsSource = compileSetFmiValueFunctions(adapClassName, SASVs);
  142. // Compile the source file
  143. val String sourceInclude = '''#include "«adapClassName».h"''';
  144. val sourceFile = compileSource(
  145. sourceInclude,
  146. deAndConstructorAndInitializeSource,
  147. getRuleThisSource,
  148. getFuncsSource,
  149. setFuncsSource,
  150. inRuleResult.generatedCpp,
  151. outRuleResult.generatedCpp,
  152. crtlRuleResult.generatedCpp
  153. );
  154. fsa.generateFile(adapClassName + ".cpp", sourceFile);
  155. // Merge the global variables for use in compiling the header file.
  156. // TODO: Check for duplicates
  157. var LinkedHashMap<String, GlobalInOutVariable> allGVars = newLinkedHashMap();
  158. allGVars.putAll(params);
  159. allGVars.putAll(outRuleResult.gVars);
  160. allGVars.putAll(inRuleResult.gVars);
  161. allGVars.putAll(crtlRuleResult.gVars);
  162. // Compile the header file
  163. val headerFile = compileHeader(
  164. adapClassName,
  165. fmusDefines,
  166. SADefines,
  167. inRuleResult.functionSignatures,
  168. outRuleResult.functionSignatures,
  169. crtlRuleResult.functionSignatures,
  170. allGVars,
  171. fmus,
  172. SASVs.values.map[CalcSVar()].toList
  173. );
  174. fsa.generateFile(adapClassName + ".h", headerFile);
  175. // Compile the model description file
  176. val modelDescCreator = new ModelDescriptionCreator(adapExternalName);
  177. val modelDescription = modelDescCreator.generateModelDescription(SASVs.values);
  178. fsa.generateFile("modelDescription.xml", modelDescription);
  179. // Compile the fmu.cpp file
  180. val fmuCppFile = StaticGenerators.GenFmuCppFile(adapClassName);
  181. fsa.generateFile("Fmu.cpp", fmuCppFile);
  182. }
  183. Log.pop("CppGenerator.compile")
  184. }
  185. def getFMUFile(String fmuUnresolvedPath, URI adaptationFolderURI) {
  186. var resolvedFolderURI = CommonPlugin.resolve(adaptationFolderURI);
  187. val fmuCompleteURI = URI.createFileURI(resolvedFolderURI.toFileString + File.separatorChar + fmuUnresolvedPath.replace('\"', ''))
  188. var fmuPath = fmuCompleteURI.toFileString
  189. Log.println("Resolved fmu path: " + fmuPath)
  190. val fmuFile = new File(fmuPath);
  191. return fmuFile
  192. }
  193. def String compileParams(LinkedHashMap<String, GlobalInOutVariable> gVars, EList<ParamDeclarations> params) {
  194. val paramsConditionSwitch = new ParamConditionSwitch(gVars);
  195. var String paramsConstructorSource = "";
  196. for (paramDecl : params) {
  197. val doSwitchRes = paramsConditionSwitch.doSwitch(paramDecl);
  198. paramsConstructorSource += doSwitchRes.code;
  199. }
  200. return paramsConstructorSource;
  201. }
  202. def calcSADefines(Collection<SAScalarVariable> variables) {
  203. var ArrayList<String> defines = newArrayList();
  204. for (SASV : variables) {
  205. defines.add("#define " + SASV.defineName + " " + SASV.valueReference);
  206. }
  207. return defines.join("\n");
  208. }
  209. def calcDefines(LinkedHashMap<String, LinkedHashMap<String, MappedScalarVariable>> map) {
  210. var ArrayList<String> defines = newArrayList();
  211. for (fmuEntries : map.entrySet) {
  212. for (MappedScalarVariable mSV : fmuEntries.value.values) {
  213. defines.add("#define " + mSV.define + " " + mSV.valueReference);
  214. }
  215. }
  216. return defines.join("\n");
  217. }
  218. // Compiles the final source file
  219. def String compileSource(String include, String constructor, String getRuleThis, String getFunctions,
  220. String setFunctions, String inFunctions, String outFunctions, String controlFunction) {
  221. return '''
  222. «include»
  223. namespace adaptation
  224. {
  225. «constructor»
  226. «getRuleThis»
  227. «getFunctions»
  228. «setFunctions»
  229. «inFunctions»
  230. «controlFunction»
  231. «outFunctions»
  232. }
  233. '''
  234. }
  235. /*
  236. * Compiles the header file split into two: The first part contains the includes and using namespace definitions and start the ,
  237. * the second part contains the class
  238. */
  239. def String compileHeader(String adapClassName, String fmusDefines, String SADefines, List<String> inRulesFuncSig,
  240. List<String> outRulesFuncSig, List<String> crtlRulesFuncSig,
  241. LinkedHashMap<String, GlobalInOutVariable> globalVariables, ArrayList<Pair<String, String>> fmus,
  242. Collection<ScalarVariable> sVars) {
  243. return '''
  244. #ifndef SRC_«adapClassName.toUpperCase»_H
  245. #define SRC_«adapClassName.toUpperCase»_H
  246. #include "SemanticAdaptation.h"
  247. #include <memory>
  248. #include "Fmu.h"
  249. using namespace std;
  250. using namespace fmi2;
  251. namespace adaptation
  252. {
  253. «fmusDefines»
  254. «SADefines»
  255. class «adapClassName» : public SemanticAdaptation<«adapClassName»>, public enable_shared_from_this<«adapClassName»>
  256. {
  257. public:
  258. «adapClassName»(shared_ptr<std::string> fmiInstanceName, shared_ptr<string> resourceLocation, const fmi2CallbackFunctions* functions);
  259. void initialize();
  260. virtual ~«adapClassName»();
  261. void setFmiValue(fmi2ValueReference id, int value);
  262. void setFmiValue(fmi2ValueReference id, bool value);
  263. void setFmiValue(fmi2ValueReference id, double value);
  264. void setFmiValue(fmi2ValueReference id, string value);
  265. int getFmiValueInteger(fmi2ValueReference id);
  266. bool getFmiValueBoolean(fmi2ValueReference id);
  267. double getFmiValueReal(fmi2ValueReference id);
  268. string getFmiValueString(fmi2ValueReference id);
  269. private:
  270. «adapClassName»* getRuleThis();
  271. /*in rules*/
  272. «inRulesFuncSig.map[x | x+";"].join("\n")»
  273. /*out rules*/
  274. «outRulesFuncSig.map[x | x+";"].join("\n")»
  275. «crtlRulesFuncSig.map[x | x+";"].join("\n")»
  276. «FOR fmu : fmus»
  277. shared_ptr<FmuComponent> «fmu.key»;
  278. «ENDFOR»
  279. «FOR sv : sVars»
  280. «Conversions.fmiTypeToCppType(sv.type)» «sv.name»;
  281. «IF sv.causality == SVCausality.input»
  282. bool isSet«sv.name»;
  283. «ENDIF»
  284. «ENDFOR»
  285. «FOR v : globalVariables.entrySet»
  286. «Conversions.fmiTypeToCppType(v.value.type)» «v.key»;
  287. «ENDFOR»
  288. };
  289. }
  290. #endif
  291. ''';
  292. }
  293. /*
  294. * Compiles the source file constructor, destructor and the initialize function
  295. */
  296. def String compileDeAndConstructorAndInitialize(String adapClassName, String fmuName, String fmuTypeName,
  297. String guid, String paramsCons, String inCons, String outCons, String crtlCons) {
  298. return '''
  299. «adapClassName»::«adapClassName»(shared_ptr<std::string> fmiInstanceName,shared_ptr<string> resourceLocation, const fmi2CallbackFunctions* functions) :
  300. SemanticAdaptation(fmiInstanceName, resourceLocation, createInputRules(),createOutputRules(), functions)
  301. {
  302. «paramsCons»
  303. «inCons»
  304. «outCons»
  305. «crtlCons»
  306. }
  307. void «adapClassName»::initialize()
  308. {
  309. auto path = make_shared<string>(*resourceLocation);
  310. path->append(string("«fmuTypeName».fmu"));
  311. auto «fmuName»Fmu = make_shared<fmi2::Fmu>(*path);
  312. «fmuName»Fmu->initialize();
  313. this->«fmuName» = «fmuName»Fmu->instantiate("«fmuName»",fmi2CoSimulation, "«guid»", true, true, shared_from_this());
  314. if(this->«fmuName»->component == NULL)
  315. this->lastErrorState = fmi2Fatal;
  316. this->instances->push_back(this->«fmuName»);
  317. }
  318. «adapClassName»::~«adapClassName»()
  319. {
  320. }
  321. ''';
  322. }
  323. /*
  324. * Compiles the source file function getRuleThis
  325. */
  326. def String compileGetRuleThis(String adaptationName) {
  327. return '''
  328. «adaptationName»* «adaptationName»::getRuleThis()
  329. {
  330. return this;
  331. }
  332. '''
  333. }
  334. /*
  335. * Compiles the source file functions getFmiValue<double, int, string, bool>
  336. */
  337. def String compileGetFmiValueFunctions(String adaptationName, LinkedHashMap<String, SAScalarVariable> variables) {
  338. var ArrayList<String> cpp = newArrayList();
  339. var List<ScalarVariable> convertedSASVs = variables.values.map[CalcSVar()].toList;
  340. var convertedSASVsOrdered = convertedSASVs.filter[causality === SVCausality.output].groupBy[type];
  341. for (SVType type : SVType.values) {
  342. val functionSignature = '''«Conversions.fmiTypeToCppType(type)» «adaptationName»::getFmiValue«type.toString»(fmi2ValueReference id)''';
  343. val functionReturn = '''return «Conversions.fmiTypeToCppDefaultValue(type)»''';
  344. if (convertedSASVsOrdered.containsKey(type)) {
  345. cpp.add(
  346. '''
  347. «functionSignature»
  348. {
  349. switch (id)
  350. {
  351. «FOR svInner : convertedSASVsOrdered.get(type)»
  352. case «variables.get(svInner.name).defineName»:
  353. {
  354. return this->«svInner.name»;
  355. }
  356. «ENDFOR»
  357. default:
  358. {
  359. «functionReturn»;
  360. }
  361. }
  362. }
  363. '''
  364. );
  365. } else {
  366. cpp.add(
  367. '''
  368. «functionSignature»
  369. {
  370. «functionReturn»;
  371. }
  372. '''
  373. );
  374. }
  375. }
  376. return cpp.join("\n");
  377. }
  378. /*
  379. * Compiles the source file functions setFmiValue<double, int, string, bool>*
  380. */
  381. def String compileSetFmiValueFunctions(String adapClassName, LinkedHashMap<String, SAScalarVariable> variables) {
  382. var ArrayList<String> cpp = newArrayList();
  383. var List<ScalarVariable> convertedSASVs = variables.values.map[CalcSVar()].filter [
  384. causality === SVCausality.input
  385. ].toList;
  386. var convertedSASVsOrdered = convertedSASVs.groupBy[type];
  387. for (SVType type : SVType.values) {
  388. cpp.add(
  389. '''
  390. void «adapClassName»::setFmiValue(fmi2ValueReference id, «Conversions.fmiTypeToCppType(type)» value)
  391. {
  392. «IF convertedSASVsOrdered.containsKey(type)»
  393. switch (id)
  394. {
  395. «FOR svInner : convertedSASVsOrdered.get(type)»
  396. case «variables.get(svInner.name).defineName»:
  397. {
  398. this->«svInner.name» = value;
  399. this->isSet«svInner.name» = true;
  400. break;
  401. }
  402. «ENDFOR»
  403. default:
  404. {
  405. }
  406. }
  407. «ENDIF»
  408. }
  409. '''
  410. );
  411. }
  412. return cpp.join("\n");
  413. }
  414. /*
  415. * Compiles the source file function executeInternalControlFlow.
  416. * Calculates necessary information on function signatures necessary for generation of the header file.
  417. */
  418. def InOutRulesBlockResult compileControlRuleBlock(Iterable<ControlRuleBlock> crtlRuleBlocks, String adaptationClassName,
  419. String adaptationName, LinkedHashMap<String, SAScalarVariable> SASVs, LinkedHashMap<String, GlobalInOutVariable> params) {
  420. var cpp = "";
  421. val visitor = new ControlConditionSwitch(adaptationClassName, adaptationName, SASVs, params);
  422. for (crtlRule : crtlRuleBlocks) {
  423. cpp += visitor.doSwitch(crtlRule).code;
  424. }
  425. return new InOutRulesBlockResult(cpp, visitor.functionSignatures, visitor.globalVars, visitor.constructorInitialization);
  426. }
  427. def String SplitAtSpaceAndRemoveFirst(String content) {
  428. content.substring(content.indexOf(" ") + 1, content.length);
  429. }
  430. def String removeEmptyArgumentParenthesis(String content) {
  431. return content.substring(0, content.length - 2);
  432. }
  433. /*
  434. * Compiles the source file functions <in/out>_rule_<condition, body, flush>.
  435. * Calculates necessary information on global in/out variables necessary for generation of the header file.
  436. * Calculates necessary information on function signatures necessary for generation of the header file.
  437. */
  438. def InOutRulesBlockResult compileInOutRuleBlocks(InputOutputRuleType ioType, Iterable<InOutRules> rulesBlocks,
  439. String adaptationClassName, String adaptationName,
  440. LinkedHashMap<String, LinkedHashMap<String, MappedScalarVariable>> mSVars,
  441. LinkedHashMap<String, SAScalarVariable> SASVs, LinkedHashMap<String, GlobalInOutVariable> params) {
  442. val visitor = if (ioType == InputOutputRuleType.Input)
  443. new InRulesConditionSwitch(adaptationClassName, adaptationName, mSVars, SASVs, params)
  444. else
  445. new OutRulesConditionSwitch(adaptationClassName, adaptationName, mSVars, SASVs, params);
  446. val functionName = "create" + ioType + "Rules()";
  447. var String cpp = "";
  448. val ruleBlock = rulesBlocks.head;
  449. if (ruleBlock !== null) {
  450. cpp += visitor.doSwitch(ruleBlock).code;
  451. if (!visitor.functionSignatures.empty) {
  452. var ArrayList<String> createRulesFunction = newArrayList();
  453. for (var int i = 0; i < (visitor.functionSignatures.length); i += 3) {
  454. createRulesFunction.add(
  455. '''
  456. list->push_back(
  457. (Rule<«adaptationClassName»>){
  458. &«adaptationClassName»::«visitor.functionSignatures.get(i).SplitAtSpaceAndRemoveFirst.removeEmptyArgumentParenthesis»,
  459. &«adaptationClassName»::«visitor.functionSignatures.get(i+1).SplitAtSpaceAndRemoveFirst.removeEmptyArgumentParenthesis»,
  460. &«adaptationClassName»::«visitor.functionSignatures.get(i+2).SplitAtSpaceAndRemoveFirst.removeEmptyArgumentParenthesis»
  461. });
  462. ''');
  463. }
  464. val functionPrefix = '''shared_ptr<list<Rule<«adaptationClassName»>>>''';
  465. visitor.functionSignatures.add(functionPrefix + " " + functionName)
  466. cpp += '''
  467. «functionPrefix» «adaptationClassName»::«functionName»
  468. {
  469. auto list = make_shared<std::list<Rule<«adaptationClassName»>>>();
  470. «createRulesFunction.join("\n")»
  471. return list;
  472. }
  473. '''
  474. }
  475. }
  476. return new InOutRulesBlockResult(cpp, visitor.functionSignatures, visitor.getGlobalVars,
  477. visitor.constructorInitialization);
  478. }
  479. /*
  480. * Calculates the semantic adaptation scalar variables via input ports and output ports.
  481. * Note: These a not fully populated yet as the in rules and out rules must be compiled first.
  482. */
  483. def LinkedHashMap<String, SAScalarVariable> calcSASVsFromInportsOutports(String definePrefix, EList<Port> inports,
  484. EList<Port> outports) {
  485. var LinkedHashMap<String, SAScalarVariable> saSVs = newLinkedHashMap();
  486. var int valueReference = 0;
  487. for (inport : inports) {
  488. var saSV = new SAScalarVariable();
  489. saSV.SetPartOfMD(true);
  490. saSV.valueReference = valueReference++;
  491. saSV.name = inport.name;
  492. saSV.defineName = (definePrefix + inport.name).toUpperCase
  493. saSV.causality = SVCausality.input;
  494. saSVs.put(saSV.name, saSV);
  495. }
  496. for (outport : outports) {
  497. var saSV = new SAScalarVariable();
  498. saSV.SetPartOfMD(true);
  499. saSV.valueReference = valueReference++;
  500. saSV.defineName = (definePrefix + outport.name).toUpperCase
  501. saSV.name = outport.name;
  502. saSV.causality = SVCausality.output;
  503. saSVs.put(saSV.name, saSV);
  504. }
  505. return saSVs;
  506. }
  507. def List<File> getResourcePaths() {
  508. return resourcePaths;
  509. }
  510. }