Pull to refresh

Интерпретатор Brainfuck размером 160 байт

Reading time 1 min
Views 4.1K
Прочитав про IP-стэк twIP, который помещается в размер твита и отвечает на пинги, корейский программист Канг Сеонгхун (Kang Seonghoon) решил создать нечто такое же миниатюрное и при этом работоспособное. И он создал самый маленький интерпретатор Brainfuck на C размером всего 160 байт.

s[99],*r=s,*d,c;main(a,b){char*v=1[d=b];for(;c=*v++%93;)for(b=c&2,b=c%7?a&&(c&17?c&1?(*r+=b-1):(r+=b-1):syscall(4-!b,b,r,1),0):v;b&&c|a**r;v=d)main(!c,&a);d=v;}

Интерпретатор способен выполнять любые программы на Brainfuck.

$ cc bf.c -o bf
$ ./bf '++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.'
Hello World!


Конечно, из-за стремления втиснуться в 160 байт пришлось многие вещи переложить на окружение. Более портативная и независимая от окружения версия интерпретатора занимает 170 байт.

s[999],*r=s,*d,c;main(a,b){char*v=1[d=b];for(;c=*v++%93;)for(b=c%7?a&&(c&17?c&1?(*r-=c-44):(r+=c-61):c&2?putchar(*r):(*r=getchar()),0):v;b&&c|a**r;v=d)main(!c,&b-1);d=v;}

Если добавить нормальную табуляцию, то код будет выглядеть так:

  // с пробелами

  s[999], *r=s, *d, c;
  
  main(a, b)
  {
      char *v=1[d=b];
      for(;c = *v++ % 93;)
          for(b = c%7 ? 
                  a &&
                      (c & 17 ? 
                            c & 1 ? 
                                (*r -= c - 44)
                                :(r += c - 61)
                             :c & 2 ?
                                putchar(*r)
                                :(*r = getchar())
                      ,0)
                  :v;
              b&&c | a * *r;
              v=d)
                  main(!c,&b-1);
      d = v;
  }
Tags:
Hubs:
+75
Comments 32
Comments Comments 32

Articles