我正在学习f#编译器的内部结构(https://github.com/Microsoft/visualfsharp回购,dev16.0
分支),并且偶然发现了其“ typecheked”抽象语法树的有趣部分。简而言之,Expr
类型用于表示树的某些节点,这是其定义的一部分:
Expr =
/// A constant expression.
| Const of Const * range * TType
///....
/// Typechecking residue: Indicates a free choice of typars that arises due to
/// minimization of polymorphism at let-rec bindings. These are
/// resolved to a concrete instantiation on subsequent rewrites.
| TyChoose of Typars * Expr * range
/// Typechecking residue: A Expr.Link occurs for every use of a recursively bound variable. While type-checking
/// the recursive bindings a dummy expression is stored in the mutable reference cell.
/// After type checking the bindings this is replaced by a use of the variable, perhaps at an
/// appropriate type instantiation. These are immediately eliminated on subsequent rewrites.
| Link of Expr ref
TyChoose
和Link
节点是什么意思?评论提供了一些解释,但对我来说仍然太模糊。是否有任何代码可以澄清此类表达?基本上,我认为类型化的ast不能有一些类型推断算法的残差(换句话说,它仅在将AST转换为带签名的AST的阶段使用)。 Final ast仅具有完整类型的表达式。
UPD :在转换TAST-> ILX期间似乎未使用Link
节点。这是一段代码,表明它已被剥离:
let rec GenExpr (cenv:cenv) (cgbuf:CodeGenBuffer) eenv sp expr sequel =
let expr = stripExpr expr
//......
let rec stripExpr e =
match e with
| Expr.Link eref -> stripExpr !eref
| _ -> e