test transformClosureIterator

This commit is contained in:
ringabout
2025-12-18 21:24:24 +08:00
parent 44d2472b08
commit 87885876e9
5 changed files with 34 additions and 7 deletions

View File

@@ -116,6 +116,16 @@ proc `transformedBody=`*(s: PSym, val: PNode) {.inline.} =
if s.state == Partial: loadSym(s)
s.transformedBodyImpl = val
proc closureBody*(s: PSym): PNode {.inline.} =
if s.state == Partial: loadSym(s)
result = s.closureBodyImpl
proc `closureBody=`*(s: PSym, val: PNode) {.inline.} =
#assert s.state != Sealed
# Make an exception here for this misfeature...
if s.state == Partial: loadSym(s)
s.closureBodyImpl = val
proc guard*(s: PSym): PSym {.inline.} =
if s.state == Partial: loadSym(s)
result = s.guardImpl

View File

@@ -705,6 +705,7 @@ type
#procInstCache*: seq[PInstantiation]
gcUnsafetyReasonImpl*: PSym # for better error messages regarding gcsafe
transformedBodyImpl*: PNode # cached body after transf pass
closureBodyImpl*: PNode # cached body after closure conversion
of skLet, skVar, skField, skForVar:
guardImpl*: PSym
bitsizeImpl*: int

View File

@@ -1285,6 +1285,9 @@ proc genProcBody(p: BProc; procBody: PNode) =
p.blocks[0].sections[cpsInit].addAssignmentWithValue("nimErr_"):
p.blocks[0].sections[cpsInit].addCall(cgsymValue(p.module, "nimErrorFlag"))
template isIterator(owner: PSym): bool =
owner.kind == skIterator and owner.typ.callConv == ccClosure
proc genProcAux*(m: BModule, prc: PSym) =
var p = newProc(prc, m)
var header = newBuilder("")
@@ -1297,9 +1300,13 @@ proc genProcAux*(m: BModule, prc: PSym) =
var returnStmt: Snippet = ""
assert(prc.ast != nil)
var procBody = transformBody(m.g.graph, m.idgen, prc, {})
if sfInjectDestructors in prc.flags:
procBody = injectDestructorCalls(m.g.graph, m.idgen, prc, procBody)
var procBody: PNode = nil
if isIterator(prc) and prc.closureBody != nil:
procBody = prc.closureBody
else:
procBody = transformBody(m.g.graph, m.idgen, prc, {})
if sfInjectDestructors in prc.flags:
procBody = injectDestructorCalls(m.g.graph, m.idgen, prc, procBody)
let tmpInfo = prc.info
discard freshLineInfo(p, prc.info)

View File

@@ -1083,6 +1083,10 @@ proc p(n: PNode; c: var Con; s: var Scope; mode: ProcessMode; tmpFlags = {sfSing
for i in 0..<n.len:
result[i] = p(n[i], c, s, mode, inReturn=true)
s.needsTry = true
of nkYieldStmt: # TODO:
result = shallowCopy(n)
for i in 0..<n.len:
result[i] = p(n[i], c, s, mode)
of nkCast:
result = shallowCopy(n)
result[0] = n[0]

View File

@@ -26,6 +26,8 @@ import
lowerings, liftlocals,
modulegraphs, lineinfos
import injectdestructors
when defined(nimPreviewSlimSystem):
import std/assertions
@@ -123,11 +125,16 @@ proc newAsgnStmt(c: PTransf, kind: TNodeKind, le: PNode, ri: PNode; isFirstWrite
proc transformSymAux(c: PTransf, n: PNode): PNode =
let s = n.sym
if s.typ != nil and s.typ.callConv == ccClosure:
var body: PNode = nil
if s.kind in routineKinds:
discard transformBody(c.graph, c.idgen, s, {useCache}+c.flags)
body = transformBody(c.graph, c.idgen, s, {useCache}+c.flags)
if s.kind == skIterator:
if c.tooEarly: return n
else: return liftIterSym(c.graph, n, c.idgen, getCurrOwner(c))
else:
let transformedBody = injectDestructorCalls(c.graph, c.idgen, s, body)
let closureBody = transformClosureIterator(c.graph, c.idgen, s, transformedBody)
s.closureBody = closureBody
return liftIterSym(c.graph, n, c.idgen, getCurrOwner(c))
elif s.kind in {skProc, skFunc, skConverter, skMethod} and not c.tooEarly:
# top level .closure procs are still somewhat supported for 'Nake':
return makeClosure(c.graph, c.idgen, s, nil, n.info)
@@ -1316,8 +1323,6 @@ proc transformBody*(g: ModuleGraph; idgen: IdGenerator; prc: PSym; flags: Transf
liftDefer(c, result)
result = liftLocalsIfRequested(prc, result, g.cache, g.config, c.idgen)
if prc.isIterator:
result = g.transformClosureIterator(c.idgen, prc, result)
incl(result.flags, nfTransf)