2017-04-07 13 views
2

私は "ステップ"評価を行う方法を見つけようとしています。関数を呼び出すと、共通のlispの最もネストされたリストが評価されます。例えばステップEval Common Lisp


'(+ 2 (+ 3 4)) 
; would eval to: 
'(+ 2 7) 

がその例ではそれだけで+ 4 3を評価し、右が停止。通常はLISPのように2 + 7の評価を続けることはできませんでした。

したがって、コードを最もネストされたリストを見つけて、リスト全体を評価することなく、最もネストされたリストを評価するようにします。例えば

'(+ 2 3 4 5 (+ 4 5 (- 5 6) 1 (+ 10 8 5 (- 10 11))) 10 7) 

それは、ほとんどのネストされたリストを見つける(- 10 11)、およびので、それをevalします:

'(+ 2 3 4 5 (+ 4 5 (- 5 6) 1 (+ 10 8 5 -1)) 10 7) 

を再び、それは一度だけ評価し、でリスト全体を評価しません。一度。

最もネストされたリストのステップ評価を行う方法について、誰も知っていますか? evalなどを使用してリストの中で最も入れ子になった部分を実行するにはevalリスト全体を一度に実行する必要はありませんか?私が抱えている問題は、最もネストされたリストをどのように評価してから戻すのか分かりません。私はこれに近づく方法を知らない。マスター・リスパーがこれをどうやって行うのか教えてください。

+0

式はネストされたリストです。このネストされたリストを歩いて、*端末*リストの場合はevalを呼び出します。最初に、関数でネストされたリストをトラバースする方法を学ぶ必要があります。 –

+0

最もネストされた部分に到達できる関数を書くことができましたが、どのように戻して戻すのか分かりません。たぶん私はこの間違ったことや何かを視覚化しているだけかもしれない。 – Loon911

答えて

1

評価の順序は左から右です。したがって、Common Lispの動作をエミュレートする場合は、最も深いネストされたリストを評価するのは正確ではありません。

まず、最初にネストされたフォームを評価する必要があります。適切な入力を仮定すると、

(defun step-eval (form) 
    (let ((sub-index (position-if #'listp form))) 
    (if sub-index 
     ;; there is a deeper list to step first 
     (append (subseq form 0 sub-index) 
       (list (step-eval (nth sub-index form))) 
       (subseq form (1+ sub-index))) 
     ;; no deeper list, eval this 
     (eval form)))) 
2

会社はstepを使用します。

(step (+ 2 (+ 3 4))) 
step 1 --> (+ 2 (+ 3 4)) 
Step 1 [4]> step 
step 2 --> 2 
Step 2 [5]> step 
step 2 ==> value: 2 
step 2 --> (+ 3 4) 
Step 2 [6]> step 
step 3 --> 3 
Step 3 [7]> step 
step 3 ==> value: 3 
step 3 --> 4 
Step 3 [8]> step 
step 3 ==> value: 4 
step 2 ==> value: 7 
step 1 ==> value: 9 
9 

それは正確に何をしたい行いませんが、それはかなり近いです。その理由は、Common Lispはステッパーが実行する順序で式を評価する必要があるからです。