/* * #%~ * VDM Code Generator * %% * Copyright (C) 2008 - 2014 Overture * %% * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this program. If not, see * <http://www.gnu.org/licenses/gpl-3.0.html>. * #~% */ package org.overture.codegen.trans; import java.util.LinkedList; import java.util.List; import org.overture.codegen.ir.INode; import org.overture.codegen.ir.IRInfo; import org.overture.codegen.ir.ITempVarGen; import org.overture.codegen.ir.SExpIR; import org.overture.codegen.ir.SMultipleBindIR; import org.overture.codegen.ir.SPatternIR; import org.overture.codegen.ir.SStmIR; import org.overture.codegen.ir.STypeIR; import org.overture.codegen.ir.analysis.AnalysisException; import org.overture.codegen.ir.analysis.DepthFirstAnalysisAdaptor; import org.overture.codegen.ir.declarations.AVarDeclIR; import org.overture.codegen.ir.expressions.AAndBoolBinaryExpIR; import org.overture.codegen.ir.expressions.ABoolLiteralExpIR; import org.overture.codegen.ir.expressions.ACaseAltExpExpIR; import org.overture.codegen.ir.expressions.ACasesExpIR; import org.overture.codegen.ir.expressions.ACompMapExpIR; import org.overture.codegen.ir.expressions.ACompSeqExpIR; import org.overture.codegen.ir.expressions.ACompSetExpIR; import org.overture.codegen.ir.expressions.AEnumMapExpIR; import org.overture.codegen.ir.expressions.AEnumSeqExpIR; import org.overture.codegen.ir.expressions.AEnumSetExpIR; import org.overture.codegen.ir.expressions.AEqualsBinaryExpIR; import org.overture.codegen.ir.expressions.AExists1QuantifierExpIR; import org.overture.codegen.ir.expressions.AExistsQuantifierExpIR; import org.overture.codegen.ir.expressions.AFieldExpIR; import org.overture.codegen.ir.expressions.AForAllQuantifierExpIR; import org.overture.codegen.ir.expressions.AIdentifierVarExpIR; import org.overture.codegen.ir.expressions.ALetBeStExpIR; import org.overture.codegen.ir.expressions.ALetDefExpIR; import org.overture.codegen.ir.expressions.AMapletExpIR; import org.overture.codegen.ir.expressions.AOrBoolBinaryExpIR; import org.overture.codegen.ir.expressions.ARecordModExpIR; import org.overture.codegen.ir.expressions.ARecordModifierIR; import org.overture.codegen.ir.expressions.ATernaryIfExpIR; import org.overture.codegen.ir.expressions.SBoolBinaryExpIR; import org.overture.codegen.ir.patterns.AIdentifierPatternIR; import org.overture.codegen.ir.patterns.ASetMultipleBindIR; import org.overture.codegen.ir.patterns.ATypeMultipleBindIR; import org.overture.codegen.ir.statements.AAssignToExpStmIR; import org.overture.codegen.ir.statements.ABlockStmIR; import org.overture.codegen.ir.statements.ACaseAltStmStmIR; import org.overture.codegen.ir.statements.ACasesStmIR; import org.overture.codegen.ir.statements.AIfStmIR; import org.overture.codegen.ir.types.ABoolBasicTypeIR; import org.overture.codegen.ir.types.AIntNumericBasicTypeIR; import org.overture.codegen.ir.types.SSetTypeIR; import org.overture.codegen.ir.utils.AHeaderLetBeStIR; import org.overture.codegen.trans.assistants.TransAssistantIR; import org.overture.codegen.trans.comp.ComplexCompStrategy; import org.overture.codegen.trans.comp.MapCompStrategy; import org.overture.codegen.trans.comp.SeqCompStrategy; import org.overture.codegen.trans.comp.SetCompStrategy; import org.overture.codegen.trans.iterator.ILanguageIterator; import org.overture.codegen.trans.let.LetBeStStrategy; import org.overture.codegen.trans.quantifier.Exists1CounterData; import org.overture.codegen.trans.quantifier.Exists1QuantifierStrategy; import org.overture.codegen.trans.quantifier.OrdinaryQuantifier; import org.overture.codegen.trans.quantifier.OrdinaryQuantifierStrategy; public class Exp2StmTrans extends DepthFirstAnalysisAdaptor { protected TransAssistantIR transAssistant; protected ILanguageIterator langIterator; protected Exists1CounterData counterData; protected Exp2StmVarPrefixes prefixes; protected IterationVarPrefixes iteVarPrefixes; public Exp2StmTrans(IterationVarPrefixes iteVarPrefixes, TransAssistantIR transAssistant, Exists1CounterData counterData, ILanguageIterator langIterator, Exp2StmVarPrefixes prefixes) { this.transAssistant = transAssistant; this.counterData = counterData; this.langIterator = langIterator; this.prefixes = prefixes; this.iteVarPrefixes = iteVarPrefixes; } @Override public void caseATernaryIfExpIR(ATernaryIfExpIR node) throws AnalysisException { SStmIR enclosingStm = transAssistant.findEnclosingStm(node); if (enclosingStm == null) { // TODO: // Cases such as // values // public x = 1 + if 2 = 3 then 4 else 5 + 6; // Will not be treated return; } String resultVarName = transAssistant.getInfo().getTempVarNameGen().nextVarName(prefixes.ternaryIfExp()); AVarDeclIR resultDecl = transAssistant.consDecl(resultVarName, node.getType().clone(), transAssistant.getInfo().getExpAssistant().consUndefinedExp()); AIdentifierVarExpIR resultVar = transAssistant.getInfo().getExpAssistant().consIdVar(resultVarName, resultDecl.getType().clone()); SExpIR condition = node.getCondition(); SExpIR trueValue = node.getTrueValue(); SExpIR falseValue = node.getFalseValue(); AAssignToExpStmIR trueBranch = new AAssignToExpStmIR(); trueBranch.setTarget(resultVar.clone()); trueBranch.setExp(trueValue.clone()); AAssignToExpStmIR falseBranch = new AAssignToExpStmIR(); falseBranch.setTarget(resultVar.clone()); falseBranch.setExp(falseValue); AIfStmIR ifStm = new AIfStmIR(); ifStm.setIfExp(condition.clone()); ifStm.setThenStm(trueBranch); ifStm.setElseStm(falseBranch); ABlockStmIR replacementBlock = new ABlockStmIR(); transAssistant.replaceNodeWith(node, resultVar); transAssistant.replaceNodeWith(enclosingStm, replacementBlock); ABlockStmIR declBlock = new ABlockStmIR(); declBlock.getLocalDefs().add(resultDecl); replacementBlock.getStatements().add(declBlock); replacementBlock.getStatements().add(ifStm); replacementBlock.getStatements().add(enclosingStm); ifStm.getIfExp().apply(this); trueBranch.getExp().apply(this); falseBranch.getExp().apply(this); } @Override public void caseAOrBoolBinaryExpIR(AOrBoolBinaryExpIR node) throws AnalysisException { // left || right // // is replaced with a variable expression 'orResult' that is // computed as: // // boolean orResult = false; // if (left) // { // orResult = true; // } // else // { // orResult = right; // } // SStmIR enclosingStm = transAssistant.findEnclosingStm(node); if (transformBoolBinaryExp(node, enclosingStm)) { String resultName = transAssistant.getInfo().getTempVarNameGen().nextVarName(prefixes.orExp()); handleLogicExp(node, enclosingStm, consOrExpCheck(node, resultName), resultName); } else { visitBoolBinary(node); } } @Override public void caseAAndBoolBinaryExpIR(AAndBoolBinaryExpIR node) throws AnalysisException { // left && right // // is replaced with a variable expression 'andResult' that is // computed as: // // boolean andResult = false; // if (left) // { // if (right) // { // andResult = true; // } // } SStmIR enclosingStm = transAssistant.findEnclosingStm(node); if (transformBoolBinaryExp(node, enclosingStm)) { String resultName = transAssistant.getInfo().getTempVarNameGen().nextVarName(prefixes.andExp()); handleLogicExp(node, enclosingStm, consAndExpCheck(node, resultName), resultName); } else { visitBoolBinary(node); } } @Override public void caseALetBeStExpIR(ALetBeStExpIR node) throws AnalysisException { SStmIR enclosingStm = transAssistant.getEnclosingStm(node, "let be st expressions"); AHeaderLetBeStIR header = node.getHeader(); if (!(header.getBinding() instanceof ASetMultipleBindIR)) { transAssistant.getInfo().addTransformationWarning(node.getHeader().getBinding(), "This transformation only works for 'let be st' " + "expressions with with multiple set binds and not multiple type binds in '" + this.getClass().getSimpleName() + "'"); return; } ASetMultipleBindIR binding = (ASetMultipleBindIR) header.getBinding(); SExpIR suchThat = header.getSuchThat(); SSetTypeIR setType = transAssistant.getSetTypeCloned(binding.getSet()); ITempVarGen tempVarNameGen = transAssistant.getInfo().getTempVarNameGen(); LetBeStStrategy strategy = new LetBeStStrategy(transAssistant, suchThat, setType, langIterator, tempVarNameGen, iteVarPrefixes); ABlockStmIR outerBlock = new ABlockStmIR(); SExpIR letBeStResult = null; if (transAssistant.hasEmptySet(binding)) { transAssistant.cleanUpBinding(binding); letBeStResult = transAssistant.getInfo().getExpAssistant().consUndefinedExp(); } else { String var = tempVarNameGen.nextVarName(prefixes.letBeSt()); SExpIR value = node.getValue(); AVarDeclIR resultDecl = transAssistant.consDecl(var, value.getType().clone(), transAssistant.getInfo().getExpAssistant().consUndefinedExp()); outerBlock.getLocalDefs().add(resultDecl); AAssignToExpStmIR setLetBeStResult = new AAssignToExpStmIR(); setLetBeStResult.setTarget(transAssistant.getInfo().getExpAssistant().consIdVar(var, value.getType().clone())); setLetBeStResult.setExp(value); outerBlock.getStatements().add(setLetBeStResult); AIdentifierVarExpIR varExpResult = new AIdentifierVarExpIR(); varExpResult.setType(value.getType().clone()); varExpResult.setIsLocal(true); varExpResult.setName(var); letBeStResult = varExpResult; } // Replace the let be st expression with the result expression transAssistant.replaceNodeWith(node, letBeStResult); LinkedList<SPatternIR> patterns = binding.getPatterns(); ABlockStmIR block = transAssistant.consIterationBlock(patterns, binding.getSet(), tempVarNameGen, strategy, iteVarPrefixes); outerBlock.getStatements().addFirst(block); // Replace the enclosing statement with the transformation transAssistant.replaceNodeWith(enclosingStm, outerBlock); // And make sure to have the enclosing statement in the transformed tree outerBlock.getStatements().add(enclosingStm); outerBlock.apply(this); outerBlock.setScoped(transAssistant.getInfo().getStmAssistant().isScoped(outerBlock)); } @Override public void caseARecordModExpIR(ARecordModExpIR node) throws AnalysisException { String recModifierName = transAssistant.getInfo().getTempVarNameGen().nextVarName(prefixes.recModExp()); AVarDeclIR recDecl = transAssistant.consDecl(recModifierName, node.getType().clone(), node.getRec().clone()); ABlockStmIR declStm = new ABlockStmIR(); declStm.getLocalDefs().add(recDecl); AIdentifierVarExpIR recVar = transAssistant.getInfo().getExpAssistant().consIdVar(recModifierName, node.getType().clone()); ABlockStmIR replacementBlock = new ABlockStmIR(); replacementBlock.getStatements().add(declStm); for (ARecordModifierIR modifier : node.getModifiers()) { String name = modifier.getName(); SExpIR value = modifier.getValue().clone(); STypeIR fieldType = transAssistant.getInfo().getTypeAssistant().getFieldType(transAssistant.getInfo().getClasses(), node.getRecType(), name); AFieldExpIR field = new AFieldExpIR(); field.setType(fieldType); field.setObject(recVar.clone()); field.setMemberName(name); AAssignToExpStmIR assignment = new AAssignToExpStmIR(); assignment.setTarget(field); assignment.setExp(value); replacementBlock.getStatements().add(assignment); } SStmIR enclosingStm = transAssistant.getEnclosingStm(node, "record modification expression"); transform(enclosingStm, replacementBlock, recVar.clone(), node); replacementBlock.apply(this); } @Override public void caseACompMapExpIR(ACompMapExpIR node) throws AnalysisException { SStmIR enclosingStm = transAssistant.getEnclosingStm(node, "map comprehension"); AMapletExpIR first = node.getFirst(); SExpIR predicate = node.getPredicate(); STypeIR type = node.getType(); ITempVarGen tempVarNameGen = transAssistant.getInfo().getTempVarNameGen(); String var = tempVarNameGen.nextVarName(prefixes.mapComp()); ComplexCompStrategy strategy = new MapCompStrategy(transAssistant, first, predicate, var, type, langIterator, tempVarNameGen, iteVarPrefixes); List<SMultipleBindIR> bindings = filterBindList(node, node.getBindings()); ABlockStmIR block = transAssistant.consComplexCompIterationBlock(bindings, tempVarNameGen, strategy, iteVarPrefixes); if (block.getStatements().isEmpty()) { // In case the block has no statements the result of the map comprehension is the empty map AEnumMapExpIR emptyMap = new AEnumMapExpIR(); emptyMap.setType(type.clone()); // Replace the map comprehension with the empty map transAssistant.replaceNodeWith(node, emptyMap); } else { replaceCompWithTransformation(enclosingStm, block, type, var, node); } block.apply(this); } @Override public void caseACompSetExpIR(ACompSetExpIR node) throws AnalysisException { SStmIR enclosingStm = transAssistant.getEnclosingStm(node, "set comprehension"); SExpIR first = node.getFirst(); SExpIR predicate = node.getPredicate(); STypeIR type = node.getType(); ITempVarGen tempVarNameGen = transAssistant.getInfo().getTempVarNameGen(); String var = tempVarNameGen.nextVarName(prefixes.setComp()); ComplexCompStrategy strategy = new SetCompStrategy(transAssistant, first, predicate, var, type, langIterator, tempVarNameGen, iteVarPrefixes); List<SMultipleBindIR> bindings = filterBindList(node, node.getBindings()); ABlockStmIR block = transAssistant.consComplexCompIterationBlock(bindings, tempVarNameGen, strategy, iteVarPrefixes); if (block.getStatements().isEmpty()) { // In case the block has no statements the result of the set comprehension is the empty set AEnumSetExpIR emptySet = new AEnumSetExpIR(); emptySet.setType(type.clone()); // Replace the set comprehension with the empty set transAssistant.replaceNodeWith(node, emptySet); } else { replaceCompWithTransformation(enclosingStm, block, type, var, node); } block.apply(this); } @Override public void caseACompSeqExpIR(ACompSeqExpIR node) throws AnalysisException { SStmIR enclosingStm = transAssistant.getEnclosingStm(node, "sequence comprehension"); SExpIR first = node.getFirst(); SExpIR predicate = node.getPredicate(); STypeIR type = node.getType(); ITempVarGen tempVarNameGen = transAssistant.getInfo().getTempVarNameGen(); String var = tempVarNameGen.nextVarName(prefixes.seqComp()); SeqCompStrategy strategy = new SeqCompStrategy(transAssistant, first, predicate, var, type, langIterator, tempVarNameGen, iteVarPrefixes); if (transAssistant.isEmptySetSeq(node.getSetSeq())) { // In case the block has no statements the result of the sequence comprehension is the empty sequence AEnumSeqExpIR emptySeq = new AEnumSeqExpIR(); emptySeq.setType(type.clone()); // Replace the sequence comprehension with the empty sequence transAssistant.replaceNodeWith(node, emptySeq); } else { LinkedList<SPatternIR> patterns = new LinkedList<SPatternIR>(); if (node.getSetBind() != null) { patterns.add(node.getSetBind().getPattern().clone()); } else { patterns.add(node.getSeqBind().getPattern().clone()); } ABlockStmIR block = transAssistant.consIterationBlock(patterns, node.getSetSeq(), transAssistant.getInfo().getTempVarNameGen(), strategy, iteVarPrefixes); replaceCompWithTransformation(enclosingStm, block, type, var, node); block.apply(this); } } @Override public void caseAForAllQuantifierExpIR(AForAllQuantifierExpIR node) throws AnalysisException { SStmIR enclosingStm = transAssistant.getEnclosingStm(node, "forall expression"); SExpIR predicate = node.getPredicate(); ITempVarGen tempVarNameGen = transAssistant.getInfo().getTempVarNameGen(); String var = tempVarNameGen.nextVarName(prefixes.forAll()); OrdinaryQuantifierStrategy strategy = new OrdinaryQuantifierStrategy(transAssistant, predicate, var, OrdinaryQuantifier.FORALL, langIterator, tempVarNameGen, iteVarPrefixes); List<SMultipleBindIR> multipleSetBinds = filterBindList(node, node.getBindList()); ABlockStmIR block = transAssistant.consComplexCompIterationBlock(multipleSetBinds, tempVarNameGen, strategy, iteVarPrefixes); if (multipleSetBinds.isEmpty()) { ABoolLiteralExpIR forAllResult = transAssistant.getInfo().getExpAssistant().consBoolLiteral(true); transAssistant.replaceNodeWith(node, forAllResult); } else { AIdentifierVarExpIR forAllResult = new AIdentifierVarExpIR(); forAllResult.setIsLocal(true); forAllResult.setType(new ABoolBasicTypeIR()); forAllResult.setName(var); transform(enclosingStm, block, forAllResult, node); block.apply(this); } } @Override public void caseAExistsQuantifierExpIR(AExistsQuantifierExpIR node) throws AnalysisException { SStmIR enclosingStm = transAssistant.getEnclosingStm(node, "exists expression"); SExpIR predicate = node.getPredicate(); ITempVarGen tempVarNameGen = transAssistant.getInfo().getTempVarNameGen(); String var = tempVarNameGen.nextVarName(prefixes.exists()); OrdinaryQuantifierStrategy strategy = new OrdinaryQuantifierStrategy(transAssistant, predicate, var, OrdinaryQuantifier.EXISTS, langIterator, tempVarNameGen, iteVarPrefixes); List<SMultipleBindIR> multipleSetBinds = filterBindList(node, node.getBindList()); ABlockStmIR block = transAssistant.consComplexCompIterationBlock(multipleSetBinds, tempVarNameGen, strategy, iteVarPrefixes); if (multipleSetBinds.isEmpty()) { ABoolLiteralExpIR existsResult = transAssistant.getInfo().getExpAssistant().consBoolLiteral(false); transAssistant.replaceNodeWith(node, existsResult); } else { AIdentifierVarExpIR existsResult = new AIdentifierVarExpIR(); existsResult.setIsLocal(true); existsResult.setType(new ABoolBasicTypeIR()); existsResult.setName(var); transform(enclosingStm, block, existsResult, node); block.apply(this); } } @Override public void caseAExists1QuantifierExpIR(AExists1QuantifierExpIR node) throws AnalysisException { SStmIR enclosingStm = transAssistant.getEnclosingStm(node, "exists1 expression"); SExpIR predicate = node.getPredicate(); ITempVarGen tempVarNameGen = transAssistant.getInfo().getTempVarNameGen(); String var = tempVarNameGen.nextVarName(prefixes.exists1()); Exists1QuantifierStrategy strategy = new Exists1QuantifierStrategy(transAssistant, predicate, var, langIterator, tempVarNameGen, iteVarPrefixes, counterData); List<SMultipleBindIR> multipleSetBinds = filterBindList(node, node.getBindList()); ABlockStmIR block = transAssistant.consComplexCompIterationBlock(multipleSetBinds, tempVarNameGen, strategy, iteVarPrefixes); if (multipleSetBinds.isEmpty()) { ABoolLiteralExpIR exists1Result = transAssistant.getInfo().getExpAssistant().consBoolLiteral(false); transAssistant.replaceNodeWith(node, exists1Result); } else { AIdentifierVarExpIR counter = new AIdentifierVarExpIR(); counter.setType(new AIntNumericBasicTypeIR()); counter.setIsLocal(true); counter.setName(var); AEqualsBinaryExpIR exists1Result = new AEqualsBinaryExpIR(); exists1Result.setType(new ABoolBasicTypeIR()); exists1Result.setLeft(counter); exists1Result.setRight(transAssistant.getInfo().getExpAssistant().consIntLiteral(1)); transform(enclosingStm, block, exists1Result, node); block.apply(this); } } public void caseALetDefExpIR(ALetDefExpIR node) throws AnalysisException { SStmIR enclosingStm = transAssistant.getEnclosingStm(node, "let def expression"); SExpIR exp = node.getExp(); transAssistant.replaceNodeWith(node, exp); ABlockStmIR topBlock = new ABlockStmIR(); ABlockStmIR current = topBlock; for (AVarDeclIR local : node.getLocalDefs()) { ABlockStmIR tmp = new ABlockStmIR(); tmp.getLocalDefs().add(local.clone()); current.getStatements().add(tmp); current = tmp; } transAssistant.replaceNodeWith(enclosingStm, topBlock); topBlock.getStatements().add(enclosingStm); exp.apply(this); topBlock.apply(this); topBlock.setScoped(transAssistant.getInfo().getStmAssistant().isScoped(topBlock)); } protected void replaceCompWithTransformation(SStmIR enclosingStm, ABlockStmIR block, STypeIR type, String var, SExpIR comp) { AIdentifierVarExpIR compResult = new AIdentifierVarExpIR(); compResult.setType(type.clone()); compResult.setName(var); compResult.setIsLambda(false); compResult.setIsLocal(true); transform(enclosingStm, block, compResult, comp); } protected void transform(SStmIR enclosingStm, ABlockStmIR block, SExpIR nodeResult, SExpIR node) { // Replace the node with the node result transAssistant.replaceNodeWith(node, nodeResult); // Replace the enclosing statement with the transformation transAssistant.replaceNodeWith(enclosingStm, block); // And make sure to have the enclosing statement in the transformed tree block.getStatements().add(enclosingStm); } protected AAssignToExpStmIR assignToVar(AIdentifierVarExpIR var, SExpIR exp) { AAssignToExpStmIR assignment = new AAssignToExpStmIR(); assignment.setTarget(var.clone()); assignment.setExp(exp.clone()); return assignment; } @Override public void caseACasesExpIR(ACasesExpIR node) throws AnalysisException { SStmIR enclosingStm = transAssistant.getEnclosingStm(node, "cases expression"); AIdentifierPatternIR idPattern = new AIdentifierPatternIR(); IRInfo info = transAssistant.getInfo(); String casesExpResultName = info.getTempVarNameGen().nextVarName(prefixes.casesExp()); idPattern.setName(casesExpResultName); AVarDeclIR resultVarDecl = info.getDeclAssistant().consLocalVarDecl(node.getType().clone(), idPattern, info.getExpAssistant().consUndefinedExp()); AIdentifierVarExpIR resultVar = new AIdentifierVarExpIR(); resultVar.setIsLocal(true); resultVar.setIsLambda(false); resultVar.setName(casesExpResultName); resultVar.setType(node.getType().clone()); ACasesStmIR casesStm = new ACasesStmIR(); casesStm.setExp(node.getExp().clone()); for (ACaseAltExpExpIR altExp : node.getCases()) { ACaseAltStmStmIR altStm = new ACaseAltStmStmIR(); altStm.setPattern(altExp.getPattern().clone()); altStm.setResult(assignToVar(resultVar, altExp.getResult())); altStm.setPatternType(altExp.getPatternType().clone()); casesStm.getCases().add(altStm); } if (node.getOthers() != null) { casesStm.setOthers(assignToVar(resultVar, node.getOthers())); } ABlockStmIR block = new ABlockStmIR(); ABlockStmIR wrapperBlock = new ABlockStmIR(); wrapperBlock.getLocalDefs().add(resultVarDecl); block.getStatements().add(wrapperBlock); block.getStatements().add(casesStm); transform(enclosingStm, block, resultVar, node); casesStm.apply(this); } protected AIfStmIR consAndExpCheck(AAndBoolBinaryExpIR node, String andResultVarName) { SExpIR left = node.getLeft().clone(); SExpIR right = node.getRight().clone(); AIfStmIR leftCheck = new AIfStmIR(); leftCheck.setIfExp(left); AIfStmIR rightCheck = new AIfStmIR(); rightCheck.setIfExp(right); AAssignToExpStmIR assignAndVar = new AAssignToExpStmIR(); assignAndVar.setTarget(transAssistant.consBoolCheck(andResultVarName, false)); assignAndVar.setExp(transAssistant.getInfo().getAssistantManager().getExpAssistant().consBoolLiteral(true)); rightCheck.setThenStm(assignAndVar); leftCheck.setThenStm(rightCheck); return leftCheck; } protected SStmIR consOrExpCheck(AOrBoolBinaryExpIR node, String orResultVarName) { SExpIR left = node.getLeft().clone(); SExpIR right = node.getRight().clone(); AIfStmIR leftCheck = new AIfStmIR(); leftCheck.setIfExp(left); AAssignToExpStmIR setOrResultVarTrue = new AAssignToExpStmIR(); setOrResultVarTrue.setTarget(transAssistant.consBoolCheck(orResultVarName, false)); setOrResultVarTrue.setExp(transAssistant.getInfo().getAssistantManager().getExpAssistant().consBoolLiteral(true)); leftCheck.setThenStm(setOrResultVarTrue); AAssignToExpStmIR setOrResultVarToRightExp = new AAssignToExpStmIR(); setOrResultVarToRightExp.setTarget(transAssistant.consBoolCheck(orResultVarName, false)); setOrResultVarToRightExp.setExp(right); leftCheck.setElseStm(setOrResultVarToRightExp); return leftCheck; } protected boolean transformBoolBinaryExp(SBoolBinaryExpIR node, SStmIR enclosingStm) { // First condition: The enclosing statement can be 'null' if we only try to code generate an expression rather // than // a complete specification. return enclosingStm != null && !transAssistant.getInfo().getExpAssistant().isLoopCondition(node); } protected void visitBoolBinary(SBoolBinaryExpIR node) throws AnalysisException { node.getLeft().apply(this); node.getRight().apply(this); node.getType().apply(this); } protected void handleLogicExp(SBoolBinaryExpIR node, SStmIR enclosingStm, SStmIR checkBlock, String resultName) throws AnalysisException { AVarDeclIR andResultDecl = transAssistant.consBoolVarDecl(resultName, false); ABlockStmIR declBlock = new ABlockStmIR(); declBlock.getLocalDefs().add(andResultDecl); ABlockStmIR replacementBlock = new ABlockStmIR(); transAssistant.replaceNodeWith(enclosingStm, replacementBlock); transAssistant.replaceNodeWith(node, transAssistant.consBoolCheck(resultName, false)); replacementBlock.getStatements().add(declBlock); replacementBlock.getStatements().add(checkBlock); replacementBlock.getStatements().add(enclosingStm); replacementBlock.apply(this); } protected List<SMultipleBindIR> filterBindList(INode node, List<SMultipleBindIR> bindList) { List<SMultipleBindIR> multipleBinds = new LinkedList<SMultipleBindIR>(); for (SMultipleBindIR b : bindList) { if (b instanceof ATypeMultipleBindIR) { transAssistant.getInfo().addTransformationWarning(node, "Transformation only works for " + "expressions with multiple set binds and not multiple " + "type binds in '" + this.getClass().getSimpleName() + "'"); } else { multipleBinds.add(b.clone()); } } return multipleBinds; } }