2013-06-20 62 views
2

我有需要部分擴展方案代碼而沒有完全評估。我想一個函數,它是這樣的:在方案中部分擴展代碼

'(let [(my-number 8) 
     (my-function (lambda args 'value))] 
    (cond 
    ((> my-number 10) (my-function 'x 'y 'z)) 
    ((= my-number 10) (my-function 'a 'b 'c)) 
    (else my-number))) 

,並把它變成這樣:

'(cond 
    ((> 8 10) 'value) 
    ((= 8 10) 'value) 
    (else 8)) 

換句話說,我想要的東西,擴展的定義,讓,letrecs等不做任何危險的評估。我打算對一些不同的方案代碼做一些靜態分析,如果所有代碼都處於相對規範化的形式,那將會很好。我希望儘可能多地進行擴展而不會冒任何I/O風險。

這需要什麼基本上是寫一個計劃評估。我寧願不。有沒有任何計劃功能可以幫助我開箱即用?

我應該說明我無法控制輸入。我現在得到了輸入,我必須分析它;我希望在進行分析之前將其歸一化。這就是我想在這裏實現的。我無法手工重寫輸入以使生活更輕鬆。

我正在使用球拍,但不幸的是我的代碼必須使用#lang scheme運行。

+0

什麼是你的「危險評估」? –

+0

突變全局範圍,休眠,分叉或以其他方式執行I/O操作。 我想擴展用戶的代碼塊中的用戶定義,包括lambda表達式,定義,讓和定義/讓家庭中的任何東西。如果可能的話,我想讓宏也被擴展。理想情況下,我想在不修改狀態或執行I/O的情況下進行所有語法擴展,但白名單可能就足夠了。你知道完整的類似定義和類似函數的列表嗎? – So8res

+0

如果你可以做'靜態分析',那麼你可以做'部分評估'... – GoZoner

回答

1

也許expand是你在找什麼?它將產生輸出作爲一個在這個問題,但它會:

展開頂級形式的所有非基本語法,並返回一個語法對象僅包含擴展形式芯的形式,通過匹配完全展開程序

這裏指定的語法是一個使用例:

(define src 
    '(let [(my-number 8) 
     (my-function (lambda args 'value))] 
    (cond 
     ((> my-number 10) (my-function 'x 'y 'z)) 
     ((= my-number 10) (my-function 'a 'b 'c)) 
     (else my-number)))) 

(syntax->datum 
(parameterize ([current-namespace (make-base-namespace)]) 
    (expand (datum->syntax #f src)))) 

有了這個輸出:

(let-values (((my-number) '8) ((my-function) (lambda args 'value))) 
    (if (#%app > my-number '10) 
    (let-values() (#%app my-function 'x 'y 'z)) 
    (if (#%app = my-number '10) 
     (let-values() (#%app my-function 'a 'b 'c)) 
     (let-values() my-number)))) 

注意,如果我們去掉syntax->datum轉換,由expand返回的值將是一個syntax object,這可能是執行你心目中的分析更爲有用。

+0

我不確定你是否理解這個問題。我需要一個函數,它將第一個代碼樣本作爲輸入,並將第二個代碼樣本作爲輸出返回。我不生成代碼示例:我將讀取一堆現有代碼,我希望在靜態分析之前對其進行規範化。 – So8res

+0

我還是覺得你不明白。我不會寫輸入。我無法控制輸入。我想做一些擴展(lambdas和定義*和let *系列中的任何東西),不再有 - 我是否可以使用某種受限制的eval? – So8res

+1

擴展是一個開始 - 它肯定會使部分評估更容易,通過縮小我自己最終編寫部分評估程序時必須處理的情況。 – So8res