fixes iterator codegen regression

This commit is contained in:
Andreas Rumpf
2016-01-14 10:52:18 +01:00
parent 15c63b8011
commit 3838cd0066
3 changed files with 70 additions and 1 deletions

View File

@@ -213,6 +213,8 @@ proc makeClosure*(prc: PSym; env: PNode; info: TLineInfo): PNode =
if env == nil:
result.add(newNodeIT(nkNilLit, info, getSysType(tyNil)))
else:
if env.kind == nkClosure:
localError(info, "internal error: taking closure of closure")
result.add(env)
proc interestingIterVar(s: PSym): bool {.inline.} =
@@ -709,6 +711,7 @@ proc liftCapturedVars(n: PNode; owner: PSym; d: DetectionPass;
of nkClosure:
if n[1].kind == nkNilLit:
n.sons[0] = liftCapturedVars(n[0], owner, d, c)
#if n.sons[0].kind == nkClosure: result = n.sons[0]
of nkLambdaKinds, nkIteratorDef:
if n.typ != nil and n[namePos].kind == nkSym:
let m = newSymNode(n[namePos].sym)

View File

@@ -313,10 +313,18 @@ proc introduceNewLocalVars(c: PTransf, n: PNode): PTransNode =
result = PTransNode(n)
of nkVarSection, nkLetSection:
result = transformVarSection(c, n)
of nkClosure:
# it can happen that for-loop-inlining produced a fresh
# set of variables, including some computed environment
# (bug #2604). We need to patch this environment here too:
let a = n[1]
if a.kind == nkSym:
n.sons[1] = transformSymAux(c, a)
return PTransNode(n)
else:
result = newTransNode(n)
for i in countup(0, sonsLen(n)-1):
result[i] = introduceNewLocalVars(c, n.sons[i])
result[i] = introduceNewLocalVars(c, n.sons[i])
proc transformYield(c: PTransf, n: PNode): PTransNode =
result = newTransNode(nkStmtList, n.info, 0)

View File

@@ -0,0 +1,58 @@
import sequtils, future
iterator permutations*[T](ys: openarray[T]): tuple[perm: seq[T], sign: int] =
var
d = 1
c = newSeq[int](ys.len)
xs = newSeq[T](ys.len)
sign = 1
for i, y in ys: xs[i] = y
yield (xs, sign)
block outter:
while true:
while d > 1:
dec d
c[d] = 0
while c[d] >= d:
inc d
if d >= ys.len: break outter
let i = if (d and 1) == 1: c[d] else: 0
swap xs[i], xs[d]
sign *= -1
yield (xs, sign)
inc c[d]
proc det(a: seq[seq[float]]): float =
let n = toSeq 0..a.high
for sigma, sign in n.permutations:
result += sign.float * n.map((i: int) => a[i][sigma[i]]).foldl(a * b)
proc perm(a: seq[seq[float]]): float =
let n = toSeq 0..a.high
for sigma, sign in n.permutations:
result += n.map((i: int) => a[i][sigma[i]]).foldl(a * b)
for a in [
@[ @[1.0, 2.0]
, @[3.0, 4.0]
],
@[ @[ 1.0, 2, 3, 4]
, @[ 4.0, 5, 6, 7]
, @[ 7.0, 8, 9, 10]
, @[10.0, 11, 12, 13]
],
@[ @[ 0.0, 1, 2, 3, 4]
, @[ 5.0, 6, 7, 8, 9]
, @[10.0, 11, 12, 13, 14]
, @[15.0, 16, 17, 18, 19]
, @[20.0, 21, 22, 23, 24]
] ]:
echo a
echo "perm: ", a.perm, " det: ", a.det
# bug #3499 last snippet fixed
# bug 705 last snippet fixed