y2q_actionman’s ゴミクズチラ裏

内向きのメモ書きを置いてます

ネタマクロ with-c-syntax の最近の更新

この文章は、 lisp Advent Calendar 2018 - Qiita の 12/9 分の記事として書かれました。

昔書いた with-c-syntax というネタマクロを、最近また少し更新したので簡単にご紹介です。

このライブラリ自体は quicklisp に入っていますが、ここで紹介する機能の半分はまだ最新の quicklisp release に反映されていません。 もし試したいという奇特な方がいましたら、直接ロードしてみてください。

github.com

リーダーマクロだけで動くように

Lisp の構文と C言語の構文とは当然違うため、山のようにエスケープを積む必要があったのですが、#{ というリーダーマクロに一本化しました。

;; リーダーマクロ有効化
(named-readtables:in-readtable with-c-syntax:with-c-syntax-readtable)
CL-USER> #{ format (t, "Hello World!"); }#
Hello World!
NIL

任意のフォームの中でも使える

  (named-readtables:in-readtable with-c-syntax:with-c-syntax-readtable)

  (defun array-transpose (arr)
    (destructuring-bind (i-max j-max) (array-dimensions arr)
      #{
        int i,j,temp;
        for (i = 0; i < i-max; i ++) {
            for (j = i + 1; j < j-max; j ++) {
                temp = arr[i][j];
                arr[i][j] = arr[j][i];
                arr[j][i] = temp;
                // pprint (arr) ;
            }
        }
      }#)
    arr)

  (array-transpose (make-array '(3 3)
        :initial-contents '((0 1 2) (3 4 5) (6 7 8))))
  ; => #2A((0 3 6) (1 4 7) (2 5 8))

関数定義もできる

  (named-readtables:in-readtable with-c-syntax:with-c-syntax-readtable)

  #{
  int sum-of-list (list) {
    int list-length = length(list);
    int i, ret = 0;

    for (i = 0; i < list-length; ++ i) {
       ret += nth(i, list);
    }

    return ret;
  }
  }#

  (sum-of-list '(1 2 3 4 5 6 7 8 9 10)) ; => 55

まとめ

当然ながらネタマクロなので本気プログラミング用では全然ないです。