プログラミング原人の進化ログ

プログラミング原人の進化論

オレ プログラミング ベンキョウ スル。マナンダ コト カク。

「プログラミング言語の基礎概念」のためのEmacsメジャーモードを書いた

プログラミング言語の基礎概念」の演習システムのためのメジャーモードを作ってみました。 ソースコードと、実際に利用するまでの流れを書いておきます。

環境

GNU Emacs 26.1

動機

プログラミング言語の基礎概念」(五十嵐淳著)という、とても良い本があります。何が良いかというと、計算理論の初学者にとってわかりやすく書かれている(まだ最初の方しか読んでないが)ことと、この本に対応するオンライン演習システムが利用できることです。

演習システムに回答する際に導出木を書く必要があるのですが、当然そのまま入力することができません。そこで、導出木を適切な形式(補助資料によればASCII表記)に直してあげる必要があります。

Emacsで書こうにも、対応するメジャーモードが見つかりません。しかし、ペアノ自然数は人間が入力するには厳しいものがあります。

じゃあ、自分でメジャーモード作ろう。

メジャーモードを作成

generic mode を使ってメジャーモードを作ることができます。init.elなどに

(require 'generic-x)

と書き、続いてメジャーモードを定義していくという流れになります。
generic mode の使い方はこちらに書かれています。

これを利用してメジャーモードascii-expression-modeを定義しました。init.elなどに次のコードを追加します。

(require 'generic-x)
;; define major mode
(define-generic-mode 'ascii-expression-mode
  ;; comments
  '("//")
  ;; keywords
  '("plus" "times" "is" "by" "evalto" "--->" "-*->" "-d->" "|-" "->" "==>" "=>" ">>")
  ;; faces
  nil
  ;; files for which to activate this mode
  '("\\.as$")
  ;; other function to call
  '(define-as-keymap)
  ;; description for this mode
  "Major mode for ASCII expression, which is used in COPL."
  )

(global-set-key (kbd "s-z") nil)

(defun define-as-keymap ()
  "This function define local keymap for ascii-expression-mode."  ;; doc string
  ;; insert "S()"
  (local-set-key (kbd "s-s") '(lambda ()
                                (interactive)
                                (insert "S()")
                                (backward-char)))
  ;; insert "Z"
  (local-set-key (kbd "s-z") '(lambda ()
                                (interactive)
                                (insert "Z"))))

ascii-expression-mode の説明

  • asという拡張子をつけたファイルを開くと今回定義したascii-expression-modeが起動します。

  • 次のようなコマンドが使えます。

    • Super + s:S()を挿入し、かっこ内にカーソルを移動します。
    • Super + z:'Z'を挿入します。

S()の次のZを入力するときに、右手をSuperキーからShiftキーに移すのがストレスだったのでこのようなコマンドを作りました。

有効化とテスト

通常、どのファイルを開いたときにメジャーモードを有効化するかを指定するには(add-to-list 'auto-mode-alist '(""\\.hoge\\'" . hoge-mode))とする必要があるのですが、上のように generic mode で拡張子を指定した場合、このような記述が必要ありません。つまり、ascii-expression-modehoge.asと言ったファイルを開くと既に起動するようになっているはずです。

それではきちんと動くかどうかテストしてみます。

Emacs.asファイルを開き、モードラインにAscii-Expressionと表示されていたら成功です。

まとめ

簡易的なメジャーモードを作ったので、そのメモです。インデントは難しくてまだ着手していませんが、作ると捗りそうなのでやってみたいと思います。
ていうか、証明すべき命題を与えたら導出木を出力するプログラムを書いた方が早そうですね。

参考

EmacsWiki: Generic Mode