|
import java.io.BufferedReader; |
|
import java.io.File; |
|
import java.io.FileReader; |
|
import java.io.FileNotFoundException; |
|
import java.io.InputStream; |
|
import java.io.InputStreamReader; |
|
import java.io.OutputStream; |
|
import java.io.PrintStream; |
|
import java.util.ArrayList; |
|
|
|
public class ClearBrain { |
|
|
|
protected static enum Token { |
|
NEXT, |
|
PREVIOUS, |
|
INC, |
|
DEC, |
|
GET, |
|
PUT, |
|
LOOP, |
|
JUMP; |
|
|
|
public String text; |
|
} |
|
|
|
protected byte[] data; |
|
protected int dataPtr = 0; |
|
protected int strPtr = 0; |
|
protected BufferedReader reader; |
|
protected InputStreamReader input; |
|
protected OutputStream output; |
|
protected ArrayList<Token> tokenList = new ArrayList(); |
|
protected ArrayList<Integer> loop = new ArrayList(); |
|
|
|
public ClearBrain(String filename) { |
|
initialize(10000); |
|
initTokenList(); |
|
input = new InputStreamReader(System.in); |
|
output = new PrintStream(System.out); |
|
compileFile(new File(filename)); |
|
} |
|
|
|
protected void initialize(int cells) { |
|
data = new byte[cells]; |
|
dataPtr = 0; |
|
strPtr = 0; |
|
} |
|
|
|
protected void initTokenList() { |
|
Token.NEXT.text = ">"; |
|
Token.PREVIOUS.text = "<"; |
|
Token.INC.text = "+"; |
|
Token.DEC.text = "-"; |
|
Token.GET.text = ","; |
|
Token.PUT.text = "."; |
|
Token.LOOP.text = "["; |
|
Token.JUMP.text = "]"; |
|
} |
|
|
|
public void compileFile(File file) { |
|
try { |
|
reader = new BufferedReader(new FileReader(file)); |
|
} catch (Exception e) { |
|
System.out.println("new BufferedReader(new FileReader): " + e); |
|
} |
|
String content = ""; |
|
String raw = ""; |
|
while (raw != null) { |
|
content += raw; |
|
try { |
|
raw = reader.readLine(); |
|
} catch (Exception e) { |
|
System.out.println("reader.readLine(): " + e); |
|
} |
|
} |
|
compileString(content); |
|
} |
|
|
|
private void compileString(String str) { |
|
String checkStr = str; |
|
for (; strPtr < str.length();) { |
|
for (Token token : Token.values()) { |
|
if (checkStr.startsWith(token.text)) { |
|
if (checkStr.substring(0, token.text.length()).equals(token.text)) { |
|
tokenList.add(token); |
|
strPtr += token.text.length(); |
|
checkStr = str.substring(strPtr); |
|
} |
|
} |
|
} |
|
} |
|
strPtr = 0; |
|
for (; strPtr < tokenList.size(); strPtr++) { |
|
compile(tokenList.get(strPtr)); |
|
} |
|
try { |
|
output.close(); |
|
} catch (Exception e) { |
|
System.out.println("output close: " + e); |
|
} |
|
initialize(data.length); |
|
} |
|
|
|
private void compile(Token token) { |
|
switch(token) { |
|
case NEXT: |
|
if ((dataPtr + 1) > data.length) { |
|
onError(token); |
|
} |
|
dataPtr++; |
|
break; |
|
case PREVIOUS: |
|
if ((dataPtr - 1) < 0) { |
|
onError(token); |
|
} |
|
dataPtr--; |
|
break; |
|
case INC: |
|
data[dataPtr]++; |
|
break; |
|
case DEC: |
|
data[dataPtr]--; |
|
break; |
|
case GET: |
|
try { |
|
data[dataPtr] = (byte) input.read(); |
|
} catch (Exception e) { |
|
System.out.println("input.read: " + e); |
|
} |
|
break; |
|
case PUT: |
|
try { |
|
output.write((char) data[dataPtr]); |
|
} catch (Exception e) { |
|
System.out.println("output.write: " + e); |
|
} |
|
break; |
|
case LOOP: |
|
if (data[dataPtr] == 0) { |
|
for(int index = strPtr; index <= tokenList.size(); index++) { |
|
if (tokenList.get(index) == Token.JUMP) { |
|
strPtr = index; |
|
break; |
|
} |
|
} |
|
} else { |
|
loop.add(strPtr); |
|
} |
|
break; |
|
case JUMP: |
|
strPtr = loop.get(0); |
|
strPtr--; |
|
loop.remove(0); |
|
break; |
|
} |
|
} |
|
|
|
private void onError(Token token) { |
|
try { |
|
throw new Exception("ERROR: " + token.text); |
|
} catch (Exception e) { |
|
System.out.println("onError: " + e); |
|
} |
|
} |
|
|
|
} |