3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

自作Lispにtcl/tk GUIを組み込んだ話

Last updated at Posted at 2022-07-12

特別休暇

ずっと働き詰めでした。たまには自分にお休みを与えてもいいと思いました。夏季臨時休暇を利用してtcl/tkを、自作Lisp Easy-ISLisp(以下、EISL)にライブラリとして組み込みました。

C言語方式

Common-Lispのtcl/tkライブラリを調べてみますと、wishをプロセス間通信で呼び出す方式と、C言語で直接呼び出す方式があるようです。M.Hiroiさんのtcl/tkのページにはC言語で呼び出す方法が説明されていました。(M.Hiroiさんのページ)http://www.nct9.ne.jp/m_hiroi/tcl_tk_doc/tcltk305.html EISLのCラッパーの機能を利用、C言語を介して呼び出す方式としました。例えばcanvasを呼び出す関数は次のようになっています。

(defun tk::canvas (obj :rest l)
  (let ((opt (tk::option l)))
    (c-lang 
      "strcpy(buff,''canvas .'');
       strcat(buff,str_to_lower(Fgetname(OBJ)));
       strcat(buff,Fgetname(OPT));
       strcat(buff,''\n'');
       Tcl_Eval(interp,buff);")))   

ライブラリは予めコンパイルしておく必要があります。

(compile-file "library/tcltk.lsp")

再帰図形

おおよそ必要な関数が揃いましたので、再帰図形を描かせてテストすることとしました。シェルピンスキーのギャスケットです。

コードは次のようになります。


(import "tcltk")

(defun recur ()
    (tk::init)
    (tk::canvas 'c0 '-width 600 '-height 600)
    (gasket #(300 0) #(0 600) #(600 600) 10)
    (tk::pack 'c0)
    (tk::mainloop))

(defun midpoint (a b)
   (let ((a0 (elt a 0))
         (a1 (elt a 1))
         (b0 (elt b 0))
         (b1 (elt b 1)))
      (vector (+ (min a0 b0) (abs (quotient (- a0 b0) 2)))
              (+ (min a1 b1) (abs (quotient (- a1 b1) 2))))))
      

(defun draw-triang (a b c)
   (let ((a0 (elt a 0))
         (a1 (elt a 1))
         (b0 (elt b 0))
         (b1 (elt b 1))
         (c0 (elt c 0))
         (c1 (elt c 1)))
      (tk::create 'c0 (line a0 a1 b0 b1 c0 c1 a0 a1) '-fill 'green)))

(defun gasket (a b c n)
    (cond ((= n 0) t)
          (t
            (draw-triang a b c)
            (draw-triang (midpoint a b) (midpoint b c) (midpoint c a))
            (gasket a (midpoint a b) (midpoint a c) (- n 1))
            (gasket (midpoint a b) b (midpoint b c) (- n 1))
            (gasket (midpoint a c) (midpoint b c) c (- n 1)) )))

これを読み込んで(recur)関数を実行するとあのシェルピンスキーの再帰図形が現れます。

Screenshot at 2022-07-12 12-35-08.png

再帰図形の思い出

初めてこの手の再帰図形を見たのはウインストンのLISP本でした。c-curveを描くものでした。昭和58年ころのことでした。あれから40年ほど経過し世の中も変わりました。当時は記号処理のできる言語というとLispくらいしかありませんでした。今やPythonやら、Rubyやらテンコ盛りです。それにしてもLispで書かれたgasketのコードを眺めてると再帰にもっとも馴染んでる言語は今でもlispではないかと思います。

bandicam 2022-07-12 16-00-33-595.jpg

ドキュメントなど

EISLはOSSです。Githubにて公開しています。ライブラリの使い方についてはdocumentフォルダーの中のTCLTK.mdにあります。追々、記述を充実させていく予定です。

3
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?