Created
January 11, 2015 04:18
-
-
Save vivekannan/4ed6f202ffd5469337ea to your computer and use it in GitHub Desktop.
A BrainF**k intepreter in Java.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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