This file implements lambda lifting for the transformator.
Procs
proc ensureEnvParam(graph: ModuleGraph; idgen: IdGenerator; prc: PSym) {. ...raises: [KeyError, Exception, ERecoverableError], tags: [ReadDirEffect, RootEffect].}
- Problem: top-level anonymous expression can explicitly use the .closure calling convention (which doesn't make sense, really). All .closure procedures need a hidden environment paramater, and so ensureEnvParam adds an empty one. Source Edit
proc finishClosureIterator(g: ModuleGraph; idgen: IdGenerator; iter: PSym) {. ...raises: [Exception, KeyError, ERecoverableError, ValueError], tags: [RootEffect, ReadDirEffect].}
- Creates the type-bound operators for the iterator's hidden environment parameter type. Source Edit
proc freshVarForClosureIter(g: ModuleGraph; s: PSym; idgen: IdGenerator; owner: PSym): PNode {. ...raises: [Exception, ERecoverableError], tags: [RootEffect].}
- Adds a unique field to owner's environment type, using the name, type, and .cursor information from the local s. Source Edit
proc getClosureIterResult(g: ModuleGraph; iter: PSym; idgen: IdGenerator): PSym {. ...raises: [], tags: [].}
- Source Edit
proc getEnvParam(routine: PSym): PSym {....raises: [], tags: [].}
- Source Edit
proc getStateField(g: ModuleGraph; owner: PSym): PSym {. ...raises: [Exception, ERecoverableError], tags: [RootEffect].}
- Source Edit
proc liftForLoop(g: ModuleGraph; body: PNode; idgen: IdGenerator; owner, breakLabel: PSym): PNode {. ...raises: [Exception, ERecoverableError, KeyError], tags: [RootEffect, ReadDirEffect].}
- Source Edit
proc liftIterSym(g: ModuleGraph; n: PNode; idgen: IdGenerator; owner, currEnv: PSym): PNode {. ...raises: [Exception, ERecoverableError, KeyError], tags: [RootEffect, ReadDirEffect].}
- Transforms (iter) to (iter, newClosure[iter]()). This cannot happen as part of liftCapturedVars, as the iterator's environment type is not available at that point. Source Edit
proc liftIterToProc(g: ModuleGraph; fn: PSym; body: PNode; ptrType: PType; idgen: IdGenerator): PNode {. ...raises: [KeyError, Exception, ERecoverableError], tags: [ReadDirEffect, RootEffect].}
- Source Edit
proc liftLambdas(g: ModuleGraph; fn: PSym; body: PNode; idgen: IdGenerator): tuple[ body: PNode, env: PSym] {....raises: [Exception, ERecoverableError, KeyError, ValueError], tags: [RootEffect, ReadDirEffect].}
-
Performs multiple things:
- produce an object type that contains all local variables and parameters of fn (with body body) that inner routines close over
- injects the AST for setting up an instance of the environment
- rewrites definitions and usages of the lifted local variables into an environment field access (but only those directly in body; the bodies of inner routines are not modified)
- rewrites usages of .closure routine symbols into closure construction expressions (i.e., nkClosure). Because of a phase- ordering problem, this step is skipped for symbols of closure iterators
- adds the produced environment type as a hidden parameter to all inner routines defined directly in body (transitive inner routines are not modified)
If fn closes over some outer locals itself, it is required that the environment type through which all closed-over locals are accessible is present as fn's hidden parameter.
In the case of closure iterators, the body of the generated environment type is not yet final -- both transf and the closureiters pass still append to it.
Source Edit proc liftLambdasForTopLevel(module: PSym; body: PNode): PNode {....raises: [], tags: [].}
- Source Edit
proc makeClosure(g: ModuleGraph; idgen: IdGenerator; prc: PSym; env: PNode; info: TLineInfo): PNode {. ...raises: [KeyError, Exception, ERecoverableError], tags: [ReadDirEffect, RootEffect].}
- Source Edit
Templates
template isIterator(owner: PSym): bool
- Source Edit