Macros
macro cdeclmacro(name: string; def: untyped)
-
Macro helper for wrapping a C macro that declares a new C variable.
It handles emitting the appropriate C code for calling the macro.
It can define Nim variables using importc to wrap the generated variable. This is done using varName: CToken in the argument list and adding a cdeclsVar(varName -> varType) pragma. The cdeclsVar tells the macro which CToken argument to use and its type.
The macro will pass any extra pragmas to the variable. If the global pragma is passed in the emitted C code will be put in the /*VARSECTION*/ section.
Example:
import macros import cdecl {.emit: """/*TYPESECTION*/ /* define example C Macro for testing */ #define C_DEFINE_VAR(NM, SZ) int NM[SZ] #define C_DEFINE_VAR_DUO(NM, SZ, NM2) int NM[SZ] """.} proc CDefineVar*(name: CToken, size: static[int]): array[size, int] {. cdeclmacro: "C_DEFINE_VAR", cdeclsVar(name -> array[size, int32]).} # Then it's possible to invoke CDefineVar to call the C macro and # generate a variable: const cVarSz = 4 CDefineVar(myVar, cVarSz) static: discard """`CDefineVar` generates code that looks like:""" discard quote do: template CDefineVar*(name: untyped, size: static[int]) = var name* {.inject, importc, nodecl.}: array[size, int] {.emit: "/*VARSECTION*/\nC_DEFINE_VAR($1, $2); " % [ symbolName(name), $size, ] .}
Example:
import macros import cdecl {.emit: """/*TYPESECTION*/ /* define example C Macro for testing */ #define C_DEFINE_VAR_ADDITION(NM, SZ, N2) \ int32_t NM[SZ]; \ NM[0] = N2 """.} proc CDefineVarStackRaw*(name: CToken, size: static[int], otherRaw: CRawStr): array[size, int32] {. cdeclmacro: "C_DEFINE_VAR_ADDITION", cdeclsVar(name -> array[size, int32]).} # Pass a raw string to the C macro: proc runCDefineVarStackRaw() = CDefineVarStackRaw(myVarStackRaw, 5, CRawStr("40+2")) assert myVarStackRaw[0] == 42
macro symbolName(x: untyped): string