package org.overture.codegen.trans; import org.overture.codegen.ir.SExpIR; import org.overture.codegen.ir.SStmIR; 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.statements.ABlockStmIR; import org.overture.codegen.ir.statements.ABreakStmIR; import org.overture.codegen.ir.statements.AIfStmIR; import org.overture.codegen.ir.statements.AWhileStmIR; import org.overture.codegen.trans.assistants.TransAssistantIR; public class WhileStmTrans extends DepthFirstAnalysisAdaptor { private TransAssistantIR transAssistant; private String whileCondExpPrefix; public WhileStmTrans(TransAssistantIR transAssistant, String whileCondExpPrefix) { this.transAssistant = transAssistant; this.whileCondExpPrefix = whileCondExpPrefix; } @Override public void caseAWhileStmIR(AWhileStmIR node) throws AnalysisException { // while(boolExp) { body; } // // boolExp is replaced with a variable expression 'whileCond' that is // computed as set for each iteration in the while loop: // // boolean whileCond = true; // // while(whileCond) // { // whileCond = boolExp; // if (!whileCond) { break; } // body; // } // // This is needed for cases where the while condition is a complex // expression that needs to be transformed. For example, when the // while condition is a quantified expression SExpIR exp = node.getExp().clone(); SStmIR body = node.getBody().clone(); String whileCondName = transAssistant.getInfo().getTempVarNameGen().nextVarName(whileCondExpPrefix); SExpIR whileCondVar = transAssistant.consBoolCheck(whileCondName, false); AIfStmIR whileCondCheck = new AIfStmIR(); whileCondCheck.setIfExp(transAssistant.consBoolCheck(whileCondName, true)); whileCondCheck.setThenStm(new ABreakStmIR()); ABlockStmIR newWhileBody = new ABlockStmIR(); newWhileBody.getStatements().add(transAssistant.consBoolVarAssignment(exp, whileCondName)); newWhileBody.getStatements().add(whileCondCheck); newWhileBody.getStatements().add(body); AWhileStmIR newWhileStm = new AWhileStmIR(); newWhileStm.setExp(whileCondVar); newWhileStm.setBody(newWhileBody); ABlockStmIR declBlock = new ABlockStmIR(); AVarDeclIR whileCondVarDecl = transAssistant.consBoolVarDecl(whileCondName, true); declBlock.getLocalDefs().add(whileCondVarDecl); declBlock.getStatements().add(newWhileStm); transAssistant.replaceNodeWith(node, declBlock); newWhileStm.getBody().apply(this); } }