ファイルダンププログラムを clisp でも作成してみた。emacs の初期設定すらもままならない僕にはやはりかなりハードルが高かった。出来上がったソースは lisp らしくないのかもしれないが、とりあえずはじめの一歩を記すことができた。以下、躓いたところを列挙。
- 本みて理解しているつもりでも、cons,list,push が解ってなかった。目的をもってREPLで試すと少し理解が深まった。
- どの言語もそうだけれど、1バイト単位の処理方法に意外と苦労する。今回は element-type,read-byte,code-char,char-code の組み合わせかな。
- while はマクロで実現されているので、自分でマクロを組まなければいけないらしい(初心者には荷が重いので loop に書き換えた)。
- return は、break のようなもので、二重ループを一気に抜け出たりはしてくれないらしい。
- format は、独特な世界観で、なかなか覚えられない。そもそもlisp は関数の名前が長めのが多い。
出来上がってみれば、他の言語同様の構造で(lispらしくない?)どこに詰まったのかと思うところが悲しい。
(defun hdmp(adr line len)
(format t "~8,'0x: " adr)
(mapc (lambda(c) (format t "~2,'0x " c)) (reverse line))
(setq zan (- 16 len))
(if (> zan 0)
(dotimes(i zan) (princ " "))))
(defun cdmp(adr line len)
(princ "| ")
(mapc (lambda(c)
(if (or (< c 32) (>= c 127))
(format t ".")
(format t "~a" (code-char c))))
(reverse line))
(setq zan (- 16 len))
(if (> zan 0)
(dotimes(i zan) (princ " ")))
(princ " |")
(fresh-line))
(defun dump(name)
(with-open-file (in name :direction :input :element-type 'unsigned-byte)
(setq adr 0)
(setq cnt 0)
(setq line nil)
(loop
(setq c (read-byte in nil nil))
(if (equal c nil) (return t))
(if (> cnt 15)
(progn
(hdmp adr line cnt)
(cdmp adr line cnt)
(setq adr (+ adr cnt))
(setq cnt 0)
(setq line nil)))
(push c line)
(setq cnt (1+ cnt)))
(if (> cnt 0)
(progn
(hdmp adr line cnt)
(cdmp adr line cnt))))
0 件のコメント:
コメントを投稿