Skip to content

Instantly share code, notes, and snippets.

@fogus
Created May 9, 2012 23:50
Show Gist options
  • Select an option

  • Save fogus/2649873 to your computer and use it in GitHub Desktop.

Select an option

Save fogus/2649873 to your computer and use it in GitHub Desktop.

Revisions

  1. fogus created this gist May 9, 2012.
    32 changes: 32 additions & 0 deletions bf.c
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,32 @@
    #include <stdio.h>
    char b[30000],z[9999],*p=b,c,*a,i;
    f(char*r,int s)
    {
    while(c=*a++)
    {
    if(!s)
    {
    (c-62)?(c-60)?(c-43)?(c-45)?(c-46)?(c-44)?0:(*p=getchar()):putchar(*p):--*p:++*p:--p:++p;
    if(c==91)f(a,!*p);
    else if(c==93){if(!*p)return;else a=r;}
    }
    else
    {
    if(c==93)
    {
    --s;
    if(!*p&&!s)return;
    }
    else if(c==91)
    {
    s++;
    }
    }
    }
    }

    main(int c,char**v){
    fread(z,1,9999,fopen(*++v,"r"));
    a=z;
    f(0,0);
    }
    19 changes: 19 additions & 0 deletions bf.hs
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,19 @@
    import IO
    import System
    z=return
    '>'#(c,(l,d:r))=z(d,(c:l,r))
    '<'#(d,(c:l,r))=z(c,(l,d:r))
    '+'#(c,m)=z(succ c,m)
    '-'#(c,m)=z(pred c,m)
    '.'#t@(c,_)=putChar c>>hFlush stdout>>z t
    ','#(_,m)=getChar>>=(\c->z(c,m))
    _#t=z t
    _%t@('\0',_)=z t
    i%t=i t>>=(i%)
    b('[':r)=k$b r
    b(']':r)=(z,r)
    b(c:r)=f(c#)$b r
    b[]=(z,[])
    f j(i,r)=(\t->j t>>=i,r)
    k(i,r)=f(i%)$b r
    main=getArgs>>=readFile.head>>=($('\0',("",repeat '\0'))).fst.b
    75 changes: 75 additions & 0 deletions bf.lua
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,75 @@
    -- > increment the data pointer (to point to the next cell to the right).
    -- < decrement the data pointer (to point to the next cell to the left).
    -- + increment (increase by one) the byte at the data pointer.
    -- - decrement (decrease by one) the byte at the data pointer.
    -- . output a character, the ASCII value of which being the byte at the data pointer.
    -- , accept one byte of input, storing its value in the byte at the data pointer.
    -- [ if the byte at the data pointer is zero, then instead of moving the instruction pointer forward to the next command, jump it forward to the
    -- command after the matching ] command*.
    -- ] if the byte at the data pointer is nonzero, then instead of moving the instruction pointer forward to the next command, jump it back to the
    -- command after the matching [ command*.
    s=setmetatable({0},{__index=function() return 0 end})

    i=1 -- index array
    j=1 -- index input
    l=loadstring
    t="><+-.,[]"
    o=0
    fh=arg[1] and io.open(arg[1]) or io.stdin
    I=fh:read"*a":gsub("[^><%+%-%.,%[%]]","")
    fh:close()
    print(I)
    for k=1,#I do io.write(k%5==1 and"+"or"-") end
    io.write"\n"
    for k=1,math.ceil(#I/5) do local n=5*(k-1)+1 local s=(" "):rep(4-math.floor(math.log10(n))) io.write(n,s) end
    io.write"\n"
    dbg=true
    f={
    "i=i+1 ", -- array index ++
    "i=i-1 ", -- array index --
    "s[i]=(s[i]+1)%256 ", -- byte + 1
    "s[i]=(s[i]-1)%256 ", -- byte - 1
    "io.write(string.char(s[i])) ", -- put byte
    "local c=io.read(1):byte()s[i]=c==10 and s[i] or c", -- read byte "Newline required!"
    [=[if s[i]==0 then
    o=0
    repeat
    if dbg then print(j,"Forward!",o,b) end
    b=I:sub(j,j):match'[%[%]]'
    o= b=='['and o+1 or b==']' and o-1 or o;
    j=j+1
    until b==']' and o == 0
    end
    ]=], -- jump to matching ]
    [=[
    if s[i]~=0 then
    o=0
    count=0
    repeat
    if dbg then print(j,"Backwards",o,b) end
    b=I:sub(j,j):match"[%[%]]"
    o= b=='['and o-1 or b==']' and o+1 or o;
    j=j-1
    until b=='[' and o == 0
    end
    ]=], -- jump to matching ]
    }
    for k,v in ipairs(f) do f[t:sub(k,k)],e=l(v) if e then error(e)end end
    function run()
    j=1
    while j<=#I do
    f[I:sub(j,j)]()
    j=j+1
    end
    end
    res,err = pcall(run)
    if not res then
    print('error=',err)
    print('Dumping state')
    print('','stack')
    for k,v in pairs(s) do print("",k,v) end
    end
    if debug then
    print("stack")
    for k,v in pairs(s) do print(k,v) end
    end
    19 changes: 19 additions & 0 deletions bf.ocaml
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,19 @@
    {let a=Array.create 30000 0
    let(%)f g h=f(g h)
    let s v i=a.(i)<-v;i
    let o d i=s(a.(i)+d)i
    let p i=print_char(Char.chr a.(i));flush stdout;i
    let r i=s(Char.code(input_char stdin))i
    let rec w g i=if 0=a.(i)then i else w g(g i)
    let n x=x}
    rule t f=parse
    |'>'{t(succ%f)lexbuf}
    |'<'{t(pred%f)lexbuf}
    |'+'{t((o 1)%f)lexbuf}
    |'-'{t((o(-1))%f)lexbuf}
    |'.'{t(p%f)lexbuf}
    |','{t(r%f)lexbuf}
    |'['{t((w(t n lexbuf))%f)lexbuf}
    |']'|eof{f}
    |_{t f lexbuf}
    {let _=t n(Lexing.from_channel(open_in Sys.argv.(1)))0}
    12 changes: 12 additions & 0 deletions bf.pl
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,12 @@
    $_=q('>;$p++;<;$p--;+;D++;-;D--;[;while(D){;];};.;print chrD;,;D=ord getc');
    s[D]'$b[$p]'g;s/;/','/g;%c=eval;$/=$,;$_=<>;s/./$c{$&};/g;eval

    <<END

    $ perl bf.pl hello.bf
    Hello World!
    $ perl bf.pl prime.bf
    Primes up to: 100
    2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97

    END
    8 changes: 8 additions & 0 deletions bf.py
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,8 @@
    import sys
    i=0
    b=[0]*30000
    t=''
    for e in open(sys.argv[1]).read():
    t+=' '*i+['i+=1','i-=1','b[i]+=1','b[i]-=1','sys.stdout.write(chr(b[i]))','b[i]=ord(sys.stdin.read(1))','while b[i]:','pass','']['><+-.,['.find(e)]+'\n'
    i+=(92-ord(e))*(e in'][')
    exec t
    15 changes: 15 additions & 0 deletions bf.rb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,15 @@
    code = "a = [0] * 3e4; i = 0;"
    more_code ARGF.bytes.map {|b|
    replacements = {
    ?. => "putc a[i]",
    ?, => "a[i] = getc",
    ?[ => "while a[i] > 0 do",
    ?] => "end",
    ?< => "i -= 1",
    ?> => "i += 1",
    ?+ =>"a[i]+=1",
    ?- =>"a[i]-=1"
    }
    replacements[b]
    }.join(";")
    eval code+more_code
    20 changes: 20 additions & 0 deletions bf2.c
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,20 @@
    #include <stdio.h>
    main(int c,char**v){
    int m[3000],s[99],p=0,i=0,n=0;
    char l[9999],d;
    FILE*f=fopen(v[1],"r");
    for(l[i]=0;i<9999&&l[i]!=EOF;l[i]=getc(f))i++;
    for(i=1;d=l[i];i++){
    if(!n){ // > < + - . , ] \n [ ]
    p+=d-62?0:1;
    p-=d-60?0:1;
    m[p]+=d-43?0:1;
    m[p]-=d-45?0:1;
    if(d==46)putchar(m[p]);
    if(d==44){m[p]=getchar();}
    if(d==93){i=s[c]-1;c--;n++;}
    }
    if(d==91){if(m[p]){c++;s[c]=i;}else{n++;}}
    n-=d-93?0:1;
    }
    }