LibfooExecutor.java
package edu.udel.cis.vsl.tass.library.libfoo;
import edu.udel.cis.vsl.tass.dynamic.IF.DynamicException;
import edu.udel.cis.vsl.tass.dynamic.IF.cell.ModelCellIF;
import edu.udel.cis.vsl.tass.dynamic.IF.value.ArrayElementReferenceValueIF;
import edu.udel.cis.vsl.tass.dynamic.IF.value.ArrayValueIF;
import edu.udel.cis.vsl.tass.dynamic.IF.value.RecordElementReferenceValueIF;
import edu.udel.cis.vsl.tass.dynamic.IF.value.RecordValueIF;
import edu.udel.cis.vsl.tass.dynamic.IF.value.ReferenceValueIF;
import edu.udel.cis.vsl.tass.dynamic.IF.value.ValueIF;
import edu.udel.cis.vsl.tass.dynamic.IF.value.VariableReferenceValueIF;
import edu.udel.cis.vsl.tass.model.IF.ProcessIF;
import edu.udel.cis.vsl.tass.model.IF.expression.ExpressionIF;
import edu.udel.cis.vsl.tass.model.IF.expression.LHSExpressionIF;
import edu.udel.cis.vsl.tass.model.IF.expression.VariableExpressionIF;
import edu.udel.cis.vsl.tass.model.IF.location.LocationIF;
import edu.udel.cis.vsl.tass.model.IF.statement.InvocationStatementIF;
import edu.udel.cis.vsl.tass.semantics.IF.EnvironmentIF;
import edu.udel.cis.vsl.tass.semantics.IF.EvaluatorIF;
import edu.udel.cis.vsl.tass.semantics.IF.ExecutionException;
import edu.udel.cis.vsl.tass.semantics.IF.ExecutionProblem;
import edu.udel.cis.vsl.tass.semantics.IF.ExecutorIF;
import edu.udel.cis.vsl.tass.semantics.IF.LibraryExecutorIF;
import edu.udel.cis.vsl.tass.semantics.IF.ExecutionProblem.Certainty;
import edu.udel.cis.vsl.tass.semantics.IF.ExecutionProblem.ErrorKind;
import edu.udel.cis.vsl.tass.util.Sourceable;
public class LibfooExecutor implements LibraryExecutorIF {
private ExecutorIF executor;
public LibfooExecutor(ExecutorIF executor, EvaluatorIF evaluator) {
this.executor = executor;
}
@Override
public boolean containsFunction(String name) {
if (name.equals("FOO_f")) {
return true;
}
return false;
}
@Override
public void execute(EnvironmentIF environment,
InvocationStatementIF invocation) throws ExecutionException {
LocationIF targetLocation = invocation.targetLocation();
ProcessIF process = invocation.process();
EvaluatorIF evaluator = executor.evaluator();
String name = invocation.callee().name();
if (name.equals("FOO_f")) {
// Execute f. This is a constant function. It returns 100 regardless
// of
// the formal parameter value.
LHSExpressionIF lhs = invocation.lhs();
if (lhs != null && lhs instanceof VariableExpressionIF) {
assignValue(environment, lhs, evaluator.dynamicFactory()
.symbolicValue(100), evaluator);
}
} else if (name.equals("square")) {
// Execute square. This returns the square of the parameter.
LHSExpressionIF lhs = invocation.lhs();
ExpressionIF arg = invocation.arguments()[0];
ValueIF argValue = executor.evaluator().evaluate(environment, arg);
if (lhs != null && lhs instanceof VariableExpressionIF) {
assignValue(environment, lhs, evaluator.dynamicFactory()
.multiply(environment.getAssumption(), argValue,
argValue), evaluator);
}
} else if (name.equals("do_nothing")) {
// Do nothing. This is just here to test the system function guards.
} else {
throw new ExecutionException(invocation, ErrorKind.LIBRARY,
Certainty.MAYBE, "Unknown function: " + name);
}
environment.setLocation(process, targetLocation);
}
private void assignValue(EnvironmentIF environment,
ReferenceValueIF reference, ValueIF value, EvaluatorIF evaluator,
Sourceable sourceable) throws ExecutionProblem {
ValueIF assumption = environment.getAssumption();
try {
if (reference instanceof VariableReferenceValueIF) {
environment.setValue(
(ModelCellIF) ((VariableReferenceValueIF) reference)
.variable(), value);
} else if (reference instanceof ArrayElementReferenceValueIF) {
ArrayElementReferenceValueIF elementReference = (ArrayElementReferenceValueIF) reference;
ReferenceValueIF parent = elementReference.parent();
ArrayValueIF parentValue = (ArrayValueIF) evaluator
.dereference(environment, parent, sourceable);
ValueIF index = elementReference.index();
ValueIF newParentValue = evaluator.dynamicFactory().arrayWrite(
assumption, parentValue, index, value);
assignValue(environment, parent, newParentValue, evaluator,
sourceable);
} else if (reference instanceof RecordElementReferenceValueIF) {
RecordElementReferenceValueIF elementReference = (RecordElementReferenceValueIF) reference;
ReferenceValueIF parent = elementReference.parent();
RecordValueIF parentValue = (RecordValueIF) evaluator
.dereference(environment, parent, sourceable);
int fieldIndex = elementReference.fieldIndex();
ValueIF newParentValue = evaluator
.dynamicFactory()
.recordWrite(assumption, parentValue, fieldIndex, value);
assignValue(environment, parent, newParentValue, evaluator,
sourceable);
} else {
throw new IllegalArgumentException("Unknown reference type:\n"
+ reference);
}
} catch (DynamicException error) {
throw new ExecutionProblem(error, Certainty.NONE);
}
}
private void assignValue(EnvironmentIF environment, LHSExpressionIF lhs,
ValueIF value, EvaluatorIF evaluator) throws ExecutionException {
try {
ReferenceValueIF reference = evaluator.referenceValue(environment,
lhs);
assignValue(environment, reference, value, evaluator, lhs);
} catch (ExecutionException error) {
throw error;
} catch (ExecutionProblem error) {
throw new ExecutionException(lhs, error);
}
}
@Override
public String name() {
return "libfoo";
}
@Override
public void initialize(EnvironmentIF environment) throws ExecutionException {
}
@Override
public void wrapUp(EnvironmentIF environment) throws ExecutionException {
}
}