Home > ブログ > GolangでのLISPインタプリタ実装

ブログ

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

タグ: プログラミング Golang

Top

アーカイブ

タグ

Server (28) 作業実績 (21) PHP (19) ネットワーク (17) プログラミング (15) OpenSSL (10) C (8) C++ (8) PHP関連更新作業 (8) EC-CUBE (7) Webアプリ (7) laravel (6) 書籍 (5) Nginx (5) Linux (5) AWS (4) Vue.js (4) JavaScript (4) 与太話 (4) Rust (3) Symfony (2) お知らせ (2) Golang (2) OSS (1) MySQL (1) デモ (1) CreateJS (1) Apache (1)