2

我正在尋找一個短演示文稿的概念驗證演示,其中運行代碼知道當前正在執行的代碼塊的散列「值」 。例如:運行時訪問AST的編程語言/平臺

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保持聯繫,我懷疑這可能會做到這一點(提示讚賞)。它不一定要很快,或者一個流行的平臺,可以成爲最具學術性和最奇怪的平臺。這只是一個演示。

有沒有人知道一個語言/平臺可以做到這一點,開箱即用或相對較少的修補?我更喜歡某種分析/樹狀的東西來處理,而不是實際的源代碼。

+0

在普通的Common Lisp中,運行函數並不知道它自己。在特定的實現中,應該可以檢查堆棧。 –

回答

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

順便說一句,計劃(及任何語言,其中這些宏是衛生的)會打擊你的牙齒和釘子,以防止你創建一個名爲me的標識符,該標識符可以被傳遞給宏的源代碼引用。

+0

除了缺少文件之外,衛生似乎是我與Julia碰撞的牆。非常感謝你!這正是我需要的。 – Secoe

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