Skip to content

Commit d040f7a

Browse files
committed
feat(inner): version: wrapPySince, templWrapExportSincePy
1 parent ed7a254 commit d040f7a

File tree

1 file changed

+60
-2
lines changed

1 file changed

+60
-2
lines changed

src/pylib/version.nim

Lines changed: 60 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,37 @@ export versionInfo
1414

1515
const
1616
Version* = asVersion(Major, Minor, Patch)
17+
template exportSincePy*(major, minor: int, sym: typed) =
18+
bind PyMajor, PyMinor
19+
when (PyMajor, PyMinor) >= (major, minor):
20+
export sym
21+
22+
import std/macros
23+
proc newCallFrom(sym, params: NimNode): NimNode =
24+
result = newCall(sym)
25+
for i in 1..<params.len:
26+
result.add params[i][0]
27+
28+
proc templWrapExportSincePyImpl(major, minor: int, sym: NimNode): NimNode =
29+
let emptyn = newEmptyNode()
30+
result = newNimNode nnkTemplateDef
31+
let
32+
impl = sym.getImpl()
33+
params = impl[3]
34+
var nparams = params.copyNimTree
35+
nparams[0] = bindSym"untyped"
36+
result.add(
37+
postfix(sym, "*"), emptyn, # term rewrite
38+
impl[2], nparams,
39+
emptyn, emptyn, # pragma, preversed
40+
newStmtList sym.newCallFrom params
41+
)
42+
43+
macro templWrapExportSincePy*(major, minor: static int, sym: typed) =
44+
## generate `template sym*(...): untyped = sym(...)`
45+
templWrapExportSincePyImpl(major, minor, sym)
1746

1847
when defined(nimdoc):
19-
import std/macros
2048
func preappendDoc(body: NimNode, doc: string) =
2149
let first = body[0]
2250
if first.kind == nnkCommentStmt:
@@ -34,17 +62,47 @@ when defined(nimdoc):
3462
## as diagnosis tools like dumpTree just omit doc node of non-proc node
3563
template descSince(ver: string): string =
3664
" .. admonition:: since Python " & ver & "\n\n"
65+
func addDocImpl(major, minor: int; def: NimNode): NimNode =
66+
addDocImpl(asVersion(major, minor).descSince, def)
3767
macro pysince*(major, minor: static int, def) =
3868
if def.kind == nnkStmtList:
3969
result = def
4070
else:
41-
result = addDocImpl(asVersion(major, minor).descSince, def)
71+
result = addDocImpl(major, minor, def)
72+
73+
proc genWrapCall(sym: NimNode): NimNode =
74+
result = sym.getImpl()
75+
var call = sym.newCallFrom result.params
76+
case result.kind
77+
of nnkIteratorDef:
78+
call = quote do:
79+
for i in `call`: yield i
80+
of nnkMacroDef, nnkTemplateDef:
81+
var nres = newNimNode nnkTemplateDef
82+
nres.add postfix(ident result[0].strVal, "*") # get rid of
83+
# Error: cannot use symbol of kind 'macro' as a 'template
84+
for i in 1..<result.len-1: # skip body
85+
nres.add result[i]
86+
nres.add newEmptyNode()
87+
result = nres
88+
else: discard
89+
result.body = newStmtList call
90+
91+
macro wrapExportSincePy*(major, minor: static int, sym: typed) =
92+
if sym.typeKind == ntyProc: # includes template, macro
93+
let def = sym.genWrapCall()
94+
result = addDocImpl(major, minor, def)
95+
else:
96+
result = newCall(bindSym"exportSincePy", major.newLit, minor.newLit, sym)
4297

4398
else:
4499
template pysince*(major, minor: int, def){.dirty.} =
45100
bind PyMajor, PyMinor
46101
when (PyMajor, PyMinor) >= (major, minor):
47102
def
103+
template wrapExportSincePy*(major, minor: int, sym: typed) =
104+
bind exportSincePy
105+
exportSincePy(major, minor, sym)
48106

49107
type MajorMinorVersion = tuple[major, minor: int]
50108

0 commit comments

Comments
 (0)