Return Styles: Pseud0ch, Terminal, Valhalla, NES, Geocities, Blue Moon. Entire thread

My first Brainfuck

Name: The Amazing Anus !Anus3nMVO2 2009-08-31 1:43

I was bored as fuck so I decided to implement a Brainfuck interpreter in C.

/* brainfuck.c ... version 0.9
 *
 * usage: brainfuck <file>
 *
 */

 
#include <stdio.h>

/* 64kb -1b each
 *
 * The Brainfuck spec says that memory should be 30000 bytes, but I prefer to
 * use a whole 64kb for both code and memory.
 *
 */
#define BRAINF_CODESIZE   65535
#define BRAINF_MEMSIZE   65535


FILE* fp;

unsigned char* code, *memory;
short unsigned int codeptr, memptr;


int main(int argc, char* argv[])
{
     if (argc != 2)
          exit(1);

     if ((fp = fopen(argv[1], "r")) == NULL)
          exit(1);

     code = malloc(BRAINF_CODESIZE);
     memory = malloc(BRAINF_MEMSIZE);

     memset(code, 0, BRAINF_CODESIZE);
     memset(memory, 0, BRAINF_MEMSIZE);

     codeptr = 0;
     memptr = 0;

     while (!feof(fp))
     {
          fread(code, BRAINF_CODESIZE -1, 1, fp);
     }


     /*** Interpreting begins ***/
     while (code[codeptr])
     {
          switch (code[codeptr])
          {
               case '>':
                    ++memptr;
                    ++codeptr;
                    break;

               case '<':
                    --memptr;
                    ++codeptr;
                    break;

               case '+':
                    ++memory[memptr];
                    ++codeptr;
                    break;

               case '-':
                    --memory[memptr];
                    ++codeptr;
                    break;

               case '.':
                    putchar(memory[memptr]);
                    ++codeptr;
                    break;

               case ',':
                    memory[memptr] = getchar();
                    ++codeptr;
                    break;

               /* :NOTE: Some kind of error handling should take
                * place if no ']' is found.
                */
               case '[':
                    if (!memory[memptr])
                    {
                         while ((code[codeptr] != ']') && (code[codeptr]))
                         {
                              ++codeptr;
                         }
                    }
                    else
                         ++codeptr;
                    break;


               /* :NOTE: Some kind of error handling should take
                * place if no '[' is found.
                */
               case ']':
                    if (memory[memptr])
                    {
                         while ((code[codeptr] != '[') && (codeptr))
                              --codeptr;
                    }
                    else
                         ++codeptr;
                    break;

               /* invalid instruction
                * For now we will just continue executing when this happens.
                * It should ignore characters 10, 13, & 32 anyways.
                */
               default:
                    ++codeptr;
                    break;
          }
     }

     free(code);
}

Name: Anonymous 2009-11-15 22:41

Dev-Cpp
Compiling Sepples0x with a Sepples2003 compiler
( ≖‿≖)

Name: The Amazing Anus 2009-11-15 22:42

Ok, I am using the bench.bf provided by >>73 (thx btw)

I compile each one with gcc -s -Os.
This is how they match up with the "real" provided by time:

bf         13.291 seconds (My own, as in >>29 )
qdbf        4.774 seconds (QDBF, forget where I found it)
bfanon34    6.287 seconds (Provided by >>34 )
bfanon38   12.527 seconds (Provided by >>38 )


I can't bench >>73 because I still can't get it to compile.

Name: Anonymous 2009-11-15 22:43

>>81
Yeah, I know.  What do you recommend?  Is gcc 4.4.2 (or whatever the newest stable build is) capable of building it?

Name: Anonymous 2009-11-16 17:32

>>77 Why thank you, Dear! I'm very fond of you too.

Here's a version that should compile w/o any trickery.

#include <iostream>

using std::cin;
using std::cout;
using std::cerr;
using std::endl;
#define MS (65536)
struct state {
        unsigned char * tape;
        size_t head;
        static state s;
private:
        state() : tape(new unsigned char[MS]), head() {}
};
state state::s;
state & s = state::s;

template <char c, int times = 1>
struct insn {
        enum { C = c };
        enum { T = 0 };
        void operator () () const {}
};

template <typename B, typename I>
struct block : B {
        typedef B base;
        typedef I insn_;

        block() {}
        block(B const &, I const &) {}

        void operator () () const { B::operator () (); I()(); }

        block<B, insn<I::C, I::T + 1> > operator , (insn<I::C, 1> const &)
        { return block<B, insn<I::C, I::T + 1> >(); }

        template <char c>
        block<block<B, I>, insn<c> > operator , (insn<c> const & i2)
        { return block<block<B, I>, insn<c> >(*this, i2); }
};

template <>
struct block<void, void> {
        typedef void insn_;

        void operator () () const { }

        template <char c>
        block<block, insn<c> > operator , (insn<c> const & i) { return block<block, insn<c> >(*this, i); }
        static block BF;
        block(block const &) {}
        block() {}
};
block<void, void> block<void, void>::BF;
block<void, void> & BF = block<void, void>::BF;

template <typename B>
struct block<B, insn<'['> > : block<void, void> {
        typedef insn<'['> insn_;

        typedef B prev_block;

        block() {}
        block(B const &, insn<'['> const &) {}

        void operator () () const { }

        template <char c>
        block<block<B, insn<'['> >, insn<c> > operator , (insn<c> const & i2)
        { return block<block<B, insn<'['> >, insn<c> >(*this, i2); }
};

template <typename B>
struct block<B, insn<']'> > : B::prev_block {
        typedef insn<']'> insn_;

        block() {}
        block(B const &, insn<']'> const &) {}

        void operator () () const {
                B::prev_block::operator () ();
                while (s.tape[s.head])
                { B()(); }
        }

        template <char c>
        block<block<B, insn<']'> >, insn<c> > operator , (insn<c> const & i2)
        { return block<block<B, insn<']'> >, insn<c> >(*this, i2); }
};

template <int times>
struct insn<'<', times> {
        enum { C = '<' };
        enum { T = times };
        void operator () () const {
                if (s.head >= times) s.head -= times;
                else s.head = 0;
        }
};

template <int times>
struct insn<'>', times> {
        enum { C = '>' };
        enum { T = times };
        void operator () () const {
                if (s.head + times < MS) s.head += times;
                else s.head = MS - 1;
        }
};

template <int times>
struct insn<'-', times> {
        enum { C = '-' };
        enum { T = times };
        void operator () () const {
                s.tape[s.head] -= times;
        }
};

template <int times>
struct insn<'+', times> {
        enum { C = '+' };
        enum { T = times };
        void operator () () const {
                s.tape[s.head] += times;
        }
};

template <int times>
struct insn<'.', times> {
        enum { C = '.' };
        enum { T = times };
void dump(unsigned char c) const
{
        static int dotc = 155;

        if (dotc-- == 0) { cerr << "too much output" << endl; *((int*)0)=1; }

        if (c == ' ' || c == '\n' || (c >= 'A' && c <= 'z')) cout << c;
        //else cout << "ip: " << ip << " head: " << head << " depth: " << depth << ' ' << (int)c << endl;
        else cout << (int)c;
}

        void operator () () const {
                for (int i = 0; i < times; i++) dump(s.tape[s.head]);
        }
};

template <int times>
struct insn<',', times> {
        enum { C = ',' };
        enum { T = times };
        void operator () () const {
                for (int i = 0; i < times; i++) cin >> s.tape[s.head];
        }
};

template <int times>
struct insn<'[', times> {
        enum { C = '[' };
        enum { T = times };
        void operator () () const {
        }
};

template <int times>
struct insn<']', times> {
        enum { C = ']' };
        enum { T = times };
        void operator () () const {
        }
};

        insn<'<'> l;
        insn<'>'> r;
        insn<'+'> p;
        insn<'-'> m;
        insn<'.'> d;
        insn<','> c;
        insn<'['> b;
        insn<']'> e;
int main()
{
        (BF
                        BFCODE
        )();
}


Compile w/ this to get the benchmark previously mentioned:
g++ -O2 -DBFCODE=,r,p,p,b,l,p,p,p,p,p,p,p,p,p,p,p,p,p,r,m,e,l,b,b,r,p,r,p,l,l,m,e,r,b,l,p,r,m,e,p,p,p,p,p,p,p,p,b,r,p,p,p,p,p,p,p,p,l,m,e,r,d,b,m,e,l,l,r,p,p,p,p,p,p,p,p,p,p,b,r,p,p,p,p,p,p,p,p,p,p,b,r,p,p,p,p,p,p,p,p,p,p,b,r,p,p,p,p,p,p,p,p,p,p,b,r,p,p,p,p,p,p,p,p,p,p,b,r,p,p,p,p,p,p,p,p,p,p,b,r,p,p,p,p,p,p,p,p,p,p,b,m,e,l,m,e,l,m,e,l,m,e,l,m,e,l,m,e,l,m,e,l,m,e,p,p,p,p,p,p,p,p,p,p,d

I reckon there's a bug hiding somewhere in there, as it emits a different/wrong result when compiled with cl.exe, than it does when compiled with g++. (I used the 20091112 snapshot of g++-4.5.)

Name: Anonymous 2009-11-16 17:36

what is that -DBFCODE bullshit for?

Name: The Amazing Anus 2009-11-16 17:44

>>84
I don't know why this one doesn't even take a file as input but it runs in 1.560 seconds.

Name: Anonymous 2009-11-16 17:50

>>86
You're an anus! *grabs brick*

Name: The Amazing Anus 2009-11-16 18:02

Now let's see who can write the fastest Brainfuck interpreter.  I want a harder benchmark program, and I want >>84 to take a file as input before I accept it into the contest.

>>87
I big anus that can talk, and feel

but I am not as great as sir ribs T_T

Name: Anonymous 2009-11-16 18:15

Can someone please post a test .bf file which we can use for benchmarking?

Name: Anonymous 2009-11-16 18:21

>>85 Thats the brainfuck program that will be in the executable.

>>86 Because it is not an interpreter. I beleive it's called domain specific language. Domain being in this case the brainfuck language.

>>88 Cf. the previous reply.

Name: Anonymous 2009-11-16 21:24

>>88
*grabs gas*

Name: Anonymous 2009-11-16 23:15

Lazy mode;
$ cat bfcc.pl
#!/usr/bin/perl

$pre=<<EOF;
#include <stdio.h>

char mem[30000];

int main() {
    char * restrict ptr = mem;
EOF

$post=<<EOF;
    return 0;
}
EOF

%inst = (
    '>' => '++ptr;',
    '<' => '--ptr;',
    '+' => '++*ptr;',
    '-' => '--*ptr;',
    '.' => 'putchar(*ptr);',
    ',' => '*ptr=getchar();',
    '[' => 'while (*ptr) {',
    ']' => '}',
);

sub compile {
    my $in=1; my $c;
    (my $x=shift) =~ s/(.)/$c=$inst{$1}and"\t"x('['eq$1?$in++:']'eq$1?--$in:$in)."$c\n"/gse;
    $pre . $x . $post
}

undef $/;
print compile <>;

$ ./bfcc.pl bench.bf | cc -O3 -o bf-bench -xc -std=gnu99 -
$ time ./bf-bench
ZYXWVUTSRQPONMLKJIHGFEDCBA

real    0m0.256s
user    0m0.250s
sys    0m0.003s
$

Name: The Amazing Anus 2009-11-16 23:25

>>92
Nice, but I bet your processor is also faster than the piece of shit I run on.  I will have to try this one out myself.

Name: Anonymous 2009-11-17 1:02

This thread makes me want to write a JIT brainfuck inpiler in Java.

Name: Anonymous 2009-11-17 1:20

A CL "compiler" for bf could be done using macros or just COMPILE, add some declarations and it might even produce some decent code on some implementations.

Name: Anonymous 2009-11-17 1:32

... but I doubt it would exceed the Perl to C compiler's performance, if at all. A better solution might be to go platform specific and generate machine code (or assembly) directly, which might just be faster, especially if one makes it an optimizing compiler...

Name: Anonymous 2009-11-17 3:16

>>94
inpiler
... what?

Name: Anonymous 2009-11-17 3:22

>>97
it's the opposite of enpiler

Name: Anonymous 2009-11-17 3:47

>>98
I'd rather say, outpiler

Name: Anonymous 2009-11-17 14:03

http://esoteric.sange.fi/brainfuck/impl/compilers/bf2c.hs
MIND=BLOWN

It's FAST too:

>>92
~ % perl bfcc.pl bench.bf|gcc -O3 -ffast-math -xc -std=gnu99 -xc -o bf1 -
~ % time ./bf1
ZYXWVUTSRQPONMLKJIHGFEDCBA
./bf1  0.04s user 0.00s system 98% cpu 0.039 total


~ % runghc bf2c.hs <bench.bf |gcc -O3 -ffast-math -xc -std=gnu99 -xc -o bf2 -
~ % time ./bf2
ZYXWVUTSRQPONMLKJIHGFEDCBA
./bf2  0.01s user 0.00s system 97% cpu 0.013 total

Name: Anonymous 2009-11-17 19:42

I HATE women. I never had a girlfriend and never will. The only times I got laid was when I paid a woman or promised her something. I'm never going to hold hands with a chick, kiss a girl intimately because we're in love, or any of the other shit that human beings were made to do. I guess that I'm suppose to be happy masturbating every fucking night. I'm a man with sexual urges and can't get with a female. I'm suppose to be alright with that? THERE IS A FUCKING CURSE ON MY LIFE. A CURSE THAT PREVENTS ANY FEMALE FROM LIKING ME. Oh I forgot, I do get interest from fat chicks and I'm not attracted to fat chicks.
I don't give a fuck anymore. I'm going to become the biggest asshole in the world. I tried the whole being considerate thing and it got me nowhere. If people can't handle my newfound harshness, then bring it on. BECAUSE I DON'T GIVE A FUCK. I DON'T GIVE A FUCK. I DON'T GIVE A FUCK.
I get happy when I hear about some college slut getting murdered or injured in a hit and run. "oh she was a beautiful and talented girl, how could this happen." I don't know but I'm glad it did.

Name: Anonymous 2009-11-17 20:29

>>10
What if you include the compilation time?

Name: Anonymous 2009-11-17 20:45

>>102
~ % time (./bf2c <bench.bf|clang -march=nocona -O3 -o bf2 -xc - && ./bf2)          
ZYXWVUTSRQPONMLKJIHGFEDCBA
(; ./bf2c < bench.bf | clang -march=nocona -O3 -o bf2 -xc - && ./bf2; )  0.07s user 0.03s system 100% cpu 0.103 total


(./bf2c is bf2c.hs compiled with ghc)

Name: Anonymous 2009-11-17 20:48

>>102
I really just wanted interpreters, not compilers

Name: Anonymous 2009-11-17 21:25

>>104
well, you get what you pay for

Name: Anonymous 2009-11-18 11:16

>>105
But I paid my anus for this!

Name: Anonymous 2010-02-06 11:28

mailto:sage

Name: Anonymous 2010-02-06 20:14

>>107
You never answer my emails >:(

Name: Anonymous 2010-02-06 20:23

BRAINFUCK MY ANUS

Name: Anonymous 2010-02-06 20:24

BRAINFUCK MY ANUS

Name: Anonymous 2010-02-06 20:29

ANUSFUCK MY BRAIN

Name: Anonymous 2010-02-07 0:52

FUCK MY BRAINUS

Name: Anonymous 2010-02-07 2:46



    FUCK MY BRAINUS

Name: Anonymous 2010-02-07 4:14

BRAINUS: the wonder of modern genetics.

Name: Anonymous 2010-04-26 10:27

I was bored as fuck so I decided to implement an ``ed'' interpreter in C.

#include <stdio.h>

int main(int argc, char* argv) {
  while (1) {
    char* c;
    scanf("%s", c);
    printf("?");
  }
  return 1;
}

Name: Anonymous 2010-04-26 17:11


$ed
#include <stdio.h>

int main(int argc, char* argv) {
  while (1) {
    char* c;
    scanf("%s", c);
    printf("?");
  }
  return 1;
} ?
?
?
?
?
?
?
?
?

Name: Anonymous 2010-04-26 21:37

Here's my shot at it..


void compile(char *code) {
    int     *memory                = (int *) malloc(MEMORY_SIZE * sizeof(int));
    int     *memory_ptr            = memory;
    int     nested_loop_level   = 0;

    while(memory_ptr <= memory + MEMORY_SIZE)
        *memory_ptr++ = 0;
    memory_ptr = memory;
   
    while(*code != '\0') {
        switch(*code) {
            case '+' :
                (*memory_ptr)++;
                break;
               
            case '-':
                (*memory_ptr)--;
                break;
               
            case '>':
                memory_ptr++;
                if(memory_ptr > memory + MEMORY_SIZE)
                    memory_ptr = memory;
                break;
               
            case '<':
                memory_ptr--;
                if(memory_ptr < memory)
                    memory_ptr = memory + MEMORY_SIZE;
                break;
               
            case '.':
                putchar(*memory_ptr);
                break;
               
            case ',':
                *memory_ptr    = getchar();
                break;
               
            case '[':
                if(*memory_ptr == 0) {
                    code++;
                    while(nested_loop_level > 0 || *code != ']' ) {
                        if(*code == '[')
                            nested_loop_level++;
                        if(*code == ']')
                            nested_loop_level--;
                        code++;
                    }
                }
                break;
               
            case ']':
                code--;
                while(nested_loop_level > 0 || *code != '[') {
                    if(*code == ']')
                        nested_loop_level++;
                    if(*code == '[')
                        nested_loop_level--;
                    code--;
                }
                code--;
        }
        code++;
    }
}


So what do you think?

Name: Anonymous 2010-11-25 12:59

Name: Anonymous 2010-12-17 1:27

Are you GAY?
Are you a NIGGER?
Are you a GAY NIGGER?

If you answered "Yes" to all of the above questions, then GNAA (GAY NIGGER ASSOCIATION OF AMERICA) might be exactly what you've been looking for!

Newer Posts
Don't change these.
Name: Email:
Entire Thread Thread List