It seems I've run into a few other syntax edge cases and rather than proliferating lots of libraries I've re-purposed CDecl into C.D.E.C.L.: Commonly Desired Edge Case Library. Originally it was just for a C-Declaration marco but luckily the name CDecl lends itself to the above acronym.
The most useful for others would likely be unpackLabelsAsArgs. It's pretty great for making YAML like API's with Nim without needing to write your own complicated macros.
The macro utilities now include:
You can see various usages in the tests folder.
Here's an example way to make a YAML like api for existing proc's, like:
Foo:
name: "buzz"
a: 11
b: 22
proc foo(name: string = "buzz", a, b: int) =
echo name, ":", " a: ", $a, " b: ", $b
template Foo(blk: varargs[untyped]) =
## create a new template to act YAML like API
unpackLabelsAsArgs(foo, blk)
Foo:
name: "buzz"
a: 11
b: 22
Will call foo(name="buzz",a=11,b=22) and print:
buzz: a: 11 b: 22
Hopefully some of these might be useful to others. :-)
macros2 provides a port of std/macros that can be used in a Nim program at runtime. This makes it easy to change code generation macros into standalone generators.
It seemed odd, but I couldn't find anywhere that someone had already done this.
It builds on compiler/ast and already works on a large-ish codegen project. Most of the basics work and it will let you create Nim code in a standalone program with minor modifications. However, a few proc's like getType and quote aren't yet working. Also NimNode fields like intVal and strVal have oddities. Basically "there be dragons".
Any feedback or help on how to do things better would be great. I used it to make a standalone version of the NimFlatbuffers code generator.
Note: This one is currently "beta" and is not unit tested and therefore isn't included in the CDECL docs.
The bitfields macro provides an easy syntax to use C-style bitfields with integer types. It uses portable getters and setters which wrap standard bitops operations. It's not intended to replace binary parsers. Instead it's oriented toward simple hardware register manipulations.
https://elcritch.github.io/cdecl/cdecl/bitfields.html
bitfields RegConfig(uint8):
## define RegConfig integer with accessors for `bitfields`
clockEnable: bool[7..7]
daisyIn: bool[6..6]
speed: int8[5..1]
## Now use it to make a new register field
var regConfig: RegConfig
regConfig.clockEnable= true
regConfig.speed= -10
assert regConfig.clockEnable == true
assert regConfig.speed == -10
It's possible to omit default parameters from unpackLabelsAsArgs? E.g. when defined:
proc line(a, b: Vec2, thickness=1) =
discard
template Line(blk: varargs[untyped]) =
## create a new template to act YAML like API
unpackLabelsAsArgs(foo, blk)
Line:
a: Vec(0,0)
b: Vec(10,10)
# omitting thickness
Yes! It does and you can find the test cases for that here: https://github.com/elcritch/cdecl/blob/30df0015378d43fe67d45f88fe0aaa2ea4cfa828/tests/testApplies.nim#L135
I tried to be thorough with every combination of defaults, positional, and named args. However if you find an edge case where it breaks, please file an issue.