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;
}
}
Brainfuck VM
最新推荐文章于 2024-05-28 09:43:42 发布