Created
August 4, 2012 10:37
-
-
Save mueschm/3256623 to your computer and use it in GitHub Desktop.
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.io.IOException; | |
import java.util.HashMap; | |
import java.util.LinkedList; | |
import java.util.Map; | |
import java.util.regex.Matcher; | |
import java.util.regex.Pattern; | |
public class BF { | |
private interface Visitor | |
{ | |
void visit (Character character); | |
void visit (Function function); | |
void visit (CallFunction functionCall); | |
void visit (Loop loop); | |
void visit (Left left); | |
void visit (Right right); | |
void visit (Increment increment); | |
void visit (Decrement decrement); | |
void visit (Number number); | |
void visit (Input input); | |
void visit (Output output); | |
void visit (Program program); | |
} | |
private interface Node | |
{ | |
void accept (Visitor v); | |
} | |
private class Character implements Node | |
{ | |
public String character; | |
public Character(String character) | |
{ | |
this.character = character; | |
} | |
public void accept (Visitor v) | |
{ | |
v.visit(this); | |
} | |
} | |
private class Function implements Node | |
{ | |
public Node body; | |
public Function(Node body) | |
{ | |
this.body = body; | |
} | |
public void accept(Visitor v) | |
{ | |
v.visit(this); | |
} | |
} | |
private class CallFunction implements Node | |
{ | |
public void accept(Visitor v) | |
{ | |
v.visit(this); | |
} | |
} | |
private class Left implements Node | |
{ | |
public void accept (Visitor v) | |
{ | |
v.visit(this); | |
} | |
} | |
private class Right implements Node | |
{ | |
public void accept (Visitor v) | |
{ | |
v.visit(this); | |
} | |
} | |
private class Increment implements Node | |
{ | |
public void accept (Visitor v) | |
{ | |
v.visit(this); | |
} | |
} | |
private class Decrement implements Node | |
{ | |
public void accept (Visitor v) | |
{ | |
v.visit(this); | |
} | |
} | |
private class Input implements Node | |
{ | |
public void accept (Visitor v) | |
{ | |
v.visit(this); | |
} | |
} | |
private class Output implements Node | |
{ | |
public void accept (Visitor v) | |
{ | |
v.visit(this); | |
} | |
} | |
private class Number implements Node | |
{ | |
public int iterations; | |
public Node command; | |
public Number(int number, Node command) | |
{ | |
iterations = number; | |
this.command = command; | |
} | |
public void accept(Visitor v) | |
{ | |
v.visit(this); | |
} | |
} | |
private class Sequence implements Node | |
{ | |
private LinkedList<Node> children; | |
public Sequence() | |
{ | |
children = new LinkedList<Node>(); | |
} | |
public void accept (Visitor v) | |
{ | |
for (Node child : children) | |
{ | |
child.accept(v); | |
} | |
} | |
public void add (Node instruction) | |
{ | |
children.add(instruction); | |
} | |
} | |
private class Loop implements Node | |
{ | |
public Node body; | |
public Loop (Node body) | |
{ | |
this.body = body; | |
} | |
public void accept (Visitor v) | |
{ | |
v.visit (this); | |
} | |
} | |
public static class Program implements Node | |
{ | |
public Node body; | |
public Program (Node body) | |
{ | |
this.body = body; | |
} | |
public void accept(Visitor v) | |
{ | |
v.visit (this); | |
} | |
} | |
private int i = 0; | |
private Sequence doParse (String str) | |
{ | |
Sequence seq = new Sequence(); | |
char c; | |
while (i < str.length ()) | |
{ | |
c = str.charAt (i); | |
if (c == '<') seq.add (new Left ()); | |
else if (c == '>') seq.add (new Right ()); | |
else if (c == '+') seq.add (new Increment ()); | |
else if (c == '-') seq.add (new Decrement ()); | |
else if (c == '.') seq.add (new Output ()); | |
else if (c == ',') seq.add (new Input ()); | |
else if (c == ':') seq.add (new CallFunction()); | |
else if (c == '[') | |
{ | |
i++; | |
seq.add (new Loop (doParse (str))); | |
} | |
else if(c == '(') | |
{ | |
i++; | |
seq.add (new Function(doParse(str))); | |
} | |
else if(str.charAt(i) >= 48 && str.charAt(i) <= 57) | |
{ | |
Pattern p = Pattern.compile("\\d+"); | |
Matcher m = p.matcher(str.substring(i)); | |
m.find(); | |
String numString = m.group(); | |
i += numString.length(); | |
int num = Integer.parseInt(numString); | |
int temp = i; | |
i = 0; | |
Node node = doParse(""+str.charAt(temp)); | |
i = temp; | |
seq.add(new Number(num,node)); | |
} | |
else if (c == ']') return seq; | |
else if (c == ')') return seq; | |
else if (c == '"') | |
{ | |
i++; | |
String characters = ""; | |
while(str.charAt(i) != '"') | |
characters += str.charAt(i++); | |
seq.add(new Character(characters)); | |
} | |
i++; | |
} | |
return seq; | |
} | |
public static Program parse (String str) | |
{ | |
return new Program (new BF().doParse(str)); | |
} | |
public static void main(String[] args) | |
{ | |
Node ascii = BF.parse("(++++++++++<[>+>+<<-]>>[<<+>>-])>::::::::::::::<<<<<<<--------.>>>---------.+++++++..>---------.<<<<<<<------.<--------.>>>>>---.>>>.+++.<.--------.<<<<<<<+."); | |
ascii.accept(new BF.CompilerVisitor()); | |
System.out.println(); | |
Node name = BF.parse("77+.>105+.>107+.>101+.>32+.>77+.>117+.>101+.>115+.>99+.>104+.>"); | |
name.accept(new BF.InterpreterVisitor()); | |
System.out.println(); | |
} | |
public static class PrintVisitor implements Visitor | |
{ | |
public void visit (Left n) { System.out.print('<'); } | |
public void visit (Right n) { System.out.print('>'); } | |
public void visit (Increment n) { System.out.print('+'); } | |
public void visit (Decrement n) { System.out.print('-'); } | |
public void visit (Input n) { System.out.print(','); } | |
public void visit (Output n) { System.out.print('.'); } | |
public void visit (Loop n) { System.out.print('['); n.body.accept(this); System.out.print(']'); } | |
public void visit (Program n) { n.body.accept(this); } | |
public void visit(Character n) {System.out.print("\""+n.character+"\"");} | |
public void visit(Number n) {System.out.print(""+n.iterations);n.command.accept(this);} | |
public void visit(Function function) {System.out.print("("); function.body.accept(this); System.out.print(")");} | |
public void visit(CallFunction functionCall) {System.out.print(":");} | |
} | |
public static void displayByteArray(byte[] array, int pointer) | |
{ | |
for(int i = 0;i < 100;i++) | |
{ | |
for(int j = 0;j < 300;j++) | |
{ | |
if(pointer == (i*300)+j) | |
System.out.print(">"); | |
else | |
System.out.print(" "); | |
System.out.print(""+array[(i*300)+j]); | |
} | |
System.out.println(); | |
} | |
System.out.println("==================================="); | |
} | |
public static class CompilerVisitor implements Visitor | |
{ | |
int loopNumber; | |
private Map<Byte,Function> functions; | |
private byte[] array; | |
private int pointer; | |
public void visit(Character character) | |
{ | |
System.out.println("string=\""+character.character+"\";"); | |
System.out.println("for(int i = 0;i < string.length();i++){"); | |
System.out.println("char c = string.charAt(i);"); | |
System.out.println("array[pointer] = (byte)c;"); | |
System.out.println("pointer++;"); | |
System.out.println("array[pointer] = 0;"); | |
System.out.println("}"); | |
} | |
public void visit(Function function) | |
{ | |
System.out.println("procedures[array[pointer]] = new Procedure() {public void execute() {"); | |
function.body.accept(this); | |
System.out.println("}};"); | |
} | |
public void visit(CallFunction functionCall) | |
{ | |
System.out.println("procedures[array[pointer]].execute();"); | |
} | |
public void visit(Loop loop) | |
{ | |
System.out.println("while(array[pointer] != 0){"); | |
loop.body.accept(this); | |
System.out.println("}"); | |
} | |
public void visit(Left left) | |
{ | |
System.out.println("pointer--;"); | |
} | |
public void visit(Right right) | |
{ | |
System.out.println("pointer++;"); | |
} | |
public void visit(Increment increment) | |
{ | |
System.out.println("array[pointer]++;"); | |
} | |
public void visit(Decrement decrement) | |
{ | |
System.out.println("array[pointer]--;"); | |
} | |
public void visit(Input input) | |
{ | |
System.out.println("array[pointer] = (byte) System.in.read();"); | |
} | |
public void visit(Output output) | |
{ | |
System.out.println("System.out.print(\"\"+(char)array[pointer]);"); | |
} | |
public void visit(Program program) | |
{ | |
loopNumber = 0; | |
array = new byte[30000]; | |
pointer = 0; | |
functions = new HashMap<Byte,Function>(); | |
System.out.println("class Prog {"); | |
System.out.println("public interface Procedure {"); | |
System.out.println(" void execute();"); | |
System.out.println("}"); | |
System.out.println("private static Procedure[] procedures;"); | |
System.out.println("private static byte[] array;"); | |
System.out.println("private static int pointer;"); | |
System.out.println("private static String string;"); | |
System.out.println("public static void main(String[] args){"); | |
System.out.println("array = new byte[30000];"); | |
System.out.println("pointer = 0;"); | |
System.out.println("procedures = new Procedure[256];"); | |
program.body.accept(this); | |
System.out.println("}}"); | |
} | |
public void visit(Number number) | |
{ | |
for(int i = 0;i < number.iterations;i++) | |
number.command.accept(this); | |
} | |
} | |
public static class InterpreterVisitor implements Visitor | |
{ | |
private byte[] array; | |
private int pointer; | |
private Map<Byte,Function> functions; | |
public void visit (Left n) { pointer--; } | |
public void visit (Right n) { pointer++; } | |
public void visit (Increment n) { array[pointer]++; } | |
public void visit (Decrement n) { array[pointer]--; } | |
public void visit (Input n) | |
{ | |
try | |
{ | |
array[pointer] = (byte) System.in.read(); | |
} | |
catch (IOException e) | |
{ | |
} | |
} | |
public void visit (Output n) | |
{ | |
System.out.print((char)array[pointer]); | |
} | |
public void visit (Loop n) | |
{ | |
while (array[pointer] != 0) | |
{ | |
n.body.accept(this); | |
} | |
} | |
public void visit (Program n) | |
{ | |
array = new byte[30000]; | |
pointer = 0; | |
functions = new HashMap<Byte,Function>(); | |
n.body.accept(this); | |
} | |
public void visit(Character n) | |
{ | |
for(int i = 0;i < n.character.length();i++) | |
{ | |
array[pointer] = (byte)n.character.charAt(i); | |
pointer++; | |
array[pointer] = 0; | |
} | |
} | |
public void visit(Function n) | |
{ | |
functions.put(Byte.parseByte(""+(array[pointer])), n); | |
} | |
public void visit(CallFunction n) | |
{ | |
Function function = functions.get(Byte.parseByte(""+array[pointer])); | |
if(function != null) | |
function.body.accept(this); | |
} | |
public void visit(Number number) | |
{ | |
for(int i = 0;i < number.iterations;i++) | |
number.command.accept(this); | |
} | |
} | |
public static class AnimationVisitor implements Visitor | |
{ | |
private byte[] array; | |
private int pointer; | |
private Map<Byte,Function> functions; | |
public void visit (Left n) { pointer--; BF.displayByteArray(array,pointer); } | |
public void visit (Right n) { pointer++; BF.displayByteArray(array,pointer); } | |
public void visit (Increment n) { array[pointer]++; BF.displayByteArray(array,pointer); } | |
public void visit (Decrement n) { array[pointer]--; BF.displayByteArray(array,pointer); } | |
public void visit (Input n) | |
{ | |
try | |
{ | |
array[pointer] = (byte) System.in.read(); | |
} | |
catch (IOException e) | |
{ | |
} | |
BF.displayByteArray(array,pointer); | |
} | |
public void visit (Output n) | |
{ | |
System.out.print((char)array[pointer]); | |
BF.displayByteArray(array,pointer); | |
} | |
public void visit (Loop n) | |
{ | |
while (array[pointer] != 0) | |
{ | |
n.body.accept(this); | |
} | |
} | |
public void visit (Program n) | |
{ | |
array = new byte[30000]; | |
pointer = 0; | |
functions = new HashMap<Byte,Function>(); | |
n.body.accept(this); | |
} | |
public void visit(Character n) | |
{ | |
for(int i = 0;i < n.character.length();i++) | |
{ | |
array[pointer] = (byte)n.character.charAt(i); | |
pointer++; | |
array[pointer] = 0; | |
BF.displayByteArray(array,pointer); | |
} | |
} | |
public void visit(Function n) | |
{ | |
functions.put(Byte.parseByte(""+(array[pointer])), n); | |
} | |
public void visit(CallFunction n) | |
{ | |
Function function = functions.get(Byte.parseByte(""+array[pointer])); | |
if(function != null) | |
function.body.accept(this); | |
} | |
public void visit(Number number) | |
{ | |
for(int i = 0;i < number.iterations;i++) | |
number.command.accept(this); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment