Answers:
评估elisp代码字符串是一个分为两个阶段的过程:您需要使用解析字符串read-from-string
,然后使用评估结果Lisp表达式eval
。
(defun my-eval-string (string)
"Evaluate elisp code stored in a string."
(eval (car (read-from-string string))))
现在(my-eval-string "(+ 1 2)")
评估为3
。
编辑:
正如指出的@lunaryorn,read-from-string
只读取第一个表达式,所以这应该是更好的:
(defun my-eval-string (string)
(eval (car (read-from-string (format "(progn %s)" string)))))
编辑2:
为了评估elisp代码的副作用,还可以使用with-temp-buffer
和eval-buffer
(eval-buffer
始终返回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!\")")
with-temp-buffer
之所以不理想,是因为它会弄乱所有与缓冲区相关的调用,例如buffer-file-name
,...
君士坦丁的答案还可以。
只是提供一些修改:
(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)")
最后一种形式返回列表(1 2 3 4)
。
(calc-eval "1 - 2 + 3")
即使这不是有效的elisp ,也更适合您的python示例。如果您还不需要calc
软件包,则需要先使用加载它(require 'calc)
。(我知道这不能回答您的问题。因此,它被表述为评论。)