package org.reasm.m68k.assembly.internal; import javax.annotation.Nonnull; import javax.annotation.concurrent.Immutable; import org.reasm.Value; import org.reasm.ValueToBooleanVisitor; import org.reasm.m68k.messages.ElseifWithoutIfErrorMessage; /** * The <code>IF</code> and <code>ELSEIF</code> directives. * * @author Francis Gagné */ @Immutable abstract class IfElseifDirective extends Mnemonic { @Nonnull static final IfElseifDirective IF = new IfElseifDirective() { @Override void notInIfBlock(M68KAssemblyContext context) { throw new AssertionError(); } }; @Nonnull static final IfElseifDirective ELSEIF = new IfElseifDirective() { @Override void notInIfBlock(M68KAssemblyContext context) { context.addMessage(new ElseifWithoutIfErrorMessage()); } }; @Override void assemble(M68KAssemblyContext context) { context.sizeNotAllowed(); final Object block = context.getParentBlock(); if (block instanceof IfBlockState) { final IfBlockState ifBlockState = (IfBlockState) block; final Value condition = context.requireNumberOfOperands(1) ? evaluateExpressionOperand(context, 0) : null; final Boolean result = condition == null ? null : Value.accept(condition, ValueToBooleanVisitor.INSTANCE); if (result != null && result.booleanValue()) { // Process the block body, then stop. ifBlockState.iterator.stopAfterNext(); } else { // Skip the block body. ifBlockState.iterator.next(); } } else { this.notInIfBlock(context); } } abstract void notInIfBlock(@Nonnull M68KAssemblyContext context); }