秀丸マクロで Brainf*ck #2
とりあえず現時点のマクロを晒しときますか。
// Brainf_ck.mac 1.09 // Copyright (C) 2003-2008 Satoshi Ogata // satosystems@gmail.com // // [usage] // Brainf*ck のスクリプトを開いた秀丸でこのマクロを実行するか // 実行したいスクリプト箇所を選択してこのマクロを実行します。 // スクリプト中では Brainf*ck に使用する 8 種類のキャラクタ以外は // 無視されます。 // また、# から行末までは完全に無視されますが、debug フラグが // true の場合は、# を読み取ったタイミングでデバッグ用ダイアログが // 表示されます。 // 最初の行に # debug=on があれば、デバッグフラグが ON になります。 // 最後の結果出力で「はい」を選択すると、結果をクリップボードにコピーします。 // // [history] // 1.09 結果をクリップボードにコピーするかどうかを問い合わせるように機能追加。 // 1.08 スクリプト上でデバッグの ON/OFF を選択できるように機能追加。 // 1.07 選択範囲外まで計算してしまう不具合を修正。 // 1.06 エディタ上をカーソルが移動するように実装変更。 // 1.05 デバッグ処理の実装。 // 1.04 バッファ内の数値の扱い方の不具合修正。 // 1.03 選択領域による部分的な実行。 // 1.02 入力の不具合修正。 // 1.01 ループの不具合修正。 // 1.00 完成。 // // [specification] // > ポインタを1進める // < ポインタを1戻す // + ポインタの指す要素の値を1増やす // - ポインタの指す要素の値を1減らす // . ポインタの指す要素の値を外に出力 // , 外から値を入力して、 ポインタの指す場所へ入れる // [ ポインタの指す要素の値が 0 だったら対応する次の ] までジャンプ // ] 対応する前の [ までジャンプ #debug = false; if (selecting) { #selecting = true; #selendx = selendx; #selendy = selendy; escape; moveto seltopx, seltopy; } else { gofiletop; } while (true) { if (code == '>') { #ptr = #ptr + 1; if (#debug) { if (#ptr > #max) #max = #ptr; } } else if (code == '<') { #ptr = #ptr - 1; } else if (code == '+') { #c[#ptr] = #c[#ptr] + 1; if (#c[#ptr] > 127) { #c[#ptr] = -128; } } else if (code == '-') { #c[#ptr] = #c[#ptr] - 1; if (#c[#ptr] < -128) { #c[#ptr] = 127; } } else if (code == '.') { $out = $out + char(#c[#ptr]); } else if (code == ',') { if ($in == "") { $in = input("Input ascii charactor"); $s = $in; } if ($s == "") { break; } #c[#ptr] = ascii($s); $s = rightstr($s, strlen($s) - 1); } else if (code == '[') { if (#c[#ptr] == 0) { #n = 0; while (true) { right; if (code == '[') { #n = #n + 1; } else if (code == ']') { if (#n == 0) { break; } #n = #n - 1; } } } } else if (code == ']') { #n = 0; while (true) { left; if (code == '[') { if (#n == 0) { left; break; } #n = #n + 1; } else if (code == ']') { #n = #n - 1; } } } else if (code == eof) { break; } else if (code == '#') { if (!#checked) { #checked = true; $s = gettext(x, y, linelen2, y); if (strstr($s, "debug=on") != -1) { #debug = true; debuginfo 1; } } if (#debug) { #j = 0; $msg = "#ptr:" + str(#ptr) + " #c[" + str(#ptr) + "]=" + str(#c[#ptr]); while (#j <= #max) { if (#j % 8 == 0) { $msg = $msg + "\n"; } else { $msg = $msg + " "; } $msg = $msg + "[0x" + hex(#c[#j]) + ":" + str(#c[#j]) + "]"; #j = #j + 1; } golineend; beginsel; golinetop2; endsel; debuginfo $msg; } golineend2; } else { // それ以外は無視する } if (#selecting && (y > #selendy || y >= #selendy && x >= #selendx)) { break; } right; } question $out; if (result) { setclipboard $out; }
このマクロは処理速度を追求してなくて、Brainf*ck のコードをマクロが一生懸命処理している様を見て楽しむ、というのが正しい用法ですからねっ。
動かしてみよう
最初はもちろん「hello, world!」でしょう(Wikipedia より)。
+++++++++[>++++++++>+++++++++++> +++++<<<-]>.>++.+++++++..+++.>-. ------------.<++++++++.-------- .+++.------.--------.>+.
ピラミッドを作るコードです(どう書く?org より)。
入力ダイアログに一桁の数字を入れてね。
>++[-<+++++>]>++++++[-<+++++++>]>++++++++[-<++++>],>++++++++ [-<------>]<[->+>+<<]>>->>+<<<[->[->+<<<<.>>>]>[-<+>]<->>- [->+<<<<<<<..>>>>>>]<<<<<<.>>>>>>>[-<+>]<++<<<<<<<.>>>>]
最後に紹介するのは、僕が動かした中でもっとも時間のかかる Brainf*ck コードです。
大文字を小文字に変換します(k.inaba さんの Brainf*ck より)。
あらかじめ伝えておくと、このコードで HOGE を hoge に変換するのに、僕のマクロだと 5 分ぐらいかかるからね。しかも CPU 100% 使うよ。欲張って長い文字列を入力すると夜が明けてしまうからね。
でも、Esc でいつでもやめられるから安心してね。
>>++++++++[->++++++++<]>>>>+++++++++[->++++++++++<]>[<<,[->+<<+<<+>>>]<<<[ ->>>+<<<]>>>>>[->+>>+<<<]>[<<[->+>>+<<<]>>>[-<<<+>>>]<<[[-]<->]>-]>>[-<<<+ >>>]<<<<<<<[-<+<<+>>>]<[>>[-<+<<+>>>]<<<[->>>+<<<]>>[[-]>-<]<-]<<[->>>+<<< ]>>>>><[[-]>++++++++++++++++++++++++++++++++>[[-]<------------------------ -------->]<<]>>[-]<.>>]
YouTube に動画を上げてみたよ。