CommonUpdateStatement.java
package dev.civl.mc.model.common.statement;
import java.util.HashSet;
import java.util.Set;
import dev.civl.mc.model.IF.CIVLFunction;
import dev.civl.mc.model.IF.CIVLSource;
import dev.civl.mc.model.IF.Scope;
import dev.civl.mc.model.IF.expression.ConditionalExpression;
import dev.civl.mc.model.IF.expression.Expression;
import dev.civl.mc.model.IF.location.Location;
import dev.civl.mc.model.IF.statement.CallOrSpawnStatement;
import dev.civl.mc.model.IF.statement.Statement;
import dev.civl.mc.model.IF.statement.UpdateStatement;
import dev.civl.mc.model.IF.variable.Variable;
import dev.civl.sarl.IF.SymbolicUniverse;
public class CommonUpdateStatement extends CommonStatement
implements
UpdateStatement {
private Expression collator;
private CIVLFunction function;
private Expression[] arguments;
public CommonUpdateStatement(CIVLSource source, Location sourceLoc,
Expression guard, Expression collator, CallOrSpawnStatement call) {
super(source, collator.expressionScope(), collator.lowestScope(),
sourceLoc, guard);
this.collator = collator;
}
public CommonUpdateStatement(CIVLSource source, Location sourceLoc,
Expression guard, Expression collator, CIVLFunction function,
Expression[] arguments) {
super(source, collator.expressionScope(), collator.lowestScope(),
sourceLoc, guard);
this.collator = collator;
this.function = function;
this.arguments = arguments;
}
@Override
public Statement replaceWith(ConditionalExpression oldExpression,
Expression newExpression) {
Expression newGuard = this.guard().replaceWith(oldExpression,
newExpression), newCollator = collator;
Expression[] newArgs = this.arguments;
boolean hasNew = false;
if (newGuard != null)
hasNew = true;
else
newGuard = this.guard();
if (!hasNew) {
newCollator = collator.replaceWith(oldExpression, newExpression);
if (newCollator != null)
hasNew = true;
else
newCollator = collator;
}
if (!hasNew) {
int numArgs = arguments.length;
newArgs = new Expression[numArgs];
for (int i = 0; i < numArgs; i++) {
Expression newArg = arguments[i].replaceWith(oldExpression,
newExpression);
if (newArg != null) {
hasNew = true;
break;
} else
newArg = arguments[i];
newArgs[i] = newArg;
}
}
if (hasNew)
return new CommonUpdateStatement(this.getSource(), this.source(),
this.guard(), newCollator, function, newArgs);
return null;
}
@Override
public Set<Variable> variableAddressedOf(Scope scope) {
Set<Variable> result = new HashSet<>();
Set<Variable> subResult = collator.variableAddressedOf();
if (subResult != null)
result.addAll(subResult);
for (Expression arg : arguments) {
subResult = arg.variableAddressedOf(scope);
if (subResult != null)
result.addAll(subResult);
}
if (result.size() > 0)
return result;
return null;
}
@Override
public Set<Variable> variableAddressedOf() {
Set<Variable> result = new HashSet<>();
Set<Variable> subResult = collator.variableAddressedOf();
if (subResult != null)
result.addAll(subResult);
for (Expression arg : arguments) {
subResult = arg.variableAddressedOf();
if (subResult != null)
result.addAll(subResult);
}
if (result.size() > 0)
return result;
return null;
}
@Override
public StatementKind statementKind() {
return StatementKind.UPDATE;
}
@Override
public Expression collator() {
return collator;
}
@Override
public CallOrSpawnStatement call() {
return null;
}
@Override
protected void calculateConstantValueWork(SymbolicUniverse universe) {
this.collator.calculateConstantValue(universe);
for (Expression arg : arguments)
arg.calculateConstantValue(universe);
}
@Override
public CIVLFunction function() {
return this.function;
}
@Override
public Expression[] arguments() {
return this.arguments;
}
@Override
public String toString() {
StringBuffer sb = new StringBuffer();
int numArgs = arguments.length;
boolean isFirst = true;
sb.append("$update (");
sb.append(collator);
sb.append(") ");
sb.append(function.name().name());
sb.append("(");
for (int i = 0; i < numArgs; i++) {
if (isFirst)
isFirst = false;
else
sb.append(", ");
sb.append(arguments[i]);
}
sb.append(")");
return sb.toString();
}
@Override
public Set<Variable> freeVariables() {
Set<Variable> result = super.freeVariables();
result.addAll(collator.freeVariables());
for (Expression arg : arguments)
result.addAll(arg.freeVariables());
return result;
}
}