簡體   English   中英

squeak(smalltalk) 如何將字符串“注入”到字符串中

[英]squeak(smalltallk) how to 'inject' string into string

我正在編寫一個名為“MyObject”的類。 類方法之一是:

addTo: aCodeString assertType: aTypeCollection

當使用aCodeString調用該方法時,我想(在運行時)向“MyObject”類添加一個新方法,其中aCodeString是它的源代碼,並將類型檢查代碼注入到源代碼中。 例如,如果我像這樣調用addTo: assertType:

a := MyObject new.
a addTo:  'foo: a boo:b baz: c
    ^(a*b+c)'
assertType: #(SmallInteger SmallInteger SmallInteger).

我希望我以后可以寫:

answer := (a foo: 2 boo: 5 baz: 10). 

並得到 20 個answer 如果我寫:

a foo: 'someString' boo: 5 baz: 10.

我得到了正確的消息,因為“someString”不是 SmallInteger。

我知道如何編寫類型檢查代碼,並且我知道要在運行時將方法添加到類中,我可以使用 Behavior 類中的“compile”方法。

問題是我想在源代碼中添加類型檢查代碼。 我不是很熟悉所有的 squeak 類,所以我不確定我是否更願意將aCodeString作為字符串編輯在addTo: assertType: ,然后使用compile:我不知道該怎么做),或者有一種方法可以將代碼注入 Behavior 類或其他 squeak 類中的現有方法。

所以基本上,我要問的是如何將字符串注入現有字符串或將代碼注入現有方法。

有很多方法可以實現這種類型檢查......

您建議修改源代碼(字符串)以插入額外的前置條件類型檢查。

這種方法的關鍵點是您必須在正確的位置插入類型檢查。 這意味着以某種方式解析原始源(或至少是選擇器和參數)以找到其確切的跨度(和參數名稱)。

參見方法initPattern:return:Parser及其發送者中。 你會發現非常低級(不是最漂亮的)代碼,它為塊(通過 return: 關鍵字傳遞)提供sap一個包含 3 個對象的數組:方法選擇器、方法參數和方法優先級(一個代碼告訴你方法是否是連接到一元、二元或關鍵字消息)。 從那里,您將獲得足夠的材料來實現源代碼操作(使用copyReplace:from:to:with:將一個字符串插入另一個字符串)。

不要猶豫,編寫小代碼片段並在調試器中執行(選擇要調試的代碼,然后使用調試菜單或 ALT+Shift+D)。 還可以廣泛使用檢查員來更深入地了解事情的運作方式!

另一種解決方案是解析源代碼的整個抽象語法樹 (AST),並操作該 AST 以插入類型檢查。 通常,解析器構建 AST,所以觀察它是如何工作的。 從修改后的 AST 中,您可以生成新的CompiledMethod (字節碼指令)並將其安裝在methodDictionary - 查看compile:的源代碼並按照發送的消息進行操作,直到您發現generateMethodFromNode:trailer: 這有點復雜,並且有一個不好的副作用,即源代碼現在與生成的代碼不同步,一旦您想要調試該方法,這可能會成為一個問題(幸運的是,Squeak 可以使用反編譯代碼代替源代碼)代碼!)。

最后,您還可以為您的某些類安排一個備用編譯器和解析器(請參閱compilerClass和/或parserClass )。 替代的TypeHintParser將接受帶有源代碼中類型提示的修改語法(曾幾何時,它是使用尖括號foo: x <Integer> bar: y <Number>內的參數后面的類型提示來實現的)。 並且備用TypeHintCompiler會根據這些類型提示自動安排編譯前提條件。 由於您將在 Squeak 中非常先進,您還將在源代碼索引和字節碼之間創建特殊映射,以便擁有健全的調試器,甚至可以識別前置條件類型檢查並將它們轉換回類型提示的特殊 Decompiler 類以防萬一.

我的建議是從您提出的第一種方法開始。

編輯

我忘了說,還有另一種方法,但它目前在 Pharo 而不是 Squeak 中可用:Pharo 編譯器(名為OpalCompiler )確實在生成階段將字節碼指令具體化為對象(類名以 IR 開頭)。 所以在這個階段也可以通過適當的hack來直接操作字節碼指令......我很確定我們可以找到使用示例。 可能是最先進的技術。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM