Advertisement
Guest User

Untitled

a guest
May 24th, 2013
212
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.16 KB | None | 0 0
  1. /*
  2. Optimizing brainfuck implementation of dialect based on
  3. Daniel's dbfi (see "A very short self-interpreter")
  4.  
  5. This interpreter has only one input: program and input to the
  6. program have to be separated with ! e.g. ",.!a" prints 'a'
  7. To use it in interactive mode paste your program as input.
  8.  
  9. This program can be compiled with NOLNR macro defined.
  10. NOLNR disables optimization of linear loops (where '<>' balanced), e.g. [->+>++<<].
  11. Linear loop is then executed in one step.
  12.  
  13. Oleg Mazonka 4 Dec 2006  http://mazonka.com/
  14.  
  15. */
  16.  
  17. #include <stdlib.h>
  18. #include <stdio.h>
  19. #include <string.h>
  20.  
  21. typedef struct _op
  22. {
  23.     int shift, off;
  24.     int * d, sz;
  25.     struct _op * go;
  26.     int c;
  27.     int igo, linear;
  28.     int * db, dbsz;
  29. } op;
  30.  
  31. void printop(op *z)
  32. {
  33.     int j;
  34.     printf("op='");
  35.     if( !strchr("<>+-",z->c) ) printf("%c",(char)z->c);
  36.     for( j=0; j<z->dbsz; j++ )  printf("%c",(char)z->db[j]);
  37.     printf("' shift=%d off=%d go=%d { "
  38.         ,z->shift, z->off, z->igo );
  39.     for( j=0; j<z->sz; j++ )
  40.         printf("%d ",z->d[j]);
  41.     printf("}\n");
  42. }
  43.  
  44. void * zalloc(void *p, int sz, int osz)
  45. {
  46.     p = realloc(p,sz);
  47.     memset((char*)p+osz,0,sz-osz);
  48.     return p;
  49. }
  50. #define zalloci(p,sz,osz) zalloc(p,(sz)*sizeof(int),(osz)*sizeof(int));
  51.  
  52. int getbf()
  53. {
  54.     int a;
  55. next:
  56.     a = getchar();
  57.     if( a==-1 ) return -1;
  58.     if( !strchr(",.[]+-<>!",a) ) goto next;    
  59.     return a;
  60. }
  61.  
  62. int consume(op *o)
  63. {
  64.     int mp=0,i;
  65.     int a = o->c;
  66.  
  67.     if( strchr("[]",a) ) a=getbf();
  68.  
  69.     o->sz = 1;
  70.     o->d = zalloci(0,1,0);
  71.     o->off = 0;
  72.  
  73.     o->dbsz=0;
  74.     o->db=0;
  75.  
  76.     for(;;a=getbf())
  77.     {
  78.         if( a==-1 || a=='!' ) break;
  79.         if( strchr(",.[]",a) ) break;
  80.  
  81.         o->db = zalloci(o->db,o->dbsz+1,o->dbsz);
  82.         o->db[o->dbsz++] = a;
  83.  
  84.         if( a=='+' ) o->d[mp]++;
  85.         if( a=='-' ) o->d[mp]--;
  86.         if( a=='>' )
  87.         {
  88.             mp++;
  89.             if( mp>=o->sz )
  90.             {
  91.                 o->d = zalloci(o->d,o->sz+1,o->sz);
  92.                 o->sz++;
  93.             }
  94.         }
  95.         if( a=='<' )
  96.         {
  97.             if( mp>0 ) mp--;
  98.             else
  99.             {
  100.                 o->off--;
  101.                 o->d = zalloci(o->d,o->sz+1,o->sz);
  102.                 for( i=o->sz; i>0; i-- ) o->d[i] = o->d[i-1];
  103.                 o->d[0] = 0;
  104.                 o->sz++;
  105.             }
  106.         }
  107.     }
  108.     o->shift = mp + o->off;
  109.  
  110.     /* cut corners */
  111.     while( o->sz && o->d[o->sz-1] == 0 ) o->sz--;
  112.     while( o->sz && o->d[0] == 0 )
  113.     {
  114.         o->sz--;
  115.         for( i=0; i<o->sz; i++ ) o->d[i] = o->d[i+1];
  116.         o->off++;
  117.     }
  118.  
  119.     return a;
  120. }
  121.  
  122. int main()
  123. {
  124.     op * o=0, *z, *zend;
  125.     int sz=0, i, *m, mp, msz;
  126.     int a = getbf();
  127.     for(;;sz++)
  128.     {
  129.         o = zalloc(o,(sz+1)*sizeof(op),sz*sizeof(op));
  130.         if( a==-1 || a=='!' ) break;
  131.  
  132.         o[sz].c = a;
  133.         if( strchr(",.",a) ){ a=getbf(); continue; }
  134.         if( a==']' )
  135.         {
  136.             int l=1, i=sz;
  137.             while(l&&i>=0) if(i--) l+=(o[i].c==']')-(o[i].c=='[');
  138.             if( i<0 ){ printf("unbalanced ']'\n"); exit(1); }
  139.             o[i].igo = sz;
  140.             o[sz].igo = i;
  141.         }
  142.         a = consume(o+sz);
  143.     }
  144.  
  145.     for( i=0;i<sz;i++ )
  146.     {
  147.         o[i].go = &o[o[i].igo];
  148. #ifndef NOLNR
  149.         if( o[i].c == '[' && o[i].igo == i+1 && o[i].shift==0 && o[i].off <= 0 )   
  150.         {
  151.             o[i].linear = -o[i].d[-o[i].off];
  152.             if( o[i].linear < 0 )
  153.             {
  154.                 printf("Warning: infinite loop "); printop(&o[i]);
  155.                 printf("linear=%d\n",o[i].linear);
  156.                 o[i].linear = 0;
  157.             }
  158.         }
  159.         else o[i].linear = 0;
  160. #endif
  161.  
  162.     }
  163.  
  164.     msz = 1000; /* any number */
  165.     m = zalloci(0,msz,0);
  166.     mp=0;
  167.  
  168.     z = o;
  169.     zend = o+sz;
  170.     for( ; z!=zend; ++z )
  171.     {
  172. #ifdef DBG
  173.         printop(z);
  174. #endif
  175.  
  176.         if( z->c == ']' )
  177.         {
  178.             if( m[mp] ) z=z->go;
  179.         }
  180.  
  181.         else if( z->c == '[' )
  182.         {
  183.             if( !m[mp] ) z=z->go;
  184.         }
  185.  
  186.         else if( z->c == ',' ){ m[mp] = getchar(); continue; }
  187.  
  188.         else if( z->c == '.' ){ putchar(m[mp]); continue; }
  189.  
  190.         /* apply */
  191.         if( z->sz )
  192.         {
  193.             int nmsz = mp+z->sz+z->off;
  194.             if( nmsz > msz )
  195.             {
  196.                 m = zalloci(m,nmsz,msz);
  197.                 msz = nmsz;
  198.             }
  199.  
  200.  
  201. #ifndef NOLNR
  202.             if( z->linear )
  203.             {
  204.                 int del = m[mp]/z->linear;
  205.                 for( i=0; i<z->sz; i++ ) m[mp+z->off+i]+=del*z->d[i];
  206.             }else
  207. #endif
  208.                 for( i=0; i<z->sz; i++ ) m[mp+z->off+i]+=z->d[i];
  209.  
  210.         }
  211.  
  212.         if( z->shift>0 )
  213.         {  
  214.             int nmsz = mp+z->shift+1;
  215.             if( nmsz > msz )
  216.             {
  217.                 m = zalloci(m,nmsz,msz);
  218.                 msz = nmsz;
  219.             }
  220.         }
  221.         mp += z->shift;
  222.  
  223. #ifdef DBG
  224.         for( i=0; i<msz; i++ )
  225.         {
  226.             if( i==mp ) printf("'");
  227.             printf("%d ",m[i]);
  228.         }
  229.         printf("\n");
  230. #endif
  231.     }
  232.     return 0;
  233. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement