compiler/sem/lambdalifting

  Source   Edit

This file implements lambda lifting for the transformator.

Consts

envName = ":env"
  Source   Edit
paramName = ":envP"
  Source   Edit
upName = ":up"
  Source   Edit

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