|
13 | 13 | import ast, types, msgs, idents, renderer, wordrecg, trees,
|
14 | 14 | options
|
15 | 15 |
|
16 |
| -import std/strutils |
| 16 | +import std/[strutils, assertions] |
17 | 17 |
|
18 | 18 | # we precompile the pattern here for efficiency into some internal
|
19 | 19 | # stack based VM :-) Why? Because it's fun; I did no benchmarks to see if that
|
@@ -216,6 +216,11 @@ proc exprRoot*(n: PNode; allowCalls = true): PSym =
|
216 | 216 | else:
|
217 | 217 | break
|
218 | 218 |
|
| 219 | +proc isAssignable*(owner: PSym, n: PNode): TAssignableResult |
| 220 | + |
| 221 | +proc isLentableBranch(owner: PSym, n: PNode): bool = |
| 222 | + result = isAssignable(owner, n) in {arLentValue, arAddressableConst, arLentValue} |
| 223 | + |
219 | 224 | proc isAssignable*(owner: PSym, n: PNode): TAssignableResult =
|
220 | 225 | ## 'owner' can be nil!
|
221 | 226 | result = arNone
|
@@ -308,6 +313,35 @@ proc isAssignable*(owner: PSym, n: PNode): TAssignableResult =
|
308 | 313 | # nkVarTy denotes an lvalue, but the example above is the only
|
309 | 314 | # possible code which will get us here
|
310 | 315 | result = arLValue
|
| 316 | + of nkIfExpr, nkIfStmt: |
| 317 | + # allow 'if' expressions to be lent if all branches are lentable |
| 318 | + for branch in n: |
| 319 | + if branch.len == 2: |
| 320 | + if not isLentableBranch(owner, branch[1]): |
| 321 | + return |
| 322 | + elif branch.len == 1: |
| 323 | + if not isLentableBranch(owner, branch[0]): |
| 324 | + return |
| 325 | + else: |
| 326 | + raiseAssert "Malformed `if` statement in isAssignable" |
| 327 | + result = arLentValue |
| 328 | + of nkCaseStmt: |
| 329 | + # allow 'case' expressions to be lent if all branches are lentable |
| 330 | + for i in 1 ..< n.len: |
| 331 | + let branch = n[i] |
| 332 | + case branch.kind |
| 333 | + of nkOfBranch: |
| 334 | + if not isLentableBranch(owner, branch[^1]): |
| 335 | + return |
| 336 | + of nkElifBranch: |
| 337 | + if not isLentableBranch(owner, branch[1]): |
| 338 | + return |
| 339 | + of nkElse: |
| 340 | + if not isLentableBranch(owner, branch[0]): |
| 341 | + return |
| 342 | + else: |
| 343 | + raiseAssert "Malformed `case` statement in isAssignable" |
| 344 | + result = arLentValue |
311 | 345 | else:
|
312 | 346 | discard
|
313 | 347 |
|
|
0 commit comments