Réponses:
L'évaluation d'une chaîne de code elisp est un processus en deux étapes: vous devez analyser la chaîne en utilisant read-from-string
puis évaluer l'expression Lisp résultante avec eval
.
(defun my-eval-string (string)
"Evaluate elisp code stored in a string."
(eval (car (read-from-string string))))
Évalue maintenant (my-eval-string "(+ 1 2)")
à 3
.
Éditer:
Comme l'a souligné @lunaryorn , read-from-string
lit uniquement la première expression , donc cela devrait être mieux:
(defun my-eval-string (string)
(eval (car (read-from-string (format "(progn %s)" string)))))
Modifier 2:
Pour évaluer le code elisp pour les effets secondaires, on pourrait également utiliser with-temp-buffer
et eval-buffer
( eval-buffer
renvoie toujours 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
est loin d'être idéal car il gâchera tous les appels liés au tampon, par exemple buffer-file-name
...
La réponse de Constantine est correcte.
Juste pour apporter une légère 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)")
Le dernier formulaire renvoie la liste (1 2 3 4)
.
(calc-eval "1 - 2 + 3")
convient mieux à votre exemple python même si ce n'est pas elisp valide. Si vous n'avez pas encore besoin ducalc
paquet, vous devez le charger auparavant avec(require 'calc)
. (Je sais que cela ne répond pas à votre question. C'est pourquoi il est formulé comme un commentaire.)