CommonFunctionContract.java
package dev.civl.mc.model.common.contract;
import java.io.PrintStream;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import dev.civl.mc.model.IF.CIVLSource;
import dev.civl.mc.model.IF.Scope;
import dev.civl.mc.model.IF.contract.FunctionBehavior;
import dev.civl.mc.model.IF.contract.FunctionContract;
import dev.civl.mc.model.IF.contract.MPICollectiveBehavior;
import dev.civl.mc.model.IF.contract.NamedFunctionBehavior;
import dev.civl.mc.model.IF.expression.Expression;
import dev.civl.mc.model.common.CommonSourceable;
public class CommonFunctionContract extends CommonSourceable
implements
FunctionContract {
private boolean pure = false;
private boolean hasMPIWaitsfors = false;
private Expression guard = null;
private FunctionBehavior defaultBehavior;
private List<MPICollectiveBehavior> mpiCollectiveBehaviors = null;
private HashMap<String, NamedFunctionBehavior> namedBehaviors = new HashMap<>();
/**
* The static cope in which the contract occurs, usually the parameter scope
* of the function definition or prototype in which the contract occurred.
* Not necessarily the same as the final value of the function's parameter
* scope because if the contract occurred first on a prototype and then
* later the function definition occurred, the function object will be
* updated to use the definition's parameter scope. Note the variable names
* used in the definition do not have to be the same as those used in the
* prototype (and contract).
*/
private Scope scope;
public CommonFunctionContract(CIVLSource source, Scope scope) {
super(source);
this.scope = scope;
defaultBehavior = new CommonFunctionBehavior(source);
}
@Override
public Scope scope() {
return scope;
}
@Override
public FunctionBehavior defaultBehavior() {
return this.defaultBehavior;
}
@Override
public Iterable<NamedFunctionBehavior> namedBehaviors() {
return this.namedBehaviors.values();
}
@Override
public Expression guard() {
return this.guard;
}
@Override
public void setGuard(Expression expression) {
this.guard = expression;
}
@Override
public void setDefaultBehavior(FunctionBehavior behavior) {
this.defaultBehavior = behavior;
}
@Override
public void addNamedBehavior(NamedFunctionBehavior behavior) {
this.namedBehaviors.put(behavior.name(), behavior);
}
@Override
public NamedFunctionBehavior getBehavior(String name) {
return this.namedBehaviors.get(name);
}
@Override
public void print(String prefix, PrintStream out, boolean isDebug) {
String subPrefix = prefix + "| ";
out.println(prefix + "contract");
if (this.pure)
out.println(subPrefix + "pure");
if (guard != null)
out.println(subPrefix + "guard: " + guard.toString());
defaultBehavior.print(subPrefix, out, isDebug);
for (NamedFunctionBehavior behavior : namedBehaviors.values()) {
behavior.print(subPrefix, out, isDebug);
}
}
@Override
public boolean isPure() {
return this.pure;
}
@Override
public void setPure(boolean value) {
this.pure = value;
}
@Override
public boolean hasReadsClause() {
return this.defaultBehavior.readsNothing()
|| defaultBehavior.numReadsMemoryUnits() > 0;
}
@Override
public boolean hasAssignsClause() {
return defaultBehavior.assignsNothing()
|| defaultBehavior.numAssignsMemoryUnits() > 0;
}
@Override
public boolean hasDependsClause() {
return defaultBehavior.dependsAnyact() || defaultBehavior.dependsNoact()
|| defaultBehavior.numDependsEvents() > 0;
}
@Override
public boolean hasRequirementsOrEnsurances() {
return (defaultBehavior.numEnsurances()
+ defaultBehavior.numRequirements()) > 0;
}
@Override
public void addMPICollectiveBehavior(MPICollectiveBehavior behavior) {
if (mpiCollectiveBehaviors == null)
mpiCollectiveBehaviors = new LinkedList<>();
mpiCollectiveBehaviors.add(behavior);
}
@Override
public Iterable<MPICollectiveBehavior> getMPIBehaviors() {
if (mpiCollectiveBehaviors == null)
mpiCollectiveBehaviors = new LinkedList<>();
return mpiCollectiveBehaviors;
}
@Override
public int numMPICollectiveBehaviors() {
if (mpiCollectiveBehaviors == null)
return 0;
else
return mpiCollectiveBehaviors.size();
}
@Override
public boolean hasMPIWaitsfor() {
return hasMPIWaitsfors;
}
@Override
public void setHasMPIWaitsfor(boolean hasWaitsfor) {
this.hasMPIWaitsfors = hasWaitsfor;
}
}