123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423 |
- 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
- import org.eclipse.emf.common.util.EList
- import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.InOutRules
- import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.Min
- import be.uantwerpen.ansymo.semanticadaptation.cg.cpp.exceptions.TypeException
- import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.Minus
- import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.For
- import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.SaveState
- import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.Rollback
- import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.Range
- import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.Close
- import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.BreakStatement
- import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.Port
- import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.CurrentTime
- import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.Var
- import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.Plus
- import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.LessThan
- class RulesConditionSwitch extends BasicConditionSwitch {
- // Global params
- protected var LinkedHashMap<String, GlobalInOutVariable> params;
- protected final String adaptationName;
- protected final String adaptationClassName;
- protected Integer count = 0;
- /** See the method {@link #createFunctionSignature(String, String)} and subclasses */
- public final String functionPrefix;
- protected List<String> functionSignatures = newArrayList();
- /*
- * Intermediate variable used for referencing external FMU.
- * Currently only used by OutRulesConditionSwitch.
- */
- protected String externalVariableOwner;
- protected final LinkedHashMap<String, LinkedHashMap<String, MappedScalarVariable>> mSVars;
- protected final LinkedHashMap<String, SAScalarVariable> SASVs;
- // Global in and out variables
- protected var LinkedHashMap<String, GlobalInOutVariable> gVars = newLinkedHashMap();
- LinkedHashMap<String, GlobalInOutVariable> inVars;
- LinkedHashMap<String, GlobalInOutVariable> outVars;
- LinkedHashMap<String, GlobalInOutVariable> crtlVars;
- protected boolean inRuleCondition;
- protected boolean inRuleTransition;
- protected boolean inRuleOutput;
- protected boolean inControlRule;
- // Flag to signal whether the declarations to be processed are global or local.
- protected boolean globalDeclaration = false;
- // Add scope information to this.
- protected var LinkedHashMap<String, SVType> localDeclarations = newLinkedHashMap();
- protected String forLoopIterVar;
- protected boolean forLoopIterVarIsSet = false;
- new(
- String adaptationClassName,
- String adaptationName,
- String functionPrefix,
- LinkedHashMap<String, LinkedHashMap<String, MappedScalarVariable>> mSVars,
- LinkedHashMap<String, SAScalarVariable> SASVs,
- LinkedHashMap<String, GlobalInOutVariable> params,
- LinkedHashMap<String, GlobalInOutVariable> inVars,
- LinkedHashMap<String, GlobalInOutVariable> outVars,
- LinkedHashMap<String, GlobalInOutVariable> crtlVars
- ) {
- super();
- this.params = params;
- this.SASVs = SASVs;
- this.adaptationName = adaptationName;
- this.adaptationClassName = adaptationClassName;
- this.functionPrefix = functionPrefix;
- this.mSVars = mSVars;
- this.outVars = outVars;
- this.inVars = inVars;
- this.crtlVars = crtlVars;
- }
- /*
- * UTILITY FUNCTIONS
- */
- /**
- * This function adds a header style function signature to the list <i>functionsignatures</i>
- * and returns the source style function signature
- */
- public def String createFunctionSignature(String functionName, String type, int count,
- List<String> functionSignatures) {
- val functionSignature = this.functionPrefix + functionName + count + "()";
- functionSignatures.add(type + " " + functionSignature);
- return type + " " + this.adaptationClassName + "::" + functionSignature;
- }
- public def getDataRuleCount() { return this.count; }
- def void incrementCount() {
- this.count++;
- }
- /*
- * COMPILATION FUNCTIONS
- */
- public def Pair<String, LinkedHashMap<String, GlobalInOutVariable>> getGlobalVars(EList<Declaration> gVars) {
- // Get the global variables added to globalVars
- this.globalDeclaration = true;
- val List<String> constructorInits = newArrayList();
- for (gVar : gVars) {
- constructorInits.add('''«doSwitch(gVar).code»''');
- }
- this.globalDeclaration = false;
- return constructorInits.join(System.lineSeparator) -> this.gVars;
- }
- protected def ReturnInformation doSwitch(EList<Declaration> gVars, InOutRules object) {
- var retVal = new ReturnInformation();
- for (dataRule : object.eAllContents.toIterable.filter(DataRule)) {
- this.incrementCount;
- retVal.appendCode(doSwitch(dataRule).code);
- }
- 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", this.count, this.functionSignatures);
- retVal.code = '''
- «functionSignature»{
- double h = 0;
- double dt = 0;
- return «doSwitch(object.condition).code»;
- }
- ''';
- return retVal;
- }
- override ReturnInformation caseStateTransitionFunction(StateTransitionFunction object) {
- var retVal = new ReturnInformation();
- val functionSig = createFunctionSignature("body", "void", this.count, this.functionSignatures);
- retVal.code = '''
- «functionSig»{
- double h = 0;
- double dt = 0;
- «IF object.expression !== null»
- «val result = doSwitch(object.expression)»
- «result.code»«if (!result.isExpression) ";"»
- «ENDIF»
- «IF object.statements !== null»
- «FOR stm : object.statements»
- «val result = doSwitch(stm)»
- «result.code»«if (!result.isExpression) ";"»
- «ENDFOR»
- «ENDIF»
- «IF object.assignment !== null»
- «val result = doSwitch(object.assignment)»
- «result.code»«if (!result.isExpression) ";"»
- «ENDIF»
- }
- ''';
- return retVal;
- }
- override ReturnInformation caseIf(If object) {
- var retVal = new ReturnInformation();
- retVal.isExpression = true;
- retVal.code = '''
- if(«doSwitch(object.ifcondition).code»){
- «FOR stm : object.ifstatements»
- «val result = doSwitch(stm)»
- «result.code»«if (!result.isExpression) ";"»
- «ENDFOR»
- }
- ''';
- if (object.elsestatements.length > 0) {
- retVal.appendCode('''
- else {
- «FOR stm : object.elsestatements»
- «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 caseSingleVarDeclaration(SingleVarDeclaration object) {
- var retVal = new ReturnInformation();
- var exprRes = doSwitch(object.expr);
- var String code = "";
- if (globalDeclaration) {
- // This is an in var, out var or crtl var declaration
- code = '''this->internalState.«object.name» = «exprRes.code»''';
- var globVar = new GlobalInOutVariable(object.name, exprRes.type);
- gVars.put(object.name, globVar)
- } else {
- // This is a local declaration.
- val String type = Conversions.fmiTypeToCppType(exprRes.type)
- code = '''«type» «object.name» = «exprRes.code»''';
- this.localDeclarations.put(object.name, exprRes.type);
- }
- retVal.code = code;
- return retVal;
- }
- override ReturnInformation caseCompositeOutputFunction(CompositeOutputFunction object) {
- var retVal = new ReturnInformation();
- val functionSig = createFunctionSignature("flush", "void", this.count, this.functionSignatures);
- retVal.code = '''
- «functionSig»{
- double h = 0;
- double dt = 0;
- «FOR stm : object.statements»
- «val result = doSwitch(stm)»
- «result.code»«if(!result.isExpression) ";"»
- «ENDFOR»
- }
- ''';
- return retVal;
- }
- override ReturnInformation caseVariable(Variable object) {
- var retVal = new ReturnInformation();
- if (object.owner === null || object.owner.name == this.adaptationName) {
- if ((SASVs !== null && SASVs.containsKey(object.ref.name)) || params.containsKey(object.ref.name) ||
- (outVars !== null && outVars.containsKey(object.ref.name)) ||
- (inVars !== null && inVars.containsKey(object.ref.name)) ||
- (crtlVars !== null && crtlVars.containsKey(object.ref.name))) {
- retVal.code = '''this->internalState.«object.ref.name»''';
- if (SASVs !== null && SASVs.containsKey(object.ref.name)) {
- retVal.conSaSv = SASVs.get(object.ref.name);
- } else if (crtlVars !== null && crtlVars.containsKey(object.ref.name)) {
- retVal.conGlobVar = crtlVars.get(object.ref.name);
- } else if (params.containsKey(object.ref.name)) {
- retVal.conGlobVar = params.get(object.ref.name);
- } else if (outVars !== null && outVars.containsKey(object.ref.name)) {
- retVal.conGlobVar = outVars.get(object.ref.name);
- } else if (inVars !== null && inVars.containsKey(object.ref.name)) {
- retVal.conGlobVar = inVars.get(object.ref.name);
- }
- } else if (localDeclarations.containsKey(object.ref.name)) {
- retVal.code = '''«object.ref.name»'''
- retVal.type = localDeclarations.get(object.ref.name);
- } else {
- throw new Exception("Variable not found: " + object.ref.name);
- }
- } else {
- this.externalVariableOwner = object.owner.name;
- val res = doSwitch(object.ref);
- retVal.code = res.code;
- retVal.type = res.type;
- }
- return retVal;
- }
- override ReturnInformation caseLValueDeclaration(LValueDeclaration object) {
- var retVal = new ReturnInformation();
- retVal.code = '''«object.name»''';
- return retVal;
- }
- override ReturnInformation caseVar(Var object) {
- var retVal = new ReturnInformation();
- return retVal;
- }
- override ReturnInformation caseDeclaration(Declaration object) {
- var retVal = new ReturnInformation();
- val code = '''
- «FOR decl : object.declarations»
- «val res = doSwitch(decl)»
- «res.code»;
- «ENDFOR»
- '''
- retVal.code = code;
- retVal.isExpression = true;
- return retVal;
- }
- override ReturnInformation caseIsSet(IsSet object) {
- var retInfo = new ReturnInformation();
- retInfo.code = '''this->internalState.isSet«(object.args as Variable).ref.name»''';
- return retInfo;
- }
- override ReturnInformation caseFor(For object) {
- {
- var retVal = new ReturnInformation();
- retVal.isExpression = true;
- val iterator = doSwitch(object.iterator);
- forLoopIterVar = iterator.code;
- forLoopIterVarIsSet = true;
- val iterable = doSwitch(object.iterable);
- retVal.appendCode('''
- for (int «forLoopIterVar» = «iterable.code»){
- «FOR stm : object.statements»
- «val result = doSwitch(stm)»
- «result.code»«if (!result.isExpression) ";"»
- «ENDFOR»
- }
- ''')
- forLoopIterVarIsSet = false;
- return retVal;
- }
- }
- override ReturnInformation caseRange(Range object) {
- var retVal = new ReturnInformation();
- val left = doSwitch(object.left);
- val right = doSwitch(object.right);
- retVal.appendCode('''«left.code»; «forLoopIterVar»<=«right.code»; «forLoopIterVar»++''')
- return retVal;
- }
- }
|