@@ -54,14 +54,28 @@ proc parseDefine(p: var Parser; hasParams: bool): PNode =
54
54
addSon(params, emptyNode)
55
55
if p.tok.xkind != pxParRi:
56
56
var identDefs = newNodeP(nkIdentDefs, p)
57
+ var isVariable = false
57
58
while p.tok.xkind != pxParRi:
59
+ if p.tok.xkind == pxDotDotDot:
60
+ isVariable = true
61
+ getTok(p)
62
+ break
58
63
addSon(identDefs, skipIdent(p, skParam))
59
64
skipStarCom(p, nil )
60
65
if p.tok.xkind != pxComma: break
61
66
getTok(p)
62
67
addSon(identDefs, newIdentNodeP(" untyped" , p))
63
68
addSon(identDefs, emptyNode)
64
69
addSon(params, identDefs)
70
+ if isVariable:
71
+ var vdefs = newNodeP(nkExprColonExpr, p)
72
+ addSon(vdefs, newIdentNodeP(" xargs" , p))
73
+ var vdecl =
74
+ newTree(nkBracketExpr,
75
+ newIdentNodeP(" varargs" , p),
76
+ newIdentNodeP(" untyped" , p))
77
+ addSon(vdefs, vdecl)
78
+ addSon(params, vdefs)
65
79
eat(p, pxParRi)
66
80
67
81
addSon(result , emptyNode) # no generic parameters
@@ -91,6 +105,78 @@ proc parseDefine(p: var Parser; hasParams: bool): PNode =
91
105
break
92
106
assert result != nil
93
107
108
+ proc parseDefineAsDecls(p: var Parser; hasParams: bool ): PNode =
109
+ var origName = p.tok.s
110
+ if hasParams:
111
+ # a macro with parameters:
112
+ result = newNodeP(nkProcDef, p)
113
+ var name = skipIdentExport(p, skTemplate)
114
+ addSon(result , name)
115
+ addSon(result , emptyNode)
116
+ eat(p, pxParLe)
117
+ var params = newNodeP(nkFormalParams, p)
118
+ # return type; not known yet:
119
+ addSon(params, emptyNode)
120
+
121
+ var pragmas = newNodeP(nkPragma, p)
122
+
123
+ if p.tok.xkind != pxParRi:
124
+ while p.tok.xkind != pxParRi:
125
+ if p.tok.xkind == pxDotDotDot: # handle varargs
126
+ getTok(p)
127
+ addSon(pragmas, newIdentNodeP(" varargs" , p))
128
+ break
129
+ else :
130
+ var vdefs = newTree(nkExprColonExpr,
131
+ skipIdent(p, skParam),
132
+ newIdentNodeP(" untyped" , p))
133
+ addSon(params, vdefs)
134
+
135
+ skipStarCom(p, nil )
136
+ if p.tok.xkind != pxComma:
137
+ break
138
+ getTok(p)
139
+
140
+ eat(p, pxParRi)
141
+
142
+ let iname = cppImportName(p, origName)
143
+ addSon(pragmas,
144
+ newIdentStrLitPair(p.options.importcLit, iname, p),
145
+ getHeaderPair(p))
146
+
147
+ addSon(result , emptyNode) # no generic parameters
148
+ addSon(result , params)
149
+ addSon(result , pragmas)
150
+ addSon(result , emptyNode)
151
+
152
+ addSon(result , emptyNode)
153
+ skipLine(p)
154
+
155
+ else :
156
+ # a macro without parameters:
157
+ result = newNodeP(nkVarTy, p)
158
+
159
+ while true :
160
+ let vname = skipIdentExport(p, skConst)
161
+ # skipStarCom(p, result)
162
+ let iname = cppImportName(p, origName)
163
+ var vpragmas = newNodeP(nkPragma, p)
164
+ addSon(vpragmas, newIdentStrLitPair(p.options.importcLit, iname, p))
165
+ addSon(vpragmas, getHeaderPair(p))
166
+ let vtype = newIdentNodeP(" int" , p)
167
+
168
+ addSon(result , vname)
169
+ addSon(result , vpragmas)
170
+ addSon(result , vtype)
171
+
172
+ skipCom(p, result )
173
+ skipLine(p) # eat the rest of the define, skip parsing
174
+ if p.tok.xkind == pxDirective and p.tok.s == " define" :
175
+ getTok(p)
176
+ else :
177
+ break
178
+ assert result != nil
179
+
94
180
proc dontTranslateToTemplateHeuristic(body: seq [ref Token]; closedParentheses: int ) : bool =
95
181
# we list all **binary** operators here too: As these cannot start an
96
182
# expression, we know the resulting #define cannot be a valid Nim template.
@@ -184,6 +270,9 @@ proc parseDef(p: var Parser, m: var Macro; hasParams: bool): bool =
184
270
if hasParams:
185
271
eat(p, pxParLe)
186
272
while p.tok.xkind != pxParRi:
273
+ if p.tok.xkind == pxDotDotDot:
274
+ getTok(p)
275
+ break
187
276
expectIdent(p)
188
277
params.add(p.tok.s)
189
278
getTok(p)
@@ -510,7 +599,12 @@ proc parseDir(p: var Parser; sectionParser: SectionParser): PNode =
510
599
if not parseDef(p, p.options.macros[L], hasParams) and not isDefOverride:
511
600
setLen(p.options.macros, L)
512
601
backtrackContext(p)
513
- result = parseDefine(p, hasParams)
602
+ if p.options.importdefines:
603
+ result = parseDefineAsDecls(p, hasParams)
604
+ elif p.options.importfuncdefines and hasParams:
605
+ result = parseDefineAsDecls(p, hasParams)
606
+ else :
607
+ result = parseDefine(p, hasParams)
514
608
else :
515
609
closeContext(p)
516
610
0 commit comments