编程语言/平台,具有对AST的运行时访问

时间:2015-07-12 19:27:32

标签: functional-programming programming-languages common-lisp metaprogramming

我希望为简短的演示实现一些概念验证演示,其中正在运行的代码知道散列的值'当前正在执行的代码块。例如:

function BBB(a) {
  a = 2 * a;
  print me.hash;          --> "xxxxxxx" (value of BBB-syntax represenation)
  return a;                              
}

function AAA(a, b, c) {
  d = BBB(a);
  print me.hash;          --> "yyyyyyy" (value of AAA-Syntax representation, possibly dependant on value of BBB, but not necessary)
  return d;
}

我本能地转向LISPish语言,但尚未成功使用Scheme。而且我很长时间没有与Common LISP联系,我怀疑它可能会这样做(提示赞赏)。它不一定非常快,或者一个受欢迎的平台,可以是最具学术性和最奇怪的平台。它只是一个演示。

是否有人知道一种语言/平台可以开箱即用或者相对较少的修补?我更喜欢使用某种解析/树状的东西,而不是实际的源代码。

2 个答案:

答案 0 :(得分:6)

你猜对了。 Common Lisp可以很容易地做到:

(defmacro reflective-defun (name args &body body)
  (let ((source-form `(reflective-defun ,name ,args ,@body)))
    `(let ((me ',source-form))
       (defun ,@(cdr source-form)))))

(reflective-defun bbb (a)
  (setf a (* 2 a))
  (print me)
  a)

(reflective-defun aaa (a b c)
  (let ((d (bbb a)))
    (print me)
    d))

(aaa 12 :x :y)

输出:

(REFLECTIVE-DEFUN BBB
    (A)
  (SETF A (* 2 A))
  (PRINT ME)
  A) 
(REFLECTIVE-DEFUN AAA
    (A B C)
  (LET ((D (BBB A)))
    (PRINT ME)
    D)) 
24

以下是如何编写自我重新定义的功能:

(defun recursive-replace (tree what with)
  "Walks down the TREE and replaces anything that is EQUALP to WHAT with WITH."
  (cond ((equalp tree what)
         with)
        ((listp tree)
         (loop for item in tree
              collect (recursive-replace item what with)))
        (t tree)))

(reflective-defun ccc (a b c)
  (let ((d (bbb a)))
    (print me)
    (if (eql b :use-me-from-now-on)
        (eval (recursive-replace me '(bbb a) '(bbb b))))
    d))

顺便提一下,Scheme(以及宏是卫生的任何语言)都会打击你,以防止你创建一个名为me的标识符,该标识符可以被传递给宏的源代码引用。

答案 1 :(得分:0)

不是哈希,但对于唯一ID,您可以使用Python对象标识。将每个函数放在自己的类中,然后使用id()。一个例子,在Python 3中:

class cBBB(object):
    def do(a):
        a=2*a
        print(self.id())    # self.id() is the "hash"-like unique value
        return a;
BBB = cBBB()     # now you can call BBB.do(a)

class cAAA(object):
    def do(a,b,c):
        d = BBB.do(a)
        print(self.id())    # self.id() is the "hash"-like unique value
        return d;
AAA = cAAA()     # now you can call AAA.do(a,b,c)

使用__call__可以更干净地完成此操作。有关__call__的更多信息,请参阅this question