compiler/sem/sem

  Source   Edit

This module implements the instantiation of generic procs. included from sem.nimThis module implements semantic checking for calls. included from sem.nimthis module does the semantic checking of type declarations included from sem.nimThe current implementation of templates might not yet conform to the description that follows.

Template Basics

Given a basic template as follows: ..code:

template identity(arg: untyped): untyped =
  arg

The template's output type is untyped, meaning the body (arg) is treated as an untyped AST fragment, that substitution of parameters will evaluate per the rules of untyped templates, and finally evaluation and insertion of the template at the callsite will be hygeinic. The template parameter arg will be captured as untyped, meaning no attempt will be made to semantically analyse the parameter prior to substitution.

Template Taxonomy

There are at least four types of templates across two categories:

  • AST templates:
    • untyped
      • dirty a non-hygienic sub-variant
    • typed
  • expression templates (all types that are not untyped or typed)

Substitution Positions

Templates are ultimately AST level constructs regardless of output type, they must be valid syntax. There are two types of positions in a template body, one is definition and the other is usage. A definition is any position where the grammar construct is intended to introduce a new symbol, i.e.: the name of a routine, including its parameters; names of variables (const, let, var), and so on. All other sites are usage sites, where a symbol referring to a "chunk" of AST might be used.

This is a draft of subsitution rules:

  • untyped template bodies accept untyped params in definition or usage positions; and all other params are usage only
  • typed template bodies accept untyped params in definition or usage positions; and all other params are usage only
  • non-ast template bodies only allow subsitutions within usage positions

This implements the first pass over the generic body; it resolves some symbols. Thus for generics there is a two-phase symbol lookup.

A two-phase lookup as today is templates and not generics, AKA mistake.

A problem is that it cannot be detected if the symbol is introduced as in var x = ... or used because macros/templates can hide this! So we have to eval templates/macros right here so that symbol lookup can be accurate.

included from sem.nim
this module does the semantic checking of statements
included from sem.nim
This module does the semantic transformation of the fields* iterators.
included from semstmts.nim
this module does the semantic checking for expressions included from sem.nimThis module implements Nim's object construction rules.

Future Considerations/Improvements:

  • The return nil pattern leads to a lot of boilerplate, most of this is for PNodes which can be converted to use nkEmpty and/or optional.
included from sem.nim

Consts

semPass = (open: myOpen, process: myProcess, close: myClose, isFrontend: true)
  Source   Edit
tyGenericLike = {tyGenericInvocation, tyGenericInst, tyArray, tySet, tySequence,
                 tyOpenArray, tyUserTypeClassInst..tyCompositeTypeClass}
  Source   Edit
tyMagicGenerics = {tySet, tySequence, tyArray, tyOpenArray}
  Source   Edit
tyUserDefinedGenerics = {tyGenericInst, tyGenericInvocation, tyUserTypeClassInst}
  Source   Edit

Procs

proc commonType(c: PContext; x, y: PType): PType {.
    ...raises: [KeyError, Exception], tags: [ReadDirEffect, RootEffect].}
  Source   Edit
proc commonType(c: PContext; x: PType; y: PNode): PType {.
    ...raises: [KeyError, Exception], tags: [ReadDirEffect, RootEffect].}
  Source   Edit
proc instGenericConvertersArg(c: PContext; a: PNode; x: TCandidate) {.
    ...raises: [Exception, ERecoverableError, KeyError, ValueError],
    tags: [RootEffect, ReadDirEffect, ReadIOEffect, ReadEnvEffect, TimeEffect].}
  Source   Edit
proc instGenericConvertersSons(c: PContext; n: PNode; x: TCandidate) {.
    ...raises: [Exception, ERecoverableError, KeyError, ValueError],
    tags: [RootEffect, ReadDirEffect, ReadIOEffect, ReadEnvEffect, TimeEffect].}
  Source   Edit
proc maybeResemArgs(c: PContext; n: PNode; startIdx: int = 1): seq[PNode] {.
    ...raises: [Exception], tags: [RootEffect].}
  Source   Edit
proc produceSymbol(kind: TSymKind; n: PNode; c: PContext): PSym {.
    ...raises: [Exception], tags: [RootEffect].}
Creates (or reuses) a symbol with the given kind kind from the identifier-like node n appearing in an identifier-binding position. Always returns a valid symbol, even when there's an error (in which case a diagnostic is emitted).   Source   Edit
proc toLiterals(vals: IntSet; t: PType): seq[PNode] {....raises: [], tags: [].}
  Source   Edit

Templates

template commonTypeBegin(): PType
  Source   Edit