package sbahjsic.interpreter.compiler;

import sbahjsic.io.BytecodeIO.BytecodeReader;
import sbahjsic.io.BytecodeIO.BytecodeWriter;
import sbahjsic.runtime.RuntimeContext;
import sbahjsic.runtime.Block;
import sbahjsic.runtime.Block.BlockBuilder;

final class While extends Instruction {
	
	private final int conditions;
	
	While(int conditionInstructions) {
		this.conditions = conditionInstructions;
	}

	@Override
	public void execute(RuntimeContext runtime) {
		Block top = runtime.blockStack().top();
		
		if(!top.isExecuted()) {
			runtime.blockStack().push(new BlockBuilder("while-indefinite")
					.setIsExecuted(false)
					.setLoop(false, 0)
					.setPermittedInstructions(InstructionType.CONTROL_FLOW)
					.build());
			return;
		}
		
		boolean whileValue = runtime.pop().asBool();
		
		runtime.blockStack().push(new BlockBuilder("while-" + whileValue)
				.setLoop(whileValue, conditions)
				.setIsExecuted(whileValue)
				.setPermittedInstructions(InstructionType.CONTROL_FLOW)
				.build());
	}
	
	@Override
	public BytecodeWriter writer() {
		return (ins, out) -> {
			out.writeByte(InstructionType.WHILE.id());
			out.writeInt(conditions);
		};
	}
	
	public static BytecodeReader reader() {
		return (in) -> {
			return new While(in.readInt());
		};
	}

	@Override
	public String toString() {
		return "while " + conditions;
	}

	@Override
	public InstructionType type() {
		return InstructionType.WHILE;
	}
	
}