diff options
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/lambdalifting.nim | 53 | ||||
-rw-r--r-- | compiler/semexprs.nim | 12 | ||||
-rw-r--r-- | compiler/semgnrc.nim | 11 | ||||
-rw-r--r-- | compiler/semthreads.nim | 2 | ||||
-rw-r--r-- | compiler/sigmatch.nim | 1 |
5 files changed, 44 insertions, 35 deletions
diff --git a/compiler/lambdalifting.nim b/compiler/lambdalifting.nim index 00fa04556..ebb4aeac4 100644 --- a/compiler/lambdalifting.nim +++ b/compiler/lambdalifting.nim @@ -637,6 +637,22 @@ proc outerProcSons(o: POuterContext, n: PNode) = let x = transformOuterProc(o, n.sons[i]) if x != nil: n.sons[i] = x +proc liftIterSym*(n: PNode): PNode = + # transforms (iter) to (let env = newClosure[iter](); (iter, env)) + let iter = n.sym + assert iter.kind == skIterator + + result = newNodeIT(nkStmtListExpr, n.info, n.typ) + + var env = copySym(getHiddenParam(iter)) + env.kind = skLet + var v = newNodeI(nkVarSection, n.info) + addVar(v, newSymNode(env)) + result.add(v) + # add 'new' statement: + result.add(newCall(getSysSym"internalNew", env)) + result.add makeClosure(iter, env, n.info) + proc transformOuterProc(o: POuterContext, n: PNode): PNode = if n == nil: return nil case n.kind @@ -649,17 +665,22 @@ proc transformOuterProc(o: POuterContext, n: PNode): PNode = return indirectAccess(newSymNode(o.closureParam), local, n.info) var closure = PEnv(idTableGet(o.lambdasToEnv, local)) - if closure != nil: - # we need to replace the lambda with '(lambda, env)': - if local.kind == skIterator and local.typ.callConv == ccClosure: - # consider: [i1, i2, i1] Since we merged the iterator's closure - # with the captured owning variables, we need to generate the - # closure generation code again: - #if local == o.fn: message(n.info, errRecursiveDependencyX, local.name.s) - # XXX why doesn't this work? + + if local.kind == skIterator and local.typ.callConv == ccClosure: + # consider: [i1, i2, i1] Since we merged the iterator's closure + # with the captured owning variables, we need to generate the + # closure generation code again: + if local == o.fn: message(n.info, errRecursiveDependencyX, local.name.s) + # XXX why doesn't this work? + if closure.isNil: + return liftIterSym(n) + else: let createdVar = generateIterClosureCreation(o, closure, closure.attachedNode) return makeClosure(local, createdVar, n.info) + + if closure != nil: + # we need to replace the lambda with '(lambda, env)': let a = closure.createdVar if a != nil: @@ -773,22 +794,6 @@ proc liftLambdasForTopLevel*(module: PSym, body: PNode): PNode = # ------------------- iterator transformation -------------------------------- -proc liftIterSym*(n: PNode): PNode = - # transforms (iter) to (let env = newClosure[iter](); (iter, env)) - let iter = n.sym - assert iter.kind == skIterator - - result = newNodeIT(nkStmtListExpr, n.info, n.typ) - - var env = copySym(getHiddenParam(iter)) - env.kind = skLet - var v = newNodeI(nkVarSection, n.info) - addVar(v, newSymNode(env)) - result.add(v) - # add 'new' statement: - result.add(newCall(getSysSym"internalNew", env)) - result.add makeClosure(iter, env, n.info) - proc liftForLoop*(body: PNode): PNode = # problem ahead: the iterator could be invoked indirectly, but then # we don't know what environment to create here: diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index 6c7679578..a8a16672d 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -1819,6 +1819,10 @@ proc semExport(c: PContext, n: PNode): PNode = c.module.ast.add x result = n +proc setGenericParams(c: PContext, n: PNode) = + for i in 1 .. <n.len: + n[i].typ = semTypeNode(c, n[i], nil) + proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode = result = n if gCmd == cmdIdeTools: suggestExpr(c, n) @@ -1924,10 +1928,12 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode = else: #liMessage(n.info, warnUser, renderTree(n)); result = semIndirectOp(c, n, flags) - elif isSymChoice(n.sons[0]) or n[0].kind == nkBracketExpr and - isSymChoice(n[0][0]): + elif n[0].kind == nkBracketExpr and isSymChoice(n[0][0]): + # indirectOp can deal with explicit instantiations; the fixes + # the 'newSeq[T](x)' bug + setGenericParams(c, n.sons[0]) result = semDirectOp(c, n, flags) - elif nfDelegate in n.flags: + elif isSymChoice(n.sons[0]) or nfDelegate in n.flags: result = semDirectOp(c, n, flags) else: result = semIndirectOp(c, n, flags) diff --git a/compiler/semgnrc.nim b/compiler/semgnrc.nim index 89a167b96..b21d851c9 100644 --- a/compiler/semgnrc.nim +++ b/compiler/semgnrc.nim @@ -1,7 +1,7 @@ # # # The Nimrod Compiler -# (c) Copyright 2012 Andreas Rumpf +# (c) Copyright 2014 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. @@ -215,8 +215,7 @@ proc semGenericStmt(c: PContext, n: PNode, if (a.kind != nkIdentDefs) and (a.kind != nkVarTuple): illFormedAst(a) checkMinSonsLen(a, 3) var L = sonsLen(a) - a.sons[L-2] = semGenericStmt(c, a.sons[L-2], flags+{withinTypeDesc}, - ctx) + a.sons[L-2] = semGenericStmt(c, a.sons[L-2], flags+{withinTypeDesc}, ctx) a.sons[L-1] = semGenericStmt(c, a.sons[L-1], flags, ctx) for j in countup(0, L-3): addPrelimDecl(c, newSymS(skUnknown, getIdentNode(a.sons[j]), c)) @@ -226,8 +225,7 @@ proc semGenericStmt(c: PContext, n: PNode, if (a.kind != nkIdentDefs): illFormedAst(a) checkMinSonsLen(a, 3) var L = sonsLen(a) - a.sons[L-2] = semGenericStmt(c, a.sons[L-2], flags+{withinTypeDesc}, - ctx) + a.sons[L-2] = semGenericStmt(c, a.sons[L-2], flags+{withinTypeDesc}, ctx) # do not perform symbol lookup for default expressions for j in countup(0, L-3): addPrelimDecl(c, newSymS(skUnknown, getIdentNode(a.sons[j]), c)) @@ -281,8 +279,7 @@ proc semGenericStmt(c: PContext, n: PNode, if (a.kind != nkIdentDefs): illFormedAst(a) checkMinSonsLen(a, 3) var L = sonsLen(a) - a.sons[L-2] = semGenericStmt(c, a.sons[L-2], flags+{withinTypeDesc}, - ctx) + a.sons[L-2] = semGenericStmt(c, a.sons[L-2], flags+{withinTypeDesc}, ctx) a.sons[L-1] = semGenericStmt(c, a.sons[L-1], flags, ctx) for j in countup(0, L-3): addPrelimDecl(c, newSymS(skUnknown, getIdentNode(a.sons[j]), c)) diff --git a/compiler/semthreads.nim b/compiler/semthreads.nim index f7322db80..d3426ca3e 100644 --- a/compiler/semthreads.nim +++ b/compiler/semthreads.nim @@ -358,7 +358,7 @@ proc analyse(c: PProcCtx, n: PNode): TThreadOwner = of nkConstSection: result = analyseConstSection(c, n) of nkTypeSection, nkCommentStmt: result = toVoid of nkIfStmt, nkWhileStmt, nkTryStmt, nkCaseStmt, nkStmtList, nkBlockStmt, - nkElifBranch, nkElse, nkExceptBranch, nkOfBranch: + nkElifBranch, nkElse, nkExceptBranch, nkOfBranch, nkFinally: for i in 0 .. <n.len: discard analyse(c, n[i]) result = toVoid of nkBreakStmt, nkContinueStmt: result = toVoid diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index f9200ea0c..335ceafeb 100644 --- a/compiler/sigmatch.nim +++ b/compiler/sigmatch.nim @@ -105,6 +105,7 @@ proc initCandidate*(ctx: PContext, c: var TCandidate, callee: PSym, var bound = binding[i].typ if bound != nil and formalTypeParam.kind != tyTypeDesc: bound = bound.skipTypes({tyTypeDesc}) + assert bound != nil put(c.bindings, formalTypeParam, bound) proc newCandidate*(ctx: PContext, callee: PSym, |