epfldata / squid

Squid – type-safe metaprogramming and compilation framework for Scala

Home Page:http://epfldata.github.io/squid/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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 add v.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 its v.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.

This was implemented in #61.

The typing scheme was then actually simplified in 4321c35.