package org.overture.codegen.trans;
import org.apache.log4j.Logger;
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.AIdentifierVarExpIR;
import org.overture.codegen.ir.patterns.AIdentifierPatternIR;
import org.overture.codegen.ir.statements.AAssignmentStmIR;
import org.overture.codegen.ir.statements.AAtomicStmIR;
import org.overture.codegen.ir.statements.ABlockStmIR;
import org.overture.codegen.trans.assistants.TransAssistantIR;
public class AtomicStmTrans extends DepthFirstAnalysisAdaptor
{
// In VDM...
// atomic
// (
// sd1 := ec1;
// ...;
// sdN := ecN
// )
//
// ..Is evaluated as:
//
// let t1 : T1 = ec1,
// ...
// tN : TN = ecN in
// (
// -- turn off invariants, threading and durations
// sd1 := t1;
// ...
// sdN := tN;
// -- turn on invariants, threading and durations
// -- and check that invariants hold.
// );
private TransAssistantIR transAssistant;
private String atomicPrefix;
private Logger log = Logger.getLogger(this.getClass().getName());
public AtomicStmTrans(TransAssistantIR transAssistant, String atomicPrefix)
{
this.transAssistant = transAssistant;
this.atomicPrefix = atomicPrefix;
}
@Override
public void caseAAtomicStmIR(AAtomicStmIR node) throws AnalysisException
{
ABlockStmIR tmpBlock = new ABlockStmIR();
for (SStmIR stm : node.getStatements())
{
if (stm instanceof AAssignmentStmIR)
{
AAssignmentStmIR assign = (AAssignmentStmIR) stm;
// Build temporary variable
String name = transAssistant.getInfo().getTempVarNameGen().nextVarName(atomicPrefix);
STypeIR type = assign.getTarget().getType().clone();
AIdentifierPatternIR pattern = transAssistant.getInfo().getPatternAssistant().consIdPattern(name);
SExpIR exp = assign.getExp().clone();
AVarDeclIR varDecl = transAssistant.getInfo().getDeclAssistant().consLocalVarDecl(type, pattern, exp);
// Add temporary variable to the block
tmpBlock.getLocalDefs().add(varDecl);
// Assign state designator to temporary variable
AIdentifierVarExpIR tmpVarExp = transAssistant.getInfo().getExpAssistant().consIdVar(name, type.clone());
transAssistant.replaceNodeWith(assign.getExp(), tmpVarExp);
} else
{
log.error("Expected all statements in atomic statement block to be assignments. Got: "
+ stm);
}
}
// Replace the atomic statement with the 'let' statement and make
// the atomic statement its body
transAssistant.replaceNodeWith(node, tmpBlock);
tmpBlock.getStatements().add(node);
}
}