143 lines
3.7 KiB
Java
143 lines
3.7 KiB
Java
import java.io.IOException;
|
|
|
|
public class Interpreter {
|
|
|
|
public final static int MEMORY_SIZE = 65536;
|
|
|
|
private final char[] memory = new char[MEMORY_SIZE];
|
|
private int dp;
|
|
private int ip;
|
|
private int border;
|
|
|
|
private void reset() {
|
|
|
|
for (int i = 0; i < MEMORY_SIZE; i++) {
|
|
memory[i] = 0;
|
|
}
|
|
ip = 0;
|
|
dp = 0;
|
|
}
|
|
|
|
private void load(String program) {
|
|
|
|
if (program.length() > MEMORY_SIZE - 2) {
|
|
throw new RuntimeException("Not enough memory.");
|
|
}
|
|
|
|
reset();
|
|
|
|
for (; dp < program.length(); dp++) {
|
|
memory[dp] = program.charAt(dp);
|
|
}
|
|
|
|
// memory[border] = 0 marks the end of instructions. dp (data pointer) cannot move lower than the
|
|
// border into the program area.
|
|
border = dp;
|
|
|
|
dp += 1;
|
|
}
|
|
|
|
public void execute(String program) {
|
|
|
|
load(program);
|
|
char instruction = memory[ip];
|
|
|
|
while (instruction != 0) {
|
|
|
|
switch (instruction) {
|
|
case '>':
|
|
dp++;
|
|
if (dp == MEMORY_SIZE) {
|
|
throw new RuntimeException("Out of memory.");
|
|
}
|
|
break;
|
|
case '<':
|
|
dp--;
|
|
if (dp == border) {
|
|
throw new RuntimeException("Invalid data pointer.");
|
|
}
|
|
break;
|
|
case '+':
|
|
memory[dp]++;
|
|
break;
|
|
case '-':
|
|
memory[dp]--;
|
|
break;
|
|
case '.':
|
|
System.out.print(memory[dp]);
|
|
break;
|
|
case ',':
|
|
try {
|
|
// Only works for one byte characters.
|
|
memory[dp] = (char) System.in.read();
|
|
} catch (IOException e) {
|
|
throw new RuntimeException(e);
|
|
}
|
|
break;
|
|
case '[':
|
|
if (memory[dp] == 0) {
|
|
skipLoop();
|
|
}
|
|
break;
|
|
case ']':
|
|
if (memory[dp] != 0) {
|
|
loop();
|
|
}
|
|
break;
|
|
default:
|
|
throw new RuntimeException("Unknown instruction.");
|
|
}
|
|
|
|
instruction = memory[++ip];
|
|
}
|
|
}
|
|
|
|
private void skipLoop() {
|
|
|
|
int loopCount = 0;
|
|
|
|
while (memory[ip] != 0) {
|
|
if (memory[ip] == '[') {
|
|
loopCount++;
|
|
} else if (memory[ip] == ']') {
|
|
loopCount--;
|
|
if (loopCount == 0) {
|
|
return;
|
|
}
|
|
}
|
|
ip++;
|
|
}
|
|
|
|
if (memory[ip] == 0) {
|
|
throw new RuntimeException("Unable to find a matching ']'.");
|
|
}
|
|
}
|
|
|
|
private void loop() {
|
|
|
|
int loopCount = 0;
|
|
|
|
while (ip >= 0) {
|
|
if (memory[ip] == ']') {
|
|
loopCount++;
|
|
} else if (memory[ip] == '[') {
|
|
loopCount--;
|
|
if (loopCount == 0) {
|
|
return;
|
|
}
|
|
}
|
|
ip--;
|
|
}
|
|
|
|
if (ip == -1) {
|
|
throw new RuntimeException("Unable to find a matching '['.");
|
|
}
|
|
}
|
|
|
|
public static void main(String[] args) {
|
|
|
|
Interpreter interpreter = new Interpreter();
|
|
interpreter.execute(">++++++++[-<+++++++++>]<.>>+>-[+]++>++>+++[>[->+++<<+++>]<<]>-----.>->+++..+++.>-.<<+[>[+>+]>>]<--------------.>>.+++.------.--------.>+.>+.");
|
|
}
|
|
}
|