स्ट्रिंग में निहित एलिस्प कोड का मूल्यांकन कैसे करें?


21

यह सवाल बहुत कुछ कहता है: मेरे पास एक स्ट्रिंग है जिसमें एक वैध एलीस्प अभिव्यक्ति के लिए स्रोत कोड है, और मैं इसका मूल्यांकन करना चाहूंगा।

(पायथन में, उदाहरण के लिए, अभिव्यक्ति eval("1 - 2 + 3")2. का मूल्यांकन करती है)


2
ध्यान दें, (calc-eval "1 - 2 + 3")अपने अजगर उदाहरण बेहतर फिट बैठता है , भले ही यह वैध नहीं है। यदि आपको अभी तक calcपैकेज की आवश्यकता नहीं है, तो आपको इसे पहले लोड करने की आवश्यकता है (require 'calc)। (मुझे पता है कि यह आपके सवाल का जवाब नहीं देता है। इसलिए इसे टिप्पणी के रूप में तैयार किया गया है।)
तोबियास

जवाबों:


24

एलीस्प कोड की एक स्ट्रिंग का मूल्यांकन एक दो-चरण की प्रक्रिया है: आपको स्ट्रिंग का उपयोग करके पार्स करने की आवश्यकता है read-from-stringऔर फिर परिणामी लिस्प के साथ मूल्यांकन करें 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 संपादित करें:

साइड इफेक्ट्स के लिए संभावित कोड का मूल्यांकन करने के लिए एक भी इस्तेमाल कर सकता है 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, ...
हा-डुओंग गुयेन

5

कॉन्स्टेंटाइन का जवाब ठीक है।

बस एक मामूली संशोधन प्रदान करने के लिए:

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

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.