2013-03-24 27 views
5

如何編寫一個函數來解析詞法環境中的符號?clojure - 解析一個符號內的符號

(let [foo some-var] 
    (let [sym 'foo] 
    (resolve-sym sym))) 

我想獲得'foo綁定的var。

+3

讓我們不創造新的增值經銷商,所以基本上你不能加以解決 – Ankur 2013-03-24 15:54:56

+0

但它有可能獲得與和ENV宏裏面的環境。 – navgeet 2013-03-24 15:59:41

+0

@navgeet,不,這是不可能的。 '(defmacro m [x&env]'(x env))'將以這種方式展開:'(m 1 2 3 4 5) - >'(1(2 3 4 5))',即'&env'會給你訪問可變參數。 Clojure無法獲得當前的詞彙環境。 – 2013-03-24 16:17:08

回答

4

我不完全知道爲什麼我想是這樣的,不過貌似也一定能做到。 從http://clojuredocs.org/circumspec/circumspec.should/local-bindings

(defmacro local-bindings 
    "Produces a map of the names of local bindings to their values. 
    For now, strip out gensymed locals. TODO: use 1.2 feature." 
    [] 
    (let [symbols (remove #(.contains (str %) "_") 
         (map key @clojure.lang.Compiler/LOCAL_ENV))] 
    (zipmap (map (fn [sym] `(quote ~sym)) symbols) symbols))) 


(let [foo 1 bar 2] 
    (local-bindings)) 
=> {foo 1, bar 2} 
1

這裏既多,越來越歪斜比你想要的東西:

(define (make-let-core name value body) 
    `(CORE LET ,name ,value ,body)) 

(define (env-extend env a-name its-denotation) 
    (lambda (name) 
    (if (equal? name a-name) 
     its-denotation 
     (if env (env name) 'unknown)))) 

(define (env-base) 
    (lambda (name) 
    (if (member name '(let resolve-sym #| ... |#)) 
     'syntactic-keyword 
     'unknown))) 

(define (expand exp env) 
    (cond ((literal? exp) ...) 
     ((symbol? exp) ...) 
     ((list? exp) 
     (let ((operator (car exp)) 
       (operands (cdr exp))) 
      (cond ((symbol? operator) 
        (case (env operator) 
        ((syntactic-keyword) 
        (case operator 
         ((let) 
         (let ((bound-name (caar operands)) 
           (bound-value (cadar operands)) 
           (body (cdr operands))) 
          (make-let-core bound-name 
             (expand bound-value env) 
             (expand body 
               (env-extend bound-name 
                  'variable))))) 
         ((resolve-sym) 
         (let ((name (car operands))) 
          ;; right here 
          ...)) 
         (...))) 
        ((variable) ;; function call 
        ...) 

        ((unknown) ;; syntax error 
        ...))) 

       ((list? operator) ;; function call 
        ...) 

       (else ;; syntax error 
        ...)))) 
     (else ;; syntax error 
     ...))) 
+0

看起來@navgeet正在尋找Clojure解決方案,但事實並非如此。 – dfreeman 2013-03-24 20:28:09

+0

,它甚至沒有解決方案... – GoZoner 2013-03-24 20:32:02

+0

好吧,問題標有「lisp」。 – 2013-03-25 11:07:25