bugfix: invoking a generic iterator twice triggers a code gen bug (titer2)
This commit is contained in:
parent
8b6f9ef5e8
commit
c3f11d1637
5 changed files with 24 additions and 19 deletions
|
|
@ -14,7 +14,7 @@ import
|
||||||
wordrecg, ropes, msgs, os, condsyms, idents, renderer, types, platform, math,
|
wordrecg, ropes, msgs, os, condsyms, idents, renderer, types, platform, math,
|
||||||
magicsys, parser, nversion, nimsets, semdata, evals, semfold, importer,
|
magicsys, parser, nversion, nimsets, semdata, evals, semfold, importer,
|
||||||
procfind, lookups, rodread, pragmas, passes, semtypinst, sigmatch, suggest,
|
procfind, lookups, rodread, pragmas, passes, semtypinst, sigmatch, suggest,
|
||||||
semthreads, intsets
|
semthreads, intsets, transf
|
||||||
|
|
||||||
proc semPass*(): TPass
|
proc semPass*(): TPass
|
||||||
# implementation
|
# implementation
|
||||||
|
|
@ -138,8 +138,8 @@ proc addCodeForGenerics(c: PContext, n: PNode) =
|
||||||
var it = c.generics.sons[i].sons[1]
|
var it = c.generics.sons[i].sons[1]
|
||||||
if it.kind != nkSym: InternalError("addCodeForGenerics")
|
if it.kind != nkSym: InternalError("addCodeForGenerics")
|
||||||
var prc = it.sym
|
var prc = it.sym
|
||||||
if (prc.kind in {skProc, skMethod, skConverter}) and (prc.magic == mNone):
|
if prc.kind in {skProc, skMethod, skConverter} and prc.magic == mNone:
|
||||||
if (prc.ast == nil) or (prc.ast.sons[codePos] == nil):
|
if prc.ast == nil or prc.ast.sons[codePos] == nil:
|
||||||
InternalError(prc.info, "no code for " & prc.name.s)
|
InternalError(prc.info, "no code for " & prc.name.s)
|
||||||
addSon(n, prc.ast)
|
addSon(n, prc.ast)
|
||||||
c.lastGenericIdx = sonsLen(c.generics)
|
c.lastGenericIdx = sonsLen(c.generics)
|
||||||
|
|
|
||||||
|
|
@ -105,6 +105,9 @@ proc generateInstance(c: PContext, fn: PSym, pt: TIdTable,
|
||||||
addResult(c, result.typ.sons[0], n.info)
|
addResult(c, result.typ.sons[0], n.info)
|
||||||
addResultNode(c, n)
|
addResultNode(c, n)
|
||||||
n.sons[codePos] = semStmtScope(c, n.sons[codePos])
|
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)
|
popProcCon(c)
|
||||||
#echo "code instantiated ", result.name.s
|
#echo "code instantiated ", result.name.s
|
||||||
else:
|
else:
|
||||||
|
|
|
||||||
|
|
@ -472,6 +472,7 @@ proc transformFor(c: PTransf, n: PNode): PTransNode =
|
||||||
# generate access statements for the parameters (unless they are constant)
|
# generate access statements for the parameters (unless they are constant)
|
||||||
# put mapping from formal parameters to actual parameters
|
# put mapping from formal parameters to actual parameters
|
||||||
if n.kind != nkForStmt: InternalError(n.info, "transformFor")
|
if n.kind != nkForStmt: InternalError(n.info, "transformFor")
|
||||||
|
#echo "transforming: ", renderTree(n)
|
||||||
result = newTransNode(nkStmtList, n.info, 0)
|
result = newTransNode(nkStmtList, n.info, 0)
|
||||||
var length = sonsLen(n)
|
var length = sonsLen(n)
|
||||||
var loopBody = transformLoopBody(c, n.sons[length-1])
|
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
|
addVar(v, copyTree(n.sons[i])) # declare new vars
|
||||||
add(result, v.ptransNode)
|
add(result, v.ptransNode)
|
||||||
var call = n.sons[length - 2]
|
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")
|
InternalError(call.info, "transformFor")
|
||||||
|
|
||||||
var newC = newTransCon(call.sons[0].sym)
|
var newC = newTransCon(call.sons[0].sym)
|
||||||
newC.forStmt = n
|
newC.forStmt = n
|
||||||
newC.forLoopBody = loopBody
|
newC.forLoopBody = loopBody
|
||||||
if (newC.owner.kind != skIterator):
|
if newC.owner.kind != skIterator: InternalError(call.info, "transformFor")
|
||||||
InternalError(call.info, "transformFor")
|
|
||||||
# generate access statements for the parameters (unless they are constant)
|
# generate access statements for the parameters (unless they are constant)
|
||||||
pushTransCon(c, newC)
|
pushTransCon(c, newC)
|
||||||
for i in countup(1, sonsLen(call) - 1):
|
for i in countup(1, sonsLen(call) - 1):
|
||||||
|
|
@ -512,6 +512,8 @@ proc transformFor(c: PTransf, n: PNode): PTransNode =
|
||||||
dec(c.inlining)
|
dec(c.inlining)
|
||||||
popInfoContext()
|
popInfoContext()
|
||||||
popTransCon(c)
|
popTransCon(c)
|
||||||
|
#echo "transformed: ", renderTree(n)
|
||||||
|
|
||||||
|
|
||||||
proc getMagicOp(call: PNode): TMagic =
|
proc getMagicOp(call: PNode): TMagic =
|
||||||
if call.sons[0].kind == nkSym and
|
if call.sons[0].kind == nkSym and
|
||||||
|
|
@ -660,7 +662,7 @@ proc transformCall(c: PTransf, n: PNode): PTransNode =
|
||||||
inc(j)
|
inc(j)
|
||||||
add(result, transform(c, a))
|
add(result, transform(c, a))
|
||||||
if len(result) == 2: result = result[1]
|
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:
|
# use the dispatcher for the call:
|
||||||
result = methodCall(transformSons(c, n).pnode).ptransNode
|
result = methodCall(transformSons(c, n).pnode).ptransNode
|
||||||
else:
|
else:
|
||||||
|
|
|
||||||
|
|
@ -19,15 +19,15 @@ iterator mycountup(a, b: int): int =
|
||||||
yield res
|
yield res
|
||||||
inc(res)
|
inc(res)
|
||||||
|
|
||||||
|
when true:
|
||||||
iterator pairs*[A, B](t: TTable[A, B]): tuple[key: A, val: B] =
|
iterator pairs*[A, B](t: TTable[A, B]): tuple[key: A, val: B] =
|
||||||
## iterates over any (key, value) pair in the table `t`.
|
## iterates over any (key, value) pair in the table `t`.
|
||||||
var h = 0
|
for h in mycountup(0, high(t.data)):
|
||||||
while h <= high(t.data):
|
|
||||||
var k = t.data[h].key
|
var k = t.data[h].key
|
||||||
if t.data[h].slot == seFilled: yield (k, t.data[h].val)
|
if t.data[h].slot == seFilled: yield (k, t.data[h].val)
|
||||||
inc(h)
|
else:
|
||||||
|
iterator pairs*(t: TTable[int, string]): tuple[key: int, val: string] =
|
||||||
when false:
|
## iterates over any (key, value) pair in the table `t`.
|
||||||
for h in mycountup(0, high(t.data)):
|
for h in mycountup(0, high(t.data)):
|
||||||
var k = t.data[h].key
|
var k = t.data[h].key
|
||||||
if t.data[h].slot == seFilled: yield (k, t.data[h].val)
|
if t.data[h].slot == seFilled: yield (k, t.data[h].val)
|
||||||
|
|
|
||||||
6
todo.txt
6
todo.txt
|
|
@ -1,10 +1,10 @@
|
||||||
High priority (version 0.8.12)
|
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
|
* implement message passing built-ins
|
||||||
* add --deadlock_prevention:on|off switch? timeout for locks?
|
* add --deadlock_prevention:on|off switch? timeout for locks?
|
||||||
* built-in serialization
|
* built-in serialization
|
||||||
|
* test encodings.nim on windows
|
||||||
|
|
||||||
|
|
||||||
version 0.9.0
|
version 0.9.0
|
||||||
|
|
@ -43,7 +43,6 @@ version 0.9.XX
|
||||||
is hard because of partial evaluation --> symbol files will fix this as
|
is hard because of partial evaluation --> symbol files will fix this as
|
||||||
a side effect
|
a side effect
|
||||||
- EcmaScript needs a new and better code gen: simply adapt the C code gen to it
|
- 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)
|
- tlastmod returns wrong results on BSD (Linux, MacOS X: works)
|
||||||
- nested tuple unpacking
|
- nested tuple unpacking
|
||||||
- 'nimrod def': does not always work?
|
- 'nimrod def': does not always work?
|
||||||
|
|
@ -99,6 +98,7 @@ Version 2
|
||||||
var x = myProc() # checks myProc() initializes every pointer explicitely
|
var x = myProc() # checks myProc() initializes every pointer explicitely
|
||||||
|
|
||||||
- the two other parsers
|
- the two other parsers
|
||||||
|
- generalized case statement (requires better transf)
|
||||||
- rethink the syntax: distinction between expr and stmt is unfortunate;
|
- rethink the syntax: distinction between expr and stmt is unfortunate;
|
||||||
indentation handling is quite complex too; problem with exception handling
|
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
|
is that often the scope of ``try`` is wrong and apart from that ``try`` is
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue