2

Emacs Lisp で反復タスクを実行するマクロの小さなシステムを作成しようとしています。whileループの先には何もないことを当然のことと思っていました。プリミティブや隠された機能はもうありませんが、私は尋ねたほうがよいと判断しました。

「隠れた機能」とはtagbody、Common Lisp に似たもの、つまり、ブロック、ジャンプ、およびラベルに関してコードをモデル化するための非常に原始的な形式を意味します。eLispにそのようなものはありますか? たとえば、バイトコードを使用するなど、「ハック」の方法でさえありませんか? もちろん、私は(catch ... (throw ... ))コンストラクトについて知っていますが、「後方へ」のジャンプのみを許可し、前方へのジャンプは許可しないため、まったく同じではありません。また、これはかなり複雑な構造であり、高速反復プリミティブの構築には適していないと想定しました。

私を悩ませているもう 1 つのことは、ハッシュ テーブルのイテレータを作成する方法がないように見えることです。つまり、ハッシュテーブルは を使用して反復する必要があり、関数maphashを終了すると、終了maphashした場所に戻ることはありません。これまでのところ、キーのベクトルと値のベクトルをエクスポートしてこれらを反復処理する必要があることを理解していますが、これらのベクトル/リスト/それらが何であれ、それらを取得する方法はないようです. それともまた間違っていますか?

clpackage がloopand dotimes/ dolist/のコードを生成する方法を調べましたが、 orの適切な方をdo使用するだけで、率直に言って、私はそれらのコードがあまり好きではありません... 2 つの句があり、最初の句は無視され (警告も表示されません)、2 番目の句のコードが生成されます:|whilemaphashloopfor-as-hash

これらの反復プリミティブを eLisp のユーザー コードから取得するためのトリックがある可能性はありますか? そうでない場合、C で拡張機能を作成することはどの程度実現可能で、実際に可能でしょうか?

4

2 に答える 2

3

tagbodyマクロとして次のことができます。

   (defmacro cl-tagbody (&rest tags-or-stmts)
     (let ((blocks '()))
       (let ((block (list 'cl--preamble)))
         (dolist (tag-or-stmt tags-or-stmts)
           (if (consp tag-or-stmt) (push tag-or-stmt block)
             ;; Add a "go to next block" to implement the fallthrough.
             (push (nreverse (cons `(go ,tag-or-stmt) block)) blocks)
             (setq block (list tag-or-stmt))))
         (push (nreverse (cons `(go cl--exit) block)) blocks))
       (let ((catch-tag (make-symbol "cl--tagbody-tag")))
         (macroexpand-all
          `(let ((next-tag 'cl--preamble))
             (while
                 (not (eq (setq next-tag
                                (catch ',catch-tag
                                  (cl-case next-tag
                                    ,@blocks)))
                          'cl--exit))))
          `((go . (lambda (tag) `(throw ',catch-tag ',tag)))
            ,@macroexpand-all-environment)))))
于 2012-12-04T14:20:07.140 に答える
2

1.他のループ構造?

Emacs Lispに組み込まれている唯一の汎用ループ構造はwhile(を参照eval.c)です。マクロdolistdotimesinsubr.el)は、どちらも。を使用して実装されwhileます。

さまざまなデータ構造にマッピングするための組み込み関数もmapatomsありますmapc:、、、、、、、、および。しかし、これらは、実行を他のLispコードとインターリーブできないように実装されています(たとえばを参照)。このような2つのデータ構造をループする場合は、一方をループしてからもう一方をループする必要があります。mapcarmap-char-tablemapconcatmaphashmap-keymapmaphashfns.c

ですから、基本的には運が悪いと思います。

2.拡張機能?

Emacsは、動的なCレベルの拡張機能を持たないように意図的に設計されており、誰かがEmacsユーザーの自由を「受け入れて拡張」する攻撃を仕掛けるのをより困難にします(たとえば、ここから始まるemacs-develスレッドを参照)。

したがって、経営幹部レベルの機能を追加する場合は、ソースコードを編集する必要があります。幸運を!

于 2012-12-04T16:06:26.877 に答える