bugfix: invoking a generic iterator twice triggers a code gen bug (titer2)

This commit is contained in:
Araq
2011-06-20 01:28:41 +02:00
parent 8b6f9ef5e8
commit c3f11d1637
5 changed files with 24 additions and 19 deletions

View File

@@ -14,7 +14,7 @@ import
wordrecg, ropes, msgs, os, condsyms, idents, renderer, types, platform, math,
magicsys, parser, nversion, nimsets, semdata, evals, semfold, importer,
procfind, lookups, rodread, pragmas, passes, semtypinst, sigmatch, suggest,
semthreads, intsets
semthreads, intsets, transf
proc semPass*(): TPass
# implementation
@@ -138,8 +138,8 @@ proc addCodeForGenerics(c: PContext, n: PNode) =
var it = c.generics.sons[i].sons[1]
if it.kind != nkSym: InternalError("addCodeForGenerics")
var prc = it.sym
if (prc.kind in {skProc, skMethod, skConverter}) and (prc.magic == mNone):
if (prc.ast == nil) or (prc.ast.sons[codePos] == nil):
if prc.kind in {skProc, skMethod, skConverter} and prc.magic == mNone:
if prc.ast == nil or prc.ast.sons[codePos] == nil:
InternalError(prc.info, "no code for " & prc.name.s)
addSon(n, prc.ast)
c.lastGenericIdx = sonsLen(c.generics)

View File

@@ -105,6 +105,9 @@ proc generateInstance(c: PContext, fn: PSym, pt: TIdTable,
addResult(c, result.typ.sons[0], n.info)
addResultNode(c, n)
n.sons[codePos] = semStmtScope(c, n.sons[codePos])
if fn.kind == skIterator:
# XXX Bad hack for tests/titer2:
n.sons[codePos] = transform(c.module, n.sons[codePos])
popProcCon(c)
#echo "code instantiated ", result.name.s
else:

View File

@@ -472,6 +472,7 @@ proc transformFor(c: PTransf, n: PNode): PTransNode =
# generate access statements for the parameters (unless they are constant)
# put mapping from formal parameters to actual parameters
if n.kind != nkForStmt: InternalError(n.info, "transformFor")
#echo "transforming: ", renderTree(n)
result = newTransNode(nkStmtList, n.info, 0)
var length = sonsLen(n)
var loopBody = transformLoopBody(c, n.sons[length-1])
@@ -480,14 +481,13 @@ proc transformFor(c: PTransf, n: PNode): PTransNode =
addVar(v, copyTree(n.sons[i])) # declare new vars
add(result, v.ptransNode)
var call = n.sons[length - 2]
if (call.kind != nkCall) or (call.sons[0].kind != nkSym):
if call.kind != nkCall or call.sons[0].kind != nkSym:
InternalError(call.info, "transformFor")
var newC = newTransCon(call.sons[0].sym)
newC.forStmt = n
newC.forLoopBody = loopBody
if (newC.owner.kind != skIterator):
InternalError(call.info, "transformFor")
if newC.owner.kind != skIterator: InternalError(call.info, "transformFor")
# generate access statements for the parameters (unless they are constant)
pushTransCon(c, newC)
for i in countup(1, sonsLen(call) - 1):
@@ -512,6 +512,8 @@ proc transformFor(c: PTransf, n: PNode): PTransNode =
dec(c.inlining)
popInfoContext()
popTransCon(c)
#echo "transformed: ", renderTree(n)
proc getMagicOp(call: PNode): TMagic =
if call.sons[0].kind == nkSym and
@@ -660,7 +662,7 @@ proc transformCall(c: PTransf, n: PNode): PTransNode =
inc(j)
add(result, transform(c, a))
if len(result) == 2: result = result[1]
elif (n.sons[0].kind == nkSym) and (n.sons[0].sym.kind == skMethod):
elif n.sons[0].kind == nkSym and n.sons[0].sym.kind == skMethod:
# use the dispatcher for the call:
result = methodCall(transformSons(c, n).pnode).ptransNode
else:

View File

@@ -19,15 +19,15 @@ iterator mycountup(a, b: int): int =
yield res
inc(res)
iterator pairs*[A, B](t: TTable[A, B]): tuple[key: A, val: B] =
## iterates over any (key, value) pair in the table `t`.
var h = 0
while h <= high(t.data):
var k = t.data[h].key
if t.data[h].slot == seFilled: yield (k, t.data[h].val)
inc(h)
when false:
when true:
iterator pairs*[A, B](t: TTable[A, B]): tuple[key: A, val: B] =
## iterates over any (key, value) pair in the table `t`.
for h in mycountup(0, high(t.data)):
var k = t.data[h].key
if t.data[h].slot == seFilled: yield (k, t.data[h].val)
else:
iterator pairs*(t: TTable[int, string]): tuple[key: int, val: string] =
## iterates over any (key, value) pair in the table `t`.
for h in mycountup(0, high(t.data)):
var k = t.data[h].key
if t.data[h].slot == seFilled: yield (k, t.data[h].val)

View File

@@ -1,10 +1,10 @@
High priority (version 0.8.12)
==============================
- bug: invoking a generic iterator twice triggers a code gen bug (titer2)
* implement write access to ``s[i]`` for macros
* implement message passing built-ins
* add --deadlock_prevention:on|off switch? timeout for locks?
* built-in serialization
* test encodings.nim on windows
version 0.9.0
@@ -43,7 +43,6 @@ version 0.9.XX
is hard because of partial evaluation --> symbol files will fix this as
a side effect
- EcmaScript needs a new and better code gen: simply adapt the C code gen to it
- generalized case statement (requires better transf)
- tlastmod returns wrong results on BSD (Linux, MacOS X: works)
- nested tuple unpacking
- 'nimrod def': does not always work?
@@ -99,6 +98,7 @@ Version 2
var x = myProc() # checks myProc() initializes every pointer explicitely
- the two other parsers
- generalized case statement (requires better transf)
- rethink the syntax: distinction between expr and stmt is unfortunate;
indentation handling is quite complex too; problem with exception handling
is that often the scope of ``try`` is wrong and apart from that ``try`` is