Hatena::Groupcadr

わだばLisperになる このページをアンテナに追加 RSSフィード

2004 | 12 |
2005 | 01 | 02 | 07 | 10 | 11 |
2006 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2007 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2008 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2009 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2010 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2011 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 11 |

2010-05-12

SLIMEとLTDを使ってCLのコードをDylanに変換して表示する

| 19:06 | SLIMEとLTDを使ってCLのコードをDylanに変換して表示する - わだばLisperになる を含むブックマーク はてなブックマーク - SLIMEとLTDを使ってCLのコードをDylanに変換して表示する - わだばLisperになる

まったくもって誰も興味がなさそうなエントリーですが、LTDとSLIMEを組み合わせてみたら面白いかなと思い、組み合わせて遊んでみました。

LTDは、最近翻訳された「実用Common Lisp」の著者であるPeter Norvig氏が作成したCommon LispをDylanに変換するツールです。

SLIME

(defun random-string (&key (length 10) (set :lower-alpha))
  "Returns a random lower-case string."
  (declare (optimize (speed 3)))
  (let ((s (make-string length)))
    (declare (simple-string s))
    (dotimes (i length s)
      (setf (schar s i) (random-char set)))))

のようなCLのコード上でslime-ltdすると

// LtD

define method random-string (#key length = 10, set = #"lower-alpha")
  // Returns a random lower-case string.
  let s :: <simple-string> = make(<string>, size: length, fill: ' ');
  for (i from 0 below length) s[i] := random-char(set); finally s; end for;
end method random-string;

のように別枠のバッファにDylanに変換され表示されるようにします。

クレジットの箇所を読むと、LTDの元になったScott McKay氏の書いたlisp-to-dylan.lispはエディタのバッファを置き換えるというものだったらしいので、なんとなく逆行してしまっている気しますが、表示されたDylanのコードを眺めるのも面白いので、これはこれで良いかなと思います。

変換されたコードでは、きちんとコメントが反映されていたり、マクロは展開されたりします。

動かすのに必要なもの

  1. slime.el
  2. dylan-mode.el

他、ANSI CLで廃止になった記述等がありコンパイルできない箇所がある(SBCL)ので適当に直します。

  1. LTDはCL-USERパッケージを前提にしているので、ltdというパッケージを利用するように変更。
  2. read.lispのrecord-file-positionsの置かれている位置を利用している関数より先に持ってゆく
  3. loopの中で、by 'cddrというのを、by #'cddrに直す
  4. string-char型は廃止なので、characterに変更

SLIME側のコード
;; LtD 
(eval-after-load "slime"
  '(progn
     (defun slime-ltd (times)
       (interactive "p")
       (slime-eval-and-ltd
        `(swank:eval-and-grab-output
          ,(format "(WITH-INPUT-FROM-STRING (IN (PRIN1-TO-STRING '%s))(LTD::LTD-EXP IN *STANDARD-OUTPUT*))" 
                   (slime-defun-at-point)))))
     
     (defun slime-eval-and-ltd (form)
       (slime-eval-async form (slime-rcurry #'slime-show-ltd
                                            (slime-current-package))))
     
     (defun slime-show-ltd (string package)
       (slime-with-popup-buffer ("*SLIME LtD*" package t t)
         (dylan-mode)
         (princ "// LtD")
         (terpri)
         (terpri)
         (princ (first string))
         (goto-char (point-min))))
     
     ;; SUPER-SHIFT-D
     (define-key slime-mode-map
       [(super shift ?d)] 'slime-ltd)))

ゲスト



トラックバック - http://cadr.g.hatena.ne.jp/g000001/20100512