0

I am trying to implement a eval function using CLISP.

My motivation: suppose I have a Lisp program like this:

(defun call (arg)
  (cond
    (some-condition (call (other (strange (functions (on arg)))))
    (t nil)
  )
)

(defun mysterious-function (arg)
  (call (strange (functions (on arg))))
)

(mysterious-function 100)       ; only this line can be changed

I want to know what is actually called in (mysterious-function 100).

Currently my idea looks like below, but the obstacles are:

  1. How to look up a symbol (currently using eval)
  2. How to grab a definition of a function (e.g. get something like (defun f (x))) and then parse it
  3. How to detect macro and expand them

Am I in the correct direction?

(defun my-eval (body)
  (cond
    ((typep body 'integer) body)
    ((typep body 'float) body)
    ((typep body 'rational) body)
    ((typep body 'complex) body)
    ((typep body 'boolean) body)
    ((typep body 'symbol) (eval body))
    ((typep body 'list) (eval body))
    (t (error))
  )
)

(my-eval '(mysterious-function 100))
4
  • 1
    This question is unclear. Do you want to write an evaluator for Common Lisp? Or for some much smaller dialect where the evaluator is written in common Lisp? There are quite a lot of resources on the web about how to write evaluators: have you looked at them? Commented May 2, 2020 at 16:01
  • I am trying to write an evaluator for Common Lisp using Common Lisp. Most online resources I find are using some other non-function programming languages like Python. I find some for other Lisp dialects, but not Common Lisp. Commented May 2, 2020 at 22:16
  • 1
    OK, well I think writing an evaluator for CL is well outside the scope of a stack exchange answer: it's a big industrial language and an evaluator for it is necessarily going to be complicated. Not because of the 'library' which you can presumably just punt on, but because of things like symbol macros &c &c. Commented May 3, 2020 at 9:47
  • 1
    SICL might be relevant to your interest: github.com/robert-strandh/SICL Commented May 3, 2020 at 17:20

1 Answer 1

1

Most of the cases in your code can be replaced with a single check: ((constantp body) body)

As for other cases:

  • You can use boundp to check if a symbol has a global value.
  • To look up a global symbol value you can use symbol-value.
  • fboundp can be used to check if a symbol is globally bound to a function
  • To look up a global function you can use symbol-function to access its function object and can sometimes use function-lambda-expression to retrieve a parseable source code list from the function object. Sometimes this will not work as built in CLISP functions can be defined in C.
  • To check if a symbol has an associated global macro, use macro-function (returns non-nil if it does).
  • To expand a macro form, use macroexpand.

You will probably also need to detect special operators with special-operator-p, and handle them accordingly.

I think what you are trying to do would be simplified if you restrict the code you interpret to macros and user-defined functions as much as possible. I remember reading about a fast-eval function used in genetic programming to skip the macroexpansion phase of evaluating code, and its approach looked similar to what you seem to have in mind.

Sign up to request clarification or add additional context in comments.

1 Comment

The functions you mentioned seem to be a good starting point. However, I gave up implementing it because there are too much to write in order to implement all the functions I need. One note about constantp: it returns true for (+ 1 2 3), so I still have to go through all possible cases I need to handle.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.