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
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: