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
試験にはパスしてるのでこれはこれで試験が微妙って事ですね。困った。