编写一个接受brainfuck程序并将其编译成可执行机器代码的程序。您可以针对x86、x86_64、jvm (java字节码)或armv6,并使用以下可执行格式之一: ELF、a.out、类文件、exe、com。可执行文件应该在Linux或Windows中工作(或者在两者中都可以使用Java )。
您的程序和生成的可执行文件都不能运行任何外部程序(例如另一个编译器、汇编程序或解释器)。
最短代码获胜。
发布于 2014-01-09 10:23:19
import sys
s='\x11\x75\x30\xbc\x08\x4b\x03\x3c'
k=[]
for c in sys.stdin.read():
if'>'==c:s+='\x84\x01\x01'
if'<'==c:s+='\x84\x01\xff'
if'+'==c:s+='\x2a\x1b\x5c\x33\x04\x60\x91\x54'
if'-'==c:s+='\x2a\x1b\x5c\x33\x04\x64\x91\x54'
if'['==c:k+=[len(s)];s+='\x2a\x1b\x33\x99\x00\x00'
if']'==c:a=k[-1];k=k[:-1];d=len(s)-a;s=s[:a+4]+'%c%c'%(d>>8,d&255)+s[a+6:]+'\xa7%c%c'%(-d>>8&255,-d&255)
if','==c:s+='\x2a\x1b\xb2\x00\x02\xb6\x00\x03\x91\x54'
if'.'==c:s+='\xb2\x00\x04\x59\x2a\x1b\x33\xb6\x00\x05\xb6\x00\x06'
s+='\xb1'
n=len(s)
sys.stdout.write('\xca\xfe\xba\xbe\x00\x03\x00-\x00+\n\x00\x08\x00\x13\t\x00\x14\x00\x15\n\x00\x16\x00\x17\t\x00\x14\x00\x18\n\x00\x19\x00\x1a\n\x00\x19\x00\x1b\x07\x00\x1c\x07\x00\x1d\x01\x00\x06<init>\x01\x00\x03()V\x01\x00\x04Code\x01\x00\x0fLineNumberTable\x01\x00\x04main\x01\x00\x16([Ljava/lang/String;)V\x01\x00\nExceptions\x07\x00\x1e\x01\x00\nSourceFile\x01\x00\x06B.java\x0c\x00\t\x00\n\x07\x00\x1f\x0c\x00 \x00!\x07\x00"\x0c\x00#\x00$\x0c\x00%\x00&\x07\x00\'\x0c\x00(\x00)\x0c\x00*\x00\n\x01\x00\x01B\x01\x00\x10java/lang/Object\x01\x00\x13java/io/IOException\x01\x00\x10java/lang/System\x01\x00\x02in\x01\x00\x15Ljava/io/InputStream;\x01\x00\x13java/io/InputStream\x01\x00\x04read\x01\x00\x03()I\x01\x00\x03out\x01\x00\x15Ljava/io/PrintStream;\x01\x00\x13java/io/PrintStream\x01\x00\x05write\x01\x00\x04(I)V\x01\x00\x05flush\x00!\x00\x07\x00\x08\x00\x00\x00\x00\x00\x02\x00\x01\x00\t\x00\n\x00\x01\x00\x0b\x00\x00\x00\x1d\x00\x01\x00\x01\x00\x00\x00\x05*\xb7\x00\x01\xb1\x00\x00\x00\x01\x00\x0c\x00\x00\x00\x06\x00\x01\x00\x00\x00\x03\x00\t\x00\r\x00\x0e\x00\x02\x00\x0b\x00\x00'+'%c%c'%((n+60)>>8,(n+60)&255)+'\x00\x04\x00\x03\x00\x00'+'%c%c'%(n>>8,n&255)+s+'\x00\x00\x00\x01\x00\x0c\x00\x00\x00*\x00\n\x00\x00\x00\x05\x00\x06\x00\x06\x00\x08\x00\t\x00\x0b\x00\x0b\x00\x13\x00\r\x00\x1d\x00\x0f\x00&\x00\x11\x00,\x00\x12\x002\x00\x14\x008\x00\x15\x00\x0f\x00\x00\x00\x04\x00\x01\x00\x10\x00\x01\x00\x11\x00\x00\x00\x02\x00\x12')
下面是对java字节码的翻译。local 0是表示磁带的字节数组,local 1是数据指针。
> iinc 1,+1
< iinc 1,-1
+ aload_0;iload_1;dup2;baload;iconst_1;iadd;i2b;bastore
- aload_0;iload_1;dup2;baload;iconst_1;isub;i2b;bastore
[ aload_0;iload_1;baload;ifeq xx xx
] goto xx xx
, aload_0;iload_1;getstatic #2;invokevirtual #3;i2b;bastore
. getstatic #4;dup;aload_0;iload_1;baload;invokevirtual #5;invokevirtual #6
xx xx
是为达到匹配的括号而设置的偏移量。#2是System.in
,#3是read()
,#4是System.out
,#5是write()
,#6是flush()
。
前导文件分配一个30000字节数组,并将磁带位置初始化为0。
最后这个巨大的包装器是通过编译一个虚拟的B.java
文件来生成的,该文件包含每个操作码的代码(以诱导生成正确的常量表和其他垃圾),然后对其执行精细的操作。
就像运行一样
python bfc.py < input.b > B.class
java B
用
javap -c B
我敢肯定它还能打更多的金牌。我很高兴它起作用了..。
https://codegolf.stackexchange.com/questions/18053
复制相似问题