もうやってる人いるだろうけど例のgolangでbrainf*ck処理系

http://golang.org/
golangという謎の言語があります。低レイヤーな静的システムプログラミング言語としてC/C++しか道具ねーのはしんどすぎんだろJKという発想の元つくられた言語じゃないかなと思っています。そういうの割と欲しいんだよなーと思っていたので脳味噌の体操。既にやってる人とかいくらでもいそうだなーと思いながら。

% 6g bf.go
% 6l bf.6
% cat hello.bf
>+++++++++[<++++++++>-]<.>+++++++[<++++>-]<+.+++++++..+++.[-]>++++++++[<++
++>-]<.>+++++++++++[<+++++>-]<.>++++++++[<+++>-]<.+++.------.--------.[-]>
++++++++[<++++>-]<+.[-]++++++++++.
% ./6.out hello.bf
Hello World!

ドキュメント眺めながら適当に。与えられた文字列を処理する単純なインタプリタ。まだ全然わからんけど「ちょっと便利なC言語みたいなもの」っぽさは割とあるんじゃないですかね。

package main

import ("fmt"; "flag"; "os"; "io"; "bytes")

func eval(codes []byte) {
  var mem [30000]byte;
  index := 0;
  var readbuf bytes.Buffer;
  var writebuf bytes.Buffer;
  pc := 0;
  for pc < len(codes) {
    switch codes[pc] {
      case '+': mem[index] += 1;
      case '-': mem[index] -= 1;
      case '>': index += 1;
      case '<': index -= 1;
      case ',':
        if readbuf.Len() == 0 {
          buf := make([]byte, 1000);
          count,err := os.Stdin.Read(buf);
          if err != nil {
            fmt.Fprintf(os.Stderr, "%v\n", err);
            os.Exit(1);
          }
          readbuf.Write(buf[0:count-1]);
        }
        b,err := readbuf.ReadByte();
        if err != nil {
          fmt.Fprintf(os.Stderr, "%v\n", err);
          os.Exit(1);
        }
        mem[index] = b;
      case '.':
        writebuf.WriteByte(mem[index]);
      case '[':
        if mem[index] == 0 {
          depth := 1;
          for depth != 0 && pc < len(codes) {
            pc += 1;
            switch codes[pc] {
              case '[': depth += 1;
              case ']': depth -= 1;
            }
          }
        }
      case ']':
        depth := -1;
        for depth != 0 && pc >= 0 {
          pc -= 1;
          switch codes[pc] {
            case '[': depth += 1;
            case ']': depth -= 1;
          }
        }
        pc -= 1;
    }
    pc += 1;
  }
  os.Stdout.Write(writebuf.Bytes());
}
func main() {
  flag.Parse();
  if flag.NArg() == 0 {
    fmt.Printf("usage: %v bf\n", os.Args[0]);
  } else {
    name := flag.Args()[0];
    code, err := io.ReadFile(name);
    if code == nil {
      fmt.Fprintf(os.Stderr, "%v\n", err);
      os.Exit(1);
    }
    eval(code);
  }
}

D言語も良いんだけど、あれはちょっととんがり過ぎてて疲れるとかそんな感じ。ライブラリが充実してるげだしこれからも充実させていくだろうし、未来は明るい。明日はきっといい日だ。

test