diff options
Diffstat (limited to 'compiler/closureiters.nim')
-rw-r--r-- | compiler/closureiters.nim | 41 |
1 files changed, 24 insertions, 17 deletions
diff --git a/compiler/closureiters.nim b/compiler/closureiters.nim index 258372d76..5ded6d054 100644 --- a/compiler/closureiters.nim +++ b/compiler/closureiters.nim @@ -462,10 +462,17 @@ proc lowerStmtListExprs(ctx: var Ctx, n: PNode, needsSplit: var bool): PNode = result.typ = n.typ for i in 0 ..< n.len: - if n[i].kind == nkStmtListExpr: + case n[i].kind + of nkExprColonExpr: + if n[i][1].kind == nkStmtListExpr: + let (st, ex) = exprToStmtList(n[i][1]) + result.add(st) + n[i][1] = ex + of nkStmtListExpr: let (st, ex) = exprToStmtList(n[i]) result.add(st) n[i] = ex + else: discard result.add(n) of nkIfStmt, nkIfExpr: @@ -852,15 +859,8 @@ proc transformClosureIteratorBody(ctx: var Ctx, n: PNode, gotoOut: PNode): PNode discard of nkStmtList, nkStmtListExpr: - assert(isEmptyType(n.typ), "nkStmtListExpr not lowered") - result = addGotoOut(result, gotoOut) for i in 0 ..< n.len: - if n[i].hasYieldsInExpressions: - # Lower nkStmtListExpr nodes inside `n[i]` first - var ns = false - n[i] = ctx.lowerStmtListExprs(n[i], ns) - if n[i].hasYields: # Create a new split let go = newNodeI(nkGotoState, n[i].info) @@ -1009,7 +1009,7 @@ proc stateFromGotoState(n: PNode): int = assert(n.kind == nkGotoState) result = n[0].intVal.int -proc tranformStateAssignments(ctx: var Ctx, n: PNode): PNode = +proc transformStateAssignments(ctx: var Ctx, n: PNode): PNode = # This transforms 3 patterns: ########################## 1 # yield e @@ -1051,7 +1051,7 @@ proc tranformStateAssignments(ctx: var Ctx, n: PNode): PNode = result.add(retStmt) else: for i in 0 ..< n.len: - n[i] = ctx.tranformStateAssignments(n[i]) + n[i] = ctx.transformStateAssignments(n[i]) of nkSkip: discard @@ -1071,7 +1071,7 @@ proc tranformStateAssignments(ctx: var Ctx, n: PNode): PNode = else: for i in 0 ..< n.len: - n[i] = ctx.tranformStateAssignments(n[i]) + n[i] = ctx.transformStateAssignments(n[i]) proc skipStmtList(ctx: Ctx; n: PNode): PNode = result = n @@ -1220,18 +1220,20 @@ proc wrapIntoStateLoop(ctx: var Ctx, n: PNode): PNode = # while true: # block :stateLoop: # gotoState :state + # local vars decl (if needed) # body # Might get wrapped in try-except let loopBody = newNodeI(nkStmtList, n.info) result = newTree(nkWhileStmt, newSymNode(ctx.g.getSysSym(n.info, "true")), loopBody) result.info = n.info + let localVars = newNodeI(nkStmtList, n.info) if not ctx.stateVarSym.isNil: let varSect = newNodeI(nkVarSection, n.info) addVar(varSect, newSymNode(ctx.stateVarSym)) - loopBody.add(varSect) + localVars.add(varSect) if not ctx.tempVars.isNil: - loopBody.add(ctx.tempVars) + localVars.add(ctx.tempVars) let blockStmt = newNodeI(nkBlockStmt, n.info) blockStmt.add(newSymNode(ctx.stateLoopLabel)) @@ -1240,7 +1242,7 @@ proc wrapIntoStateLoop(ctx: var Ctx, n: PNode): PNode = gs.add(ctx.newStateAccess()) gs.add(ctx.g.newIntLit(n.info, ctx.states.len - 1)) - var blockBody = newTree(nkStmtList, gs, n) + var blockBody = newTree(nkStmtList, gs, localVars, n) if ctx.hasExceptions: blockBody = ctx.wrapIntoTryExcept(blockBody) @@ -1292,13 +1294,18 @@ proc transformClosureIterator*(g: ModuleGraph; fn: PSym, n: PNode): PNode = # should folllow the same logic. ctx.stateVarSym = newSym(skVar, getIdent(ctx.g.cache, ":state"), fn, fn.info) ctx.stateVarSym.typ = g.createClosureIterStateType(fn) - ctx.stateLoopLabel = newSym(skLabel, getIdent(ctx.g.cache, ":stateLoop"), fn, fn.info) - let n = n.toStmtList + var n = n.toStmtList discard ctx.newState(n, nil) let gotoOut = newTree(nkGotoState, g.newIntLit(n.info, -1)) + var ns = false + n = ctx.lowerStmtListExprs(n, ns) + + if n.hasYieldsInExpressions(): + internalError(ctx.g.config, "yield in expr not lowered") + # Splitting transformation discard ctx.transformClosureIteratorBody(n, gotoOut) @@ -1314,7 +1321,7 @@ proc transformClosureIterator*(g: ModuleGraph; fn: PSym, n: PNode): PNode = result.add(s) result.add(body) - result = ctx.tranformStateAssignments(result) + result = ctx.transformStateAssignments(result) result = ctx.wrapIntoStateLoop(result) # echo "TRANSFORM TO STATES: " |