Dear All,
I'm trying to wrap this string matching code: https
The algorithms are all of a standard type and can be wrapped quite easily e.g.
{.compile: "smart/source/algos/kr.c".}
proc kr(x: pointer; m:cint; y: pointer; n:cint): cint {.importc.}
However, I'd like to use macros to automate the wrapping over many algorithms. However, I'm not familiar with Nim metaprogramming, so the following doesn't work:
import macros
const algodir = "smart/source/algos"
const algos = @["bf","kr"]
macro compile_algo(f: string): typed =
result = nnkStmtList.newTree(
nnkPragma.newTree(
nnkExprColonExpr.newTree(
newIdentNode("compile"),
newLit(f)
)
)
)
for algo in algos:
compile_algo(algo)
Here, f is a NimNode, not a string, so throws an error. Any tips?
Hi @shasklick
I could just hack a solution for this, as you rightly point out, but I thought it would be a good opportunity to learn a bit about Nim macros...
I have an example for mpdecimal (a multi-precision floating point decimal library) in my nim-mpdecimal repo:
macro compileFilesFromDir(path: static[string], fileNameBody: untyped): untyped =
# Generate the list of compile statement like so:
# {.compile: "mpdecimal_wrapper/generated/constants.c".}
# {.compile: "mpdecimal_wrapper/generated/mpdecimal.c".}
# ...
#
# from
# compileFilesFromDir("mpdecimal_wrapper/generated/"):
# "constants.c"
# "mpdecimal.c"
# ...
result = newStmtList()
for file in fileNameBody:
assert file.kind == nnkStrLit
result.add nnkPragma.newTree(
nnkExprColonExpr.newTree(
newIdentNode("compile"),
newLit(path & $file)
)
)
# Order is important
compileFilesFromDir("mpdecimal_wrapper/generated/"):
"basearith.c"
"context.c"
"constants.c"
"convolute.c"
"crt.c"
"mpdecimal.c"
"mpsignal.c"
"difradix2.c"
"fnt.c"
"fourstep.c"
"io.c"
"memory.c"
"numbertheory.c"
"sixstep.c"
"transpose.c"
also you can use quote proc which easier to use
macro compileFiles(path: static[string], files: untyped): untyped =
result = newStmtList()
for f in files:
let file = newLit(path & $f)
result.add quote do:
{.compile: `file`.}
compileFiles("/base/path/"):
"a.c"
"b.c"
"c.c"