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:
and
not to mention
Also lo and behold the classic "99 Bottles of Beer" written in 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):
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.
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 ""
PT You could try the following program with the above interpreter...
= = badger badger mushroom snake = >>++++[<+++++[<+++++>-]>-]<<---[>>+>+>+>+>+>+<<<<<<<-] >>+ b > a >+++ d >++++++ g >++++ e >>++++[<++++>-]<+ r <<<<<<< >++++[<++++>-]< [>+++++[>.>.>.>.>.>.<<<<<<-]<-] mushroom ++++[>>+++>+++>+++>>+++<<<<<<-]>>->++++++++>+++>+>+> [>>>>+<<<<-] >>>>[<+<+<+<+>>>>-] <<-----<---<---< <<<<<< print ++[>>.>.>.>.>.>.>.>.<<<<<<<<<-] snake! >>>--.-----.>>>[-]>[-]<<[>+>+<<-]>-------.>+++.<++++. <<<[-]>[-]++++++[<+++++>-]<+++.
dbohdan 2016-02-11: The following module leverages the Tcl interpreter itself to interpret Brainfuck. It was originally developed to compete in a cross-language microbenchmark. I measured its performance when run with Tcl 8.6.4 on x86_64 Linux.
The translate command translates Brainfuck instructions into Tcl code, which is then run with apply (to ensure bytecode compilation). This is up to several times faster than interpreting the code directly, e.g., when running mandel.b , and I find it more idiomatic. Storing the tape data in dictionaries resulted in better performance than arrays, lists or dynamically named variables. Compressing repeated + and - into dict incr tape $pos ±N where N is the number of times the instruction is repeated noticeably improved the performance. Compressing < and >, which change a value not stored in a dictionary, had minimal impact.
package require Tcl 8.5 namespace eval ::brainfuck { variable verson 0.2.1 variable debug 0 proc emit code { upvar 1 transl transl foreach line [split [string trim $code] \n] { append transl [string trimleft $line]\n } } proc translate source { set transl {} emit { if {![info exists tape] || ($tape eq {})} { for {set i 0} {$i < 30000} {incr i} { dict set tape $i 0 } } if {![info exists pos] || ($pos eq {})} { set pos 0 } } set commands [split $source {}] for {set i 0} {$i < [llength $commands]} {incr i} { switch -exact -- [lindex $commands $i] { [ { emit [format %s\{ {if {[dict get $tape $pos] != 0} }] emit "while 1 \{" } ] { emit {if {[dict get $tape $pos] == 0} {break}} emit \} emit \} } > - < { # Compress repeated Brainfuck instructions into a single Tcl # command. if {[lindex $commands $i] eq {<}} { set op < set sign - } else { set op > set sign + } set count 0 while {[lindex $commands $i] eq $op} { incr count incr i } incr i -1 emit [format {incr pos %s%d} $sign $count] } + - - { if {[lindex $commands $i] eq {+}} { set op + } else { set op - } set count 0 while {[lindex $commands $i] eq $op} { incr count incr i } incr i -1 emit [format {dict incr tape $pos %s%d} $op $count] } . { emit { puts -nonewline [format %c [dict get $tape $pos]] } } , { # Noncompliant implementation. emit { set input [read stdin 1] dict set tape $pos [scan $input %c] } } default { # Ignore. } } } emit { return [list $tape $pos] } return $transl } proc interpret source { variable debug set translated [translate $source] if {$debug} { puts $translated } set result [apply [list {{tape {}} {pos {}}} $translated]] return $result } } proc main filename { set ch [open $filename r] set source [read $ch] close $ch fconfigure stdout -buffering none ::brainfuck::interpret $source } main [lindex $argv 0]