Source Edit

This module provides an API for macros to collect compile-time information across module boundaries. It should be used instead of global {.compileTime.} variables as those break incremental compilation.

The main feature of this module is that if you create CacheTables or any other Cache types with the same name in different modules, their content will be shared, meaning that you can fill a CacheTable in one module, and iterate over its contents in another.

Example:

  1. import std/macrocache
  2. import std/macros
  3. const mcTable = CacheTable"myTable"
  4. const mcSeq = CacheSeq"mySeq"
  5. const mcCounter = CacheCounter"myCounter"
  6. static:
  7. # add new key "val" with the value `myval`
  8. let myval = newLit("hello ic")
  9. mcTable["val"] = myval
  10. assert mcTable["val"].kind == nnkStrLit
  11. # Can access the same cache from different static contexts
  12. # All the information is retained
  13. static:
  14. # get value from `mcTable` and add it to `mcSeq`
  15. mcSeq.add(mcTable["val"])
  16. assert mcSeq.len == 1
  17. static:
  18. assert mcSeq[0].strVal == "hello ic"
  19. # increase `mcCounter` by 3
  20. mcCounter.inc(3)
  21. assert mcCounter.value == 3

Types

  1. CacheCounter = distinct string

Compile-time counter, uses int for storing the count. Source Edit

  1. CacheSeq = distinct string

Compile-time sequence of NimNodes. Source Edit

  1. CacheTable = distinct string

Compile-time table of key-value pairs.

Keys are strings and values are NimNodes.

Source Edit

Procs

  1. proc `[]`(s: CacheSeq; i: BackwardsIndex): NimNode {....raises: [], tags: [],
  2. forbids: [].}

Returns the ith last value from s.

Example:

  1. import std/macros
  2. const mySeq = CacheSeq"backTest"
  3. static:
  4. mySeq &= newLit(42)
  5. mySeq &= newLit(7)
  6. assert mySeq[^1].intVal == 7 # Last item
  7. assert mySeq[^2].intVal == 42 # Second last item

Source Edit

  1. proc `[]`(s: CacheSeq; i: int): NimNode {.magic: "NcsAt", ...raises: [], tags: [],
  2. forbids: [].}

Returns the ith value from s.

Example:

  1. import std/macros
  2. const mySeq = CacheSeq"subTest"
  3. static:
  4. mySeq.add(newLit(42))
  5. assert mySeq[0].intVal == 42

Source Edit

  1. proc `[]`(t: CacheTable; key: string): NimNode {.magic: "NctGet", ...raises: [],
  2. tags: [], forbids: [].}

Retrieves the NimNode value at t[key].

Example:

  1. import std/macros
  2. const mcTable = CacheTable"subTest"
  3. static:
  4. mcTable["toAdd"] = newStmtList()
  5. # get the NimNode back
  6. assert mcTable["toAdd"].kind == nnkStmtList

Source Edit

  1. proc `[]=`(t: CacheTable; key: string; value: NimNode) {.magic: "NctPut",
  2. ...raises: [], tags: [], forbids: [].}

Inserts a (key, value) pair into t.

Warning: key has to be unique! Assigning value to a key that is already in the table will result in a compiler error.

Example:

  1. import std/macros
  2. const mcTable = CacheTable"subTest"
  3. static:
  4. # assign newLit(5) to the key "value"
  5. mcTable["value"] = newLit(5)
  6. # check that we can get the value back
  7. assert mcTable["value"].kind == nnkIntLit

Source Edit

  1. proc add(s: CacheSeq; value: NimNode) {.magic: "NcsAdd", ...raises: [], tags: [],
  2. forbids: [].}

Adds value to s.

Example:

  1. import std/macros
  2. const mySeq = CacheSeq"addTest"
  3. static:
  4. mySeq.add(newLit(5))
  5. mySeq.add(newLit("hello ic"))
  6. assert mySeq.len == 2
  7. assert mySeq[1].strVal == "hello ic"

Source Edit

  1. proc contains(t: CacheTable; key: string): bool {.inline, ...raises: [], tags: [],
  2. forbids: [].}

Alias of hasKey for use with the in operator.

Example:

  1. import std/macros
  2. const mcTable = CacheTable"containsEx"
  3. static:
  4. mcTable["foo"] = newEmptyNode()
  5. # Will be true since we gave it a value before
  6. assert "foo" in mcTable

Source Edit

  1. proc hasKey(t: CacheTable; key: string): bool {....raises: [], tags: [],
  2. forbids: [].}

Returns true if key is in the table t.

See also:

Example:

  1. import std/macros
  2. const mcTable = CacheTable"hasKeyEx"
  3. static:
  4. assert not mcTable.hasKey("foo")
  5. mcTable["foo"] = newEmptyNode()
  6. # Will now be true since we inserted a value
  7. assert mcTable.hasKey("foo")

Source Edit

  1. proc inc(c: CacheCounter; by = 1) {.magic: "NccInc", ...raises: [], tags: [],
  2. forbids: [].}

Increments the counter c with the value by.

Example:

  1. static:
  2. let counter = CacheCounter"incTest"
  3. inc counter
  4. inc counter, 5
  5. assert counter.value == 6

Source Edit

  1. proc incl(s: CacheSeq; value: NimNode) {.magic: "NcsIncl", ...raises: [], tags: [],
  2. forbids: [].}

Adds value to s.

Hint: This doesn’t do anything if value is already in s.

Example:

  1. import std/macros
  2. const mySeq = CacheSeq"inclTest"
  3. static:
  4. mySeq.incl(newLit(5))
  5. mySeq.incl(newLit(5))
  6. # still one element
  7. assert mySeq.len == 1

Source Edit

  1. proc len(s: CacheSeq): int {.magic: "NcsLen", ...raises: [], tags: [], forbids: [].}

Returns the length of s.

Example:

  1. import std/macros
  2. const mySeq = CacheSeq"lenTest"
  3. static:
  4. let val = newLit("helper")
  5. mySeq.add(val)
  6. assert mySeq.len == 1
  7. mySeq.add(val)
  8. assert mySeq.len == 2

Source Edit

  1. proc len(t: CacheTable): int {.magic: "NctLen", ...raises: [], tags: [],
  2. forbids: [].}

Returns the number of elements in t.

Example:

  1. import std/macros
  2. const dataTable = CacheTable"lenTest"
  3. static:
  4. dataTable["key"] = newLit(5)
  5. assert dataTable.len == 1

Source Edit

  1. proc value(c: CacheCounter): int {.magic: "NccValue", ...raises: [], tags: [],
  2. forbids: [].}

Returns the value of a counter c.

Example:

  1. static:
  2. let counter = CacheCounter"valTest"
  3. # default value is 0
  4. assert counter.value == 0
  5. inc counter
  6. assert counter.value == 1

Source Edit

Iterators

  1. iterator items(s: CacheSeq): NimNode {....raises: [], tags: [], forbids: [].}

Iterates over each item in s.

Example:

  1. import std/macros
  2. const myseq = CacheSeq"itemsTest"
  3. static:
  4. myseq.add(newLit(5))
  5. myseq.add(newLit(42))
  6. for val in myseq:
  7. # check that all values in `myseq` are int literals
  8. assert val.kind == nnkIntLit

Source Edit

  1. iterator pairs(t: CacheTable): (string, NimNode) {....raises: [], tags: [],
  2. forbids: [].}

Iterates over all (key, value) pairs in t.

Example:

  1. import std/macros
  2. const mytabl = CacheTable"values"
  3. static:
  4. mytabl["intVal"] = newLit(5)
  5. mytabl["otherVal"] = newLit(6)
  6. for key, val in mytabl:
  7. # make sure that we actually get the same keys
  8. assert key in ["intVal", "otherVal"]
  9. # all vals are int literals
  10. assert val.kind == nnkIntLit

Source Edit