M4でBrainfuckを動かす話

99b72ba4c7dd4da957edb3e619a6d71f?s=47 MakKi
October 12, 2017

 M4でBrainfuckを動かす話

99b72ba4c7dd4da957edb3e619a6d71f?s=128

MakKi

October 12, 2017
Tweet

Transcript

  1. M4でBrainfuckを 動かす話 KLab株式会社 EM部 牧内大輔

  2. 自己紹介 牧内大輔(MakKi) twitter: @makki_d GitHub: makiuchi-d 学生時代: 動画編集関連のフリーソフト 就職してから: ブラウザゲームの開発(モバゲー・GREE)

    EMLauncher(デバッグアプリ配布ツール) 同期対戦通信基盤(Unity・Websocket・Go)
  3. まずアンケート • M4知ってる人

  4. まずアンケート • M4知ってる人 • Brainfuck知ってる人

  5. まずアンケート • M4知ってる人 • Brainfuck知ってる人 • チューリング完全知ってる人

  6. M4 is 何?

  7. M4 is 何? “m4 は、ブライアン・カーニハンとデニス・リッチー が設計した汎用マクロプロセッサである。その 名称は、"macro" の "m" と、AP-3ミニコンピュータ

    でデニス・リッチーがそれ以前に書いたマクロプロ セッサ "m3" の次、というところから来ている。 出展:wikipedia http://ja.wikipedia.org/wiki/M4_(プログラミング言語)
  8. マクロプロセッサ?

  9. マクロプロセッサ define(`H’, `Hello, $1!!’) こんなマクロを定義して

  10. マクロプロセッサ define(`H’, `Hello, $1!!’) H(KLab) こんなふうに呼び出すと

  11. マクロプロセッサ define(`H’, `Hello, $1!!’) H(KLab) Hello, KLab!! これが出力される

  12. マクロプロセッサ define(`H’, `Hello, $1!!’) H(KLab) Hello, KLab!! これが出力される テキストを置換するのが基本動作

  13. M4 is 何? “......それ以前のマクロプロセッサとは異なり、特 定のコンピュータ言語や自然言語を対象としたも のではない。ただし、もとはFORTRANの方言であ るRatforの開発で使うために開発された。他のマク ロプロセッサとは異なり、m4 は一般的なプログラミ ング言語と同様、チューリング完全である。

    出展:wikipedia http://ja.wikipedia.org/wiki/M4_(プログラミング言語)
  14. チューリング完全?

  15. チューリング完全 “計算理論において、ある計算のメカニズムが万能チューリン グマシンと同じ計算能力をもつとき、その計算モデルはチューリ ング完全(チューリングかんぜん、Turing-complete)あるいは 計算完備であるという。 (中略) 簡単に言えば、チューリング完全であれば、実現 可能なアルゴリズムや手続きはすべて処理できる ということを意味している。 出展:wikipedia

    http://ja.wikipedia.org/wiki/チューリング完全
  16. つまり コンピュータで動かせるアルゴリズムは 全てM4でも記述できる

  17. つまり コンピュータで動かせるアルゴリズムは 全てM4でも記述できる M4は万能

  18. 確かめてみよう

  19. 確かめてみよう チューリング完全の証明 • チューリング完全な処理系を 実装できればOK

  20. 確かめてみよう チューリング完全の証明 • チューリング完全な処理系を 実装できればOK チューリング完全な処理系 Brainfuck

  21. Brainfuckとは +++++++++[>++++++++>+++++++++++>+++++<<< -]>.>++.+++++++..+++.>-.------------.<++ ++++++.--------.+++.------.--------.>+. Hello, world!

  22. M4で実装してみた

  23. 実演

  24. 結論 M4はチューリング完全である みんなもM4をつかってみよう!!

  25. ありがとうございました。

  26. 実装の詳細

  27. Brainfuckの構成要素 • メモリ配列 • その上を動くポインタ • 入力 • 出力

  28. Brainfuckの命令 • > : ポインタのインクリメント • < : ポインタのデクリメント •

    + : ポインタの指す値のインクリメント • - : ポインタの指す値のデクリメント • [ : ループ始点 • ] : ループ終点 (ポインタの指す値が0以外なら対応する[へジャンプ) • . : ポインタの指す値を出力 • , : 入力をポインタの指す場所に書き込む
  29. 対応するマクロ • > : ip • < : dp •

    + : ic • - : dc • [ : bn • ] : ed • . : pr • , : ???
  30. Brainfuckをマクロに変換 変換前  >++++[-<++++++++>]<+. 変換後  `'ip`'ic`'ic`'ic`'ic`'bn(``'dc  `'dp`'ic`'ic`'ic`'ic`'ic`'ic  `'ic`'ic`'ip')`'ed`'dp`'ic`'pr

  31. 変換 define(`token', `changequote({,})ifelse( {$1}, {>}, {`'ip}, {$1}, {<}, {`'dp}, {$1},

    {+}, {`'ic}, {$1}, {-}, {`'dc}, {$1}, {.}, {`'pr}, {$1}, {[}, {`'bn(`}, {$1}, {]}, {')`'ed}){}changequote') define(`parse', `ifelse( eval(len(`$*')>0), 1, `token(substr(`$*',0,1))`'parse(substr(`$*',1))')') define(`internal', parse(include(`/dev/stdin')))
  32. ポインタの実装 define(`ptr', `0') 初期値0として定義 define(`ip', `define(`ptr', incr(defn(`ptr')))`'') ptrの定義をincrした値でptrを再定義 define(`dp', `define(`ptr',

    decr(defn(`ptr')))`'') ptrの定義をdecrした値でptrを再定義
  33. 配列の実装 M4には配列がない… そこで、 “_0_”, “_1_”, “_2_”, … を配列とする 値の書き込み define(`_’defn(`ptr’)`_’,

    1) 値の取り出し defn(`_’defn(`ptr’)`_’) ⇒ “1”
  34. 配列の値の操作の実装 define(`cv', `eval(defn(`_'defn(`ptr')`_')+0)') ポインタの指す値を取り出す define(`ic', `define(`_'defn(`ptr')`_', incr(cv))`'') cvで取り出した値をincrして再定義 define(`dc', `define(`_'defn(`ptr')`_',

    decr(cv))`'') cvで取り出した値をdecrして再定義
  35. ループの実装 define(`bn', `pushdef(`s', `ifelse(eval(cv>0), 1, `$1`'s')')') 次のようなマクロ s を定義 cvの値が0以上のとき

    引数の文字列をまるごと展開 s自身を再帰呼出し define(`ed', `s`'popdef(`s')') bnで定義された s を展開
  36. 出力の実装 define(`pr', `format(`%c', cv)') cvで取り出した値をフォーマットして出力

  37. 入力は? 標準入力はBrainfuckコードの入力 このままでは “,” を実装できない

  38. 入力は? 標準入力はBrainfuckコードの入力 このままでは “,” を実装できない “A”が入力したければ “+”を65回書けばいいじゃない ⇒ “,”は実質不要

  39. 詳しく見たい人は… GitHubにて公開しているのでどうぞ https://github.com/makiuchi-d/bfm4 もし技術書典3に参加されるなら… 「い03企」にて掲載本頒布予定 (後日web配信も計画中)

  40. ありがとうございました。

  41. None
  42. 実際問題使えるの?

  43. None
  44. スクフェスモブキャラ相関図

  45. スクフェスモブキャラ相関図 https://github.com/makiuchi-d/mob-graph • m4スクリプトでdotスクリプトを生成 • graphvizでグラフ化