package net.sf.orcc.backends.promela.transform; import java.util.Map.Entry; import java.util.Set; import org.eclipse.emf.ecore.EObject; import net.sf.orcc.OrccRuntimeException; import net.sf.orcc.df.Action; import net.sf.orcc.df.Actor; import net.sf.orcc.df.Pattern; import net.sf.orcc.df.Port; import net.sf.orcc.df.State; import net.sf.orcc.ir.BlockWhile; import net.sf.orcc.ir.util.ValueUtil; import net.sf.orcc.tools.classifier.AbstractInterpreter; public class PromelaAbstractInterpreter extends AbstractInterpreter { protected Action nextPath = null; public void setNextPath(Action nextPath) { this.nextPath = nextPath; } @Override protected void execute(Action action) { executedAction = action; Pattern inputPattern = action.getInputPattern(); for (Port port : inputPattern.getPorts()) { int numTokens = inputPattern.getNumTokens(port); port.increaseTokenConsumption(numTokens); } // allocate output pattern (but not input pattern) Pattern outputPattern = action.getOutputPattern(); allocatePattern(outputPattern); // execute action doSwitch(action.getBody()); // update token production for (Port port : outputPattern.getPorts()) { int numTokens = outputPattern.getNumTokens(port); port.increaseTokenProduction(numTokens); } } @Override protected boolean isSchedulable(Action action) { // don't care about the guard this time if (nextPath != null) { if (nextPath == originalActions.get(action)) { nextPath=null; return true; } else { return false; } } /*Object result = doSwitch(action.getScheduler()); if (result == null) { throw new OrccRuntimeException("could not determine if action " + action.toString() + " is schedulable"); } return ValueUtil.isTrue(result);*/ return super.isSchedulable(action); } public State getCurrChoiseState(Set<State> states) { for (State s : states) { if (copier.get(s) == getFsmState()) {return s;} } return null; } public State getFsmStateOrig() { if (getFsmState()==null) {return null;} for (Entry<EObject, EObject> entry : copier.entrySet()) { if (getFsmState().equals(entry.getValue())) { return (State)entry.getKey(); } } return null; } public PromelaAbstractInterpreter(Actor actor) { super(actor); } @Override public Object caseBlockWhile(BlockWhile block) { int oldBranch = branch; branch = 0; doSwitch(block.getJoinBlock()); Object condition = exprInterpreter.doSwitch(block.getCondition()); int timeout=0; if (ValueUtil.isBool(condition)) { branch = 1; while (ValueUtil.isTrue(condition)) { doSwitch(block.getBlocks()); doSwitch(block.getJoinBlock()); condition = exprInterpreter.doSwitch(block.getCondition()); timeout++; if (!ValueUtil.isBool(condition)||timeout>1000) { nullWasNormal=false; throw new OrccRuntimeException( "Condition not boolean at line " + block.getLineNumber() + "\n"); } } } branch = oldBranch; return null; } private boolean nullWasNormal = true; public boolean nullWasNormal() { return nullWasNormal; } }