PLAI by Shriram Krishnamurthiを5章まで読んだ
「Programming Languages: Application and Interpretation by Shriram Krishnamurthi」というPDFを読んでいます。http://cs.brown.edu/~sk/Publications/Books/ProgLangs/
これは、言語処理系に関する本のようです。インターネットで調べたところCPS変換についても詳しく書かれているようです。
使用するプログラミング環境はRacketで、言語はplai-typedという型付きのSchemeのような言語です。本の題名を略すとPLAIとなるので、そこから名付けているのだと思います。LISPの基本が理解できれば、読んでいくうちにわかるので、plai-typedについての知識は全く必要ありません。
わかりやすい英語で書かれていて、英語の苦手な僕でも、辞書を引きながら読み進むことができています。普段、英語をあまり読まないので、とても勉強になっています。
5章までで、以下の簡単なインタープリタを作成します。
#lang plai-typed (define-type ExprC [numC (n : number)] [idC (s : symbol)] [appC (fun : symbol) (arg : ExprC)] [plusC (l : ExprC) (r : ExprC)] [multC (l : ExprC) (r : ExprC)]) (define-type FunDefC [fdC (name : symbol) (arg : symbol) (body : ExprC)]) (define (subst [what : ExprC] [for : symbol] [in : ExprC]) : ExprC (type-case ExprC in [numC (n) in] [idC (s) (cond [(symbol=? s for) what] [else in])] [appC (f a) (appC f (subst what for a))] [plusC (l r) (plusC (subst what for l) (subst what for r))] [multC (l r) (multC (subst what for l) (subst what for r))])) (define (get-fundef [n : symbol] [fds : (listof FunDefC)]) : FunDefC (cond [(empty? fds) (error 'get-fundef "reference to undefined function")] [(cons? fds) (cond [(equal? n (fdC-name (first fds))) (first fds)] [else (get-fundef n (rest fds))])])) (define (interp [e : ExprC] [fds : (listof FunDefC)]) : number (type-case ExprC e [numC (n) n] [idC (_) (error 'interp "shouldn't get here")] [appC (f a) (local ([define fd (get-fundef f fds)]) (interp (subst a (fdC-arg fd) (fdC-body fd)) fds))] [plusC (l r) (+ (interp l fds) (interp r fds))] [multC (l r) (* (interp l fds) (interp r fds))]))
以下のように実行します。
> (define double (fdC 'double 'x (plusC (idC 'x) (idC 'x)))) > (interp (appC 'double (numC 3)) (list double)) - number 6