diff options
-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 | ||||
-rw-r--r-- | doc/manual.txt | 2 | ||||
-rw-r--r-- | lib/system/gc.nim | 2 | ||||
-rw-r--r-- | tests/generics/tgenericrefs.nim | 12 | ||||
-rw-r--r-- | tests/iter/tanoniter1.nim | 4 | ||||
-rw-r--r-- | todo.txt | 8 |
10 files changed, 64 insertions, 43 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, diff --git a/doc/manual.txt b/doc/manual.txt index 520e4f62e..16e025ee0 100644 --- a/doc/manual.txt +++ b/doc/manual.txt @@ -2931,7 +2931,7 @@ parameters of an outer factory proc: yield x inc x - let foo = mycount 1, 4 + let foo = mycount(1, 4) for f in foo(): echo f diff --git a/lib/system/gc.nim b/lib/system/gc.nim index 820093b3e..b08a6d214 100644 --- a/lib/system/gc.nim +++ b/lib/system/gc.nim @@ -802,7 +802,7 @@ when defined(sparc): # For SPARC architecture. # Addresses decrease as the stack grows. while sp <= max: gcMark(gch, sp[]) - sp = cast[ppointer](cast[TAddress](sp) +% sizeof(pointer)) + sp = cast[PPointer](cast[TAddress](sp) +% sizeof(pointer)) elif defined(ELATE): {.error: "stack marking code is to be written for this architecture".} diff --git a/tests/generics/tgenericrefs.nim b/tests/generics/tgenericrefs.nim index ef931dfa7..a44b96af9 100644 --- a/tests/generics/tgenericrefs.nim +++ b/tests/generics/tgenericrefs.nim @@ -6,6 +6,18 @@ var a: PA[string] new(a) a.field = "some string" + +proc someOther[T](len: string): seq[T] = discard +proc someOther[T](len: int): seq[T] = echo "we" + +proc foo[T](x: T) = + var s = someOther[T](34) + #newSeq[T](34) + +foo 23 + + + when false: # Compiles unless you use var a: PA[string] type diff --git a/tests/iter/tanoniter1.nim b/tests/iter/tanoniter1.nim index 9db5ab8ec..578749caf 100644 --- a/tests/iter/tanoniter1.nim +++ b/tests/iter/tanoniter1.nim @@ -22,11 +22,11 @@ proc factory2(a, b: int): iterator (): int = yield x inc x -let foo = factory 1, 4 +let foo = factory(1, 4) for f in foo(): echo f -let foo2 = factory2 1,2 +let foo2 = factory2(1,2) for f in foo2(): echo f diff --git a/todo.txt b/todo.txt index 738e9b3fa..44aa39791 100644 --- a/todo.txt +++ b/todo.txt @@ -4,10 +4,7 @@ version 0.9.4 - fix GC issues - fix macros\tstringinterp.nim - test and fix showoff -- test C source code generation -- fix closures -- test and fix exception handling -- implement 'union' and 'bits' pragmas +- fix closure iterators Bugs @@ -28,6 +25,9 @@ Bugs version 0.9.x ============= +- implement 'union' and 'bits' pragmas +- fix closures +- test and fix exception handling - ensure (ref T)(a, b) works as a type conversion and type constructor - optimize 'genericReset'; 'newException' leads to code bloat - stack-less GC |