gc:destructors: progress
This commit is contained in:
parent
9563be37d3
commit
728ff1004a
6 changed files with 85 additions and 2 deletions
|
|
@ -306,7 +306,9 @@ proc instantiateProcType(c: PContext, pt: TIdTable,
|
||||||
|
|
||||||
resetIdTable(cl.symMap)
|
resetIdTable(cl.symMap)
|
||||||
resetIdTable(cl.localCache)
|
resetIdTable(cl.localCache)
|
||||||
|
cl.isReturnType = true
|
||||||
result.sons[0] = replaceTypeVarsT(cl, result.sons[0])
|
result.sons[0] = replaceTypeVarsT(cl, result.sons[0])
|
||||||
|
cl.isReturnType = false
|
||||||
result.n.sons[0] = originalParams[0].copyTree
|
result.n.sons[0] = originalParams[0].copyTree
|
||||||
if result.sons[0] != nil:
|
if result.sons[0] != nil:
|
||||||
propagateToOwner(result, result.sons[0])
|
propagateToOwner(result, result.sons[0])
|
||||||
|
|
|
||||||
|
|
@ -481,6 +481,7 @@ proc semVarOrLet(c: PContext, n: PNode, symkind: TSymKind): PNode =
|
||||||
if typ == nil: continue
|
if typ == nil: continue
|
||||||
typeAllowedCheck(c.config, a.info, typ, symkind, if c.matchedConcept != nil: {taConcept} else: {})
|
typeAllowedCheck(c.config, a.info, typ, symkind, if c.matchedConcept != nil: {taConcept} else: {})
|
||||||
liftTypeBoundOps(c.graph, typ, a.info)
|
liftTypeBoundOps(c.graph, typ, a.info)
|
||||||
|
instAllTypeBoundOp(c, a.info)
|
||||||
var tup = skipTypes(typ, {tyGenericInst, tyAlias, tySink})
|
var tup = skipTypes(typ, {tyGenericInst, tyAlias, tySink})
|
||||||
if a.kind == nkVarTuple:
|
if a.kind == nkVarTuple:
|
||||||
if tup.kind != tyTuple:
|
if tup.kind != tyTuple:
|
||||||
|
|
|
||||||
|
|
@ -88,6 +88,7 @@ type
|
||||||
allowMetaTypes*: bool # allow types such as seq[Number]
|
allowMetaTypes*: bool # allow types such as seq[Number]
|
||||||
# i.e. the result contains unresolved generics
|
# i.e. the result contains unresolved generics
|
||||||
skipTypedesc*: bool # wether we should skip typeDescs
|
skipTypedesc*: bool # wether we should skip typeDescs
|
||||||
|
isReturnType*: bool
|
||||||
owner*: PSym # where this instantiation comes from
|
owner*: PSym # where this instantiation comes from
|
||||||
recursionLimit: int
|
recursionLimit: int
|
||||||
|
|
||||||
|
|
@ -594,6 +595,21 @@ proc replaceTypeVarsTAux(cl: var TReplTypeVars, t: PType): PType =
|
||||||
eraseVoidParams(result)
|
eraseVoidParams(result)
|
||||||
skipIntLiteralParams(result)
|
skipIntLiteralParams(result)
|
||||||
|
|
||||||
|
of tySequence:
|
||||||
|
if cl.isReturnType and cl.c.config.selectedGc == gcDestructors and result.destructor.isNil and
|
||||||
|
result[0].kind != tyEmpty:
|
||||||
|
let s = cl.c.graph.sysTypes[tySequence]
|
||||||
|
var old = copyType(s, s.owner, keepId=false)
|
||||||
|
# Remove the 'T' parameter from tySequence:
|
||||||
|
old.sons.setLen 0
|
||||||
|
old.n = nil
|
||||||
|
old.flags = {tfHasAsgn}
|
||||||
|
old.addSonSkipIntLit result[0]
|
||||||
|
result.destructor = old.destructor
|
||||||
|
result.assignment = old.assignment
|
||||||
|
result.sink = old.sink
|
||||||
|
cl.c.typesWithOps.add((result, old))
|
||||||
|
|
||||||
else: discard
|
else: discard
|
||||||
else:
|
else:
|
||||||
# If this type doesn't refer to a generic type we may still want to run it
|
# If this type doesn't refer to a generic type we may still want to run it
|
||||||
|
|
|
||||||
|
|
@ -118,7 +118,7 @@ proc shrink*[T](x: var seq[T]; newLen: Natural) =
|
||||||
when not supportsCopyMem(T):
|
when not supportsCopyMem(T):
|
||||||
for i in countdown(x.len - 1, newLen - 1):
|
for i in countdown(x.len - 1, newLen - 1):
|
||||||
`=destroy`(x[i])
|
`=destroy`(x[i])
|
||||||
|
# XXX This is wrong for const seqs that were moved into 'x'!
|
||||||
cast[ptr NimSeqV2[T]](addr x).len = newLen
|
cast[ptr NimSeqV2[T]](addr x).len = newLen
|
||||||
|
|
||||||
proc grow*[T](x: var seq[T]; newLen: Natural; value: T) =
|
proc grow*[T](x: var seq[T]; newLen: Natural; value: T) =
|
||||||
|
|
|
||||||
|
|
@ -164,6 +164,7 @@ proc mnewString(len: int): NimStringV2 {.compilerProc.} =
|
||||||
proc setLengthStrV2(s: var NimStringV2, newLen: int) {.compilerRtl.} =
|
proc setLengthStrV2(s: var NimStringV2, newLen: int) {.compilerRtl.} =
|
||||||
if newLen > s.len:
|
if newLen > s.len:
|
||||||
prepareAdd(s, newLen - s.len)
|
prepareAdd(s, newLen - s.len)
|
||||||
|
# XXX This is wrong for const strings that got moved into 's'!
|
||||||
s.len = newLen
|
s.len = newLen
|
||||||
# this also only works because the destructor
|
# this also only works because the destructor
|
||||||
# looks at s.p and not s.len
|
# looks at s.p and not s.len
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ discard """
|
||||||
output: '''hi
|
output: '''hi
|
||||||
ho
|
ho
|
||||||
ha
|
ha
|
||||||
1 1'''
|
7 7'''
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import allocators
|
import allocators
|
||||||
|
|
@ -21,6 +21,69 @@ const
|
||||||
for t in test:
|
for t in test:
|
||||||
echo t
|
echo t
|
||||||
|
|
||||||
|
type
|
||||||
|
InterpolatedKind* = enum
|
||||||
|
ikStr, ## ``str`` part of the interpolated string
|
||||||
|
ikDollar, ## escaped ``$`` part of the interpolated string
|
||||||
|
ikVar, ## ``var`` part of the interpolated string
|
||||||
|
ikExpr ## ``expr`` part of the interpolated string
|
||||||
|
|
||||||
|
iterator interpolatedFragments*(s: string): tuple[kind: InterpolatedKind,
|
||||||
|
value: string] =
|
||||||
|
var i = 0
|
||||||
|
var kind: InterpolatedKind
|
||||||
|
while true:
|
||||||
|
var j = i
|
||||||
|
if j < s.len and s[j] == '$':
|
||||||
|
if j+1 < s.len and s[j+1] == '{':
|
||||||
|
inc j, 2
|
||||||
|
var nesting = 0
|
||||||
|
block curlies:
|
||||||
|
while j < s.len:
|
||||||
|
case s[j]
|
||||||
|
of '{': inc nesting
|
||||||
|
of '}':
|
||||||
|
if nesting == 0:
|
||||||
|
inc j
|
||||||
|
break curlies
|
||||||
|
dec nesting
|
||||||
|
else: discard
|
||||||
|
inc j
|
||||||
|
raise newException(ValueError,
|
||||||
|
"Expected closing '}': " & substr(s, i, s.high))
|
||||||
|
inc i, 2 # skip ${
|
||||||
|
kind = ikExpr
|
||||||
|
elif j+1 < s.len and s[j+1] in {'A'..'Z', 'a'..'z', '_'}:
|
||||||
|
inc j, 2
|
||||||
|
while j < s.len and s[j] in {'A'..'Z', 'a'..'z', '0'..'9', '_'}: inc(j)
|
||||||
|
inc i # skip $
|
||||||
|
kind = ikVar
|
||||||
|
elif j+1 < s.len and s[j+1] == '$':
|
||||||
|
inc j, 2
|
||||||
|
inc i # skip $
|
||||||
|
kind = ikDollar
|
||||||
|
else:
|
||||||
|
raise newException(ValueError,
|
||||||
|
"Unable to parse a varible name at " & substr(s, i, s.high))
|
||||||
|
else:
|
||||||
|
while j < s.len and s[j] != '$': inc j
|
||||||
|
kind = ikStr
|
||||||
|
if j > i:
|
||||||
|
# do not copy the trailing } for ikExpr:
|
||||||
|
yield (kind, substr(s, i, j-1-ord(kind == ikExpr)))
|
||||||
|
else:
|
||||||
|
break
|
||||||
|
i = j
|
||||||
|
|
||||||
|
let input = "$test{} $this is ${an{ example}} "
|
||||||
|
let expected = @[(ikVar, "test"), (ikStr, "{} "), (ikVar, "this"),
|
||||||
|
(ikStr, " is "), (ikExpr, "an{ example}"), (ikStr, " ")]
|
||||||
|
var i = 0
|
||||||
|
for s in interpolatedFragments(input):
|
||||||
|
doAssert s == expected[i]
|
||||||
|
inc i
|
||||||
|
|
||||||
|
|
||||||
#echo s
|
#echo s
|
||||||
let (a, d) = allocCounters()
|
let (a, d) = allocCounters()
|
||||||
cprintf("%ld %ld\n", a, d)
|
cprintf("%ld %ld\n", a, d)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue