Loon911
Loon911

Reputation: 43

Step Eval Common Lisp

I have been trying to find a method to do a "step" eval. Where I call the a function and it evaluates the most nested list for common lisp.

For example:

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

In that example it just evaluated 3 + 4 and stopped right there. It did not continue on to eval 2 + 7 like what lisp would normally do.

So I want the code to find the most nested list and eval the most nested list, without evaluating the whole list.

For example:

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

It would find the most nested list, (- 10 11), and eval it so:

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

Again it only evaluates once, and does not evaluate the whole list at once.

Does anybody know how you could go about this to make a step evaluation for the most nested list? To use eval or something to execute the most nested part of the list without evaling the whole list at once? The problem I'm having is that I don't know how to evaluate the most nested list and then put it back together. I don't know how to approach this. Please enlighten me on how a master lisper would do this.

Upvotes: 2

Views: 512

Answers (2)

Svante
Svante

Reputation: 51501

The order of evaluation is left-to-right, so it is not exactly right to evaluate the deepest nested list if you want to emulate Common Lisp's behaviour.

You rather have to evaluate the first nested form first. Assuming well-formed input:

(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))))

Upvotes: 1

Sylwester
Sylwester

Reputation: 48745

Us use 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

It doesn't do exactly what you want but it is pretty close. The reason is that Common Lisp is required to evaluate the expressions in exactly the order the stepper does it.

Upvotes: 2

Related Questions