GolangでのLISPインタプリタ実装
外出自粛で土日も家にいるので、GoでLISPインタプリタの実装をしてみました。
https://github.com/kztomita/golisp
たまにはGoを使わないと忘れそうなのと、Go言語でつくるインタプリタに触発されたのもあります。
現状、扱える値は整数と実数のみで分数や複素数などは扱えないのと、使用可能な関数も限られています。
レキシカルスコープは実装しているので関数の再帰呼び出しは可能です。
フィボナッチ数
$ go run golisp.go
#[1] (defun fib (n)
(if (or (= n 0) (= n 1))
n
(+ (fib (- n 2))
(fib (- n 1)))))
nil
#[2] (fib 0)
0
#[3] (fib 1)
1
#[4] (fib 5)
5
一応、マクロも実装しました。
マクロの例
$ go run golisp.go #[1] (defmacro inc (var) (list 'setq var (list '+ var 1))) nil #[2] (setq a 1) nil #[3] (inc a) nil #[4] a 2
Go実装なので、Goから簡単にインタプリタを呼び出して組み込み言語のように使うこともできます。
package main
import (
"fmt"
"log"
"github.com/kztomita/golisp/interpreter"
)
func main() {
// LISP構文を字句解析、構文解析して構文木を構築
node, err := interpreter.Parse("(+ 1 2)")
if err != nil {
log.Fatalf("%v\n", err)
}
// 作成した構文木を評価
ev := interpreter.NewEvaluator()
result, err := ev.Eval(node)
if err != nil {
log.Fatalf("%v", err)
}
fmt.Println(result.ToString());
}
LISPに関しては「LISP完全に理解した」レベルの知識しかないので、おかしな動作をしている点もあるかもしれません。当面外出自粛は続きそうなので、インタプリタの実装を続けて遊んでみようと思います。
投稿日:2020/04/20 22:50