EoPL reading (142) 3.2 The Front End
アタマが違う方面に行ってるのですが、明日向けのリハビリ、という事で無理矢理手を動かしてみます。
Exercise 3.6
ええと、scan&parse ではなく parse-program 使います。例示されているナニ的には以下なカンジでしょうか。
gosh> (run '(minus (+ (minus 5) 9))) -4 gosh>
ええと、新たな primitive の追加については
- primitive な define-datatype への追加
- parse-expression 手続きへの追加
- apply-primitive 手続きへの追加
ってコトで、define-datatype が以下。
(define-datatype primitive primitive? (add-prim) (subtract-prim) (mult-prim) (incr-prim) (decr-prim) (print-prim) (minus-prim))
次。parse-expression 手続きが以下。
(define parse-expression (lambda (datum) (cond ((number? datum) (list 'lit-exp datum)) ((symbol? datum) (list 'var-exp datum)) ((pair? datum) (list 'primapp-exp (list (cond ((eq? '+ (car datum)) 'add-prim) ((eq? '- (car datum)) 'subtract-prim) ((eq? '* (car datum)) 'mult-prim) ((eq? 'add1 (car datum)) 'incr-prim) ((eq? 'sub1 (car datum)) 'decr-prim) ((eq? 'print (car datum)) 'print-prim) ((eq? 'minus (car datum)) 'minus-prim) )) (map (lambda (x) (parse-expression x)) (cdr datum)))))))
最後に apply-primitive が以下。
(define apply-primitive (lambda (prim args) (cases primitive prim (add-prim () (+ (car args) (cadr args))) (subtract-prim () (- (car args) (cadr args))) (mult-prim () (* (car args) (cadr args))) (incr-prim () (+ (car args) 1)) (decr-prim () (- (car args) 1)) (print-prim () (print (car args)) 1) (minus-prim () (- (car args))) )))
順番逆なんですが、試験は以下。
(use gauche.test) (add-load-path ".") (load "parse-program") (load "Fig3.2") (load "run") (test-start "Ex.3.6") (test-section "example") (test* "(run '(minus (+ (minus 5) 9)))" -4 (run '(minus (+ (minus 5) 9)))) (test* "(run '(minus (minus (minus 5))))" -5 (run '(minus (minus (minus 5))))) (test-end)
一応試験パス。