Skip to content

Instantly share code, notes, and snippets.

@vivekannan
Created January 11, 2015 04:18
Show Gist options
  • Save vivekannan/4ed6f202ffd5469337ea to your computer and use it in GitHub Desktop.
Save vivekannan/4ed6f202ffd5469337ea to your computer and use it in GitHub Desktop.
A BrainF**k intepreter in Java.
import java.util.Stack;
import java.util.Scanner;
import java.util.HashMap;
import java.io.FileReader;
import java.util.ArrayList;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
class Juck {
static int[] array;
static int size = 32;
static int pointer = 0;
static String code = "";
static String type = "int";
static BufferedReader source;
static boolean checkBoundary = false;
static HashMap<Integer, Integer> brackets;
static final String DOC_STRING = "Usage: java Juck [-options] filename\n\nwhere options include:\n\t-s power\t\tsize of the array is given by pow(2, power + 5). Default value is 0. Can range from 0 to 5, inclusive.\n\t-t type\t\t\tthe type of the array, either integer (default) or character. type should be int for integer or char for character.\n\t-x\t\t\tChecks array boundary.\n\t-h\t\t\tPrints this documentation and exits.";
public static void printHelp() {
System.out.println(Juck.DOC_STRING);
System.exit(-1);
}
public static void parseOptions(String[] args) {
int i;
if(args.length == 0)
Juck.printHelp();
for(i = 0; i < args.length; i++) {
if(args[i].equals("-h"))
Juck.printHelp();
else if(args[i].equals("-s")) {
try {
Juck.size = 1 << (5 + Integer.parseInt(args[++i]));
if(Juck.size < 32 || Juck.size > 1024)
Juck.printHelp();
}
catch(Exception e) {
Juck.printHelp();
}
}
else if(args[i].equals("-t")) {
Juck.type = args[++i];
if(!(Juck.type.equals("int") || Juck.type.equals("char")))
Juck.printHelp();
}
else if(args[i].equals("-x"))
checkBoundary = true;
else if(i != args.length - 1) {
System.out.println("Invalid operand: " + args[i]);
Juck.printHelp();
}
}
try {
Juck.source = new BufferedReader(new FileReader(args[--i]));
}
catch(FileNotFoundException e) {
System.out.println("Cannot find the given file.");
System.exit(-2);
}
catch(IOException e) {
System.out.println("Cannot read the given file.");
System.exit(-3);
}
catch(Exception e) {
Juck.printHelp();
}
}
public static void readSource() {
int c;
try {
while((c = source.read()) != -1)
if((c > 42 && c < 47) || c == 60 || c == 62 || c == 91 || c ==93)
Juck.code += (char) c;
}
catch(IOException e) {
System.out.println("Cannnot read the given file.");
System.exit(-4);
}
}
public static void grabBrackets() {
int j;
Stack<Integer> stack = new Stack<Integer>();
Juck.brackets = new HashMap<Integer, Integer>();
for(int i = 0; i < Juck.code.length(); i++) {
if(Juck.code.charAt(i) == '[')
stack.push(i);
else if(Juck.code.charAt(i) == ']') {
if(stack.empty()) {
System.out.println("Unexpected ']'");
System.exit(-5);
}
j = stack.pop();
Juck.brackets.put(i, j);
Juck.brackets.put(j, i);
}
}
if(!stack.empty()) {
System.out.println("Cannot find matching ']'");
System.exit(-5);
}
}
public static void run() {
int i = 0;
char current;
int eol = Juck.code.length();
Scanner terminal = new Scanner(System.in);
Juck.array = new int[Juck.size];
while(i != eol) {
current = Juck.code.charAt(i);
if(current == '>') {
pointer++;
if(pointer == Juck.size) {
if(checkBoundary) {
System.out.println("Array Index Out of Bounds.");
System.exit(-6);
}
pointer = 0;
}
}
else if(current == '<') {
pointer--;
if(pointer == -1) {
if(checkBoundary) {
System.out.println("Array Index Out of Bounds.");
System.exit(-6);
}
pointer += Juck.size;
}
}
else if(current == '+')
Juck.array[pointer]++;
else if(current == '-')
Juck.array[pointer]--;
else if(current == '.') {
if(Juck.type.equals("char"))
System.out.print((char) Juck.array[pointer]);
else
System.out.println(Juck.array[pointer]);
}
else if(current == ',') {
System.out.print(">");
try {
if(Juck.type.equals("char"))
Juck.array[pointer] = (char) System.in.read();
else
Juck.array[pointer] = terminal.nextInt();
}
catch(Exception e) {
System.out.println("Invalid input.");
System.exit(-7);
}
}
else if(current == '[' && Juck.array[pointer] == 0)
i = Juck.brackets.get(i);
else if(current == ']' && Juck.array[pointer] != 0)
i = Juck.brackets.get(i);
i++;
}
}
public static void main(String args[]) {
Juck.parseOptions(args);
Juck.readSource();
Juck.grabBrackets();
Juck.run();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment