123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406 |
- package be.uantwerpen.ansymo.semanticadaptation.cg.cpp.generation
- import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.util.SemanticAdaptationSwitch
- import java.util.LinkedHashMap
- import be.uantwerpen.ansymo.semanticadaptation.cg.cpp.data.SVType
- import be.uantwerpen.ansymo.semanticadaptation.cg.cpp.data.GlobalInOutVariable
- import java.util.List
- import be.uantwerpen.ansymo.semanticadaptation.cg.cpp.data.MappedScalarVariable
- import be.uantwerpen.ansymo.semanticadaptation.cg.cpp.data.SAScalarVariable
- import be.uantwerpen.ansymo.semanticadaptation.cg.cpp.data.ReturnInformation
- import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.Literal
- import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.RealLiteral
- import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.IntLiteral
- import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.BoolLiteral
- import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.OutRulesBlock
- import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.DataRule
- import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.InRulesBlock
- import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.RuleCondition
- import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.StateTransitionFunction
- import org.eclipse.emf.ecore.EObject
- import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.Assignment
- import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.Multi
- import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.Neg
- import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.SingleVarDeclaration
- import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.If
- import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.CompositeOutputFunction
- import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.Variable
- import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.LValueDeclaration
- import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.Declaration
- import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.IsSet
- import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.Div
- abstract class InOutRulesConditionSwitch extends SemanticAdaptationSwitch<ReturnInformation> {
- protected var LinkedHashMap<String, Pair<SVType, Object>> globalVars = newLinkedHashMap();
- protected var LinkedHashMap<String, GlobalInOutVariable> globalVars2 = newLinkedHashMap();
- protected var LinkedHashMap<String, GlobalInOutVariable> params;
- private var Pair<SVType, Object> lastVal;
- protected final String adaptationName;
- protected final String adaptationClassName;
- private Integer count = 0;
- private final String functionPrefix;
- protected List<String> functionSignatures = newArrayList();
- protected String externalVariableOwner;
- protected final LinkedHashMap<String, LinkedHashMap<String, MappedScalarVariable>> mSVars;
- protected final LinkedHashMap<String, SAScalarVariable> SASVs;
- protected boolean inRuleCondition;
- protected boolean inRuleTransition;
- protected boolean inRuleOutput;
- protected String constructorInitialization = "";
- protected boolean inControlRule;
- protected boolean globalDeclaration = false;
- // Add scope information to this.
- protected var LinkedHashMap<String, SVType> localDeclarations = newLinkedHashMap();
- new(
- String adaptationClassName,
- String adaptationName,
- String functionPrefix,
- LinkedHashMap<String, LinkedHashMap<String, MappedScalarVariable>> mSVars,
- LinkedHashMap<String, SAScalarVariable> SASVs,
- LinkedHashMap<String, GlobalInOutVariable> params
- ) {
- this.params = params;
- this.SASVs = SASVs;
- this.adaptationName = adaptationName;
- this.adaptationClassName = adaptationClassName;
- this.functionPrefix = functionPrefix;
- this.mSVars = mSVars;
- }
- /*
- * UTILITY FUNCTIONS
- */
- private def Object convertTypeToObject(SVType type, Literal object) {
- switch (type) {
- case Real: {
- return (object as RealLiteral).value.doubleValue;
- }
- case Integer: {
- return (object as IntLiteral).value;
- }
- case Boolean: {
- return Boolean.parseBoolean((object as BoolLiteral).value);
- }
- default: {
- }
- }
- }
- public def getVars() { return this.globalVars; }
- public def getGlobalVars() { return this.globalVars2; }
- public def getConstructorInitialization() { return this.constructorInitialization; }
- /**
- * This function adds a header style function signature to the list <i>functionsignatures</i>
- * and returns the source style function signature
- */
- protected def String createFunctionSignature(String functionName, String type) {
- val functionSignature = this.functionPrefix + functionName + this.count + "()";
- this.functionSignatures.add(type + " " + functionSignature);
- return type + " " + this.adaptationClassName + "::" + functionSignature;
- }
- def void incrementCount() {
- this.count++;
- }
- /*
- * COMPILATION FUNCTIONS
- */
- override ReturnInformation caseOutRulesBlock(OutRulesBlock object) {
- this.globalDeclaration = true;
- var retVal = new ReturnInformation();
- // Get the global variables added to globalVars
- for (gVar : object.globalOutVars) {
- constructorInitialization += doSwitch(gVar).code;
- }
- for (dataRule : object.eAllContents.toIterable.filter(DataRule)) {
- this.incrementCount;
- retVal.appendCode(doSwitch(dataRule).code);
- }
- this.globalDeclaration = false;
- return retVal;
- }
- override ReturnInformation caseInRulesBlock(InRulesBlock object) {
- this.globalDeclaration = true;
- var retVal = new ReturnInformation();
- // Get the global variables added to globalVars
- for (gVar : object.globalInVars) {
- constructorInitialization += doSwitch(gVar).code
- }
- for (DataRule dataRule : object.eAllContents.toIterable.filter(DataRule)) {
- // This is used for naming each datarule
- this.incrementCount;
- retVal.appendCode(doSwitch(dataRule).code);
- }
- this.globalDeclaration = false;
- return retVal;
- }
- override ReturnInformation caseDataRule(DataRule object) {
- var retVal = new ReturnInformation();
- inRuleCondition = true;
- val conditionSwitch = doSwitch(object.condition);
- inRuleCondition = false;
- inRuleTransition = true;
- val transitionSwitch = doSwitch(object.statetransitionfunction);
- inRuleTransition = false;
- inRuleOutput = true;
- val outputSwitch = doSwitch(object.outputfunction);
- inRuleOutput = false;
- retVal.code = '''
- «conditionSwitch.code»
- «transitionSwitch.code»
- «outputSwitch.code»
- '''
- return retVal;
- }
- override ReturnInformation caseRuleCondition(RuleCondition object) {
- var retVal = new ReturnInformation();
- val functionSignature = createFunctionSignature("condition", "bool");
- retVal.code = '''
- «functionSignature»{
- return «doSwitch(object.condition).code»;
- }
- ''';
- return retVal;
- }
- override ReturnInformation caseStateTransitionFunction(StateTransitionFunction object) {
- var retVal = new ReturnInformation();
- val functionSig = createFunctionSignature("body", "void");
- retVal.code = '''
- «functionSig»{
- «IF object.expression !== null»
- «doSwitch(object.expression).code»
- «ENDIF»
- «IF object.statements !== null»
- «FOR stm : object.statements»
- «doSwitch(stm).code»
- «ENDFOR»
- «ENDIF»
- «IF object.assignment !== null»
- «doSwitch(object.assignment).code»
- «ENDIF»
- }
- ''';
- return retVal;
- }
- override ReturnInformation defaultCase(EObject object) {
- var retVal = new ReturnInformation();
- retVal.code = '''[«object.class»]''';
- return retVal;
- }
- override ReturnInformation caseIf(If object) {
- var retVal = new ReturnInformation();
- retVal.code = '''
- if(«doSwitch(object.ifcondition).code»){
- «FOR stm : object.ifstatements»
- «doSwitch(stm).code»
- «ENDFOR»
- }
- ''';
- return retVal;
- }
- private def calcConSaSvData(SAScalarVariable SASV, ReturnInformation rI) {
- if (SASV !== null) {
- if (rI.typeIsSet) {
- SASV.type = rI.type;
- SASV.variability = Conversions.fmiTypeToFmiVariability(rI.type);
- return;
- } else if (rI.conGlobVar !== null) {
- SASV.type = rI.conGlobVar.type;
- SASV.variability = Conversions.fmiTypeToFmiVariability(rI.conGlobVar.type);
- return;
- }
- }
- throw new Exception("Not enough information to determine content of the SASV: " + SASV.name);
- }
- override ReturnInformation caseAssignment(Assignment object) {
- var retVal = new ReturnInformation();
- var lValSwitch = doSwitch(object.lvalue);
- var rValSwitch = doSwitch(object.expr);
- // Here we set the information necessary to create a scalar variables in the model description for the SA.
- if (inRuleTransition) {
- if (rValSwitch.conSaSv !== null) {
- calcConSaSvData(rValSwitch.conSaSv, lValSwitch);
- }
- } else if (inRuleOutput) {
- calcConSaSvData(lValSwitch.conSaSv, rValSwitch);
- }
- retVal.code = '''«lValSwitch.code» = «rValSwitch.code»;''';
- return retVal;
- }
- override ReturnInformation caseMulti(Multi object) {
- val doSwitchLeft = doSwitch(object.left);
- val doSwitchRight = doSwitch(object.right);
- var retVal = new ReturnInformation(doSwitchLeft, doSwitchRight);
- retVal.code = '''«doSwitchLeft.code» * «doSwitchRight.code»''';
- return retVal;
- }
- override ReturnInformation caseDiv(Div object) {
- val doSwitchLeft = doSwitch(object.left);
- val doSwitchRight = doSwitch(object.right);
- var retVal = new ReturnInformation(doSwitchLeft, doSwitchRight);
- retVal.code = '''«doSwitchLeft.code» / «doSwitchRight.code»''';
- retVal.type = SVType.Real;
- retVal.forceType = true;
- return retVal;
- }
- override ReturnInformation caseNeg(Neg object) {
- var doSwitch = doSwitch(object.right);
- var retVal = new ReturnInformation(doSwitch);
- retVal.code = doSwitch.code;
- return retVal;
- }
- override ReturnInformation caseSingleVarDeclaration(SingleVarDeclaration object) {
- var retVal = new ReturnInformation();
- retVal.code = '''«object.name»''';
- return retVal;
- }
- override ReturnInformation caseCompositeOutputFunction(CompositeOutputFunction object) {
- var retVal = new ReturnInformation();
- val functionSig = createFunctionSignature("flush", "void");
- retVal.code = '''
- «functionSig»{
- «FOR stm : object.statements»
- «doSwitch(stm).code»
- «ENDFOR»
- }
- ''';
- return retVal;
- }
- override ReturnInformation caseVariable(Variable object) {
- var retVal = new ReturnInformation();
- if (object.owner === null || object.owner.name == this.adaptationName) {
- retVal.code = '''this->«object.ref.name»''';
- if (SASVs.containsKey(object.ref.name) || globalVars2.containsKey(object.ref.name) ||
- params.containsKey(object.ref.name)) {
-
- retVal.code = '''this->«object.ref.name»''';
-
- if (SASVs.containsKey(object.ref.name)) {
- retVal.conSaSv = SASVs.get(object.ref.name);
- } else if (globalVars2.containsKey(object.ref.name)) {
- retVal.conGlobVar = globalVars2.get(object.ref.name);
- } else if (params.containsKey(object.ref.name)) {
- retVal.conGlobVar = params.get(object.ref.name);
- }
- } else if (localDeclarations.containsKey(object.ref.name)) {
- retVal.code = '''«object.ref.name»'''
- retVal.type = localDeclarations.get(object.ref.name);
- }
- } else {
- // TODO: Extract the correct variable here
- this.externalVariableOwner = object.owner.name;
- retVal.code = '''«doSwitch(object.ref).code»''';
- }
- return retVal;
- }
- override ReturnInformation caseLValueDeclaration(LValueDeclaration object) {
- var retVal = new ReturnInformation();
- retVal.code = '''«object.name»''';
- return retVal;
- }
- override ReturnInformation caseDeclaration(Declaration object) {
- var retVal = new ReturnInformation();
- for (SingleVarDeclaration decl : object.declarations) {
- var doSwitchRes = doSwitch(decl.expr);
- var String code = "";
- if (globalDeclaration) {
- // This is an in var or out var declaration
- code = '''
- this->«decl.name» = «doSwitchRes.code»;
- '''
- var globVar = new GlobalInOutVariable();
- globVar.name = decl.name;
- globVar.value = doSwitchRes.value;
- globVar.type = doSwitchRes.type;
- globalVars2.put(decl.name, globVar);
- } else {
- // This is a local declaration.
- val String type = Conversions.fmiTypeToCppType(doSwitchRes.type)
- code = '''«type» «decl.name» = «doSwitchRes.code»''';
- this.localDeclarations.put(decl.name, doSwitchRes.type);
- }
- retVal.appendCode = code;
- }
- return retVal;
- }
- override ReturnInformation caseIsSet(IsSet object) {
- var retInfo = new ReturnInformation();
- retInfo.code = '''this->isSet«(object.args as Variable).ref.name»''';
- return retInfo;
- }
- override ReturnInformation caseRealLiteral(RealLiteral object) {
- var retInfo = new ReturnInformation();
- retInfo.type = SVType.Real;
- retInfo.value = convertTypeToObject(retInfo.type, object);
- retInfo.code = '''«object.value»''';
- return retInfo;
- }
- override ReturnInformation caseIntLiteral(IntLiteral object) {
- var retInfo = new ReturnInformation();
- retInfo.type = SVType.Integer;
- retInfo.value = convertTypeToObject(retInfo.type, object);
- retInfo.code = '''«object.value»''';
- return retInfo;
- }
- override ReturnInformation caseBoolLiteral(BoolLiteral object) {
- var retInfo = new ReturnInformation();
- retInfo.type = SVType.Boolean;
- retInfo.value = convertTypeToObject(retInfo.type, object);
- retInfo.code = '''«object.value»''';
- return retInfo;
- }
- }
|