LoginSignup
8
3

More than 5 years have passed since last update.

Go 言語で BrainFuck を実装してみた

Posted at

はじめに

  • 難解プログラミング言語 BrainFuck についてちょっと怖かったのでずっと避けてきていたけどそろそろわかりたいと思ったので Go 言語で実装してみた

ソースコード

main.go
package main

import (
    "fmt"
    "io/ioutil"
    "os"
)

const (
    INCR  byte = 62 // +
    DECR  byte = 60 // -
    NEXT  byte = 43 // >
    PREV  byte = 45 // <
    READ  byte = 44 // ,
    WRITE byte = 46 // .
    OPEN  byte = 91 // [
    CLOSE byte = 93 // ]
)

var MAX_BUFFER_SIZE = 3000

func main() {
    if len(os.Args) < 2 {
        fmt.Println("Usage: " + os.Args[0] + " FILE")
        return
    }
    src, err := ioutil.ReadFile(os.Args[1])
    if err != nil {
        panic(err)
    }
    b := make([]byte, MAX_BUFFER_SIZE, MAX_BUFFER_SIZE)
    i := 0
    si := 0
    buf := make([]byte, 1)
    for {
        switch src[si] {
        case INCR:
            i++
        case DECR:
            i--
        case NEXT:
            b[i]++
        case PREV:
            b[i]--
        case WRITE:
            buf[0] = b[i]
            os.Stdout.Write(buf)
        case READ:
            os.Stdin.Read(buf)
            b[i] = buf[0]
        case OPEN:
            if b[i] == 0 {
                n := 0
                for {
                    si++
                    if src[si] == OPEN {
                        n++
                    } else if src[si] == CLOSE {
                        n--
                        if n < 0 {
                            break
                        }
                    }
                }
            }
        case CLOSE:
            if b[i] != 0 {
                n := 0
                for {
                    si--
                    if src[si] == CLOSE {
                        n++
                    } else if src[si] == OPEN {
                        n--
                        if n < 0 {
                            break
                        }
                    }
                }
            }
        }
        si++
        if si >= len(src) {
            break
        }
    }
}

実行方法

  • BrainFuck ファイルを渡して実行する
go build -o bf main.go
./bf hello.b
hello.b
+++++++++[>++++++++>+++++++++++>+++++<<<-]>.>++.+++++++..+++.>-.
------------.<++++++++.--------.+++.------.--------.>+.
fizzbuzz.b
++++++[->++++> >+>+>-<<<<<]>[<++++> >+++>++++> >+++>+
++++>+++++> > > > > >++> >++<<<<<<<<<<<<<<-]<++++>+++
>-->+++>-> >--->++> > >+++++[->++>++<<]<<<<<<<<<<[->-
[> > > > > > >]>[<+++>.>.> > > >..> > >+<]<<<<<-[> > > >]>[<+
++++>.>.>..> > >+<]> > > >+<-[<<<]<[[-<<+> >]> > >+>+<<<<<
<[-> >+>+>-<<<<]<]>>[[-]<]>[> > >[>.<<.<<<]<[.<<<<]>]>.<<<<
<<<<<<<]

おわりに

  • BrainFuck は読み書きが難解なだけで言語仕様も実装もとても簡単だった
  • 新しい言語を覚えたいときの手習いとかに実装してみるのもいいかも
  • BrainFuck について読み書きはしたくないが大したことはやってないということがわかったので今後の人生で怖がったり気にしたりする必要がなくなったのはよかった
  • あと Gist のコメントに BrainFuck のコードをそのまま貼るとボットだと思われて BAN されるという学びもあった
8
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
3