作爲學習Racket宏觀系統的練習,我一直在實現一個基於C++ catch framework的單元測試框架。其中的該框架的特點是,如果我寫這樣的檢查:在球拍中記錄評估步驟和中間值的宏?
CHECK(x == y); // (check x y)
當檢查違反錯誤信息會打印出x和y的值,即使使用的宏是完全通用的,而不像其他測試框架那樣需要使用像CHECK_EQUALS,CHECK_GREATER等宏。這可能通過一些涉及表達式模板和運算符重載的hackery來實現。
在我看來,在球拍中你應該能夠做得更好。在C++版本的宏無法看到裏面的子表達式,所以如果你寫的東西,如:
CHECK(f(x, g(y)) == z); // (check (= (f x (g y)) z))
當檢查侵犯您只找出等號的左邊和右邊的值,而不是x,y或g(y)的值。在球拍中,我認爲應該可以遞歸到子表達式中並打印顯示評估每一步的樹。
問題是我不知道該怎麼做到這一點的最好辦法是:
- 我已經得到相當熟悉語法解析,但這似乎超出了自己的能力。
- 我閱讀了關於自定義#%應用程序,這幾乎看起來像我想要的,但如果例如f是一個宏,我不想打印每個擴展表達式的評估,只是評估當用戶調用檢查宏時可見的表達式。也不確定我是否可以在不定義語言的情況下使用它。
- 我可以使用syntax-parameterize來劫持基本操作符的含義,但是這對g(y)等函數調用沒有幫助。
- 我可以使用語法 - >數據並手動走AST,自己調用子表達式的eval。這似乎很棘手。
- 跟蹤庫幾乎看起來像它做我想要的,但你必須先給它一個函數列表,它似乎不給你任何控制輸出的地方(我只想打印任何如果檢查失敗,不成功,所以我需要在執行過程中將中間值保存到一邊)。
什麼是最好的或至少是慣用的方式來實現這個?
將誰投票決定關閉心靈解釋爲什麼?這個問題非常具體,我不確定它如何被解釋爲「廣泛」 –