5

如何编写函数来解析词法环境中的符号?

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

我想得到 'foo 绑定到的 var。

4

2 回答 2

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}
于 2013-03-25T05:12:04.043 回答
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
         ...)))
于 2013-03-24T17:47:08.793 回答