サイズ: 3160
コメント:
|
サイズ: 3585
コメント:
|
削除された箇所はこのように表示されます。 | 追加された箇所はこのように表示されます。 |
行 1: | 行 1: |
Naoaki Iwakiri/Scheme課題memo |
|
行 69: | 行 66: |
さて、ここまで落ちつけば、ここでするべきは 1. ''変数リスト''にあるシンボルに''args''をその順であてはめる。つまり、''lambda評価時のenv''を''lambdaの変数''と''args''で拡張する。 1. 先の課題のextend-envに渡せるリストを、''変数リスト''と''lambdaの中身''を操作して作る。 2. extend-envする 1. ''lambdaの中身''を評価させる事 だとわかります。 |
Guileだとスタックトレースが見易くて便利らしいけれど、gaucheでもとりあえずは(print hoge)でprintfデバッグすると十分に便利。
とりあえず課題ページの例が動くところまで、ほとんど課題ページの内容をコピペです。ちょこちょこ改訂されてるので一度コピペしなおしてみると便利かも。 自分で書く部分は、
make-top-env内のdefine-var!の羅列の中で<,>等を追加
- base-apply内で*lambda*を見つけた場合の処理
- def-eval
- if-eval
- quote-eval
の五つくらいです。 よって根幹部分はこんな風になります。上にないfoo-evalは課題ページのもので確かOK。beginも簡単だけど、例では使ってないので省略。システムテストも通っちゃう。
(cond ((eof-object? exp) '*exit*) ((boolean? exp) exp) ((number? exp) exp) ((string? exp) exp) ((symbol? exp) (var-eval exp env)) ((null? exp) exp) ((not (list? exp)) (eval-error 'syntax-error exp)) ((equal? (car exp) 'exit) '*exit*) ;; ((equal? (car exp) 'begin ((equal? (car exp) 'lambda) (lambda-eval exp env)) ((equal? (car exp) 'let) (let-eval exp env)) ((equal? (car exp) 'define) (def-eval exp env)) ;; ((equal? (car exp) 'letrec) ((equal? (car exp) 'if) (if-eval exp env)) ((equal? (car exp) 'quote) (quote-eval exp env)) (#t (app-eval exp env))))
make-top-env内のdefine-var!の羅列については課題ページ中の他のprimitive行を見て真似すればいいので省略。
if-evalについて。
これも標準のifを真似るだけ、なのですが、環境とかその辺を考慮してあげないといけないので評価はbase-evalを使います。標準のifを使うのは手抜きっぽい? どうするにせよ評価しない式がある以上、特殊形式は必要だろうから特に恥ずかしい事じゃないよ!
(if (base-eval '''expの該当部分''' env) (base-eval '''expの該当部分''' env) (base-eval '''expの該当部分''' env))
def-evalについて。
環境の拡張だから前の課題のdefine-var!一発だね! base-evalしてあげることを忘れずにね!
quote-evalについて。
といってもexp、つまり入力のリスト(quote hoge)から必要部分を返すだけなので、
(car (cdr exp))
で。特に難しいところなし。
base-applyで*lambda*をみつけた時の処理について
たぶん課題の真打ちがこれ。とりあえず俺俺処理系に渡されたリストは課題ページのapp-evalによっていい感じにリストの深い中身が評価されてから、base-applyにfun,args,envが渡ってくるはずです。
fun,argsの中身は中身評価後のcarとcdrで、funはlambda-evalで決めた通り(*lambda* lambda評価時のenv (変数リスト) lambdaの中身)の形をしてかえってくるはずで、argsが残りの部分のリストです。
さて、ここまで落ちつけば、ここでするべきは
変数リストにあるシンボルにargsをその順であてはめる。つまり、lambda評価時のenvをlambdaの変数とargsで拡張する。
先の課題のextend-envに渡せるリストを、変数リストとlambdaの中身を操作して作る。
- extend-envする
lambdaの中身を評価させる事
だとわかります。