Step Eval Common Lisp

时间:2017-04-07 05:20:30

标签: lisp common-lisp

我一直在努力寻找一种方法来进行“步骤”评估。我调用a函数的地方,它评估了最常见的lisp的嵌套列表。

例如:

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

在那个例子中,它只评估了3 + 4并在那里停了下来。它没有像lisp通常那样继续进行eval 2 + 7。

所以我希望代码能够找到最嵌套的列表并评估最嵌套的列表,而无需评估整个列表。

例如:

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

它会找到最嵌套的列表(- 10 11),并将其评估为:

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

同样,它只评估一次,并且不会立即评估整个列表。

有人知道如何对最嵌套的列表进行步骤评估吗?使用eval或其他东西来执行列表中嵌套最多的部分而不立即eval整个列表?我遇到的问题是我不知道如何评估最嵌套的列表然后将它重新组合在一起。我不知道如何处理这个问题。请告诉我一个主要的lisper将如何做到这一点。

2 个答案:

答案 0 :(得分: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需要按照步进器的顺序来计算表达式。

答案 1 :(得分: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))))