Search code examples
lispnumericclispoperations

LISP functions that perform both symbolic and numeric operations on expressions using +, -, *, and /


I'm currently working on a LISP exercise for a small project and need severe help. This may be more or less of a beginner's question but I'm absolutely lost on writing a certain function that takes in two unevaluated functions and spits out the result dependent on if the variables were given an assignment or not.

An example would be

(setq p1 '(+ x (* x (- y (/ z 2)))))

Where

(evalexp p1 '( (x 2) (z 8) ))
    returns (+ 2 (* 2 (- y 4)))

My goal is to write the evalexp function but I can't even think of where to start.

So far I have

(defun evalexp (e b) )

.. not very much. If anyone could please help or lead me in a good direction I'd be more than appreciative.


Solution

  • Here's a full solution. It's pretty straightforward, so I'll leave out a full explanation. Ask me in the comments if there's anything you can't figure out yourself.

    (Using eval to do the actual evaluation might not be what you want in your exercise/project. Look up "meta-circular interpreter" for another way.)

    (defun apply-env (exp env)
      (reduce (lambda (exp bdg) (subst (cadr bdg) (car bdg) exp))
              env :initial-value exp))
    
    (defun try-eval (exp)
      (if (atom exp)
          exp
          (let ((exp (mapcar #'try-eval exp)))
            (if (every #'numberp (cdr exp))
                (eval exp)
                exp))))
    
    (defun evalexp (exp env)
      (try-eval (apply-env exp env)))