0

私は、Scheme で単純なプログラミング言語のインタープリターを作成しようとしています。現在、break ステートメントを使用して while ループを処理する手順を作成しています。この問題に対処するために、call/cc を使用しています。

言語を解析すると、次のようになります。

var x = 0;
while (x < 10) {
  x = x - 1;
  break;
  x = x + 100;
}
return x;

になる

((var x 0) (while (< x 10) (begin (= x (- x 1)) (break) (= x (+ x 100)))) (return x))

これらのステートメントを解釈するための私のアプローチは次のとおりです。

(define while_break
  (lambda (cond body state)
    (call/cc
     (lambda (break-cont)
       (letrec
           ((Mstate_loop (lambda (cond body state)
                         ; Need second loop
                         (if (eq? (M_Bool cond state) #t)
                             (call/cc
                              (lambda (second-break-cont)
                                (letrec
                                  ((Body_loop (lambda (body_line state)
                                                (cond
                                                  ((null? body_line) (second-break-cont state))
                                              ; Conditions to exit the loop
                                              ((eq? (first_line body_line) 'break) (second-break-cont state))
                                              ; If this is the last line, run it and break
                                              ((null? (rest_of_lines body_line)) (second-break-cont (M_State body_line state)))
                                              ; Otherwise, run the next line
                                              (else (Body_loop (rest_of_lines body_line) (M_State (first_line body_line) state)))))))
                            (Body_loop body state))))
                          (break-cont state)
                          ))))
        (Mstate_loop cond body state))
     ))))


(define first_line car)
(define rest_of_lines cdr)

Where (M_State statement state) は、ステートメントを反映するように更新された現在の状態を返します (たとえば、状態 ((x) (2)) は x = 2 を表します。(M_State '(var x 5) '((x) (2))) は、 return ((x) (5)).)

これをデバッガーに通すと、body_line が null でなくても、行 ((null? body_line) (second-break-cont state)) は常に second-break-cont を呼び出します。これをデバッグするのに多くの時間を費やしましたが、エラーが見つからないようです。私の間違いを見つけるための助けをいただければ幸いです。

4

1 に答える 1

1

あなたのコードを詳しく調べたわけではありませんが、1 つのことに気付きました。condメイン関数と外側のループの両方に名前が付けられたパラメーターがありました。condこれにより、内側のループで使用しようとした組み込みマクロがシャドウされます。

実際、これだけで your(second-break-cont state)が常に呼び出される理由が説明できます。式はcondもはやマクロ呼び出しではなく、通常の関数呼び出しであるため、内部のすべての式が評価されます。

パラメータを 以外の名前にする必要がありますcond

于 2016-03-05T02:26:31.493 に答える