compiler/sem/sempass2

  Source   Edit

This module contains the second semantic checking pass over the AST. Necessary because the old way had some inherent problems. Performs:

  • effect+exception tracking
  • "usage before definition" checking
  • checking of captured entities
  • detection of whether a procedure captures something and, if necessary, adjusting the calling convention
  • also now calls the "lift destructor logic" at strategic positions, this is about to be put into the spec:

We treat assignment and sinks and destruction as identical.

In the construct let/var x = expr() x's type is marked.

In x = y the type of x is marked.

For every sink parameter of type T T is marked.

For every call f() the return type of f() is marked.

Captured entities

If a local is used inside procedure X but the local does not belong to X, the local needs to be captured. Turning the procedure into a top-level procedure with a hidden environment parameter is later performed by the lambdalifting transformation, but semantic analysis already needs to know which procedures require the closure calling convention, as this information is part of the procedure's type.

Procs

proc canCaptureFrom(captor, target: PSym): bool {....raises: [], tags: [].}

Tests if the captor routine is allowed to capture a local from target, taking the compile-time/run-time boundary into account:

1) attempting to capture a local defined outside an inner macro from

inside the macro is illegal

2) routines usable at run-time may close over locals of compile-time-only

routines

  1. a compile-time-only routine closing over a run-time location is illegal
  Source   Edit
proc checkForSink(config: ConfigRef; idgen: IdGenerator; owner: PSym; arg: PNode) {.
    ...raises: [Exception, ERecoverableError], tags: [RootEffect].}
  Source   Edit
proc checkMethodEffects(g: ModuleGraph; disp, branch: PSym) {.
    ...raises: [Exception, ERecoverableError], tags: [RootEffect].}
checks for consistent effects for multi methods.   Source   Edit
proc setEffectsForProcType(g: ModuleGraph; t: PType; n: PNode; s: PSym = nil) {.
    ...raises: [Exception, ERecoverableError], tags: [RootEffect].}
  Source   Edit
proc trackProc(c: PContext; s: PSym; body: PNode) {.
    ...raises: [Exception, ERecoverableError, KeyError, ValueError],
    tags: [RootEffect, ReadDirEffect].}
  Source   Edit
proc trackStmt(c: PContext; module: PSym; n: PNode; isTopLevel: bool) {.
    ...raises: [Exception, ERecoverableError, KeyError, ValueError],
    tags: [RootEffect, ReadDirEffect].}
  Source   Edit