package org.reasm.m68k.assembly.internal;
import javax.annotation.Nonnull;
import javax.annotation.concurrent.Immutable;
import org.reasm.Value;
import org.reasm.ValueToBooleanVisitor;
/**
* The <code>WHILE</code> directive.
*
* @author Francis Gagné
*/
@Immutable
class WhileDirective extends Mnemonic {
@Nonnull
static final WhileDirective WHILE = new WhileDirective();
private WhileDirective() {
}
@Override
void assemble(M68KAssemblyContext context) {
context.sizeNotAllowed();
final Object blockState = context.getParentBlock();
if (!(blockState instanceof WhileBlockState)) {
throw new AssertionError();
}
final WhileBlockState whileBlockState = (WhileBlockState) blockState;
// The WHILE directive is assembled on every iteration.
// Parse the condition operand on the first iteration only.
if (!whileBlockState.parsedCondition) {
if (context.requireNumberOfOperands(1)) {
whileBlockState.conditionExpression = parseExpressionOperand(context, 0);
}
whileBlockState.parsedCondition = true;
}
final Value condition;
if (whileBlockState.conditionExpression != null) {
condition = whileBlockState.conditionExpression.evaluate(context.getEvaluationContext());
} else {
condition = null;
}
final Boolean result = Value.accept(condition, ValueToBooleanVisitor.INSTANCE);
if (!(result != null && result.booleanValue())) {
// Skip the block body and stop the iteration.
whileBlockState.iterator.next();
whileBlockState.hasNextIteration = false;
}
}
}