Support cross-quotation references in quasicode
LPTK opened this issue · comments
Cross-quotation references (CQR) are variables at a given stage that refer to binders at the same stage but across quotation boundaries (not to be confused with cross-stage references).
For example:
code"(x: Int) => ${ foo(code"x+1") }" // occurrence of x refers to binding in outside quote
Because of fundamental limitations, cross-quotation references are impossible to support in quasiquotes. However, it should be possible to support them in quasicode, as in:
code{(x: Int) => ${ foo(code{x+1}) }} // occurrence of x refers to binding in outside quote
What needs to be done:
-
disable implicit cross-stage reference support in quasicode (so doing CSP in quasicode requires using explicit
CrossStage(...)
expressions), as they would be locally ambiguous with CQRs; -
when QuasiEmbedder encounters a reference to a variable not defined within the quote, it uses that variable's symbol to look up its associated
v:Variable[T]
symbol in an external macro cache, and creates one if none exists – this symbol is used to addv.Ctx
to the current context requirement; now, in place of the CQR, generates a special tree that should not compile (containing a@compileTimeOnly
) to be substituted by the outer quote (if any); -
when QuasiEmbedder finds a binding of some variable
v
, it makes sure to check the macro cache to see if it's a cross-quotation binding, in which case it accounts for itsv.Ctx
context being bound there; then in each further inserted tree of the quote, it looks for the corresponding@compileTimeOnly
trees and substitutes them with a reference to the bound variable.