@@ -499,7 +499,6 @@ proc handleNested(n, dest: PNode; c: var Con; mode: ProcessMode): PNode =
499499 result [last] = processCall (n[last])
500500 # A statement list does not introduce a scope, the AST can
501501 # contain silly nested statement lists.
502- # result = handleScope(n, dest, n.typ, 0, c, mode)
503502 of nkBlockStmt, nkBlockExpr:
504503 result = handleScope (n, dest, n.typ, 1 , c, mode)
505504 of nkIfStmt, nkIfExpr:
@@ -513,13 +512,11 @@ proc handleNested(n, dest: PNode; c: var Con; mode: ProcessMode): PNode =
513512 result .add handleScope (n[i], dest, n[i][^ 1 ].typ, n[i].len - 1 , c, mode)
514513 of nkWhen: # This should be a "when nimvm" node.
515514 result = copyTree (n)
516- result [1 ][0 ] = handleScope (n[1 ][0 ], dest, n[1 ][0 ][^ 1 ].typ, 0 , c, mode)
515+ result [1 ][0 ] = processCall (n[1 ][0 ])
516+ # handleScope(n[1][0], dest, n[1][0][^1].typ, 0, c, mode)
517517 of nkWhileStmt:
518- # result = copyNode(n)
519518 inc c.inLoop
520519 result = handleScope (n, dest, nil , 0 , c, mode)
521- # result.add p(n[0], c, normal)
522- # result.add p(n[1], c, normal)
523520 dec c.inLoop
524521 else : assert (false )
525522
@@ -634,10 +631,101 @@ proc pVarScoped(v: PNode; c: var Con; ri, res: PNode) =
634631 elif ri.kind != nkEmpty:
635632 res.add moveOrCopy (v, ri, c)
636633
634+ template handleNestedTempl (n: untyped , processCall: untyped ) =
635+ case n.kind
636+ of nkStmtList, nkStmtListExpr:
637+ if n.len == 0 : return n
638+ result = copyNode (n)
639+ for i in 0 ..< n.len- 1 :
640+ result .add p (n[i], c, normal)
641+ template node : untyped = n[^ 1 ]
642+ result .add processCall
643+ of nkBlockStmt, nkBlockExpr:
644+ result = copyNode (n)
645+ result .add n[0 ]
646+ template node : untyped = n[1 ]
647+ result .add processCall
648+ of nkIfStmt, nkIfExpr:
649+ result = copyNode (n)
650+ for son in n:
651+ var branch = copyNode (son)
652+ if son.kind in {nkElifBranch, nkElifExpr}:
653+ template node : untyped = son[1 ]
654+ branch.add p (son[0 ], c, normal) # The condition
655+ branch.add if node.typ == nil : p (node, c, normal) # noreturn
656+ else : processCall
657+ else :
658+ template node : untyped = son[0 ]
659+ branch.add if node.typ == nil : p (node, c, normal) # noreturn
660+ else : processCall
661+ result .add branch
662+ of nkCaseStmt:
663+ result = copyNode (n)
664+ result .add p (n[0 ], c, normal)
665+ for i in 1 ..< n.len:
666+ var branch: PNode
667+ if n[i].kind == nkOfBranch:
668+ branch = n[i] # of branch conditions are constants
669+ template node : untyped = n[i][^ 1 ]
670+ branch[^ 1 ] = if node.typ == nil : p (node, c, normal) # noreturn
671+ else : processCall
672+ elif n[i].kind in {nkElifBranch, nkElifExpr}:
673+ branch = copyNode (n[i])
674+ branch.add p (n[i][0 ], c, normal) # The condition
675+ template node : untyped = n[i][1 ]
676+ branch.add if node.typ == nil : p (node, c, normal) # noreturn
677+ else : processCall
678+ else :
679+ branch = copyNode (n[i])
680+ template node : untyped = n[i][0 ]
681+ branch.add if node.typ == nil : p (node, c, normal) # noreturn
682+ else : processCall
683+ result .add branch
684+ of nkWhen: # This should be a "when nimvm" node.
685+ result = copyTree (n)
686+ template node : untyped = n[1 ][0 ]
687+ result [1 ][0 ] = processCall
688+ of nkWhileStmt:
689+ inc c.inLoop
690+ result = copyNode (n)
691+ result .add p (n[0 ], c, normal)
692+ result .add p (n[1 ], c, normal)
693+ dec c.inLoop
694+ else : assert (false )
695+
696+ when false :
697+ proc eqTrees * (a, b: PNode ): bool =
698+ if a == b:
699+ result = true
700+ elif (a != nil ) and (b != nil ) and (a.kind == b.kind):
701+ case a.kind
702+ of nkSym:
703+ # result = a.sym == b.sym or (a.sym.kind == skTemp and b.sym.kind == skTemp)
704+ result = true
705+ of nkIdent: result = a.ident.id == b.ident.id
706+ of nkCharLit.. nkUInt64Lit: result = a.intVal == b.intVal
707+ of nkFloatLit.. nkFloat64Lit:
708+ result = cast [uint64 ](a.floatVal) == cast [uint64 ](b.floatVal)
709+ of nkStrLit.. nkTripleStrLit: result = a.strVal == b.strVal
710+ of nkCommentStmt: result = a.comment == b.comment
711+ of nkEmpty, nkNilLit, nkType: result = true
712+ else :
713+ if a.len == b.len:
714+ for i in 0 ..< a.len:
715+ if not eqTrees (a[i], b[i]): return
716+ result = true
717+ if not result :
718+ # if a.kind == nkFloat64Lit and b.kind == nkFloat64Lit:
719+ echo " not the same " , a.kind, " " , b.kind
720+ # echo a.floatVal, "##", b.floatVal, "##"
721+
637722proc p (n: PNode ; c: var Con ; mode: ProcessMode ): PNode =
638723 if n.kind in {nkStmtList, nkStmtListExpr, nkBlockStmt, nkBlockExpr, nkIfStmt,
639724 nkIfExpr, nkCaseStmt, nkWhen, nkWhileStmt}:
640- result = handleNested (n, nil , c, mode)
725+ when not scopeBasedDestruction:
726+ handleNestedTempl (n): p (node, c, mode)
727+ else :
728+ result = handleNested (n, nil , c, mode)
641729 elif mode == sinkArg:
642730 if n.containsConstSeq:
643731 # const sequences are not mutable and so we need to pass a copy to the
@@ -884,7 +972,10 @@ proc moveOrCopy(dest, ri: PNode; c: var Con): PNode =
884972 else :
885973 result = genSink (c, dest, p (ri, c, sinkArg))
886974 of nkStmtListExpr, nkBlockExpr, nkIfExpr, nkCaseStmt:
887- result = handleNested (ri, dest, c, normal)
975+ when scopeBasedDestruction:
976+ result = handleNested (ri, dest, c, normal)
977+ else :
978+ handleNestedTempl (ri): moveOrCopy (dest, node, c)
888979 else :
889980 if isAnalysableFieldAccess (ri, c.owner) and isLastRead (ri, c) and
890981 canBeMoved (c, dest.typ):
0 commit comments