Vegetarianboy30

The fascist, score-computing branflakes interpreter in C

Jan 17th, 2021
605
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /*Make any use you like of this software. I can't stop you anyway. :)*/
  2.  
  3. /*  This interpreter uses byte cells, and gives an error on overflow or
  4.     underflow, or if the pointer is moved out of the array (whose size
  5.     is defined in ARRAYSIZE). It translates newlines, and leaves cell
  6.     values unchanged on end-of-file. It also reports the pointer's final
  7.     location and the final values of all cells visited during execution,
  8.     plus the number of brainfuck commands in the program, the number of
  9.     commands executed (using Faase's [] semantics), and the amount of
  10.     memory used, plus a composite score which is the product of these
  11.     last three numbers.
  12.     The pseudo-command '#' will zero all three numbers; this is to avoid
  13.     scoring any framework which is needed to set things up before the
  14.     execution of the component being tested, in the competition.  */
  15.  
  16.  
  17. #include <stdio.h>
  18. #include <float.h>
  19. #include <math.h>
  20. #define ARRAYSIZE 65536
  21. #define CODESIZE 65536
  22.  
  23. unsigned long stackp=CODESIZE, targets[CODESIZE];
  24. unsigned char array[ARRAYSIZE], code[CODESIZE];
  25. long p=0, q=0, length, c, max;
  26. unsigned long census[256];
  27. char *filename="";
  28. FILE *prog;
  29. double count=0, maxcount;
  30.  
  31. void err(char *s){
  32.     fprintf(stderr, "Error detected at byte %d of %s: %s!\n", q,filename,s);
  33.     exit(1);
  34. }
  35.  
  36. int main(int argc, char **argv){
  37.     if (argc > 2) err("Too many arguments");
  38.     if (argc < 2) err("I need a program filename");
  39.     if(!(prog = fopen(argv[1], "r"))) err("Can't open that file");
  40.     filename=argv[1];
  41.     length = fread(code, 1, CODESIZE, prog);
  42.     fclose(prog);
  43.     maxcount=pow(FLT_RADIX, DBL_MANT_DIG);
  44.     for(q=0; q<length; q++){
  45.         ++census[code[q]];
  46.         if (code[q]=='[') targets[--stackp]=q;
  47.         if (code[q]==']'){
  48.             if(stackp<CODESIZE) targets[targets[q]=targets[stackp++]]=q;
  49.             else err("Unmatched ']'");
  50.         }
  51.         if (code[q]=='#') for (p='+'; p<=']'; p++) census[p]=0;
  52.     }
  53.     if(stackp<CODESIZE) q=targets[stackp], err("Unmatched '['");
  54.     for(q=0,p=0;q<length;q++){
  55.         switch(code[q]){
  56.             case '+': if(array[p]++>=255) err("Overflow"); break;
  57.             case '-': if(array[p]--<=0) err("Underflow"); break;
  58.             case '<': p--; if(p<0) err("Too far left"); break;
  59.             case '>': if(++p>max)max=p;if(p>=ARRAYSIZE)err("Too far right");
  60.                           break;
  61. #if '\n' == 10
  62.             case ',': if((c=getchar())!= EOF) array[p]=c; break;
  63.             case '.': putchar(array[p]); break;
  64. #else
  65.             case ',': if((c=getchar())!=EOF) array[p]=c=='\n'?10:c; break;
  66.             case '.': putchar(array[p]==10?'\n':array[p]); break;
  67. #endif
  68.             case '[': if(!array[p]) q=targets[q]; break;
  69.             case ']': if(array[p]) q=targets[q]; break;
  70.             case '#': count=-1; max=0; break;
  71.             default: count--;
  72.         }
  73.         if(count++>=maxcount) err("Command count overflow");
  74.     }
  75.     printf("Pointer: %ld\nFinal memory state:\n", p);
  76.     for (p=0; p<=max;++p) printf(" %3d", array[p]);
  77.     printf("\n\n");
  78.     length=census['+']+census['-']+census['<']+census['>'];
  79.     length+=census[',']+census['.']+census['[']+census[']'];
  80.     printf("Program length: %ld.\nCommands executed: %.0f.\n", length,count);
  81.     printf("Memory used: %ld.\nScore: %.0f.\n", max+1, length*count*(max+1));
  82.     exit(0);
  83. }
RAW Paste Data