সি, 866 783 বাইট
যেহেতু আমার কোডটি 32 বিট ইএলএফ এক্সিকিউটেবলের আউটপুট দেয় আমি প্রতিশ্রুতি দিতে পারি না যে এটি প্রত্যেকের সেটআপে কাজ করবে। আমার কম্পিউটারে সেগফোল্টিং বন্ধ করতে এক্সিকিউটেবলটি পেতে এটি যথেষ্ট টুইট করেছে।
যে কেউ এটি চালানোর চেষ্টা করছেন তাদের জন্য:
$ uname --all
Linux 4.4.0-24-generic #43-Ubuntu SMP Wed Jun 8 19:27:37 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux
একটি ব্রেইনফাক প্রোগ্রাম স্টিডিন থেকে পড়ে এবং সংকলিত ইএলএফ স্টাডআউটে লেখা হয়।
#define P *(t++)
#define C case
#define B break
char a[30000],b[65535],f,*t=b;*c[100];**d=c;main(g){P=188;t+=4;while((f=getchar())!=-1)switch(f){C'>':P=68;B;C'<':P=76;B;C'+':P=254;P=4;P=36;B;C'-':P=254;P=12;P=36;B;C'.':P=187;t+=4;P=137;P=225;P=186;P=1;t+=3;P=184;P=4;t+=3;P=205;P=128;B;C',':P=187;P=1;t+=3;P=137;P=225;P=186;P=1;t+=3;P=184;P=3;t+=3;P=205;P=128;B;C'[':P=138;P=4;P=36;P=133;P=192;P=15;P=132;t+=4;*d=(int*)t-1;d++;B;C']':P=138;P=4;P=36;P=133;P=192;P=15;P=133;t+=4;d--;g=((char*)(*d+1))-t;*((int*)t-1)=g;**d=-g;B;}P=184;P=1;t+=3;P=187;t+=4;P=205;P=128;*(int*)(b+1)=0x8048054+t-b;long long z[]={282579962709375,0,4295163906,223472812116,0,4297064500,4294967296,577727389698621440,36412867248128,30064779550,140720308490240};write(1,&z,84);write(1,b,t-b);write(1,a,30000);}
Ungolfed
কোডটির অদম্য সংস্করণে, আপনি কী চলছে তার একটি ভাল ধারণা পেতে পারেন। গল্ফড কোডের শেষে অক্ষরের অ্যারেটি হ'ল বিভক্ত কোডটিতে ইএলএফ এবং প্রোগ্রাম শিরোনামের একটি এনকোডিং। এই কোডটি দেখায় যে কীভাবে প্রতিটি ব্রেইনফাক নির্দেশকে বাইকোডে অনুবাদ করা হয়।
#include <linux/elf.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <stdio.h>
#include <stdint.h>
#define MAX_BIN_LEN 65535
#define MAX_JUMPS 100
unsigned int org = 0x08048000;
unsigned char move_right[] = {0x44}; /*inc esp */
unsigned char move_left[] = {0x4c}; /*dec esp */
unsigned char inc_cell[] = {0xfe,0x04,0x24}; /*inc [esp] */
unsigned char dec_cell[] = {0xfe,0x0c,0x24}; /*dec [esp] */
unsigned char read_char[] = {0xbb,0x00,0x00,0x00,0x00, /*mov ebx, 0 */
0x89,0xe1, /*mov ecx, esp */
0xba,0x01,0x00,0x00,0x00, /*mov edx, 1 */
0xb8,0x03,0x00,0x00,0x00, /*mov eax, 3 */
0xcd,0x80}; /*int 0x80 */
unsigned char print_char[] = {0xbb,0x01,0x00,0x00,0x00, /*mov ebx, 1 */
0x89,0xe1, /*mov ecx, esp */
0xba,0x01,0x00,0x00,0x00, /*mov edx, 1 */
0xb8,0x04,0x00,0x00,0x00, /*mov eax, 4 */
0xcd,0x80}; /*int 0x80 */
unsigned char loop_start[] = {0x8a,0x04,0x24, /*mov eax, [esp] */
0x85,0xc0, /*test eax, eax */
0x0f,0x84,0x00,0x00,0x00,0x00}; /*je int32_t */
unsigned char loop_end[] = {0x8a,0x04,0x24, /*mov eax, [esp] */
0x85,0xc0, /*test eax, eax */
0x0f,0x85,0x00,0x00,0x00,0x00}; /*jne int32_t */
unsigned char call_exit[] = {0xb8,0x01,0x00,0x00,0x00, /*mov eax, 1 */
0xbb,0x00,0x00,0x00,0x00, /*mov ebx, 0 */
0xcd,0x80}; /*int 0x80 */
unsigned char prelude[] = {0xbc,0x00,0x00,0x00,0x00}; /*mov esp, int32_t*/
unsigned char tape[100];
int main(){
unsigned char text[MAX_BIN_LEN];
unsigned char *txt_ptr = text;
int32_t *loop_jmps[MAX_JUMPS];
int32_t **loop_jmps_ptr = loop_jmps;
Elf32_Off entry;
entry = org + sizeof(Elf32_Ehdr) + 1 * sizeof(Elf32_Phdr);
memcpy(txt_ptr,prelude,sizeof(prelude));
txt_ptr += sizeof(prelude);
char input;
while((input = getchar()) != -1){
switch(input){
case '>':
memcpy(txt_ptr,move_right,sizeof(move_right));
txt_ptr += sizeof(move_right);
break;
case '<':
memcpy(txt_ptr,move_left,sizeof(move_left));
txt_ptr += sizeof(move_left);
break;
case '+':
memcpy(txt_ptr,inc_cell,sizeof(inc_cell));
txt_ptr += sizeof(inc_cell);
break;
case '-':
memcpy(txt_ptr,dec_cell,sizeof(dec_cell));
txt_ptr += sizeof(dec_cell);
break;
case '.':
memcpy(txt_ptr,print_char,sizeof(print_char));
txt_ptr += sizeof(print_char);
break;
case ',':
memcpy(txt_ptr,read_char,sizeof(read_char));
txt_ptr += sizeof(read_char);
break;
case '[':
memcpy(txt_ptr,loop_start,sizeof(loop_start));
txt_ptr += sizeof(loop_start);
*loop_jmps_ptr = (int32_t*) txt_ptr - 1;
loop_jmps_ptr++;
break;
case ']':
memcpy(txt_ptr,loop_end,sizeof(loop_end));
txt_ptr += sizeof(loop_end);
loop_jmps_ptr--;
int32_t offset = ((unsigned char*) (*loop_jmps_ptr + 1)) - txt_ptr;
*((int32_t*)txt_ptr - 1) = offset;
**loop_jmps_ptr = -offset;
break;
}
}
memcpy(txt_ptr,call_exit,sizeof(call_exit));
txt_ptr += sizeof(call_exit);
*(int32_t*)(text + 1) = entry + (txt_ptr - text);
Elf32_Ehdr ehdr = {
{0x7F,'E','L','F',ELFCLASS32,ELFDATA2LSB,EV_CURRENT,0,0,0,0,0,0,0,0,0},
ET_EXEC,
EM_386,
EV_CURRENT,
entry,
sizeof(Elf32_Ehdr),
0,
0,
sizeof(Elf32_Ehdr),
sizeof(Elf32_Phdr),
1,
0,
0,
SHN_UNDEF,
};
Elf32_Phdr phdr = {
PT_LOAD,
0,
org,
org,
sizeof(Elf32_Ehdr) + sizeof(Elf32_Phdr) + (txt_ptr - text),
sizeof(Elf32_Ehdr) + sizeof(Elf32_Phdr) + (txt_ptr - text),
PF_R | PF_X | PF_W,
0x1000,
};
int out = open("a.out",O_CREAT|O_TRUNC|O_WRONLY,S_IRWXU);
write(out,&ehdr,sizeof(Elf32_Ehdr));
write(out,&phdr,sizeof(Elf32_Phdr));
write(out,text,txt_ptr-text);
write(out,tape,sizeof(tape));
close(out);
}
স্ব পরিবর্তনকারী ব্রেনফাক rain
বাইটগুলিতে সঞ্চয় করার জন্য, আমার সংকলকটির জন্য টেপ কোনও .bss
বিভাগে বরাদ্দ করা হয়নি বা এর মতো অভিনব কোনও কিছু নেই। পরিবর্তে, টেপটি ব্রেইনফাক প্রোগ্রামের সংকলিত বাইট কোডের পরে সরাসরি 30,000 নাল বাইট লেখা হয়। এটি জেনে রাখা এবং আমার কম্পাইলার দ্বারা বাইট কোডটি কী উত্পন্ন তা সম্পর্কে সচেতন হওয়ার অর্থ আপনি রানটাইমে বাইট কোড তৈরি বা সংশোধন করতে পারবেন। এই 'বৈশিষ্ট্যটির' সাধারণ চিত্রণ একটি ব্রেনফাক প্রোগ্রাম যা তার নিজস্ব প্রস্থান মূল্য নির্ধারণ করে।
<<<<<<+
বাইট কোডে টেপটির বাম প্রান্তটি প্রান্তে চলে যায় যে প্রস্থান কোডটি সাধারণত 0 সেট করা হয় this অধ্যবসায় দিয়ে, এটি ব্রেনফাকে সিস্টেম স্তরের প্রোগ্রামিং করতে ব্যবহৃত হতে পারে।