Schemeの開発環境

Windowsの再セットアップに伴い、Scheme環境もインストールしなおした。
この機会に備忘録をば。
ちなみに、ほぼhttp://kayui.blog38.fc2.com/blog-entry-45.htmlのコピペ。
emacsとかあんまし慣れてないんで、間違いとかあったらツッ込んでください、口汚く罵ってください。

必要なもの

使おうとしているScheme処理系のGaucheは、Unix向けのソースしかないらしいので、ビルドするためにCygwinが必要。
http://www.cygwin.com/

  • slib

Scheme用のライブラリ。どんなライブラリなのかは知らん。
http://swiss.csail.mit.edu/~jaffer/SLIB

Gaucheソースコード
http://practical-scheme.net/gauche/index.html

お好みでおk。自分は(無理に)emacsを。
秀丸とかサクラエディタとかでも、インタプリタの設定ができればいいのかな。(よくわからん

導入の手順

gaucheコンパイルのためにmakeが必要になるのでcygwinインストーラでdevel -> makeをチェックしておくこと。
インストールが終わったら、C:\cygwin\binにパスを通しとく。
(C:\cygwinにインストールしたと仮定して進める。違う人は適当に読み替えるべし)

  • slib解凍

/usr/share/slib直下にalist.scmとかalist.txiとかがある状態。
Windows上ではC:\cygwin\usr\share\slibになる。
Cygwin Bash Shellを実行する場合は、C:\cygwinがルートに相当する。

Gaucheのソースをどこか適当に解凍。
Cygwin Bash Shellにて解凍したディレクトリに移動し、

configure --enable-multibyte=utf-8 --with-slib=/usr/share/slib --with-iconv=/usr/lib
make
make install

を順に実行。

  • emacsをインストール(emacs使う人だけ)

適当にやってちょ。

emacsはHOME環境変数に設定されているフォルダにある.emacs.elというファイルから個人設定を読もうとするらしい。
だもんで、まず適当にディレクトリ作ってHOMEに設定。
んで、その中に.emacs.elっていうファイルを作って、以下のelispソースコードをコピペして保存。

;; Gaucheのデフォルトエンコーディングに合わせます。
;; Gaucheのデフォルトエンコーディングがeuc-jpの時はutf-8をeuc-jpに
;; してください。
(setq process-coding-system-alist
      (cons '("gosh" utf-8 . utf-8) process-coding-system-alist))
;; goshインタプリタのパスに合わせます。-iは対話モードを意味します。
(setq gosh-program-name "C:/cygwin/usr/local/bin/gosh -i")
;; schemeモードとrun-schemeモードにcmuscheme.elを使用します。
(autoload 'scheme-mode "cmuscheme" "Major mode for Scheme." t)
(autoload 'run-scheme "cmuscheme" "Run an inferior Scheme process." t)
;; ウィンドウを2つに分け、一方でgoshインタプリタを実行するコマンドを定義します。
(defun scheme-other-window ()
  "Run scheme on other window"
  (interactive)
  (switch-to-buffer-other-window
   (get-buffer-create "*scheme*"))
  (run-scheme gosh-program-name))
;; そのコマンドをCtrl-cSで呼び出します。
(define-key global-map
  "\C-cS" 'scheme-other-window)

;; 直前/直後の括弧に対応する括弧を光らせます。
(show-paren-mode)

;; 以下はインデントの定義です。
(put 'and-let* 'scheme-indent-function 1)
(put 'begin0 'scheme-indent-function 0)
(put 'call-with-client-socket 'scheme-indent-function 1)
(put 'call-with-input-conversion 'scheme-indent-function 1)
(put 'call-with-input-file 'scheme-indent-function 1)
(put 'call-with-input-process 'scheme-indent-function 1)
(put 'call-with-input-string 'scheme-indent-function 1)
(put 'call-with-iterator 'scheme-indent-function 1)
(put 'call-with-output-conversion 'scheme-indent-function 1)
(put 'call-with-output-file 'scheme-indent-function 1)
(put 'call-with-output-string 'scheme-indent-function 0)
(put 'call-with-temporary-file 'scheme-indent-function 1)
(put 'call-with-values 'scheme-indent-function 1)
(put 'dolist 'scheme-indent-function 1)
(put 'dotimes 'scheme-indent-function 1)
(put 'if-match 'scheme-indent-function 2)
(put 'let*-values 'scheme-indent-function 1)
(put 'let-args 'scheme-indent-function 2)
(put 'let-keywords* 'scheme-indent-function 2)
(put 'let-match 'scheme-indent-function 2)
(put 'let-optionals* 'scheme-indent-function 2)
(put 'let-syntax 'scheme-indent-function 1)
(put 'let-values 'scheme-indent-function 1)
(put 'let/cc 'scheme-indent-function 1)
(put 'let1 'scheme-indent-function 2)
(put 'letrec-syntax 'scheme-indent-function 1)
(put 'make 'scheme-indent-function 1)
(put 'multiple-value-bind 'scheme-indent-function 2)
(put 'match 'scheme-indent-function 1)
(put 'parameterize 'scheme-indent-function 1)
(put 'parse-options 'scheme-indent-function 1)
(put 'receive 'scheme-indent-function 2)
(put 'rxmatch-case 'scheme-indent-function 1)
(put 'rxmatch-cond 'scheme-indent-function 0)
(put 'rxmatch-if  'scheme-indent-function 2)
(put 'rxmatch-let 'scheme-indent-function 2)
(put 'syntax-rules 'scheme-indent-function 1)
(put 'unless 'scheme-indent-function 1)
(put 'until 'scheme-indent-function 1)
(put 'when 'scheme-indent-function 1)
(put 'while 'scheme-indent-function 1)
(put 'with-builder 'scheme-indent-function 1)
(put 'with-error-handler 'scheme-indent-function 0)
(put 'with-error-to-port 'scheme-indent-function 1)
(put 'with-input-conversion 'scheme-indent-function 1)
(put 'with-input-from-port 'scheme-indent-function 1)
(put 'with-input-from-process 'scheme-indent-function 1)
(put 'with-input-from-string 'scheme-indent-function 1)
(put 'with-iterator 'scheme-indent-function 1)
(put 'with-module 'scheme-indent-function 1)
(put 'with-output-conversion 'scheme-indent-function 1)
(put 'with-output-to-port 'scheme-indent-function 1)
(put 'with-output-to-process 'scheme-indent-function 1)
(put 'with-output-to-string 'scheme-indent-function 1)
(put 'with-port-locking 'scheme-indent-function 1)
(put 'with-string-io 'scheme-indent-function 1)
(put 'with-time-counter 'scheme-indent-function 1)
(put 'with-signal-handlers 'scheme-indent-function 1)
(put 'with-locking-mutex 'scheme-indent-function 1)
(put 'guard 'scheme-indent-function 1)

これはhttp://karetta.jp/book-node/gauche-hacks/004682の内容そのまま。
これでC-c Sでインタプリタが起動したり、対応するカッコが分かりやすくハイライトされたり。
emacsemacs lispでもって自分の使いやすいようにいろいろカスタマイズできる。
たぶんこの辺をいじっていくことでemacsは手放せないエディタになるんだろうけど、自分はまだそこまで到達できてない。

以上でemacsを起動してC-c Sでウィンドウが分割、一方のウィンドウでgoshが走り出す。
あとはC-c C-lでschemeソースコードをロードしてやればインタプリタでテストできる。
こんな感じ。