@@ -4,6 +4,7 @@ import std/macrocache
4
4
from std/ strutils import toLowerAscii, normalize
5
5
import ../../ pystring/ [strimpl, strprefix]
6
6
import ../../ builtins/ [list_decl, set , dict, pyslice]
7
+ import ./ frame
7
8
8
9
const CollectionSyms = CacheSeq " CollectionSyms"
9
10
static :
@@ -13,25 +14,26 @@ static:
13
14
CollectionSyms .add bindSym " slice"
14
15
15
16
using e: NimNode
16
- proc toPyExpr * (atm: NimNode ): NimNode
17
+ using mparser: var PyAsgnRewriter
18
+ proc toPyExpr * (mparser; atm: NimNode ): NimNode
17
19
18
20
template newSlice (a, b: NimNode ): NimNode =
19
21
newCall (CollectionSyms [3 ], a, b)
20
22
21
- proc colonToSlice (colonExpr: NimNode ): NimNode =
23
+ proc colonToSlice (mparser; colonExpr: NimNode ): NimNode =
22
24
# # a:b -> slice(a,b)
23
- newSlice (colonExpr[0 ].toPyExpr, colonExpr[1 ].toPyExpr )
25
+ newSlice (mparser. toPyExpr colonExpr[0 ], mparser .toPyExpr colonExpr[1 ])
24
26
25
- proc rewriteSliceInBracket (bracketExpr: NimNode ): NimNode =
27
+ proc rewriteSliceInBracket (mparser; bracketExpr: NimNode ): NimNode =
26
28
result = bracketExpr.copyNimNode
27
- result .add bracketExpr[0 ].toPyExpr
29
+ result .add mparser. toPyExpr bracketExpr[0 ]
28
30
for i in 1 ..< bracketExpr.len:
29
31
let ele = bracketExpr[i]
30
32
result .add:
31
33
let k = ele.kind
32
- if k == nnkExprColonExpr: colonToSlice ele
34
+ if k == nnkExprColonExpr: mparser. colonToSlice ele
33
35
elif k == nnkInfix and ele[0 ].eqIdent " :-" : # like `ls[1:-1]`
34
- newSlice (ele[1 ].toPyExpr , prefix (ele[2 ].toPyExpr , " -" ))
36
+ newSlice (mparser. toPyExpr ele[1 ], prefix (mparser. toPyExpr ele[2 ], " -" ))
35
37
else : ele
36
38
37
39
#[
@@ -75,14 +77,14 @@ func validStrLit(e: NimNode): bool =
75
77
actStr.normalize == " fmt"
76
78
77
79
78
- proc rewriteStrLitCat (e: NimNode ): NimNode =
80
+ proc rewriteStrLitCat (mparser; e: NimNode ): NimNode =
79
81
if e.len != 2 :
80
82
return e
81
83
let
82
84
lhs = e[0 ]
83
85
rhs = e[1 ]
84
86
if not lhs.validStrLit: return e
85
- result = infix (lhs .toPyExpr, " &" , rhs .toPyExpr)
87
+ result = infix (mparser .toPyExpr lhs , " &" , mparser .toPyExpr rhs )
86
88
87
89
func toStr (e): NimNode =
88
90
result = nnkCallStrLit.newTree (bindSym " u" , e)
@@ -94,12 +96,12 @@ template asisIfEmpty(e) =
94
96
func getTypeof (e: NimNode ): NimNode =
95
97
newCall (" typeof" , e)
96
98
97
- proc rewriteEachEle (e: NimNode ; bracketNode = nnkBracket): NimNode =
99
+ proc rewriteEachEle (mparser; e: NimNode ; bracketNode = nnkBracket): NimNode =
98
100
result = newNimNode bracketNode
99
101
for i in e:
100
- result .add i .toPyExpr
102
+ result .add mparser .toPyExpr i
101
103
102
- template mapEleCall (
104
+ template mapEleCall (mparser;
103
105
initCall, e: NimNode ;
104
106
bracketNode = nnkBracket,
105
107
): NimNode =
@@ -112,7 +114,7 @@ template mapEleCall(
112
114
with original `PyTComplex` type (a.k.a. being regarded as a new type)
113
115
]#
114
116
e.asisIfEmpty
115
- let res = rewriteEachEle (e, bracketNode)
117
+ let res = mparser. rewriteEachEle (e, bracketNode)
116
118
let eleTyp = getTypeof res[0 ]
117
119
newCall (
118
120
nnkBracketExpr.newTree (
@@ -122,16 +124,16 @@ template mapEleCall(
122
124
)
123
125
124
126
125
- proc toList (e): NimNode = mapEleCall (CollectionSyms [0 ], e)
126
- proc toSet (e): NimNode = mapEleCall (CollectionSyms [1 ], e)
127
- proc toDict (e): NimNode =
127
+ proc toList (mparser; e): NimNode = mparser. mapEleCall (CollectionSyms [0 ], e)
128
+ proc toSet (mparser; e): NimNode = mparser. mapEleCall (CollectionSyms [1 ], e)
129
+ proc toDict (mparser; e): NimNode =
128
130
e.asisIfEmpty
129
131
130
132
var eles = e.copyNimNode
131
133
for i in e:
132
134
var n = i.copyNimNode
133
135
n.add i[0 ].toStr
134
- n.add i[1 ].toPyExpr
136
+ n.add mparser. toPyExpr i[1 ]
135
137
eles.add n
136
138
137
139
let
@@ -146,41 +148,41 @@ proc toDict(e): NimNode =
146
148
eleValTyp
147
149
), eles
148
150
)
149
- proc toTuple (e): NimNode =
151
+ proc toTuple (mparser; e): NimNode =
150
152
result = newNimNode nnkTupleConstr
151
153
for i in e:
152
- result .add i .toPyExpr
154
+ result .add mparser .toPyExpr i
153
155
154
- proc rewriteEqualMinus (e; k= nnkAsgn): NimNode =
156
+ proc rewriteEqualMinus (mparser; e; k= nnkAsgn): NimNode =
155
157
# # x==-1 -> x == -1
156
158
# # x=-1 -> x = -1
157
159
158
- let lhs = e[1 ].toPyExpr
159
- template rhs : NimNode = newCall (" -" , e[2 ].toPyExpr )
160
+ let lhs = mparser. toPyExpr e[1 ]
161
+ template rhs : NimNode = newCall (" -" , mparser. toPyExpr e[2 ])
160
162
if e[0 ].eqIdent " =-" :
161
163
k.newTree lhs, rhs
162
164
elif e[0 ].eqIdent " ==-" :
163
165
newCall " ==" , lhs, rhs
164
166
else : e
165
167
166
- proc callToPyExpr * (e): NimNode
168
+ proc callToPyExpr * (mparser; e): NimNode
167
169
168
- template toPyExprImpl (atm: NimNode ; toListCb; equalMinusAs= nnkAsgn): NimNode =
170
+ template toPyExprImpl (mparser; atm: NimNode ; toListCb; equalMinusAs= nnkAsgn): NimNode =
169
171
case atm.kind
170
172
of nnkExprEqExpr:
171
- nnkExprEqExpr.newTree (atm[0 ], atm[1 ].toPyExpr )
173
+ nnkExprEqExpr.newTree (atm[0 ], mparser. toPyExpr atm[1 ])
172
174
of nnkBracketExpr:
173
- rewriteSliceInBracket atm
175
+ mparser. rewriteSliceInBracket atm
174
176
of nnkCommand:
175
- rewriteStrLitCat atm
177
+ mparser. rewriteStrLitCat atm
176
178
of nnkCall:
177
- callToPyExpr atm
179
+ mparser. callToPyExpr atm
178
180
of nnkPrefix:
179
- nnkPrefix.newTree atm[0 ], atm[1 ].toPyExpr
181
+ nnkPrefix.newTree atm[0 ], mparser. toPyExpr atm[1 ]
180
182
of nnkPar:
181
- nnkPar.newTree atm[0 ].toPyExpr
183
+ nnkPar.newTree mparser. toPyExpr atm[0 ]
182
184
of nnkInfix:
183
- rewriteEqualMinus atm, equalMinusAs
185
+ mparser. rewriteEqualMinus atm, equalMinusAs
184
186
185
187
of nnkTripleStrLit,
186
188
nnkStrLit, nnkRStrLit:
@@ -189,22 +191,62 @@ template toPyExprImpl(atm: NimNode; toListCb; equalMinusAs=nnkAsgn): NimNode =
189
191
# NOTE: f"xxx" does perform `translateEscape`
190
192
# so we don't perform translation here
191
193
192
- of nnkBracket: atm .toListCb
193
- of nnkCurly: atm .toSet
194
- of nnkTableConstr:atm .toDict
195
- of nnkTupleConstr:atm .toTuple
194
+ of nnkBracket: mparser .toListCb atm
195
+ of nnkCurly: mparser .toSet atm
196
+ of nnkTableConstr:mparser .toDict atm
197
+ of nnkTupleConstr:mparser .toTuple atm
196
198
else :
197
199
atm
198
200
199
- proc toPyExpr * (atm: NimNode ): NimNode = toPyExprImpl atm, toList
200
- proc toPyExprNoList * (atm: NimNode ): NimNode = toPyExprImpl atm, rewriteEachEle
201
+ proc toPyExpr * (mparser; atm: NimNode ): NimNode = mparser. toPyExprImpl atm, toList
202
+ proc toPyExprNoList * (mparser; atm: NimNode ): NimNode = mparser. toPyExprImpl atm, rewriteEachEle
201
203
202
- proc argInCallToPyExpr (atm: NimNode ): NimNode =
204
+ proc argInCallToPyExpr (mparser; atm: NimNode ): NimNode =
203
205
# # f(x=-1) needs to be rewritten as Call(ExprEqExpr(Ident"x", -1))
204
- toPyExprImpl atm, toList, nnkExprEqExpr
205
-
206
- proc callToPyExpr * (e): NimNode =
207
- result = e.copyNimNode
208
- for i in e:
209
- result .add i.argInCallToPyExpr
206
+ mparser.toPyExprImpl atm, toList, nnkExprEqExpr
207
+
208
+ proc preNew (n: NimNode ): NimNode =
209
+ ident (" new" & n.strVal)
210
+
211
+ proc callToPyExpr * (mparser; e): NimNode =
212
+ # # In addition, it will rewrite `cls(xxx)` to `newCls(xxx)`
213
+ let callee = e[0 ]
214
+ template addArg (addArgCb) =
215
+ for i in 1 ..< e.len:
216
+ let arg{.inject .} = mparser.argInCallToPyExpr e[i]
217
+ addArgCb
218
+ template retAfterAddOriCall =
219
+ addArg:
220
+ oriCall.add arg
221
+ return oriCall
222
+
223
+ var
224
+ newCls: NimNode
225
+ oriCall = newCall callee
226
+ case callee.kind
227
+ of nnkIdent: newCls = callee.preNew
228
+ of nnkDotExpr:
229
+ if callee[1 ].len == 0 :
230
+ var lhs = callee[0 ]
231
+ # in case `module.cls`
232
+ newCls = newDotExpr (lhs, callee[1 ].preNew)
233
+ while true :
234
+ if lhs.len == 0 :
235
+ break
236
+ elif lhs.kind != nnkDotExpr or lhs[1 ].kind != nnkIdent:
237
+ retAfterAddOriCall
238
+ lhs = lhs[0 ]
239
+ else :
240
+ retAfterAddOriCall
241
+ else :
242
+ retAfterAddOriCall
243
+ var newClsCall = newCall newCls
244
+ addArg:
245
+ oriCall.add arg
246
+ newClsCall.add arg
247
+ result = quote do :
248
+ when declared (`newCls`) and declared (`callee`) and compiles (`newClsCall`):
249
+ `newClsCall`
250
+ else :
251
+ `oriCall`
210
252
0 commit comments