Emacs Stack Exchange is a question and answer site for those using, extending or developing Emacs. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

The question pretty much says it all: I have a string containing the source code for a valid Elisp expression, and I would like to evaluate it.

(In Python, for example, the expression eval("1 - 2 + 3") evaluates to 2.)

share|improve this question
2  
Note, (calc-eval "1 - 2 + 3") fits your python example better even if this is not valid elisp. If you do not yet require the calc package you need to load it before with (require 'calc). (I know that this does not answer your question. Hence it is formulated as comment.) – Tobias Jan 28 at 12:35
up vote 15 down vote accepted

Evaluating a string of elisp code is a two-stage process: you need to parse the string using read-from-string and then evaluate the resulting Lisp expression with eval.

(defun my-eval-string (string)
  "Evaluate elisp code stored in a string."
  (eval (car (read-from-string string))))

Now (my-eval-string "(+ 1 2)") evaluates to 3.

Edit:

As pointed out by @lunaryorn, read-from-string reads the first expression only, so this should be better:

(defun my-eval-string (string)
  (eval (car (read-from-string (format "(progn %s)" string)))))

Edit 2:

To evaluate elisp code for side effects one could also use with-temp-buffer and eval-buffer (eval-buffer always returns nil).

(defun my-eval-string-for-side-effects (string)
  "Evaluate a string of elisp code for side effects."
  (with-temp-buffer
    (insert string)
    (eval-buffer)))

(my-eval-string-for-side-effects "(message \"hello!\")")
share|improve this answer
    
It should be noted that read-from-string only reads the first expression, and doesn't guarantee to read the whole string. – lunaryorn Jan 28 at 7:08
    
@lunaryorn: Oops. Thanks for pointing this out! – Constantine Jan 28 at 7:40

The answer of Constantine is okay.

Just to provide a slight modification:

(defun my-eval-string (str)
  "Read and evaluate all forms in str.
Return the results of all forms as a list."
  (let ((next 0)
    ret)
    (condition-case err
    (while t
      (setq ret (cons (funcall (lambda (ret) (setq next (cdr ret)) (eval (car ret))) (read-from-string str next)) ret)))
      (end-of-file))
    (nreverse ret)))

(my-eval-string "1 2 3 (+ 3 1)")

The last form returns the list (1 2 3 4).

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.