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:
import std/macrocache import std/macros const mcTable = CacheTable"myTable" const mcSeq = CacheSeq"mySeq" const mcCounter = CacheCounter"myCounter" static: # add new key "val" with the value `myval` let myval = newLit("hello ic") mcTable["val"] = myval assert mcTable["val"].kind == nnkStrLit # Can access the same cache from different static contexts # All the information is retained static: # get value from `mcTable` and add it to `mcSeq` mcSeq.add(mcTable["val"]) assert mcSeq.len == 1 static: assert mcSeq[0].strVal == "hello ic" # increase `mcCounter` by 3 mcCounter.inc(3) assert mcCounter.value == 3
Types
CacheCounter = distinct string
- Compile-time counter, uses int for storing the count. Source Edit
CacheTable = distinct string
-
Compile-time table of key-value pairs.
Keys are strings and values are NimNodes.
Source Edit
Procs
proc `[]`(s: CacheSeq; i: BackwardsIndex): NimNode {....raises: [], tags: [], forbids: [].}
-
Returns the ith last value from s.
Example:
Source Editimport std/macros const mySeq = CacheSeq"backTest" static: mySeq &= newLit(42) mySeq &= newLit(7) assert mySeq[^1].intVal == 7 # Last item assert mySeq[^2].intVal == 42 # Second last item
-
Returns the ith value from s.
Example:
Source Editimport std/macros const mySeq = CacheSeq"subTest" static: mySeq.add(newLit(42)) assert mySeq[0].intVal == 42
proc `[]`(t: CacheTable; key: string): NimNode {.magic: "NctGet", ...raises: [], tags: [], forbids: [].}
-
Retrieves the NimNode value at t[key].
Example:
Source Editimport std/macros const mcTable = CacheTable"subTest" static: mcTable["toAdd"] = newStmtList() # get the NimNode back assert mcTable["toAdd"].kind == nnkStmtList
proc `[]=`(t: CacheTable; key: string; value: NimNode) {.magic: "NctPut", ...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:
Source Editimport std/macros const mcTable = CacheTable"subTest" static: # assign newLit(5) to the key "value" mcTable["value"] = newLit(5) # check that we can get the value back assert mcTable["value"].kind == nnkIntLit
proc contains(t: CacheTable; key: string): bool {.inline, ...raises: [], tags: [], forbids: [].}
-
Alias of hasKey for use with the in operator.
Example:
Source Editimport std/macros const mcTable = CacheTable"containsEx" static: mcTable["foo"] = newEmptyNode() # Will be true since we gave it a value before assert "foo" in mcTable
proc hasKey(t: CacheTable; key: string): bool {....raises: [], tags: [], forbids: [].}
-
Returns true if key is in the table t.
See also:
- contains proc for use with the in operator
Example:
Source Editimport std/macros const mcTable = CacheTable"hasKeyEx" static: assert not mcTable.hasKey("foo") mcTable["foo"] = newEmptyNode() # Will now be true since we inserted a value assert mcTable.hasKey("foo")
proc inc(c: CacheCounter; by = 1) {.magic: "NccInc", ...raises: [], tags: [], forbids: [].}
-
Increments the counter c with the value by.
Example:
Source Editstatic: let counter = CacheCounter"incTest" inc counter inc counter, 5 assert counter.value == 6
-
Returns the length of s.
Example:
Source Editimport std/macros const mySeq = CacheSeq"lenTest" static: let val = newLit("helper") mySeq.add(val) assert mySeq.len == 1 mySeq.add(val) assert mySeq.len == 2
proc len(t: CacheTable): int {.magic: "NctLen", ...raises: [], tags: [], forbids: [].}
-
Returns the number of elements in t.
Example:
Source Editimport std/macros const dataTable = CacheTable"lenTest" static: dataTable["key"] = newLit(5) assert dataTable.len == 1
proc value(c: CacheCounter): int {.magic: "NccValue", ...raises: [], tags: [], forbids: [].}
-
Returns the value of a counter c.
Example:
Source Editstatic: let counter = CacheCounter"valTest" # default value is 0 assert counter.value == 0 inc counter assert counter.value == 1
Iterators
iterator pairs(t: CacheTable): (string, NimNode) {....raises: [], tags: [], forbids: [].}
-
Iterates over all (key, value) pairs in t.
Example:
Source Editimport std/macros const mytabl = CacheTable"values" static: mytabl["intVal"] = newLit(5) mytabl["otherVal"] = newLit(6) for key, val in mytabl: # make sure that we actually get the same keys assert key in ["intVal", "otherVal"] # all vals are int literals assert val.kind == nnkIntLit