package bfrc.interpreter;

import java.io.IOException;

import bfrc.ast.BlockNode;
import bfrc.ast.ChangeNode;
import bfrc.ast.Node;
import bfrc.ast.RootNode;
import bfrc.backend.Backend;

/**
 * A simple interpreter backend, that directly traverses the AST during
 * execution.
 * 
 * @author oreissig
 */
public class Interpreter implements Backend {

	private final byte[] mem = new byte[MEM_SIZE];
	private final InputOutput io;
	private int p = 0;

	public Interpreter() {
		this(new ConsoleIO());
	}

	public Interpreter(InputOutput io) {
		this.io = io;
	}

	@Override
	public void work(RootNode root) {
		for (Node n : root.sub)
			visit(n);
	}

	/**
	 * This method implements a custom traversion mechanism to handle repeated
	 * loop execution.
	 * 
	 * @param n node to visit
	 */
	private void visit(Node n) {
		try {
			switch (n.type) {
				case LOOP:
					BlockNode block = (BlockNode) n;
					while (mem[p] != 0)
						for (Node child : block.sub)
							visit(child);
					break;
				case VALUE:
					ChangeNode cn = (ChangeNode) n;
					if (cn.absolute)
						mem[p] = (byte) cn.change;
					else
						mem[p] += cn.change;
					break;
				case POINTER:
					cn = (ChangeNode) n;
					p += cn.change;
					break;
				case INPUT:
					mem[p] = read();
					break;
				case OUTPUT:
					write(mem[p]);
					break;
				default:
					throw new RuntimeException("unexpected node type: " + n.type);
			}
		} catch (Exception e) {
			throw new RuntimeException("Error interpreting " + n, e);
		}
	}

	void write(byte value) throws IOException {
		io.write(value);
	}

	byte read() throws IOException {
		return io.read();
	}
}

@@ -24,37 +24,8 @@
 r;%0A%0A
-import java.io.IOException;%0A%0A
 impo
@@ -43,24 +43,24 @@
 .BlockNode;%0A
+
 import bfrc.
@@ -317,29 +317,31 @@
 ckend %7B%0A%0A%09pr
-ivate
+otected
  final byte%5B
@@ -368,16 +368,38 @@
 _SIZE%5D;%0A
+%09protected int p = 0;%0A
 %09private
@@ -424,28 +424,8 @@
  io;
-%0A%09private int p = 0;
 %0A%0A%09p
@@ -763,21 +763,23 @@
 %09 */%0A%09pr
-ivate
+otected
  void vi
@@ -1231,16 +1231,19 @@
 em%5Bp%5D = 
+io.
 read();%0A
@@ -1276,16 +1276,19 @@
 T:%0A%09%09%09%09%09
+io.
 write(me
@@ -1483,139 +1483,13 @@
 e);%0A
+
 %09%09%7D%0A%09%7D
-%0A%0A%09void write(byte value) throws IOException %7B%0A%09%09io.write(value);%0A%09%7D%0A%0A%09byte read() throws IOException %7B%0A%09%09return io.read();%0A%09%7D
 %0A%7D%0A

enable Interpreter for inheritance