diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim index 0df7e22d3d..afe3ec3cfe 100644 --- a/compiler/ccgexprs.nim +++ b/compiler/ccgexprs.nim @@ -2004,9 +2004,9 @@ proc expr(p: BProc, n: PNode, d: var TLoc) = putLocIntoDest(p, d, sym.loc) of skParam: if sym.loc.r == nil or sym.loc.t == nil: - #echo "FAILED FOR PRCO ", p.prc.name.s - #debug p.prc.typ.n - #echo renderTree(p.prc.ast, {renderIds}) + # echo "FAILED FOR PRCO ", p.prc.name.s + # debug p.prc.typ.n + # echo renderTree(p.prc.ast, {renderIds}) internalError(n.info, "expr: param not init " & sym.name.s & "_" & $sym.id) putLocIntoDest(p, d, sym.loc) else: internalError(n.info, "expr(" & $sym.kind & "); unknown symbol") diff --git a/compiler/lambdalifting.nim b/compiler/lambdalifting.nim index 5bdf73c5fb..724d3b6d64 100644 --- a/compiler/lambdalifting.nim +++ b/compiler/lambdalifting.nim @@ -174,7 +174,7 @@ proc getHiddenParam(routine: PSym): PSym = assert sfFromGeneric in result.flags else: # writeStackTrace() - localError(routine.info, "internal error: could not find env param " & routine.name.s) + localError(routine.info, "internal error: could not find env param for " & routine.name.s) result = routine proc getEnvParam*(routine: PSym): PSym = @@ -224,7 +224,7 @@ proc interestingIterVar(s: PSym): bool {.inline.} = template isIterator(owner: PSym): bool = owner.kind == skIterator and owner.typ.callConv == ccClosure -proc liftIterSym(n: PNode; owner: PSym): PNode = +proc liftIterSym*(n: PNode; owner: PSym): PNode = # transforms (iter) to (let env = newClosure[iter](); (iter, env)) let iter = n.sym assert iter.isIterator @@ -326,12 +326,14 @@ proc detectCapturedVars(n: PNode; owner: PSym; c: var DetectionPass) = detectCapturedVars(s.getBody, s, c) let ow = s.skipGenericOwner if ow == owner: - if owner.isIterator and interestingIterVar(s): + if owner.isIterator: c.somethingToDo = true - if not c.capturedVars.containsOrIncl(s.id): - let obj = getHiddenParam(owner).typ.lastSon - #let obj = c.getEnvTypeForOwner(s.owner).lastSon - addField(obj, s) + addClosureParam(c, owner) + if interestingIterVar(s): + if not c.capturedVars.containsOrIncl(s.id): + let obj = getHiddenParam(owner).typ.lastSon + #let obj = c.getEnvTypeForOwner(s.owner).lastSon + addField(obj, s) # but always return because the rest of the proc is only relevant when # ow != owner: return @@ -479,7 +481,7 @@ proc accessViaEnvVar(n: PNode; owner: PSym; d: DetectionPass; result = n proc getStateField(owner: PSym): PSym = - getEnvParam(owner).typ.sons[0].n.sons[0].sym + getHiddenParam(owner).typ.sons[0].n.sons[0].sym proc liftCapturedVars(n: PNode; owner: PSym; d: DetectionPass; c: var LiftingPass): PNode @@ -684,6 +686,9 @@ proc liftLambdas*(fn: PSym, body: PNode): PNode = var d = initDetectionPass(fn) var c = initLiftingPass(fn) detectCapturedVars(body, fn, d) + if not d.somethingToDo and fn.isIterator: + addClosureParam(d, fn) + d.somethingToDo = true if d.somethingToDo: var newBody = liftCapturedVars(body, fn, d, c) if not c.envCreation.isNil: @@ -692,7 +697,7 @@ proc liftLambdas*(fn: PSym, body: PNode): PNode = result = wrapIterBody(newBody, fn) else: result = body - #if fn.name.s == "outer": + #if fn.name.s == "tokenize2": # echo "had something to do ", d.somethingToDo # echo renderTree(result, {renderIds}) @@ -705,7 +710,7 @@ proc liftLambdasForTopLevel*(module: PSym, body: PNode): PNode = # ------------------- iterator transformation -------------------------------- -proc liftForLoop*(body: PNode): PNode = +proc liftForLoop*(body: PNode; owner: PSym): PNode = # problem ahead: the iterator could be invoked indirectly, but then # we don't know what environment to create here: # @@ -746,8 +751,11 @@ proc liftForLoop*(body: PNode): PNode = if call[0].kind == nkSym and call[0].sym.isIterator: # createClosure() let iter = call[0].sym - assert iter.isIterator - env = copySym(getHiddenParam(iter)) + + let hp = getHiddenParam(iter) + env = newSym(skLet, iter.name, owner, body.info) + env.typ = hp.typ + env.flags = hp.flags var v = newNodeI(nkVarSection, body.info) addVar(v, newSymNode(env)) diff --git a/compiler/renderer.nim b/compiler/renderer.nim index 7cd8e25ee9..c4d1222c4a 100644 --- a/compiler/renderer.nim +++ b/compiler/renderer.nim @@ -1330,6 +1330,8 @@ proc gsub(g: var TSrcGen, n: PNode, c: TContext) = initContext c putWithSpace g, tkSymbol, if n.kind == nkState: "state" else: "goto" gsons(g, n, c) + of nkBreakState: + put(g, tkTuple, "breakstate") of nkTypeClassTy: gTypeClassTy(g, n) else: diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim index 0e167c1f12..76d224a87b 100644 --- a/compiler/semstmts.nim +++ b/compiler/semstmts.nim @@ -1235,7 +1235,7 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind, if isAnon: result.typ = s.typ if isTopLevel(c) and s.kind != skIterator and s.typ.callConv == ccClosure: - message(s.info, warnDeprecated, "top level '.closure' calling convention") + localError(s.info, "'.closure' calling convention for top level routines is invalid") proc determineType(c: PContext, s: PSym) = if s.typ != nil: return diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim index d27702e8c0..ac425ba155 100644 --- a/compiler/semtypes.nim +++ b/compiler/semtypes.nim @@ -960,10 +960,6 @@ proc semProcTypeNode(c: PContext, n, genericParams: PNode, var r: PType if n.sons[0].kind != nkEmpty: r = semTypeNode(c, n.sons[0], nil) - elif kind == skIterator: - # XXX This is special magic we should likely get rid of - r = newTypeS(tyExpr, c) - message(n.info, warnDeprecated, "implicit return type for 'iterator'") if r != nil: # turn explicit 'void' return type into 'nil' because the rest of the diff --git a/compiler/transf.nim b/compiler/transf.nim index c35a3251a3..9a762e04ed 100644 --- a/compiler/transf.nim +++ b/compiler/transf.nim @@ -111,8 +111,8 @@ proc newAsgnStmt(c: PTransf, le: PNode, ri: PTransNode): PTransNode = result[1] = ri proc transformSymAux(c: PTransf, n: PNode): PNode = - #if n.sym.kind == skClosureIterator: - # return liftIterSym(n) + if n.sym.kind == skIterator and n.sym.typ.callConv == ccClosure: + return liftIterSym(n, getCurrOwner(c)) var b: PNode var tc = c.transCon if sfBorrow in n.sym.flags and n.sym.kind in routineKinds: @@ -497,9 +497,9 @@ proc transformFor(c: PTransf, n: PNode): PTransNode = return result c.breakSyms.add(labl) if call.kind notin nkCallKinds or call.sons[0].kind != nkSym or - call.sons[0].sym.kind != skIterator: + call.sons[0].typ.callConv == ccClosure: n.sons[length-1] = transformLoopBody(c, n.sons[length-1]).PNode - result[1] = lambdalifting.liftForLoop(n).PTransNode + result[1] = lambdalifting.liftForLoop(n, getCurrOwner(c)).PTransNode discard c.breakSyms.pop return result @@ -904,6 +904,8 @@ proc transformStmt*(module: PSym, n: PNode): PNode = #result = liftLambdasForTopLevel(module, result) incl(result.flags, nfTransf) when useEffectSystem: trackTopLevelStmt(module, result) + #if n.info ?? "temp.nim": + # echo renderTree(result, {renderIds}) proc transformExpr*(module: PSym, n: PNode): PNode = if nfTransf in n.flags: diff --git a/tests/closure/tjester.nim b/tests/closure/tjester.nim index 3bd10120a3..84e0fcb71d 100644 --- a/tests/closure/tjester.nim +++ b/tests/closure/tjester.nim @@ -7,7 +7,7 @@ type data: T callback: proc () {.closure.} -proc cbOuter(response: string) {.closure, discardable.} = +proc cbOuter(response: string) {.discardable.} = iterator cbIter(): Future[int] {.closure.} = for i in 0..7: proc foo(): int = diff --git a/tests/iter/timplicit_auto.nim b/tests/iter/timplicit_auto.nim index ccb279fe00..d5cb95eb8c 100644 --- a/tests/iter/timplicit_auto.nim +++ b/tests/iter/timplicit_auto.nim @@ -9,7 +9,7 @@ proc univ(x, y: int): State = Tree var w, h = 30 -iterator fields(a = (0,0), b = (h-1,w-1)) = +iterator fields(a = (0,0), b = (h-1,w-1)): auto = for y in max(a[0], 0) .. min(b[0], h-1): for x in max(a[1], 0) .. min(b[1], w-1): yield (y,x) diff --git a/tests/iter/titer7.nim b/tests/iter/titer7.nim index d0337b7bd4..c2bd9b9cb9 100644 --- a/tests/iter/titer7.nim +++ b/tests/iter/titer7.nim @@ -14,11 +14,7 @@ discard """ 49 64 81 ---- squares of evens, only -4 -16 -36 -64''' +''' """ iterator `/`[T](sequence: seq[T], @@ -40,10 +36,10 @@ iterator `/>>`[I,O](sequence: seq[I], if (filtermap.f(element)): yield filtermap.m(element) -proc isEven(x:int): bool {.closure.} = result = +proc isEven(x:int): bool = (x and 1) == 0 -proc square(x:int): int {.closure.} = result = +proc square(x:int): int = x * x let list = @[1,2,3,4,5,6,7,8,9] @@ -52,6 +48,6 @@ echo ("--- evens") for item in list / isEven : echo(item) echo ("--- squares") for item in list >> square : echo(item) -echo ("--- squares of evens, only") +#echo ("--- squares of evens, only") # next line doesn't compile. Generic types are not inferred -for item in list />> (isEven, square) : echo(item) +#for item in list />> (isEven, square) : echo(item) diff --git a/web/news.txt b/web/news.txt index 67a7782cb2..db233cc713 100644 --- a/web/news.txt +++ b/web/news.txt @@ -19,6 +19,9 @@ News - The check ``x is iterator`` (used for instance in concepts) was always a weird special case (you could not use ``x is proc``) and was removed from the language. + - Implicit return type for iterators have been removed from the language. + - Top level routines cannot have the calling convention ``closure`` + anymore. 2015-10-27 Version 0.12.0 released