Schemeでシミュレーションの可視化がしたい。。。
というわけでグラフィックスのプログラムを準備していきます。奥村さんの本でビットマップファイルを扱うプログラムがあるので、同様のことをSchemeでできるように頑張ります。奥村本p.63にはWindows BMP形式を扱うためのプログラムgrBMP.cがありますが、とりあえず今回はその中のputbytesという関数を実装します。
putbytesのやることはシンプルで引数xの末尾からnバイト分を出力します。
試しにx=1000の末尾4バイト分を出力してみます。
(define (putbytes f n x)
(use scheme.bitwise)
(do
([i 0 (+ i 1)])
([= n i] [print "=> Finished"])
(begin
(print (bitwise-and x 255))
(write-byte (bitwise-and x 255) f)
(set! x (arithmetic-shift x -8))
)
)
)
(define f1 (open-output-file "sample"))
(putbytes f1 4 1000)
(close-output-port f1)
実行結果は次の通りです。
> gosh .\main.scm
232
3
0
0
=> Finished
1000は2進数で表すと 000000 000000 00000011 11101000 となるので、末尾から8桁ずつ取り出す操作は当然1バイトずつ取り出す操作と同じことになります。11101000は10進数で232、00000011は10進数で3なので、ちゃんと末尾から出力できています。わーい。
そもそもなぜ末尾から出力する必要があるかというと、どうやらBMP形式はファイルタイプ以外の情報がリトルエンディアンで記録されるから*1、らしいです。なるほど。
以下、雑感。
- モジュールの書き方*2がこれであっているのかよくわからない。
- ビット演算はここを参考にしたが、特に支障なさそう。
- ファイル操作もリファレンスをちょっと見ただけで実はよくわかっていない。というか、わかっていないこと多すぎ。
- 時間あるときに入出力関係*3を簡単におさらいしたい。
今回はputbytesの実装をしましたが、これをどう使っていくかという話はまた次回以降していきたいです。