はじめに
ISLisp規格はとてもコンパクトで洗練されています。小さなコードを書く分にはこれで全く問題ありません。しかし、コンパイラのように数千行、1万行ともなるとモジュールがあった方が便利です。モダンな言語仕様のElixirにヒントを得て次のようなことを考えています。
アイディア
file "tests/module.lsp"
(defmodule foo
(defglobal a 3)
(defpublic bar (x)
(+ (boo x) (gfib x)))
(defun boo (x)
(+ x a))
(defpublic baz (x)
(uoo x))
(defmacro uoo (x)
`(+ ,x ,x))
(defgeneric gfib (n)
(:method ((n <integer>)) (cond ((= n 1) 1)
((= n 2) 1)
(t (+ (gfib (- n 1)) (gfib (- n 2)))) )))
(defpublic fact (n)
(if (= n 0)
1
(* n (fact (- n 1)))))
)
Easy-ISLisp Ver1.72
> (load "tests/module.lsp")
T
> (bar 10)
68
> (baz 10)
20
> (uoo 2)
Unbound function at eval UOO
debug mode ?(help)
>>:q
Easy-ISLisp Ver1.72
> (fact 10)
3628800
>
外部からはdefpublicで定義した関数だけが参照できます。booはプライベートです。大域変数の宣言、 (defglobal x n) はプライベートにし外部からは参照不可とします。動的変数 (defdynamic x n) も同様です。
実装
実験的にEasy-ISLispのインタプリタに実装してあります。
https://github.com/sasagawa888/eisl
コンパイラを単純にするために名前空間を探索するハッシュテーブルは今まで通りにします。単に関数名、変数名に接頭辞を付加する方式にします。上記の例ですと関数booはfoo::booです。