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)

一応試験パス。