Simple Scheme interpreter in Perl

昨日 Brainfuckを書いてみたので、今日は Scheme(Lisp)の処理系を書いてみました。
当然本格的なものではなく、簡単なものです。


Lispy: Scheme Interpreter in Python


Perl版になります。


kidd/hascheme · GitHub


に lis.pyにインスパイアされて書いたという Scheme in Perlがあったの
ですが、本格的な感じだし、いろいろモジュール使いまくっていたので、
とりあえず元のものに忠実に作ってみました。

コード

実行

ファイルを標準入力にリダイレクトした場合、元の式と結果を表示するように
してみました。Schemeとは若干挙動が違うものがあるようにも思えますが、
lis.pyと同じように動作していると思われます。

% perl lis.pl < test.txt
12345678 => 12345678
(quote 12345678) => 12345678
(quote lispl) => lispl
(quote (a b c)) => (a b c)
(+ 1 2 3 4 5 6 7 8 9 10) => 55
(- 2 1 0) => 1
(* 3 3 3) => 27
(/ 50 5 10) => 1
(not 0) => 1
(> 1 2) => 0
(< 3 1) => 0
(>= 1 1) => 1
(<= 2 2) => 1
(= 10 10) => 1
(equal? (quote aaa) (quote aaa)) => 1
(equal? 100 80) => 0
(length (quote aaa)) => 3
(length (quote (a b c d e))) => 5
(car (quote (a b))) => a
(cdr (quote (a b))) => (b)
(append (quote (a b)) (quote c) (quote d) (quote (e f))) => (a b c d e f)
(list 1 2 3 4 5 (quote (a b c)) 6 7 8 9 10) => (1 2 3 4 5 (a b c) 6 7 8 9 10)
(list? 1) => 0
(list? (quote (1))) => 1
(null? (quote ())) => 1
(null? (quote (1))) => 0
(null? 10) => 0
(symbol? 10) => 0
(symbol? (quote a)) => 1
(if (- 10 5) (quote then) (quote else)) => then
(if 0 (quote then) (quote else)) => else
(set! var (quote lispl)) => var
var => lispl
(define myadd (lambda (a b) (+ a b))) => CODE(0x11ff1f8)
(myadd 10 20) => 30
(begin (define mylist (lambda (a) (list var a))) (mylist var)) => (lispl lispl)
(not-defined a b) ===>  Not found symbol 'not-defined'

) ===>  unexpected ')'

var => lispl

おわりに

PythonRuby版の実装と違って、簡潔さが欠けているように思えますが、
それは Perlのせいではなく、私の実力不足によるものです。賢い人なら
もっとエレガントに書けると思います。


Rubyにおける NendoJavaにおける Clojureのように
Perlと親和性の高い Lispなんてものがあると面白いのかなぁと思いました。
誰か実装しないだろうか・・・。