C.D.E.C.L.: Commonly Desired Edge Case Library
See full docs at docs or source on github at elcritch/cdecl.
Small library for macros to handle various edge cases for Nim syntax. These are mostly edge case syntax handlers or tricky C Macro interfacings. The goal is to implement them as generically and well unit tested as possible.
Current macros includes:
- cdecls: Macros to help using C macros that declare variables
- cdeclmacro
- applies: Macros that unpack arguments from various forms and calls functions
- unpackObjectArgs: macro to splat an object to position arguments
- unpackObjectArgFields: macro to splat an object to keyword arguments
- unpackLabelsAsArgs: turn labels to named arguments
- bitfields: Macros for making bitfield style accessor
- bitfields: create bitfield accessors for hardware registers using any int type
You can see various usages in the tests folder.
Macros
unpackObjectArgs
Helper to apply all fields of an object as named paramters.
type AddObj = object a*: int b*: int proc add(a, b: int): int = result = a + b let args = AddObj(a: 1, b: 2) let res = unpackObjectArgs(add, args) assert res == 3
unpackLabelsAsArgs
Helper to transform labels as named arguments to a function. Labels are regular Nim syntax for calling procs but are transformed to parameter names:
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
cdeclmacro
Macro helper for wrapping a C macro that declares a new C variable.
It handles emitting the appropriate C code for calling the macro. Additionally it defines a new Nim variable using importc which imports the declared variable.
Basic Example
import cdecl/cdecls import cdecl/cdeclapi export cdeclapi # this is needed clients to use the declared apis proc CDefineVar*(name: CToken, size: static[int]) {. cdeclmacro: "C_MACRO_VARIABLE_DECLARER", cdeclsVar(name -> array[size, int32]).} CMacroDeclare(myVar, 128, someExternalCVariable) # creates myVar
macro cdeclmacro(name: string; def: untyped)
CRawStr Example
import macros import cdecl proc CDefineVarStackRaw*(name: CToken, size: static[int], otherRaw: CRawStr): array[size, int32] {. cdeclmacro: "C_DEFINE_VAR_ADDITION".} # Pass a raw string to the C macro: proc runCDefineVarStackRaw() = CDefineVarStackRaw(myVarStackRaw, 5, CRawStr("40+2")) assert myVarStackRaw[0] == 42