Execute Brain****/Java: Difference between revisions

From Rosetta Code
Content added Content deleted
m (Optimized a bit on loops)
m (Added syntax highlighting and now it looks all cool)
Line 10: Line 10:
More detailed information about the rest of the code can be found in the comments throughout it.<br clear=all>
More detailed information about the rest of the code can be found in the comments throughout it.<br clear=all>


import java.io.BufferedReader;
<java>import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.ArrayList;

/**
/**
* Interprets Brainf**k source from std in or a file.
* Interprets Brainf**k source from std in or a file.
*
*
* @author Mike Neurohr
* @author Mike Neurohr
*/
*/
public class BF{
public class BF{
private static int pointer;//memory pointer
private static int pointer;//memory pointer
private static int codeIndex;//instruction number
private static int codeIndex;//instruction number
private static final int INITIAL_SIZE= 1000;//initial size of memory
private static final int INITIAL_SIZE= 1000;//initial size of memory
private static final String instChars= "[]<>,.+-";//valid code characters
private static final String instChars= "[]<>,.+-";//valid code characters

/**
/**
* The main program. Holds the input loop and error-handling.
* The main program. Holds the input loop and error-handling.
*
*
* @param args 0: Source file others: ignored
* @param args 0: Source file others: ignored
*/
*/
public static void main(String[] args){
public static void main(String[] args){
BufferedReader source;
BufferedReader source;
try{
try{
if(args.length == 0){//if no file specified
if(args.length == 0){//if no file specified
source= new BufferedReader(new InputStreamReader(System.in));
source= new BufferedReader(new InputStreamReader(System.in));
}else{
}else{
source= new BufferedReader(new FileReader(args[0]));
source= new BufferedReader(new FileReader(args[0]));
}
}
char instruction;
char instruction;

//holds the cleaned up code
//holds the cleaned up code
StringBuilder code= new StringBuilder();
StringBuilder code= new StringBuilder();

//count for loop syntax errors
//count for loop syntax errors
int bCnt= 0;
int bCnt= 0;

//read whole source in
//read whole source in
for(instruction= (char)source.read(); source.ready(); instruction=
for(instruction= (char)source.read(); source.ready(); instruction=
(char)source.read()){
(char)source.read()){
//remove extra characters
//remove extra characters
if(instChars.contains(instruction + "")){
if(instChars.contains(instruction + "")){
//add the instruction to the clean code
//add the instruction to the clean code
code.append(instruction);
code.append(instruction);
if(instruction == '[') bCnt++;
if(instruction == '[') bCnt++;
if(instruction == ']') bCnt--;
if(instruction == ']') bCnt--;
}
}
}
}
if(bCnt != 0){//if there is a bracket with no match
if(bCnt != 0){//if there is a bracket with no match
System.err.println("Error: Uneven brackets.");
System.err.println("Error: Uneven brackets.");
return;
return;
}
}

//set up input for ,
//set up input for ,
BufferedReader input=
BufferedReader input=
new BufferedReader(new InputStreamReader(System.in));
new BufferedReader(new InputStreamReader(System.in));
//set up memory
//set up memory
ArrayList<Integer> memory= new ArrayList<Integer>(INITIAL_SIZE);
ArrayList<Integer> memory= new ArrayList<Integer>(INITIAL_SIZE);
memory.add(new Integer(0));
memory.add(new Integer(0));
pointer= 0; //initialize pointer
pointer= 0; //initialize pointer
//loop through the cleaned up code and execute
//loop through the cleaned up code and execute
for(codeIndex= 0;codeIndex < code.length();codeIndex++){
for(codeIndex= 0;codeIndex < code.length();codeIndex++){
instruction= code.charAt(codeIndex);
instruction= code.charAt(codeIndex);
switch(instruction){
switch(instruction){
case '+':
case '+':
memory.set(pointer, memory.get(pointer) + 1);
memory.set(pointer, memory.get(pointer) + 1);
break;
break;
case '-':
case '-':
memory.set(pointer, memory.get(pointer) - 1);
memory.set(pointer, memory.get(pointer) - 1);
break;
break;
case '.':
case '.':
System.out.print((char)memory.get(pointer).intValue());
System.out.print((char)memory.get(pointer).intValue());
break;
break;
case ',':
case ',':
input(memory, input);
input(memory, input);
break;
break;
case '[':
case '[':
if(memory.get(pointer) == 0){
if(memory.get(pointer) == 0){
//skip the code inside the loop
//skip the code inside the loop
jumpForward(code);
jumpForward(code);
}
}
//if the loop can continue...
//if the loop can continue...
//we don't need to check other things
//we don't need to check other things
break;
break;
case ']':
case ']':
if(memory.get(pointer) != 0){
if(memory.get(pointer) != 0){
//go back to the corresponding [ to check
//go back to the corresponding [ to check
jumpBack(code);
jumpBack(code);
}
}
//if the loop should stop...
//if the loop should stop...
//we don't need to check other things
//we don't need to check other things
break;
break;
case '>':
case '>':
pointer++;
pointer++;
//gets rid of NullPointerExceptions
//gets rid of NullPointerExceptions
while(pointer + 1 > memory.size()) memory.add(0);
while(pointer + 1 > memory.size()) memory.add(0);
break;
break;
case '<':
case '<':
if(--pointer < 0){
if(--pointer < 0){
//can't do it
//can't do it
System.err.println("Pointer out of range (negative).");
System.err.println("Pointer out of range (negative).");
return;
return;
}
}
default:
default:
}
}
}
}
}catch(FileNotFoundException e){
}catch(FileNotFoundException e){
System.err.println("Error opening file: " + args[0] + ".");
System.err.println("Error opening file: " + args[0] + ".");
}catch(IOException e){
}catch(IOException e){
System.err.println("Error on input.");
System.err.println("Error on input.");
}
}
}

public static void jumpBack(StringBuilder code){
//initial count for the bracket we're on
int bracketCnt= 1;
//count brackets until the corresponding [
while(codeIndex >= 0 && bracketCnt != 0){
codeIndex--;
char inst= code.charAt(codeIndex);
if(inst == '[') bracketCnt--;
if(inst == ']') bracketCnt++;
}
//"- 1" to offset the next "codeIndex++".
codeIndex= codeIndex - 1;
}

public static void jumpForward(StringBuilder code){
//initial count for the bracket we're on
int bracketCnt= 1;
//count brackets until the corresponding ]
while(codeIndex < code.length() && bracketCnt != 0){
codeIndex++;
char inst= code.charAt(codeIndex);
if(inst == ']') bracketCnt--;
if(inst == '[') bracketCnt++;
}
}

public static void input(ArrayList<Integer> mem, BufferedReader input)
throws IOException{
int val;
//read until something comes in other than return chars
for(val= input.read(); val == 10 || val == 13; val= input.read());
mem.set(pointer, new Integer(val));
}
}
}</java>
public static void jumpBack(StringBuilder code){
//initial count for the bracket we're on
int bracketCnt= 1;
//count brackets until the corresponding [
while(codeIndex >= 0 && bracketCnt != 0){
codeIndex--;
char inst= code.charAt(codeIndex);
if(inst == '[') bracketCnt--;
if(inst == ']') bracketCnt++;
}
//"- 1" to offset the next "codeIndex++".
codeIndex= codeIndex - 1;
}
public static void jumpForward(StringBuilder code){
//initial count for the bracket we're on
int bracketCnt= 1;
//count brackets until the corresponding ]
while(codeIndex < code.length() && bracketCnt != 0){
codeIndex++;
char inst= code.charAt(codeIndex);
if(inst == ']') bracketCnt--;
if(inst == '[') bracketCnt++;
}
}
public static void input(ArrayList<Integer> mem, BufferedReader input)
throws IOException{
int val;
//read until something comes in other than return chars
for(val= input.read(); val == 10 || val == 13; val= input.read());
mem.set(pointer, new Integer(val));
}
}

Revision as of 00:11, 8 March 2008

Execute Brain****/Java is an implementation of Brainf***. Other implementations of Brainf***.
Execute Brain****/Java is part of RCBF. You may find other members of RCBF at Category:RCBF.

In this implementation of Brainf***, the code is read in all at once and checked for uneven brackets (unequal amounts of [ and ] commands). If that error occurs, the code will obviously not be run.

Under the hood, the program memory is an ArrayList of Integers which expands "infinitely" (limited by your system's memory) to the right (still Turing complete). So, if the pointer moves past zero to the left, the program will exit and a "Pointer out of range" error message will be displayed.

Due to the BufferedReader input class, return characters (ASCII 10 and 13) are ignored on input (the , command), but are not ignored on output (the . command).

Loops are handled in the jumpForward and jumpBack methods. In each method, the bracket that the code pointer is on is counted as 1 (the counter is initialized to 1). The method then moves the code pointer forward or back and counts other brackets along the way. If it finds a bracket of the same type, 1 is added to the counter; if it finds a bracket of the other type, 1 is subtracted from the counter. The search continues until the counter reaches 0. For jumping forward, the code pointer must be allowed to skip the ending bracket, or else it will jump back on the next execution iteration. For jumping back, the pointer can remain at the starting bracket. So, jumpBack offsets the next code pointer increment to make sure the check for 0 happens.

More detailed information about the rest of the code can be found in the comments throughout it.

<java>import java.io.BufferedReader; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.ArrayList;

/**

* Interprets Brainf**k source from std in or a file.
* 
* @author Mike Neurohr
*/

public class BF{ private static int pointer;//memory pointer private static int codeIndex;//instruction number private static final int INITIAL_SIZE= 1000;//initial size of memory private static final String instChars= "[]<>,.+-";//valid code characters

/** * The main program. Holds the input loop and error-handling. * * @param args 0: Source file others: ignored */ public static void main(String[] args){ BufferedReader source; try{ if(args.length == 0){//if no file specified source= new BufferedReader(new InputStreamReader(System.in)); }else{ source= new BufferedReader(new FileReader(args[0])); } char instruction;

//holds the cleaned up code StringBuilder code= new StringBuilder();

//count for loop syntax errors int bCnt= 0;

//read whole source in for(instruction= (char)source.read(); source.ready(); instruction= (char)source.read()){ //remove extra characters if(instChars.contains(instruction + "")){ //add the instruction to the clean code code.append(instruction); if(instruction == '[') bCnt++; if(instruction == ']') bCnt--; } } if(bCnt != 0){//if there is a bracket with no match System.err.println("Error: Uneven brackets."); return; }

//set up input for , BufferedReader input= new BufferedReader(new InputStreamReader(System.in)); //set up memory ArrayList<Integer> memory= new ArrayList<Integer>(INITIAL_SIZE); memory.add(new Integer(0));

pointer= 0; //initialize pointer //loop through the cleaned up code and execute for(codeIndex= 0;codeIndex < code.length();codeIndex++){ instruction= code.charAt(codeIndex); switch(instruction){ case '+': memory.set(pointer, memory.get(pointer) + 1); break; case '-': memory.set(pointer, memory.get(pointer) - 1); break; case '.': System.out.print((char)memory.get(pointer).intValue()); break; case ',': input(memory, input); break; case '[': if(memory.get(pointer) == 0){ //skip the code inside the loop jumpForward(code); } //if the loop can continue... //we don't need to check other things break; case ']': if(memory.get(pointer) != 0){ //go back to the corresponding [ to check jumpBack(code); } //if the loop should stop... //we don't need to check other things break; case '>': pointer++; //gets rid of NullPointerExceptions while(pointer + 1 > memory.size()) memory.add(0); break; case '<': if(--pointer < 0){ //can't do it System.err.println("Pointer out of range (negative)."); return; } default: } } }catch(FileNotFoundException e){ System.err.println("Error opening file: " + args[0] + "."); }catch(IOException e){ System.err.println("Error on input."); } }

public static void jumpBack(StringBuilder code){ //initial count for the bracket we're on int bracketCnt= 1; //count brackets until the corresponding [ while(codeIndex >= 0 && bracketCnt != 0){ codeIndex--; char inst= code.charAt(codeIndex); if(inst == '[') bracketCnt--; if(inst == ']') bracketCnt++; } //"- 1" to offset the next "codeIndex++". codeIndex= codeIndex - 1; }

public static void jumpForward(StringBuilder code){ //initial count for the bracket we're on int bracketCnt= 1; //count brackets until the corresponding ] while(codeIndex < code.length() && bracketCnt != 0){ codeIndex++; char inst= code.charAt(codeIndex); if(inst == ']') bracketCnt--; if(inst == '[') bracketCnt++; } }

public static void input(ArrayList<Integer> mem, BufferedReader input) throws IOException{ int val; //read until something comes in other than return chars for(val= input.read(); val == 10 || val == 13; val= input.read()); mem.set(pointer, new Integer(val));

	}

}</java>