Exercise 2.9

(a b c) を parse すると以下。

gosh> (parse-expression '(a b c))
(app-exp (free-info a) (free-info b))

あるいは (lambda) を parse すると以下。

gosh> (parse-expression '(lambda))
*** ERROR: pair required, but got ()

どうすりゃ良いのかな。51p な parse-expression だと datum が pair の場合は lambda と app 限定って考えると簡単っちゃ簡単なのかどうか。

例えば

app-exp な場合だと渡されたリストの cddr が '() でないと駄目ってカンジなのか。あるいは lambda-exp な場合だと

  • cdr は '() でないこと
  • cddr も '() でないこと

で良いのかどうか。if-exp も同様に、ですね。

  • cdr が '() ではないこと
  • cadr は pair
  • cddr が '() ではないこと
  • cdddr が '() ではないこと

なのか。で、この判定をどこに入れれば良いのやら。とりあえず以下みたいなカンジで書いてみます。

(define parse-expression
  (lambda (datum)
    (cond
     ((number? datum) (lit-exp datum))
     ((symbol? datum) (var-exp datum))
     ((pair? datum)
      (cond
       ((eqv? (car datum) 'if)
        (parse-if-exp datum))
       ((eqv? (car datum) 'lambda)
        (parse-lambda-exp datum))
       (else
        (parse-app-exp datum))
     (else
      (eopl:error 'parse-expression
		  "Invalid concrete syntas ~s" datum)))))

つうかまずは試験か。どうしたものか。上の条件が羅列されてれば良いのかな。以下がでっちあがって試験パスも確認してます。

(use gauche.test)
(add-load-path ".")
(load "parse-expression")

(test-start "parse-expression")
(test-section "if-exp")
(test* "cdr is null"
       (test-error)
       (parse-expression '(if)))
(test* "cadr is not pair"
       (test-error)
       (parse-expression '(if a)))
(test* "cddr is null"
       (test-error)
       (parse-expression '(if (a))))
(test* "cdddr is null"
       (test-error)
       (parse-expression '(if (a) x)))

(test-section "lambda-exp")
(test* "cdr is null"
       (test-error)
       (parse-expression '(lambda)))
(test* "cddr is null"
       (test-error)
       (parse-expression '(lambda ())))

(test-section "app-exp")
(test* "cddr is not null"
       (test-error)
       (parse-expression '(a b c)))

(test-end)

もすこし時間があるみたいなのでリファクタするのかどうなのか。

と、思ったら

error にならないケイスと app-exp な試験が微妙な事が発覚。むむむ。
特に

(test* "cddr is not null"
       (test-error)
       (parse-expression '(a b c)))

な試験にパスしない。と思ったらソースファイルを破壊していましたorz
試験にはパスしてるのでこれはこれで試験が微妙って事ですね。困った。