Brainfuck

I don't think it qualifies as an actual language, but it is so interesting it does deserve a wiki page. Learn more about it here:

http://www.muppetlabs.com/~breadbox/bf/

and

http://cydathria.com/bf/brainfuck.html

not to mention

http://www.hevanet.com/cristofd/brainfuck/brainfuck.html

Also lo and behold the classic "99 Bottles of Beer" written in brainfuck:

http://99-bottles-of-beer.ls-la.net/b.html#Brainfuck

Here's a random number generator:

 >>>++[<++++++++[<[<++>-]>>[>>]+>>+[-[->>+<<<[<[<<]<+>]>[>[>>]]]<[>>[-]]>[>[-
 <<]>[<+<]]+<<]<[>+<-]>>-]<.[-]>>] http://www.hevanet.com/cristofd/brainfuck/

And a brainfuck interpreter written in Tcl (you can type brainfuck — or a close approximation — directly into a tcl interpreter):

http://www.fishpool.com/~setok/proj/tclbf/

PT writes: And here is a BrainFuck interpreter as an Internet Explorer plugin language — http://brainscript.sourceforge.net/

And BF is a real language — it's Turing complete after all.

Now Malbolge on the other hand....

Another amusing language: Beatnik

AM (18 may 2009) And then there is Intercal ... http://en.wikipedia.org/wiki/Intercal - mentioned several times on this Wiki.


Awib is a brainfuck compiler entirely written in brainfuck.

Awib is a 4-language polyglot and can be run/compiled as brainfuck, Tcl, C and bash

Awib has 6 separate backends and is capable of compiling brainfuck source code to Linux executables (i386) and five programming languages: C, Tcl, Go, Ruby and Java


Interpreter

RHS A brainfuck interpreter written in Tcl... can take input as a filename, or from stdin

#!/bin/sh
# This line continues for Tcl, but is a single line for 'sh' \
exec tclsh8.5 "$0" ${1+"$@"}

proc getp {} {
    global pc program
    lindex $program $pc
}
proc getd {} {
    global xc data
    while {[llength $data]-1 < $xc} {
        lappend data 0
    }
    lindex $data $xc
}
proc setd {c} {
    global xc data
    while {[llength $data]-1 < $xc} {
        lappend data 0
    }
    lset data $xc $c
}

proc main {commands} {
    global program data pc xc

    set program [split $commands ""]
    set plen [llength $program]
    set data {0}
    set xc 0

    for {set pc 0} {$pc < $plen} {incr pc} {
        switch [lindex $program $pc] {
            > {
                incr xc
            }
            < {
                incr xc -1
            }
            + {
                setd [expr {[getd] + 1}]
            }
            - {
                setd [expr {[getd] - 1}]
            }
            . {
                puts -nonewline [format "%c" [getd]]
            }
            , { 
                if {![eof stdin]} {
                    scan [read stdin 1] "%c" var
                    setd $var
                } else {
                    setd 0
                }
            }

            \[ {
                if {[getd] == 0} {
                    incr pc
                    set nest 0
                    while {$nest || [getp] ne "\]"} {
                        switch [getp] {
                            \[ {incr nest}
                            \] {incr nest -1}
                        }
                        incr pc
                    }
                }
            }
            \] {
                if {[getd] != 0} {
                    incr pc -1
                    set nest 0
                    while {$nest || [getp] ne "\["} {
                        switch [getp] {
                            \[ {incr nest -1}
                            \] {incr nest}
                        }
                        incr pc -1
                    }
                }
            }
            \# {
                # Purely for debugging
                puts -nonewline "\nDebug: "
                for {set tmp 0} {$tmp < 10} {incr tmp} {
                    puts -nonewline "[lindex $data $tmp]:"
                }
                puts ""
            }
        }
    }
}

proc readfile {args} {
    switch [llength $args] {
        0 {
            set fd stdin
        }
        1 {
            set fd [open [lindex $args 0]]
        }
        default {
            puts stderr "Usage: [file tail [info script]] ?filename?"
            exit 1
        }
    }
    set text [read $fd]
    if {$fd ne "stdin"} {
        close $fd
    }
    return $text
}

fconfigure stdout -buffering none
fconfigure stdin -buffering none

set commands [readfile {*}$argv]
main $commands

puts ""
[The version at Rosetta Code is derived from this one.]

PT You could try the following program with the above interpreter...

 =
 =  badger badger mushroom snake
 =
 
 >>++++[<+++++[<+++++>-]>-]<<---[>>+>+>+>+>+>+<<<<<<<-]
 >>+     b
 >       a
 >+++    d
 >++++++ g
 >++++   e
 >>++++[<++++>-]<+ r
 
 <<<<<<<
 >++++[<++++>-]<
 [>+++++[>.>.>.>.>.>.<<<<<<-]<-]
 
 mushroom
 ++++[>>+++>+++>+++>>+++<<<<<<-]>>->++++++++>+++>+>+>
 [>>>>+<<<<-]
 >>>>[<+<+<+<+>>>>-]
 <<-----<---<---<
 <<<<<<
 print
 ++[>>.>.>.>.>.>.>.>.<<<<<<<<<-]
 
 snake!
 >>>--.-----.>>>[-]>[-]<<[>+>+<<-]>-------.>+++.<++++.
 <<<[-]>[-]++++++[<+++++>-]<+++.

Brainfuck-to-Tcl transpiler

See the corresponding page.