com.github.bloodshura.sparkium.brainfxck.BrainfuckContext Maven / Gradle / Ivy
Show all versions of sparkium-brainfxck Show documentation
package com.github.bloodshura.sparkium.brainfxck;
import com.github.bloodshura.ignitium.collection.map.XMap;
import com.github.bloodshura.ignitium.collection.map.impl.XLinkedMap;
import com.github.bloodshura.ignitium.collection.store.impl.XStack;
import com.github.bloodshura.sparkium.brainfxck.action.Action;
import javax.annotation.Nonnull;
import java.io.IOException;
/**
* This class is responsible for maintaining the execution context of a Brainfuck code.
* The context includes, but is not limited to, management flags, loop stack, and a reference to the interpreter.
*/
public class BrainfuckContext {
private final XMap flags;
private int index;
private final BrainfuckInterpreter interpreter;
private final XStack loopStack;
/**
* Constructs a new context, which targets the specified {@link BrainfuckInterpreter}.
*
* @param interpreter The interpreter
*/
public BrainfuckContext(@Nonnull BrainfuckInterpreter interpreter) {
this.flags = new XLinkedMap<>();
this.interpreter = interpreter;
this.loopStack = new XStack<>();
}
/**
* The current character position being processed.
* Note that, this may NOT be sequential, since loops can reset to a previous position using the {@link #getLoopStack()}, or even custom actions can manipulate it.
*
This position is relative to the original Brainfuck source code, passed to the interpreter via {@link BrainfuckInterpreter#interpret(CharSequence)}.
*
* @return The current character position
* @see #getLoopStack()
*/
public int getCurrentIndex() {
return index;
}
/**
* Returns the flag map, which contains action-defined flags.
*
* @return The flag map
*/
@Nonnull
public XMap getFlags() {
return flags;
}
/**
* Returns the interpreter this context targets.
*
* @return The interpreter
*/
@Nonnull
public BrainfuckInterpreter getInterpreter() {
return interpreter;
}
/**
* Returns the {@link XStack} (LIFO) which represents the current loop stack of this context.
*
* @return The stack
*/
@Nonnull
public XStack getLoopStack() {
return loopStack;
}
/**
* Interprets the specified single character on this context.
*
* @param ch The character to be interpreted
* @return boolean indicating if any action processed this character
* @throws IOException If an I/O exception occurs on any action
*/
public boolean interpret(char ch) throws IOException {
boolean anyAction = false;
for (Action action : getInterpreter().getActionSet()) {
if (action.act(ch, this)) {
anyAction = true;
}
}
return anyAction;
}
/**
* Changes the scan character position to be processed.
* Note that, the index is set automatically in the main interpretation loop, but it will detect any outside-changes and properly redirect the loop to the defined index.
*
* @param index The scan character position
* @see #getCurrentIndex()
*/
public void setCurrentIndex(int index) {
this.index = index;
}
}