CommonConditionalExpression.java
/**
*
*/
package dev.civl.mc.model.common.expression;
import java.util.HashSet;
import java.util.Set;
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.expression.VariableExpression;
import dev.civl.mc.model.IF.type.CIVLType;
import dev.civl.mc.model.IF.variable.Variable;
/**
* @author zirkel
*
*/
public class CommonConditionalExpression extends CommonExpression
implements
ConditionalExpression {
Expression condition;
Expression trueBranch;
Expression falseBranch;
/**
* The ternary conditional expression ("?" in C).
*
* @param condition
* The condition evaluated in this conditional.
* @param trueBranch
* The expression returned if the branch evaluates to true.
* @param falseBranch
* The expression returned if the branch evaluates to false.
*/
public CommonConditionalExpression(CIVLSource source, Scope hscope,
Scope lscope, CIVLType type, Expression condition,
Expression trueBranch, Expression falseBranch) {
super(source, hscope, lscope, type);
this.condition = condition;
this.trueBranch = trueBranch;
this.falseBranch = falseBranch;
}
/*
* (non-Javadoc)
*
* @see dev.civl.mc.model.IF.expression.ConditionalExpression#
* getCondition ()
*/
@Override
public Expression getCondition() {
return condition;
}
/*
* (non-Javadoc)
*
* @see dev.civl.mc.model.IF.expression.ConditionalExpression#
* getTrueBranch ()
*/
@Override
public Expression getTrueBranch() {
return trueBranch;
}
/*
* (non-Javadoc)
*
* @see dev.civl.mc.model.IF.expression.ConditionalExpression#
* getFalseBranch()
*/
@Override
public Expression getFalseBranch() {
return falseBranch;
}
@Override
public String toString() {
return "(" + condition + " ? " + trueBranch + " : " + falseBranch + ")";
}
@Override
public ExpressionKind expressionKind() {
return ExpressionKind.COND;
}
@Override
public void calculateDerefs() {
this.condition.calculateDerefs();
this.trueBranch.calculateDerefs();
this.falseBranch.calculateDerefs();
this.hasDerefs = this.condition.hasDerefs()
|| this.trueBranch.hasDerefs() || this.falseBranch.hasDerefs();
}
@Override
public void purelyLocalAnalysisOfVariables(Scope funcScope) {
this.condition.purelyLocalAnalysisOfVariables(funcScope);
this.trueBranch.purelyLocalAnalysisOfVariables(funcScope);
this.falseBranch.purelyLocalAnalysisOfVariables(funcScope);
}
@Override
public void purelyLocalAnalysis() {
if (this.hasDerefs) {
this.purelyLocal = false;
return;
}
this.condition.purelyLocalAnalysis();
this.trueBranch.purelyLocalAnalysis();
this.falseBranch.purelyLocalAnalysis();
this.purelyLocal = this.condition.isPurelyLocal()
&& this.trueBranch.isPurelyLocal()
&& this.falseBranch.isPurelyLocal();
}
@Override
public void replaceWith(ConditionalExpression oldExpression,
VariableExpression newExpression) {
if (condition == oldExpression) {
condition = newExpression;
return;
}
if (trueBranch == oldExpression) {
trueBranch = newExpression;
return;
}
if (falseBranch == oldExpression) {
falseBranch = newExpression;
return;
}
condition.replaceWith(oldExpression, newExpression);
trueBranch.replaceWith(oldExpression, newExpression);
falseBranch.replaceWith(oldExpression, newExpression);
}
@Override
public Expression replaceWith(ConditionalExpression oldExpression,
Expression newExpression) {
Expression newCondition, newTrue, newFalse, result = null;
if (this == oldExpression)
return newExpression;
newCondition = condition.replaceWith(oldExpression, newExpression);
if (newCondition != null) {
result = new CommonConditionalExpression(this.getSource(),
this.expressionScope(), this.lowestScope(),
this.expressionType, newCondition, trueBranch, falseBranch);
} else {
newTrue = trueBranch.replaceWith(oldExpression, newExpression);
if (newTrue != null) {
result = new CommonConditionalExpression(this.getSource(),
this.expressionScope(), this.lowestScope(),
this.expressionType, condition, newTrue, falseBranch);
} else {
newFalse = falseBranch.replaceWith(oldExpression,
newExpression);
if (newFalse != null)
result = new CommonConditionalExpression(this.getSource(),
this.expressionScope(), this.lowestScope(),
this.expressionType, condition, trueBranch,
newFalse);
}
}
return result;
}
@Override
public Set<Variable> variableAddressedOf(Scope scope) {
Set<Variable> variableSet = new HashSet<>();
Set<Variable> operandResult = condition.variableAddressedOf(scope);
if (operandResult != null)
variableSet.addAll(operandResult);
operandResult = this.trueBranch.variableAddressedOf(scope);
if (operandResult != null)
variableSet.addAll(operandResult);
operandResult = this.falseBranch.variableAddressedOf(scope);
if (operandResult != null)
variableSet.addAll(operandResult);
return variableSet;
}
@Override
public Set<Variable> variableAddressedOf() {
Set<Variable> variableSet = new HashSet<>();
Set<Variable> operandResult = condition.variableAddressedOf();
if (operandResult != null)
variableSet.addAll(operandResult);
operandResult = this.trueBranch.variableAddressedOf();
if (operandResult != null)
variableSet.addAll(operandResult);
operandResult = this.falseBranch.variableAddressedOf();
if (operandResult != null)
variableSet.addAll(operandResult);
return variableSet;
}
@Override
protected boolean expressionEquals(Expression expression) {
ConditionalExpression that = (ConditionalExpression) expression;
return this.condition.equals(that.getCondition())
&& this.trueBranch.equals(that.getTrueBranch())
&& this.falseBranch.equals(that.getFalseBranch());
}
@Override
public boolean containsHere() {
return condition.containsHere() || trueBranch.containsHere()
|| falseBranch.containsHere();
}
@Override
protected void addFreeVariables(Set<Variable> result) {
((CommonExpression) condition).addFreeVariables(result);
((CommonExpression) trueBranch).addFreeVariables(result);
((CommonExpression) falseBranch).addFreeVariables(result);
}
}