Bir dizgede bulunan Elisp kodu nasıl değerlendirilir?


21

Soru hemen hemen her şeyi söylüyor: Geçerli bir Elisp ifadesi için kaynak kodunu içeren bir dize var ve değerlendirmek istiyorum.

(Örneğin Python'da ifade 2 olarak eval("1 - 2 + 3")değerlendirilir.)


2
Not, (calc-eval "1 - 2 + 3")geçerli bir elisp olmasa bile python örneğinize daha iyi uyar. calcPaketi henüz istemiyorsanız, daha önce ile birlikte yüklemeniz gerekir (require 'calc). (Bunun sorunuzu yanıtlamadığını biliyorum. Bu nedenle yorum olarak formüle edilmiştir.)
Tobias

Yanıtlar:


24

Bir dizi elisp kodunu değerlendirmek iki aşamalı bir işlemdir: dize kullanarak ayrıştırmanız read-from-stringve sonra ortaya çıkan Lisp ifadesini değerlendirmeniz gerekir eval.

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

Şimdi (my-eval-string "(+ 1 2)")değerlendirir 3.

Düzenle:

@Lunaryorn tarafından işaret edildiği gibi , read-from-string sadece ilk ifadeyi okuyor , bu yüzden bu daha iyi olmalı:

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

Düzenleme 2:

Yanal kodlar için elisp kodunu değerlendirmek için kişi de kullanabilir with-temp-bufferve eval-buffer( eval-bufferher zaman geri döner 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-bufferideal olandan daha az çünkü tamponla ilgili tüm çağrıları bozacak, örneğin buffer-file-name, ...
Ha-Duong Nguyen

5

Constantine'in cevabı tamamdır.

Sadece küçük bir değişiklik yapmak için:

(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)")

Son form listeyi döndürür (1 2 3 4).

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.