Add documentation to the macrocache module (#17431)
* Add docs to macrocache * use hint * Use incl in the incl example * add macrocache to lib * consistency * Update doc/lib.rst Co-authored-by: konsumlamm <44230978+konsumlamm@users.noreply.github.com> * apply suggestions * clarify the warning Co-authored-by: konsumlamm <44230978+konsumlamm@users.noreply.github.com>
This commit is contained in:
parent
eca0b87544
commit
c5b109233a
2 changed files with 179 additions and 15 deletions
|
|
@ -64,6 +64,9 @@ Core
|
||||||
* `locks <locks.html>`_
|
* `locks <locks.html>`_
|
||||||
Locks and condition variables for Nim.
|
Locks and condition variables for Nim.
|
||||||
|
|
||||||
|
* `macrocache <macrocache.html>`_
|
||||||
|
Provides an API for macros to collect compile-time information across modules.
|
||||||
|
|
||||||
* `macros <macros.html>`_
|
* `macros <macros.html>`_
|
||||||
Contains the AST API and documentation of Nim for writing macros.
|
Contains the AST API and documentation of Nim for writing macros.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,38 +7,199 @@
|
||||||
# distribution, for details about the copyright.
|
# distribution, for details about the copyright.
|
||||||
#
|
#
|
||||||
|
|
||||||
## This module provides an API for macros that need to collect compile
|
## This module provides an API for macros to collect compile-time information
|
||||||
## time information across module boundaries in global variables.
|
## across module boundaries. It should be used instead of global `{.compileTime.}`
|
||||||
## Starting with version 0.19 of Nim this is not directly supported anymore
|
## variables as those break incremental compilation.
|
||||||
## as it breaks incremental compilations.
|
##
|
||||||
## Instead the API here needs to be used.
|
## The main feature of this module is that if you create `CacheTable`s 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.
|
||||||
|
|
||||||
|
runnableExamples:
|
||||||
|
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
|
||||||
|
|
||||||
|
|
||||||
type
|
type
|
||||||
CacheSeq* = distinct string
|
CacheSeq* = distinct string
|
||||||
|
## Compile-time sequence of `NimNode`s.
|
||||||
CacheTable* = distinct string
|
CacheTable* = distinct string
|
||||||
|
## Compile-time table of key-value pairs.
|
||||||
|
##
|
||||||
|
## Keys are `string`s and values are `NimNode`s.
|
||||||
CacheCounter* = distinct string
|
CacheCounter* = distinct string
|
||||||
|
## Compile-time counter, uses `int` for storing the count.
|
||||||
|
|
||||||
proc value*(c: CacheCounter): int {.magic: "NccValue".}
|
proc value*(c: CacheCounter): int {.magic: "NccValue".} =
|
||||||
proc inc*(c: CacheCounter; by = 1) {.magic: "NccInc".}
|
## Returns the value of a counter `c`.
|
||||||
|
runnableExamples:
|
||||||
|
static:
|
||||||
|
let counter = CacheCounter"valTest"
|
||||||
|
# default value is 0
|
||||||
|
assert counter.value == 0
|
||||||
|
|
||||||
proc add*(s: CacheSeq; value: NimNode) {.magic: "NcsAdd".}
|
inc counter
|
||||||
proc incl*(s: CacheSeq; value: NimNode) {.magic: "NcsIncl".}
|
assert counter.value == 1
|
||||||
proc len*(s: CacheSeq): int {.magic: "NcsLen".}
|
|
||||||
proc `[]`*(s: CacheSeq; i: int): NimNode {.magic: "NcsAt".}
|
proc inc*(c: CacheCounter; by = 1) {.magic: "NccInc".} =
|
||||||
|
## Increments the counter `c` with the value `by`.
|
||||||
|
runnableExamples:
|
||||||
|
static:
|
||||||
|
let counter = CacheCounter"incTest"
|
||||||
|
inc counter
|
||||||
|
inc counter, 5
|
||||||
|
|
||||||
|
assert counter.value == 6
|
||||||
|
|
||||||
|
proc add*(s: CacheSeq; value: NimNode) {.magic: "NcsAdd".} =
|
||||||
|
## Adds `value` to `s`.
|
||||||
|
runnableExamples:
|
||||||
|
import std/macros
|
||||||
|
const mySeq = CacheSeq"addTest"
|
||||||
|
|
||||||
|
static:
|
||||||
|
mySeq.add(newLit(5))
|
||||||
|
mySeq.add(newLit("hello ic"))
|
||||||
|
|
||||||
|
assert mySeq.len == 2
|
||||||
|
assert mySeq[1].strVal == "hello ic"
|
||||||
|
|
||||||
|
proc incl*(s: CacheSeq; value: NimNode) {.magic: "NcsIncl".} =
|
||||||
|
## Adds `value` to `s`.
|
||||||
|
##
|
||||||
|
## .. hint:: This doesn't do anything if `value` is already in `s`.
|
||||||
|
runnableExamples:
|
||||||
|
import std/macros
|
||||||
|
const mySeq = CacheSeq"inclTest"
|
||||||
|
|
||||||
|
static:
|
||||||
|
mySeq.incl(newLit(5))
|
||||||
|
mySeq.incl(newLit(5))
|
||||||
|
|
||||||
|
# still one element
|
||||||
|
assert mySeq.len == 1
|
||||||
|
|
||||||
|
proc len*(s: CacheSeq): int {.magic: "NcsLen".} =
|
||||||
|
## Returns the length of `s`.
|
||||||
|
runnableExamples:
|
||||||
|
import 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 `[]`*(s: CacheSeq; i: int): NimNode {.magic: "NcsAt".} =
|
||||||
|
## Returns the `i`th value from `s`.
|
||||||
|
runnableExamples:
|
||||||
|
import std/macros
|
||||||
|
|
||||||
|
const mySeq = CacheSeq"subTest"
|
||||||
|
static:
|
||||||
|
mySeq.add(newLit(42))
|
||||||
|
assert mySeq[0].intVal == 42
|
||||||
|
|
||||||
iterator items*(s: CacheSeq): NimNode =
|
iterator items*(s: CacheSeq): NimNode =
|
||||||
|
## Iterates over each item in `s`.
|
||||||
|
runnableExamples:
|
||||||
|
import std/macros
|
||||||
|
const myseq = CacheSeq"itemsTest"
|
||||||
|
|
||||||
|
static:
|
||||||
|
myseq.add(newLit(5))
|
||||||
|
myseq.add(newLit(42))
|
||||||
|
|
||||||
|
for val in myseq:
|
||||||
|
# check that all values in `myseq` are int literals
|
||||||
|
assert val.kind == nnkIntLit
|
||||||
|
|
||||||
for i in 0 ..< len(s): yield s[i]
|
for i in 0 ..< len(s): yield s[i]
|
||||||
|
|
||||||
proc `[]=`*(t: CacheTable; key: string, value: NimNode) {.magic: "NctPut".}
|
proc `[]=`*(t: CacheTable; key: string, value: NimNode) {.magic: "NctPut".} =
|
||||||
## 'key' has to be unique!
|
## 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.
|
||||||
|
runnableExamples:
|
||||||
|
import std/macros
|
||||||
|
|
||||||
proc len*(t: CacheTable): int {.magic: "NctLen".}
|
const mcTable = CacheTable"subTest"
|
||||||
proc `[]`*(t: CacheTable; key: string): NimNode {.magic: "NctGet".}
|
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 len*(t: CacheTable): int {.magic: "NctLen".} =
|
||||||
|
## Returns the number of elements in `t`.
|
||||||
|
runnableExamples:
|
||||||
|
import std/macros
|
||||||
|
|
||||||
|
const dataTable = CacheTable"lenTest"
|
||||||
|
static:
|
||||||
|
dataTable["key"] = newLit(5)
|
||||||
|
assert dataTable.len == 1
|
||||||
|
|
||||||
|
proc `[]`*(t: CacheTable; key: string): NimNode {.magic: "NctGet".} =
|
||||||
|
## Retrieves the `NimNode` value at `t[key]`.
|
||||||
|
runnableExamples:
|
||||||
|
import std/macros
|
||||||
|
|
||||||
|
const mcTable = CacheTable"subTest"
|
||||||
|
static:
|
||||||
|
mcTable["toAdd"] = newStmtList()
|
||||||
|
|
||||||
|
# get the NimNode back
|
||||||
|
assert mcTable["toAdd"].kind == nnkStmtList
|
||||||
|
|
||||||
proc hasNext(t: CacheTable; iter: int): bool {.magic: "NctHasNext".}
|
proc hasNext(t: CacheTable; iter: int): bool {.magic: "NctHasNext".}
|
||||||
proc next(t: CacheTable; iter: int): (string, NimNode, int) {.magic: "NctNext".}
|
proc next(t: CacheTable; iter: int): (string, NimNode, int) {.magic: "NctNext".}
|
||||||
|
|
||||||
iterator pairs*(t: CacheTable): (string, NimNode) =
|
iterator pairs*(t: CacheTable): (string, NimNode) =
|
||||||
|
## Iterates over all `(key, value)` pairs in `t`.
|
||||||
|
runnableExamples:
|
||||||
|
import 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
|
||||||
|
|
||||||
var h = 0
|
var h = 0
|
||||||
while hasNext(t, h):
|
while hasNext(t, h):
|
||||||
let (a, b, h2) = next(t, h)
|
let (a, b, h2) = next(t, h)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue