package org.overture.codegen.trans; import java.util.List; import org.overture.codegen.assistant.ExpAssistantIR; import org.overture.codegen.ir.SExpIR; 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.AGeneralIsExpIR; import org.overture.codegen.ir.expressions.AOrBoolBinaryExpIR; import org.overture.codegen.ir.expressions.SVarExpBase; import org.overture.codegen.ir.statements.ABlockStmIR; import org.overture.codegen.ir.types.ABoolBasicTypeIR; import org.overture.codegen.ir.types.AUnionTypeIR; import org.overture.codegen.trans.assistants.TransAssistantIR; public class IsExpTrans extends DepthFirstAnalysisAdaptor { private TransAssistantIR transAssistant; private String isExpSubjectNamePrefix; public IsExpTrans(TransAssistantIR transAssistant, String isExpSubjectNamePrefix) { this.transAssistant = transAssistant; this.isExpSubjectNamePrefix = isExpSubjectNamePrefix; } @Override public void caseAGeneralIsExpIR(AGeneralIsExpIR node) throws AnalysisException { STypeIR checkedType = node.getCheckedType(); if (!(checkedType instanceof AUnionTypeIR)) { node.getExp().apply(this); return; } AUnionTypeIR unionType = (AUnionTypeIR) checkedType; List<STypeIR> types = unionType.getTypes(); types = transAssistant.getInfo().getTypeAssistant().clearObjectTypes(types); SExpIR exp = node.getExp(); STypeIR expType = node.getExp().getType(); ExpAssistantIR expAssistant = transAssistant.getInfo().getExpAssistant(); if (types.size() == 1) { SExpIR isExp = expAssistant.consIsExp(exp, types.get(0)); transAssistant.replaceNodeWith(node, isExp); isExp.apply(this); } else { ABlockStmIR replacementBlock = new ABlockStmIR(); SExpIR expVar = null; if (!(exp instanceof SVarExpBase)) { String varName = transAssistant.getInfo().getTempVarNameGen().nextVarName(isExpSubjectNamePrefix); AVarDeclIR expDecl = transAssistant.consDecl(varName, expType.clone(), exp.clone()); replacementBlock.getLocalDefs().add(expDecl); expVar = transAssistant.getInfo().getExpAssistant().consIdVar(varName, expType.clone()); } else { expVar = exp; } AOrBoolBinaryExpIR topOrExp = new AOrBoolBinaryExpIR(); topOrExp.setType(new ABoolBasicTypeIR()); STypeIR firstType = types.get(0); SExpIR nextIsExp = expAssistant.consIsExp(expVar, firstType); topOrExp.setLeft(nextIsExp); AOrBoolBinaryExpIR nextOrExp = topOrExp; for (int i = 1; i < types.size() - 1; i++) { STypeIR currentType = types.get(i); nextIsExp = expAssistant.consIsExp(expVar, currentType); AOrBoolBinaryExpIR tmp = new AOrBoolBinaryExpIR(); tmp.setType(new ABoolBasicTypeIR()); tmp.setLeft(nextIsExp); nextOrExp.setRight(tmp); nextOrExp = tmp; } STypeIR lastType = types.get(types.size() - 1); nextIsExp = expAssistant.consIsExp(expVar, lastType); nextOrExp.setRight(nextIsExp); SStmIR enclosingStm = transAssistant.getEnclosingStm(node, "general is-expression"); transAssistant.replaceNodeWith(enclosingStm, replacementBlock); transAssistant.replaceNodeWith(node, topOrExp); replacementBlock.getStatements().add(enclosingStm); topOrExp.apply(this); } } }