mirror of
https://github.com/nim-lang/Nim.git
synced 2026-01-06 13:07:48 +00:00
refactoring: no inheritance for PType/PSym (#23403)
This commit is contained in:
@@ -780,10 +780,6 @@ proc hash*(x: ItemId): Hash =
|
||||
|
||||
|
||||
type
|
||||
TIdObj* {.acyclic.} = object of RootObj
|
||||
itemId*: ItemId
|
||||
PIdObj* = ref TIdObj
|
||||
|
||||
PNode* = ref TNode
|
||||
TNodeSeq* = seq[PNode]
|
||||
PType* = ref TType
|
||||
@@ -886,7 +882,8 @@ type
|
||||
PScope* = ref TScope
|
||||
|
||||
PLib* = ref TLib
|
||||
TSym* {.acyclic.} = object of TIdObj # Keep in sync with PackedSym
|
||||
TSym* {.acyclic.} = object # Keep in sync with PackedSym
|
||||
itemId*: ItemId
|
||||
# proc and type instantiations are cached in the generic symbol
|
||||
case kind*: TSymKind
|
||||
of routineKinds:
|
||||
@@ -955,11 +952,12 @@ type
|
||||
attachedTrace,
|
||||
attachedDeepCopy
|
||||
|
||||
TType* {.acyclic.} = object of TIdObj # \
|
||||
TType* {.acyclic.} = object # \
|
||||
# types are identical iff they have the
|
||||
# same id; there may be multiple copies of a type
|
||||
# in memory!
|
||||
# Keep in sync with PackedType
|
||||
itemId*: ItemId
|
||||
kind*: TTypeKind # kind of type
|
||||
callConv*: TCallingConvention # for procs
|
||||
flags*: TTypeFlags # flags of the type
|
||||
@@ -991,24 +989,6 @@ type
|
||||
|
||||
TPairSeq* = seq[TPair]
|
||||
|
||||
TIdPair* = object
|
||||
key*: PIdObj
|
||||
val*: RootRef
|
||||
|
||||
TIdPairSeq* = seq[TIdPair]
|
||||
TIdTable* = object # the same as table[PIdent] of PObject
|
||||
counter*: int
|
||||
data*: TIdPairSeq
|
||||
|
||||
TIdNodePair* = object
|
||||
key*: PIdObj
|
||||
val*: PNode
|
||||
|
||||
TIdNodePairSeq* = seq[TIdNodePair]
|
||||
TIdNodeTable* = object # the same as table[PIdObj] of PNode
|
||||
counter*: int
|
||||
data*: TIdNodePairSeq
|
||||
|
||||
TNodePair* = object
|
||||
h*: Hash # because it is expensive to compute!
|
||||
key*: PNode
|
||||
@@ -1146,7 +1126,7 @@ proc getPIdent*(a: PNode): PIdent {.inline.} =
|
||||
const
|
||||
moduleShift = when defined(cpu32): 20 else: 24
|
||||
|
||||
template id*(a: PIdObj): int =
|
||||
template id*(a: PType | PSym): int =
|
||||
let x = a
|
||||
(x.itemId.module.int shl moduleShift) + x.itemId.item.int
|
||||
|
||||
@@ -1445,11 +1425,6 @@ proc copyStrTable*(dest: var TStrTable, src: TStrTable) =
|
||||
setLen(dest.data, src.data.len)
|
||||
for i in 0..high(src.data): dest.data[i] = src.data[i]
|
||||
|
||||
proc copyIdTable*(dest: var TIdTable, src: TIdTable) =
|
||||
dest.counter = src.counter
|
||||
newSeq(dest.data, src.data.len)
|
||||
for i in 0..high(src.data): dest.data[i] = src.data[i]
|
||||
|
||||
proc copyObjectSet*(dest: var TObjectSet, src: TObjectSet) =
|
||||
dest.counter = src.counter
|
||||
setLen(dest.data, src.data.len)
|
||||
@@ -1770,24 +1745,10 @@ proc initStrTable*(): TStrTable =
|
||||
result = TStrTable(counter: 0)
|
||||
newSeq(result.data, StartSize)
|
||||
|
||||
proc initIdTable*(): TIdTable =
|
||||
result = TIdTable(counter: 0)
|
||||
newSeq(result.data, StartSize)
|
||||
|
||||
proc resetIdTable*(x: var TIdTable) =
|
||||
x.counter = 0
|
||||
# clear and set to old initial size:
|
||||
setLen(x.data, 0)
|
||||
setLen(x.data, StartSize)
|
||||
|
||||
proc initObjectSet*(): TObjectSet =
|
||||
result = TObjectSet(counter: 0)
|
||||
newSeq(result.data, StartSize)
|
||||
|
||||
proc initIdNodeTable*(): TIdNodeTable =
|
||||
result = TIdNodeTable(counter: 0)
|
||||
newSeq(result.data, StartSize)
|
||||
|
||||
proc initNodeTable*(): TNodeTable =
|
||||
result = TNodeTable(counter: 0)
|
||||
newSeq(result.data, StartSize)
|
||||
@@ -2308,3 +2269,16 @@ const
|
||||
proc isTrue*(n: PNode): bool =
|
||||
n.kind == nkSym and n.sym.kind == skEnumField and n.sym.position != 0 or
|
||||
n.kind == nkIntLit and n.intVal != 0
|
||||
|
||||
type
|
||||
TypeMapping* = Table[ItemId, PType]
|
||||
SymMapping* = Table[ItemId, PSym]
|
||||
|
||||
template idTableGet*(tab: typed; key: PSym | PType): untyped = tab.getOrDefault(key.itemId)
|
||||
template idTablePut*(tab: typed; key, val: PSym | PType) = tab[key.itemId] = val
|
||||
|
||||
template initSymMapping*(): Table[ItemId, PSym] = initTable[ItemId, PSym]()
|
||||
template initTypeMapping*(): Table[ItemId, PType] = initTable[ItemId, PType]()
|
||||
|
||||
template resetIdTable*(tab: Table[ItemId, PSym]) = tab.clear()
|
||||
template resetIdTable*(tab: Table[ItemId, PType]) = tab.clear()
|
||||
|
||||
@@ -65,16 +65,6 @@ template mdbg*: bool {.deprecated.} =
|
||||
else:
|
||||
error()
|
||||
|
||||
# --------------------------- ident tables ----------------------------------
|
||||
proc idTableGet*(t: TIdTable, key: PIdObj): RootRef
|
||||
proc idTableGet*(t: TIdTable, key: int): RootRef
|
||||
proc idTablePut*(t: var TIdTable, key: PIdObj, val: RootRef)
|
||||
proc idTableHasObjectAsKey*(t: TIdTable, key: PIdObj): bool
|
||||
# checks if `t` contains the `key` (compared by the pointer value, not only
|
||||
# `key`'s id)
|
||||
proc idNodeTableGet*(t: TIdNodeTable, key: PIdObj): PNode
|
||||
proc idNodeTablePut*(t: var TIdNodeTable, key: PIdObj, val: PNode)
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
proc lookupInRecord*(n: PNode, field: PIdent): PSym
|
||||
@@ -723,119 +713,6 @@ iterator items*(tab: TStrTable): PSym =
|
||||
yield s
|
||||
s = nextIter(it, tab)
|
||||
|
||||
proc hasEmptySlot(data: TIdPairSeq): bool =
|
||||
for h in 0..high(data):
|
||||
if data[h].key == nil:
|
||||
return true
|
||||
result = false
|
||||
|
||||
proc idTableRawGet(t: TIdTable, key: int): int =
|
||||
var h: Hash
|
||||
h = key and high(t.data) # start with real hash value
|
||||
while t.data[h].key != nil:
|
||||
if t.data[h].key.id == key:
|
||||
return h
|
||||
h = nextTry(h, high(t.data))
|
||||
result = - 1
|
||||
|
||||
proc idTableHasObjectAsKey(t: TIdTable, key: PIdObj): bool =
|
||||
var index = idTableRawGet(t, key.id)
|
||||
if index >= 0: result = t.data[index].key == key
|
||||
else: result = false
|
||||
|
||||
proc idTableGet(t: TIdTable, key: PIdObj): RootRef =
|
||||
var index = idTableRawGet(t, key.id)
|
||||
if index >= 0: result = t.data[index].val
|
||||
else: result = nil
|
||||
|
||||
proc idTableGet(t: TIdTable, key: int): RootRef =
|
||||
var index = idTableRawGet(t, key)
|
||||
if index >= 0: result = t.data[index].val
|
||||
else: result = nil
|
||||
|
||||
iterator pairs*(t: TIdTable): tuple[key: int, value: RootRef] =
|
||||
for i in 0..high(t.data):
|
||||
if t.data[i].key != nil:
|
||||
yield (t.data[i].key.id, t.data[i].val)
|
||||
|
||||
proc idTableRawInsert(data: var TIdPairSeq, key: PIdObj, val: RootRef) =
|
||||
var h: Hash
|
||||
h = key.id and high(data)
|
||||
while data[h].key != nil:
|
||||
assert(data[h].key.id != key.id)
|
||||
h = nextTry(h, high(data))
|
||||
assert(data[h].key == nil)
|
||||
data[h].key = key
|
||||
data[h].val = val
|
||||
|
||||
proc idTablePut(t: var TIdTable, key: PIdObj, val: RootRef) =
|
||||
var
|
||||
index: int
|
||||
n: TIdPairSeq
|
||||
index = idTableRawGet(t, key.id)
|
||||
if index >= 0:
|
||||
assert(t.data[index].key != nil)
|
||||
t.data[index].val = val
|
||||
else:
|
||||
if mustRehash(t.data.len, t.counter):
|
||||
newSeq(n, t.data.len * GrowthFactor)
|
||||
for i in 0..high(t.data):
|
||||
if t.data[i].key != nil:
|
||||
idTableRawInsert(n, t.data[i].key, t.data[i].val)
|
||||
assert(hasEmptySlot(n))
|
||||
swap(t.data, n)
|
||||
idTableRawInsert(t.data, key, val)
|
||||
inc(t.counter)
|
||||
|
||||
iterator idTablePairs*(t: TIdTable): tuple[key: PIdObj, val: RootRef] =
|
||||
for i in 0..high(t.data):
|
||||
if not isNil(t.data[i].key): yield (t.data[i].key, t.data[i].val)
|
||||
|
||||
proc idNodeTableRawGet(t: TIdNodeTable, key: PIdObj): int =
|
||||
var h: Hash
|
||||
h = key.id and high(t.data) # start with real hash value
|
||||
while t.data[h].key != nil:
|
||||
if t.data[h].key.id == key.id:
|
||||
return h
|
||||
h = nextTry(h, high(t.data))
|
||||
result = - 1
|
||||
|
||||
proc idNodeTableGet(t: TIdNodeTable, key: PIdObj): PNode =
|
||||
var index: int
|
||||
index = idNodeTableRawGet(t, key)
|
||||
if index >= 0: result = t.data[index].val
|
||||
else: result = nil
|
||||
|
||||
proc idNodeTableRawInsert(data: var TIdNodePairSeq, key: PIdObj, val: PNode) =
|
||||
var h: Hash
|
||||
h = key.id and high(data)
|
||||
while data[h].key != nil:
|
||||
assert(data[h].key.id != key.id)
|
||||
h = nextTry(h, high(data))
|
||||
assert(data[h].key == nil)
|
||||
data[h].key = key
|
||||
data[h].val = val
|
||||
|
||||
proc idNodeTablePut(t: var TIdNodeTable, key: PIdObj, val: PNode) =
|
||||
var index = idNodeTableRawGet(t, key)
|
||||
if index >= 0:
|
||||
assert(t.data[index].key != nil)
|
||||
t.data[index].val = val
|
||||
else:
|
||||
if mustRehash(t.data.len, t.counter):
|
||||
var n: TIdNodePairSeq
|
||||
newSeq(n, t.data.len * GrowthFactor)
|
||||
for i in 0..high(t.data):
|
||||
if t.data[i].key != nil:
|
||||
idNodeTableRawInsert(n, t.data[i].key, t.data[i].val)
|
||||
swap(t.data, n)
|
||||
idNodeTableRawInsert(t.data, key, val)
|
||||
inc(t.counter)
|
||||
|
||||
iterator pairs*(t: TIdNodeTable): tuple[key: PIdObj, val: PNode] =
|
||||
for i in 0..high(t.data):
|
||||
if not isNil(t.data[i].key): yield (t.data[i].key, t.data[i].val)
|
||||
|
||||
proc initIITable(x: var TIITable) =
|
||||
x.counter = 0
|
||||
newSeq(x.data, StartSize)
|
||||
|
||||
@@ -309,7 +309,7 @@ proc conceptMatchNode(c: PContext; n: PNode; m: var MatchCon): bool =
|
||||
# error was reported earlier.
|
||||
result = false
|
||||
|
||||
proc conceptMatch*(c: PContext; concpt, arg: PType; bindings: var TIdTable; invocation: PType): bool =
|
||||
proc conceptMatch*(c: PContext; concpt, arg: PType; bindings: var TypeMapping; invocation: PType): bool =
|
||||
## Entry point from sigmatch. 'concpt' is the concept we try to match (here still a PType but
|
||||
## we extract its AST via 'concpt.n.lastSon'). 'arg' is the type that might fullfill the
|
||||
## concept's requirements. If so, we return true and fill the 'bindings' with pairs of
|
||||
|
||||
@@ -17,8 +17,8 @@ type
|
||||
owner, genSymOwner: PSym
|
||||
instLines: bool # use the instantiation lines numbers
|
||||
isDeclarative: bool
|
||||
mapping: TIdTable # every gensym'ed symbol needs to be mapped to some
|
||||
# new symbol
|
||||
mapping: SymMapping # every gensym'ed symbol needs to be mapped to some
|
||||
# new symbol
|
||||
config: ConfigRef
|
||||
ic: IdentCache
|
||||
instID: int
|
||||
@@ -47,7 +47,7 @@ proc evalTemplateAux(templ, actual: PNode, c: var TemplCtx, result: PNode) =
|
||||
handleParam actual[s.owner.typ.signatureLen + s.position - 1]
|
||||
else:
|
||||
internalAssert c.config, sfGenSym in s.flags or s.kind == skType
|
||||
var x = PSym(idTableGet(c.mapping, s))
|
||||
var x = idTableGet(c.mapping, s)
|
||||
if x == nil:
|
||||
x = copySym(s, c.idgen)
|
||||
# sem'check needs to set the owner properly later, see bug #9476
|
||||
@@ -186,7 +186,7 @@ proc evalTemplate*(n: PNode, tmpl, genSymOwner: PSym;
|
||||
genSymOwner: genSymOwner,
|
||||
config: conf,
|
||||
ic: ic,
|
||||
mapping: initIdTable(),
|
||||
mapping: initSymMapping(),
|
||||
instID: instID[],
|
||||
idgen: idgen
|
||||
)
|
||||
|
||||
@@ -530,7 +530,7 @@ proc semAfterMacroCall(c: PContext, call, macroResult: PNode,
|
||||
# e.g. template foo(T: typedesc): seq[T]
|
||||
# We will instantiate the return type here, because
|
||||
# we now know the supplied arguments
|
||||
var paramTypes = initIdTable()
|
||||
var paramTypes = initTypeMapping()
|
||||
for param, value in genericParamsInMacroCall(s, call):
|
||||
var givenType = value.typ
|
||||
# the sym nodes used for the supplied generic arguments for
|
||||
|
||||
@@ -663,7 +663,7 @@ proc inheritBindings(c: PContext, x: var TCandidate, expectedType: PType) =
|
||||
if t[i] == nil or u[i] == nil: return
|
||||
stackPut(t[i], u[i])
|
||||
of tyGenericParam:
|
||||
let prebound = x.bindings.idTableGet(t).PType
|
||||
let prebound = x.bindings.idTableGet(t)
|
||||
if prebound != nil:
|
||||
continue # Skip param, already bound
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ type
|
||||
breakInLoop*: bool # whether we are in a loop without block
|
||||
next*: PProcCon # used for stacking procedure contexts
|
||||
mappingExists*: bool
|
||||
mapping*: TIdTable
|
||||
mapping*: Table[ItemId, PSym]
|
||||
caseContext*: seq[tuple[n: PNode, idx: int]]
|
||||
localBindStmts*: seq[PNode]
|
||||
|
||||
@@ -122,8 +122,6 @@ type
|
||||
converters*: seq[PSym]
|
||||
patterns*: seq[PSym] # sequence of pattern matchers
|
||||
optionStack*: seq[POptionEntry]
|
||||
symMapping*: TIdTable # every gensym'ed symbol needs to be mapped
|
||||
# to some new symbol in a generic instantiation
|
||||
libs*: seq[PLib] # all libs used by this module
|
||||
semConstExpr*: proc (c: PContext, n: PNode; expectedType: PType = nil): PNode {.nimcall.} # for the pragmas
|
||||
semExpr*: proc (c: PContext, n: PNode, flags: TExprFlags = {}, expectedType: PType = nil): PNode {.nimcall.}
|
||||
@@ -138,8 +136,8 @@ type
|
||||
semOverloadedCall*: proc (c: PContext, n, nOrig: PNode,
|
||||
filter: TSymKinds, flags: TExprFlags, expectedType: PType = nil): PNode {.nimcall.}
|
||||
semTypeNode*: proc(c: PContext, n: PNode, prev: PType): PType {.nimcall.}
|
||||
semInferredLambda*: proc(c: PContext, pt: TIdTable, n: PNode): PNode
|
||||
semGenerateInstance*: proc (c: PContext, fn: PSym, pt: TIdTable,
|
||||
semInferredLambda*: proc(c: PContext, pt: Table[ItemId, PType], n: PNode): PNode
|
||||
semGenerateInstance*: proc (c: PContext, fn: PSym, pt: Table[ItemId, PType],
|
||||
info: TLineInfo): PSym
|
||||
includedFiles*: IntSet # used to detect recursive include files
|
||||
pureEnumFields*: TStrTable # pure enum fields that can be used unambiguously
|
||||
@@ -251,14 +249,14 @@ proc popProcCon*(c: PContext) {.inline.} = c.p = c.p.next
|
||||
|
||||
proc put*(p: PProcCon; key, val: PSym) =
|
||||
if not p.mappingExists:
|
||||
p.mapping = initIdTable()
|
||||
p.mapping = initTable[ItemId, PSym]()
|
||||
p.mappingExists = true
|
||||
#echo "put into table ", key.info
|
||||
p.mapping.idTablePut(key, val)
|
||||
p.mapping[key.itemId] = val
|
||||
|
||||
proc get*(p: PProcCon; key: PSym): PSym =
|
||||
if not p.mappingExists: return nil
|
||||
result = PSym(p.mapping.idTableGet(key))
|
||||
result = p.mapping.getOrDefault(key.itemId)
|
||||
|
||||
proc getGenSym*(c: PContext; s: PSym): PSym =
|
||||
if sfGenSym notin s.flags: return s
|
||||
|
||||
@@ -2418,7 +2418,7 @@ proc instantiateCreateFlowVarCall(c: PContext; t: PType;
|
||||
let sym = magicsys.getCompilerProc(c.graph, "nimCreateFlowVar")
|
||||
if sym == nil:
|
||||
localError(c.config, info, "system needs: nimCreateFlowVar")
|
||||
var bindings: TIdTable = initIdTable()
|
||||
var bindings = initTypeMapping()
|
||||
bindings.idTablePut(sym.ast[genericParamsPos][0].typ, t)
|
||||
result = c.semGenerateInstance(c, sym, bindings, info)
|
||||
# since it's an instantiation, we unmark it as a compilerproc. Otherwise
|
||||
|
||||
@@ -34,7 +34,7 @@ proc pushProcCon*(c: PContext; owner: PSym) =
|
||||
const
|
||||
errCannotInstantiateX = "cannot instantiate: '$1'"
|
||||
|
||||
iterator instantiateGenericParamList(c: PContext, n: PNode, pt: TIdTable): PSym =
|
||||
iterator instantiateGenericParamList(c: PContext, n: PNode, pt: TypeMapping): PSym =
|
||||
internalAssert c.config, n.kind == nkGenericParams
|
||||
for a in n.items:
|
||||
internalAssert c.config, a.kind == nkSym
|
||||
@@ -43,7 +43,7 @@ iterator instantiateGenericParamList(c: PContext, n: PNode, pt: TIdTable): PSym
|
||||
let symKind = if q.typ.kind == tyStatic: skConst else: skType
|
||||
var s = newSym(symKind, q.name, c.idgen, getCurrOwner(c), q.info)
|
||||
s.flags.incl {sfUsed, sfFromGeneric}
|
||||
var t = PType(idTableGet(pt, q.typ))
|
||||
var t = idTableGet(pt, q.typ)
|
||||
if t == nil:
|
||||
if tfRetType in q.typ.flags:
|
||||
# keep the generic type and allow the return type to be bound
|
||||
@@ -92,7 +92,7 @@ when false:
|
||||
proc `$`(x: PSym): string =
|
||||
result = x.name.s & " " & " id " & $x.id
|
||||
|
||||
proc freshGenSyms(c: PContext; n: PNode, owner, orig: PSym, symMap: var TIdTable) =
|
||||
proc freshGenSyms(c: PContext; n: PNode, owner, orig: PSym, symMap: var SymMapping) =
|
||||
# we need to create a fresh set of gensym'ed symbols:
|
||||
#if n.kind == nkSym and sfGenSym in n.sym.flags:
|
||||
# if n.sym.owner != orig:
|
||||
@@ -100,7 +100,7 @@ proc freshGenSyms(c: PContext; n: PNode, owner, orig: PSym, symMap: var TIdTable
|
||||
if n.kind == nkSym and sfGenSym in n.sym.flags: # and
|
||||
# (n.sym.owner == orig or n.sym.owner.kind in {skPackage}):
|
||||
let s = n.sym
|
||||
var x = PSym(idTableGet(symMap, s))
|
||||
var x = idTableGet(symMap, s)
|
||||
if x != nil:
|
||||
n.sym = x
|
||||
elif s.owner == nil or s.owner.kind == skPackage:
|
||||
@@ -124,7 +124,7 @@ proc instantiateBody(c: PContext, n, params: PNode, result, orig: PSym) =
|
||||
inc c.inGenericInst
|
||||
# add it here, so that recursive generic procs are possible:
|
||||
var b = n[bodyPos]
|
||||
var symMap: TIdTable = initIdTable()
|
||||
var symMap = initSymMapping()
|
||||
if params != nil:
|
||||
for i in 1..<params.len:
|
||||
let param = params[i].sym
|
||||
@@ -174,12 +174,12 @@ proc instGenericContainer(c: PContext, info: TLineInfo, header: PType,
|
||||
allowMetaTypes = false): PType =
|
||||
internalAssert c.config, header.kind == tyGenericInvocation
|
||||
|
||||
var cl: TReplTypeVars = TReplTypeVars(symMap: initIdTable(),
|
||||
localCache: initIdTable(), typeMap: LayeredIdTable(),
|
||||
var cl: TReplTypeVars = TReplTypeVars(symMap: initSymMapping(),
|
||||
localCache: initTypeMapping(), typeMap: LayeredIdTable(),
|
||||
info: info, c: c, allowMetaTypes: allowMetaTypes
|
||||
)
|
||||
|
||||
cl.typeMap.topLayer = initIdTable()
|
||||
cl.typeMap.topLayer = initTypeMapping()
|
||||
|
||||
# We must add all generic params in scope, because the generic body
|
||||
# may include tyFromExpr nodes depending on these generic params.
|
||||
@@ -217,7 +217,7 @@ proc referencesAnotherParam(n: PNode, p: PSym): bool =
|
||||
if referencesAnotherParam(n[i], p): return true
|
||||
return false
|
||||
|
||||
proc instantiateProcType(c: PContext, pt: TIdTable,
|
||||
proc instantiateProcType(c: PContext, pt: TypeMapping,
|
||||
prc: PSym, info: TLineInfo) =
|
||||
# XXX: Instantiates a generic proc signature, while at the same
|
||||
# time adding the instantiated proc params into the current scope.
|
||||
@@ -332,7 +332,7 @@ proc getLocalPassC(c: PContext, s: PSym): string =
|
||||
for p in n:
|
||||
extractPassc(p)
|
||||
|
||||
proc generateInstance(c: PContext, fn: PSym, pt: TIdTable,
|
||||
proc generateInstance(c: PContext, fn: PSym, pt: TypeMapping,
|
||||
info: TLineInfo): PSym =
|
||||
## Generates a new instance of a generic procedure.
|
||||
## The `pt` parameter is a type-unsafe mapping table used to link generic
|
||||
|
||||
@@ -1834,7 +1834,7 @@ proc semProcAnnotation(c: PContext, prc: PNode;
|
||||
|
||||
return result
|
||||
|
||||
proc semInferredLambda(c: PContext, pt: TIdTable, n: PNode): PNode =
|
||||
proc semInferredLambda(c: PContext, pt: TypeMapping, n: PNode): PNode =
|
||||
## used for resolving 'auto' in lambdas based on their callsite
|
||||
var n = n
|
||||
let original = n[namePos].sym
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
|
||||
# This module does the instantiation of generic types.
|
||||
|
||||
import std / tables
|
||||
|
||||
import ast, astalgo, msgs, types, magicsys, semdata, renderer, options,
|
||||
lineinfos, modulegraphs
|
||||
|
||||
@@ -64,14 +66,14 @@ proc cacheTypeInst(c: PContext; inst: PType) =
|
||||
|
||||
type
|
||||
LayeredIdTable* {.acyclic.} = ref object
|
||||
topLayer*: TIdTable
|
||||
topLayer*: TypeMapping
|
||||
nextLayer*: LayeredIdTable
|
||||
|
||||
TReplTypeVars* = object
|
||||
c*: PContext
|
||||
typeMap*: LayeredIdTable # map PType to PType
|
||||
symMap*: TIdTable # map PSym to PSym
|
||||
localCache*: TIdTable # local cache for remembering already replaced
|
||||
symMap*: SymMapping # map PSym to PSym
|
||||
localCache*: TypeMapping # local cache for remembering already replaced
|
||||
# types during instantiation of meta types
|
||||
# (they are not stored in the global cache)
|
||||
info*: TLineInfo
|
||||
@@ -86,23 +88,23 @@ proc replaceTypeVarsTAux(cl: var TReplTypeVars, t: PType): PType
|
||||
proc replaceTypeVarsS(cl: var TReplTypeVars, s: PSym, t: PType): PSym
|
||||
proc replaceTypeVarsN*(cl: var TReplTypeVars, n: PNode; start=0; expectedType: PType = nil): PNode
|
||||
|
||||
proc initLayeredTypeMap*(pt: TIdTable): LayeredIdTable =
|
||||
proc initLayeredTypeMap*(pt: sink TypeMapping): LayeredIdTable =
|
||||
result = LayeredIdTable()
|
||||
copyIdTable(result.topLayer, pt)
|
||||
result.topLayer = pt
|
||||
|
||||
proc newTypeMapLayer*(cl: var TReplTypeVars): LayeredIdTable =
|
||||
result = LayeredIdTable(nextLayer: cl.typeMap, topLayer: initIdTable())
|
||||
result = LayeredIdTable(nextLayer: cl.typeMap, topLayer: initTable[ItemId, PType]())
|
||||
|
||||
proc lookup(typeMap: LayeredIdTable, key: PType): PType =
|
||||
result = nil
|
||||
var tm = typeMap
|
||||
while tm != nil:
|
||||
result = PType(idTableGet(tm.topLayer, key))
|
||||
result = getOrDefault(tm.topLayer, key.itemId)
|
||||
if result != nil: return
|
||||
tm = tm.nextLayer
|
||||
|
||||
template put(typeMap: LayeredIdTable, key, value: PType) =
|
||||
idTablePut(typeMap.topLayer, key, value)
|
||||
typeMap.topLayer[key.itemId] = value
|
||||
|
||||
template checkMetaInvariants(cl: TReplTypeVars, t: PType) = # noop code
|
||||
when false:
|
||||
@@ -361,7 +363,7 @@ proc handleGenericInvocation(cl: var TReplTypeVars, t: PType): PType =
|
||||
var header = t
|
||||
# search for some instantiation here:
|
||||
if cl.allowMetaTypes:
|
||||
result = PType(idTableGet(cl.localCache, t))
|
||||
result = getOrDefault(cl.localCache, t.itemId)
|
||||
else:
|
||||
result = searchInstTypes(cl.c.graph, t)
|
||||
|
||||
@@ -400,7 +402,7 @@ proc handleGenericInvocation(cl: var TReplTypeVars, t: PType): PType =
|
||||
if not cl.allowMetaTypes:
|
||||
cacheTypeInst(cl.c, result)
|
||||
else:
|
||||
idTablePut(cl.localCache, t, result)
|
||||
cl.localCache[t.itemId] = result
|
||||
|
||||
let oldSkipTypedesc = cl.skipTypedesc
|
||||
cl.skipTypedesc = true
|
||||
@@ -547,7 +549,7 @@ proc replaceTypeVarsTAux(cl: var TReplTypeVars, t: PType): PType =
|
||||
# type
|
||||
# Vector[N: static[int]] = array[N, float64]
|
||||
# TwoVectors[Na, Nb: static[int]] = (Vector[Na], Vector[Nb])
|
||||
result = PType(idTableGet(cl.localCache, t))
|
||||
result = getOrDefault(cl.localCache, t.itemId)
|
||||
if result != nil: return result
|
||||
inc cl.recursionLimit
|
||||
|
||||
@@ -623,7 +625,7 @@ proc replaceTypeVarsTAux(cl: var TReplTypeVars, t: PType): PType =
|
||||
of tyGenericInst, tyUserTypeClassInst:
|
||||
bailout()
|
||||
result = instCopyType(cl, t)
|
||||
idTablePut(cl.localCache, t, result)
|
||||
cl.localCache[t.itemId] = result
|
||||
for i in FirstGenericParamAt..<result.kidsLen:
|
||||
result[i] = replaceTypeVarsT(cl, result[i])
|
||||
propagateToOwner(result, result.last)
|
||||
@@ -635,7 +637,7 @@ proc replaceTypeVarsTAux(cl: var TReplTypeVars, t: PType): PType =
|
||||
result = instCopyType(cl, t)
|
||||
result.size = -1 # needs to be recomputed
|
||||
#if not cl.allowMetaTypes:
|
||||
idTablePut(cl.localCache, t, result)
|
||||
cl.localCache[t.itemId] = result
|
||||
|
||||
for i, resulti in result.ikids:
|
||||
if resulti != nil:
|
||||
@@ -690,11 +692,11 @@ proc replaceTypeVarsTAux(cl: var TReplTypeVars, t: PType): PType =
|
||||
|
||||
proc initTypeVars*(p: PContext, typeMap: LayeredIdTable, info: TLineInfo;
|
||||
owner: PSym): TReplTypeVars =
|
||||
result = TReplTypeVars(symMap: initIdTable(),
|
||||
localCache: initIdTable(), typeMap: typeMap,
|
||||
result = TReplTypeVars(symMap: initSymMapping(),
|
||||
localCache: initTypeMapping(), typeMap: typeMap,
|
||||
info: info, c: p, owner: owner)
|
||||
|
||||
proc replaceTypesInBody*(p: PContext, pt: TIdTable, n: PNode;
|
||||
proc replaceTypesInBody*(p: PContext, pt: TypeMapping, n: PNode;
|
||||
owner: PSym, allowMetaTypes = false,
|
||||
fromStaticExpr = false, expectedType: PType = nil): PNode =
|
||||
var typeMap = initLayeredTypeMap(pt)
|
||||
@@ -731,7 +733,7 @@ proc recomputeFieldPositions*(t: PType; obj: PNode; currPosition: var int) =
|
||||
inc currPosition
|
||||
else: discard "cannot happen"
|
||||
|
||||
proc generateTypeInstance*(p: PContext, pt: TIdTable, info: TLineInfo,
|
||||
proc generateTypeInstance*(p: PContext, pt: TypeMapping, info: TLineInfo,
|
||||
t: PType): PType =
|
||||
# Given `t` like Foo[T]
|
||||
# pt: Table with type mappings: T -> int
|
||||
@@ -747,7 +749,7 @@ proc generateTypeInstance*(p: PContext, pt: TIdTable, info: TLineInfo,
|
||||
var position = 0
|
||||
recomputeFieldPositions(objType, objType.n, position)
|
||||
|
||||
proc prepareMetatypeForSigmatch*(p: PContext, pt: TIdTable, info: TLineInfo,
|
||||
proc prepareMetatypeForSigmatch*(p: PContext, pt: TypeMapping, info: TLineInfo,
|
||||
t: PType): PType =
|
||||
var typeMap = initLayeredTypeMap(pt)
|
||||
var cl = initTypeVars(p, typeMap, info, nil)
|
||||
@@ -756,6 +758,6 @@ proc prepareMetatypeForSigmatch*(p: PContext, pt: TIdTable, info: TLineInfo,
|
||||
result = replaceTypeVarsT(cl, t)
|
||||
popInfoContext(p.config)
|
||||
|
||||
template generateTypeInstance*(p: PContext, pt: TIdTable, arg: PNode,
|
||||
template generateTypeInstance*(p: PContext, pt: TypeMapping, arg: PNode,
|
||||
t: PType): untyped =
|
||||
generateTypeInstance(p, pt, arg.info, t)
|
||||
|
||||
@@ -15,7 +15,7 @@ import
|
||||
magicsys, idents, lexer, options, parampatterns, trees,
|
||||
linter, lineinfos, lowerings, modulegraphs, concepts
|
||||
|
||||
import std/[intsets, strutils]
|
||||
import std/[intsets, strutils, tables]
|
||||
|
||||
when defined(nimPreviewSlimSystem):
|
||||
import std/assertions
|
||||
@@ -55,7 +55,7 @@ type
|
||||
calleeScope*: int # scope depth:
|
||||
# is this a top-level symbol or a nested proc?
|
||||
call*: PNode # modified call
|
||||
bindings*: TIdTable # maps types to types
|
||||
bindings*: TypeMapping # maps types to types
|
||||
magic*: TMagic # magic of operation
|
||||
baseTypeMatch: bool # needed for conversions from T to openarray[T]
|
||||
# for example
|
||||
@@ -113,14 +113,14 @@ proc initCandidateAux(ctx: PContext,
|
||||
proc initCandidate*(ctx: PContext, callee: PType): TCandidate =
|
||||
result = initCandidateAux(ctx, callee)
|
||||
result.calleeSym = nil
|
||||
result.bindings = initIdTable()
|
||||
result.bindings = initTypeMapping()
|
||||
|
||||
proc put(c: var TCandidate, key, val: PType) {.inline.} =
|
||||
## Given: proc foo[T](x: T); foo(4)
|
||||
## key: 'T'
|
||||
## val: 'int' (typeof(4))
|
||||
when false:
|
||||
let old = PType(idTableGet(c.bindings, key))
|
||||
let old = idTableGet(c.bindings, key)
|
||||
if old != nil:
|
||||
echo "Putting ", typeToString(key), " ", typeToString(val), " and old is ", typeToString(old)
|
||||
if typeToString(old) == "float32":
|
||||
@@ -141,7 +141,7 @@ proc initCandidate*(ctx: PContext, callee: PSym,
|
||||
result.diagnostics = @[] # if diagnosticsEnabled: @[] else: nil
|
||||
result.diagnosticsEnabled = diagnosticsEnabled
|
||||
result.magic = result.calleeSym.magic
|
||||
result.bindings = initIdTable()
|
||||
result.bindings = initTypeMapping()
|
||||
if binding != nil and callee.kind in routineKinds:
|
||||
var typeParams = callee.ast[genericParamsPos]
|
||||
for i in 1..min(typeParams.len, binding.len-1):
|
||||
@@ -174,7 +174,7 @@ proc copyCandidate(dest: var TCandidate, src: TCandidate) =
|
||||
dest.calleeSym = src.calleeSym
|
||||
dest.call = copyTree(src.call)
|
||||
dest.baseTypeMatch = src.baseTypeMatch
|
||||
copyIdTable(dest.bindings, src.bindings)
|
||||
dest.bindings = src.bindings
|
||||
|
||||
proc typeRel*(c: var TCandidate, f, aOrig: PType,
|
||||
flags: TTypeRelFlags = {}): TTypeRelation
|
||||
@@ -362,7 +362,7 @@ proc concreteType(c: TCandidate, t: PType; f: PType = nil): PType =
|
||||
of tyGenericParam, tyAnything, tyConcept:
|
||||
result = t
|
||||
while true:
|
||||
result = PType(idTableGet(c.bindings, t))
|
||||
result = idTableGet(c.bindings, t)
|
||||
if result == nil:
|
||||
break # it's ok, no match
|
||||
# example code that triggers it:
|
||||
@@ -500,7 +500,7 @@ proc genericParamPut(c: var TCandidate; last, fGenericOrigin: PType) =
|
||||
if fGenericOrigin != nil and last.kind == tyGenericInst and
|
||||
last.kidsLen-1 == fGenericOrigin.kidsLen:
|
||||
for i in FirstGenericParamAt..<fGenericOrigin.kidsLen:
|
||||
let x = PType(idTableGet(c.bindings, fGenericOrigin[i]))
|
||||
let x = idTableGet(c.bindings, fGenericOrigin[i])
|
||||
if x == nil:
|
||||
put(c, fGenericOrigin[i], last[i])
|
||||
|
||||
@@ -639,7 +639,7 @@ proc procParamTypeRel(c: var TCandidate; f, a: PType): TTypeRelation =
|
||||
a = a
|
||||
|
||||
if a.isMetaType:
|
||||
let aResolved = PType(idTableGet(c.bindings, a))
|
||||
let aResolved = idTableGet(c.bindings, a)
|
||||
if aResolved != nil:
|
||||
a = aResolved
|
||||
if a.isMetaType:
|
||||
@@ -763,7 +763,7 @@ proc matchUserTypeClass*(m: var TCandidate; ff, a: PType): PType =
|
||||
typeParamName = ff.base[i-1].sym.name
|
||||
typ = ff[i]
|
||||
param: PSym = nil
|
||||
alreadyBound = PType(idTableGet(m.bindings, typ))
|
||||
alreadyBound = idTableGet(m.bindings, typ)
|
||||
|
||||
if alreadyBound != nil: typ = alreadyBound
|
||||
|
||||
@@ -1090,7 +1090,7 @@ proc typeRel(c: var TCandidate, f, aOrig: PType,
|
||||
|
||||
case f.kind
|
||||
of tyGenericParam:
|
||||
var prev = PType(idTableGet(c.bindings, f))
|
||||
var prev = idTableGet(c.bindings, f)
|
||||
if prev != nil: candidate = prev
|
||||
of tyFromExpr:
|
||||
let computedType = tryResolvingStaticExpr(c, f.n).typ
|
||||
@@ -1140,7 +1140,7 @@ proc typeRel(c: var TCandidate, f, aOrig: PType,
|
||||
return res
|
||||
|
||||
template considerPreviousT(body: untyped) =
|
||||
var prev = PType(idTableGet(c.bindings, f))
|
||||
var prev = idTableGet(c.bindings, f)
|
||||
if prev == nil: body
|
||||
else: return typeRel(c, prev, a, flags)
|
||||
|
||||
@@ -1265,7 +1265,7 @@ proc typeRel(c: var TCandidate, f, aOrig: PType,
|
||||
var fRange = f.indexType
|
||||
var aRange = a.indexType
|
||||
if fRange.kind in {tyGenericParam, tyAnything}:
|
||||
var prev = PType(idTableGet(c.bindings, fRange))
|
||||
var prev = idTableGet(c.bindings, fRange)
|
||||
if prev == nil:
|
||||
put(c, fRange, a.indexType)
|
||||
fRange = a
|
||||
@@ -1502,7 +1502,7 @@ proc typeRel(c: var TCandidate, f, aOrig: PType,
|
||||
else:
|
||||
result = isNone
|
||||
of tyGenericInst:
|
||||
var prev = PType(idTableGet(c.bindings, f))
|
||||
var prev = idTableGet(c.bindings, f)
|
||||
let origF = f
|
||||
var f = if prev == nil: f else: prev
|
||||
|
||||
@@ -1634,14 +1634,14 @@ proc typeRel(c: var TCandidate, f, aOrig: PType,
|
||||
#
|
||||
# we steal the generic parameters from the tyGenericBody:
|
||||
for i in 1..<f.len:
|
||||
let x = PType(idTableGet(c.bindings, genericBody[i-1]))
|
||||
let x = idTableGet(c.bindings, genericBody[i-1])
|
||||
if x == nil:
|
||||
discard "maybe fine (for e.g. a==tyNil)"
|
||||
elif x.kind in {tyGenericInvocation, tyGenericParam}:
|
||||
internalError(c.c.graph.config, "wrong instantiated type!")
|
||||
else:
|
||||
let key = f[i]
|
||||
let old = PType(idTableGet(c.bindings, key))
|
||||
let old = idTableGet(c.bindings, key)
|
||||
if old == nil:
|
||||
put(c, key, x)
|
||||
elif typeRel(c, old, x, flags + {trDontBind}) == isNone:
|
||||
@@ -1764,7 +1764,7 @@ proc typeRel(c: var TCandidate, f, aOrig: PType,
|
||||
result = isGeneric
|
||||
of tyGenericParam:
|
||||
let doBindGP = doBind or trBindGenericParam in flags
|
||||
var x = PType(idTableGet(c.bindings, f))
|
||||
var x = idTableGet(c.bindings, f)
|
||||
if x == nil:
|
||||
if c.callee.kind == tyGenericBody and not c.typedescMatched:
|
||||
# XXX: The fact that generic types currently use tyGenericParam for
|
||||
@@ -1828,7 +1828,7 @@ proc typeRel(c: var TCandidate, f, aOrig: PType,
|
||||
elif doBind:
|
||||
# careful: `trDontDont` (set by `checkGeneric`) is not always respected in this call graph.
|
||||
# typRel having two different modes (binding and non-binding) can make things harder to
|
||||
# reason about and maintain. Refactoring typeRel to not be responsible for setting, or
|
||||
# reason about and maintain. Refactoring typeRel to not be responsible for setting, or
|
||||
# at least validating, bindings can have multiple benefits. This is debatable. I'm not 100% sure.
|
||||
# A design that allows a proper complexity analysis of types like `tyOr` would be ideal.
|
||||
concrete = concreteType(c, a, f)
|
||||
@@ -1846,7 +1846,7 @@ proc typeRel(c: var TCandidate, f, aOrig: PType,
|
||||
result = typeRel(c, x, a, flags) # check if it fits
|
||||
if result > isGeneric: result = isGeneric
|
||||
of tyStatic:
|
||||
let prev = PType(idTableGet(c.bindings, f))
|
||||
let prev = idTableGet(c.bindings, f)
|
||||
if prev == nil:
|
||||
if aOrig.kind == tyStatic:
|
||||
if f.base.kind notin {tyNone, tyGenericParam}:
|
||||
@@ -1899,7 +1899,7 @@ proc typeRel(c: var TCandidate, f, aOrig: PType,
|
||||
c.inferredTypes.add f
|
||||
f.add a
|
||||
of tyTypeDesc:
|
||||
var prev = PType(idTableGet(c.bindings, f))
|
||||
var prev = idTableGet(c.bindings, f)
|
||||
if prev == nil:
|
||||
# proc foo(T: typedesc, x: T)
|
||||
# when `f` is an unresolved typedesc, `a` could be any
|
||||
@@ -1983,7 +1983,7 @@ proc cmpTypes*(c: PContext, f, a: PType): TTypeRelation =
|
||||
|
||||
proc getInstantiatedType(c: PContext, arg: PNode, m: TCandidate,
|
||||
f: PType): PType =
|
||||
result = PType(idTableGet(m.bindings, f))
|
||||
result = idTableGet(m.bindings, f)
|
||||
if result == nil:
|
||||
result = generateTypeInstance(c, m.bindings, arg, f)
|
||||
if result == nil:
|
||||
@@ -2200,9 +2200,9 @@ proc paramTypesMatchAux(m: var TCandidate, f, a: PType,
|
||||
var instantiationCounter = 0
|
||||
var lastBindingCount = -1
|
||||
while r in {isBothMetaConvertible, isInferred, isInferredConvertible} and
|
||||
lastBindingCount != m.bindings.counter and
|
||||
lastBindingCount != m.bindings.len and
|
||||
instantiationCounter < 100:
|
||||
lastBindingCount = m.bindings.counter
|
||||
lastBindingCount = m.bindings.len
|
||||
inc(instantiationCounter)
|
||||
if arg.kind in {nkProcDef, nkFuncDef, nkIteratorDef} + nkLambdaKinds:
|
||||
result = c.semInferredLambda(c, m.bindings, arg)
|
||||
@@ -2359,10 +2359,10 @@ proc paramTypesMatch*(m: var TCandidate, f, a: PType,
|
||||
else:
|
||||
# symbol kinds that don't participate in symchoice type disambiguation:
|
||||
let matchSet = {low(TSymKind)..high(TSymKind)} - {skModule, skPackage, skType}
|
||||
|
||||
|
||||
var best = -1
|
||||
result = arg
|
||||
|
||||
|
||||
var actingF = f
|
||||
if f.kind == tyVarargs:
|
||||
if m.calleeSym.kind in {skTemplate, skMacro}:
|
||||
@@ -2398,7 +2398,7 @@ proc paramTypesMatch*(m: var TCandidate, f, a: PType,
|
||||
x.calleeSym = m.calleeSym
|
||||
y.calleeSym = m.calleeSym
|
||||
z.calleeSym = m.calleeSym
|
||||
|
||||
|
||||
for i in 0..<arg.len:
|
||||
if arg[i].sym.kind in matchSet:
|
||||
copyCandidate(z, m)
|
||||
@@ -2783,7 +2783,7 @@ proc matches*(c: PContext, n, nOrig: PNode, m: var TCandidate) =
|
||||
# proc foo(x: T = 0.0)
|
||||
# foo()
|
||||
if {tfImplicitTypeParam, tfGenericTypeParam} * formal.typ.flags != {}:
|
||||
let existing = PType(idTableGet(m.bindings, formal.typ))
|
||||
let existing = idTableGet(m.bindings, formal.typ)
|
||||
if existing == nil or existing.kind == tyTypeDesc:
|
||||
# see bug #11600:
|
||||
put(m, formal.typ, defaultValue.typ)
|
||||
|
||||
@@ -38,7 +38,7 @@ from wordrecg import wDeprecated, wError, wAddr, wYield
|
||||
import std/[algorithm, sets, parseutils, tables]
|
||||
|
||||
when defined(nimsuggest):
|
||||
import std/tables, pathutils # importer
|
||||
import pathutils # importer
|
||||
|
||||
const
|
||||
sep = '\t'
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
# * performs lambda lifting for closure support
|
||||
# * transforms 'defer' into a 'try finally' statement
|
||||
|
||||
import std / tables
|
||||
|
||||
import
|
||||
options, ast, astalgo, trees, msgs,
|
||||
idents, renderer, types, semfold, magicsys, cgmeth,
|
||||
@@ -38,7 +40,7 @@ import closureiters, lambdalifting
|
||||
|
||||
type
|
||||
PTransCon = ref object # part of TContext; stackable
|
||||
mapping: TIdNodeTable # mapping from symbols to nodes
|
||||
mapping: Table[ItemId, PNode] # mapping from symbols to nodes
|
||||
owner: PSym # current owner
|
||||
forStmt: PNode # current for stmt
|
||||
forLoopBody: PNode # transformed for loop body
|
||||
@@ -76,7 +78,7 @@ proc newTransNode(kind: TNodeKind, n: PNode,
|
||||
|
||||
proc newTransCon(owner: PSym): PTransCon =
|
||||
assert owner != nil
|
||||
result = PTransCon(mapping: initIdNodeTable(), owner: owner)
|
||||
result = PTransCon(mapping: initTable[ItemId, PNode](), owner: owner)
|
||||
|
||||
proc pushTransCon(c: PTransf, t: PTransCon) =
|
||||
t.next = c.transCon
|
||||
@@ -159,7 +161,7 @@ proc transformSymAux(c: PTransf, n: PNode): PNode =
|
||||
else:
|
||||
b = n
|
||||
while tc != nil:
|
||||
result = idNodeTableGet(tc.mapping, b.sym)
|
||||
result = getOrDefault(tc.mapping, b.sym.itemId)
|
||||
if result != nil:
|
||||
# this slightly convoluted way ensures the line info stays correct:
|
||||
if result.kind == nkSym:
|
||||
@@ -194,7 +196,7 @@ proc transformVarSection(c: PTransf, v: PNode): PNode =
|
||||
if vn.kind == nkSym:
|
||||
internalAssert(c.graph.config, it.len == 3)
|
||||
let x = freshVar(c, vn.sym)
|
||||
idNodeTablePut(c.transCon.mapping, vn.sym, x)
|
||||
c.transCon.mapping[vn.sym.itemId] = x
|
||||
var defs = newTransNode(nkIdentDefs, it.info, 3)
|
||||
if importantComments(c.graph.config):
|
||||
# keep documentation information:
|
||||
@@ -215,7 +217,7 @@ proc transformVarSection(c: PTransf, v: PNode): PNode =
|
||||
for j in 0..<it.len-2:
|
||||
if it[j].kind == nkSym:
|
||||
let x = freshVar(c, it[j].sym)
|
||||
idNodeTablePut(c.transCon.mapping, it[j].sym, x)
|
||||
c.transCon.mapping[it[j].sym.itemId] = x
|
||||
defs[j] = x
|
||||
else:
|
||||
defs[j] = transform(c, it[j])
|
||||
@@ -256,7 +258,7 @@ proc transformBlock(c: PTransf, n: PNode): PNode =
|
||||
var labl: PSym
|
||||
if c.inlining > 0:
|
||||
labl = newLabel(c, n[0])
|
||||
idNodeTablePut(c.transCon.mapping, n[0].sym, newSymNode(labl))
|
||||
c.transCon.mapping[n[0].sym.itemId] = newSymNode(labl)
|
||||
else:
|
||||
labl =
|
||||
if n[0].kind != nkEmpty:
|
||||
@@ -328,7 +330,7 @@ proc introduceNewLocalVars(c: PTransf, n: PNode): PNode =
|
||||
of nkProcDef: # todo optimize nosideeffects?
|
||||
result = newTransNode(n)
|
||||
let x = newSymNode(copySym(n[namePos].sym, c.idgen))
|
||||
idNodeTablePut(c.transCon.mapping, n[namePos].sym, x)
|
||||
c.transCon.mapping[n[namePos].sym.itemId] = x
|
||||
result[namePos] = x # we have to copy proc definitions for iters
|
||||
for i in 1..<n.len:
|
||||
result[i] = introduceNewLocalVars(c, n[i])
|
||||
@@ -759,7 +761,7 @@ proc transformFor(c: PTransf, n: PNode): PNode =
|
||||
let pa = putArgInto(arg, formal.typ)
|
||||
case pa
|
||||
of paDirectMapping:
|
||||
idNodeTablePut(newC.mapping, formal, arg)
|
||||
newC.mapping[formal.itemId] = arg
|
||||
of paFastAsgn, paFastAsgnTakeTypeFromArg:
|
||||
var t = formal.typ
|
||||
if pa == paFastAsgnTakeTypeFromArg:
|
||||
@@ -773,10 +775,10 @@ proc transformFor(c: PTransf, n: PNode): PNode =
|
||||
#incl(temp.sym.flags, sfCursor)
|
||||
addVar(v, temp)
|
||||
stmtList.add(newAsgnStmt(c, nkFastAsgn, temp, arg, true))
|
||||
idNodeTablePut(newC.mapping, formal, temp)
|
||||
newC.mapping[formal.itemId] = temp
|
||||
of paVarAsgn:
|
||||
assert(skipTypes(formal.typ, abstractInst).kind in {tyVar, tyLent})
|
||||
idNodeTablePut(newC.mapping, formal, arg)
|
||||
newC.mapping[formal.itemId] = arg
|
||||
# XXX BUG still not correct if the arg has a side effect!
|
||||
of paViaIndirection:
|
||||
let t = formal.typ
|
||||
@@ -787,13 +789,13 @@ proc transformFor(c: PTransf, n: PNode): PNode =
|
||||
var addrExp = newNodeIT(nkHiddenAddr, formal.info, makeVarType(t.owner, t, c.idgen, tyPtr))
|
||||
addrExp.add(arg)
|
||||
stmtList.add(newAsgnStmt(c, nkFastAsgn, temp, addrExp, true))
|
||||
idNodeTablePut(newC.mapping, formal, newDeref(temp))
|
||||
newC.mapping[formal.itemId] = newDeref(temp)
|
||||
of paComplexOpenarray:
|
||||
# arrays will deep copy here (pretty bad).
|
||||
var temp = newTemp(c, arg.typ, formal.info)
|
||||
addVar(v, temp)
|
||||
stmtList.add(newAsgnStmt(c, nkFastAsgn, temp, arg, true))
|
||||
idNodeTablePut(newC.mapping, formal, temp)
|
||||
newC.mapping[formal.itemId] = temp
|
||||
|
||||
let body = transformBody(c.graph, c.idgen, iter, {useCache}+c.flags)
|
||||
pushInfoContext(c.graph.config, n.info)
|
||||
|
||||
Reference in New Issue
Block a user