package org.vizee.brainfuckvm; public class BrainfuckVM { private byte[] ds; private byte[] cs; private int[] es; private int dp; private void ds_resize(int size, boolean preserve) { byte[] backup = null; if(preserve && ds != null) backup = ds; ds = new byte[size]; if(backup != null) System.arraycopy(ds, 0, backup, 0, Math.min(backup.length, size)); return; } public int run() { if(cs == null) return 1; ds_resize(1024, false); dp = 0; for(int i = 0;i < cs.length;i++) { switch(cs[i]) { case 0x1: //+ | - ds[dp] += es[i]; break; case 0x2: //< | > dp += es[i]; if(dp >= ds.length) ds_resize(dp + 1024, true); else if(dp < 0) { ds = null; return 0; } break; case 0x4: //, try { ds[dp] = (byte)System.in.read(); } catch (Exception e) { System.out.println(e.toString()); } break; case 0x6: //. System.out.print((char)ds[dp]); break; case 0x8: //[ if(ds[dp] == 0) i = es[i]; break; case 0xa: //] if(ds[dp] != 0) i = es[i]; break; } } ds = null; return 0; } public int load(String code) { int length = 0; char[] stream = code.toCharArray(); int count = 0; for(int i = 0;i < stream.length;i++) { switch(stream[i]) { case '[': count++; case ']': if(stream[i] == ']') { if(count == 0) return 0; count--; } case ',': case '.': length++; break; case '+': case '-': case '<': case '>': int j; for(j = i + 1;j < stream.length;j++) if(stream[i] != stream[j]) break; i = j - 1; length++; } } if(count == 0 && length > 0) { cs = new byte[length]; es = new int[length]; int[] match = new int[length]; int current = 0; count = 0; for(int i = 0;i < stream.length;i++) { switch(stream[i]) { case '[': cs[current] = 0x8; match[count++] = current; break; case ']': cs[current] = 0xa; es[current] = match[--count]; es[es[current]] = current; break; case ',': cs[current] = 0x4; break; case '.': cs[current] = 0x6; break; case '+': case '-': case '<': case '>': int j; for(j = i + 1;j < stream.length;j++) if(stream[i] != stream[j]) break; if(stream[i] == '<' || stream[i] == '>') cs[current] = 0x2; else cs[current] = 0x1; if(stream[i] == '<' || stream[i] == '-') es[current] = i - j; else es[current] = j - i; i = j - 1; } if(cs[current] != 0) current++; } } return length; } public BrainfuckVM() { cs = null; ds = null; es = null; dp = 0; } }