Відповіді:
Оцінка рядка коду 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")краще підходить ваш приклад python, навіть якщо це неправильний elisp. Якщо вам ще не потрібенcalcпакет, його потрібно завантажити перед цим(require 'calc). (Я знаю, що це не відповідає на ваше запитання. Отже, це сформульовано як коментар.)