# # # The Nim Compiler # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. # # This module implements the instantiation of generic procs. # included from sem.nim proc addObjFieldsToLocalScope(c: PContext; n: PNode) = template rec(n) = addObjFieldsToLocalScope(c, n) case n.kind of nkRecList: for i in countup(0, len(n)-1): rec n[i] of nkRecCase: if n.len > 0: rec n.sons[0] for i in countup(1, len(n)-1): if n[i].kind in {nkOfBranch, nkElse}: rec lastSon(n[i]) of nkSym: let f = n.sym if f.kind == skField and fieldVisible(c, f): c.currentScope.symbols.strTableIncl(f, onConflictKeepOld=true) incl(f.flags, sfUsed) # it is not an error to shadow fields via parameters else: discard proc rawPushProcCon(c: PContext, owner: PSym) = var x: PProcCon new(x) x.owner = owner x.next = c.p c.p = x proc rawHandleSelf(c: PContext; owner: PSym) = const callableSymbols = {skProc, skFunc, skMethod, skConverter, skIterator, skMacro} if c.selfName != nil and owner.kind in callableSymbols and owner.typ != nil: let params = owner.typ.n if params.len > 1: let arg = params[1].sym if arg.name.id == c.selfName.id: c.p.selfSym = arg arg.flags.incl sfIsSelf var t = c.p.selfSym.typ.skipTypes(abstractPtrs) while t.kind == tyObject: addObjFieldsToLocalScope(c, t.n) if t.sons[0] == nil: break t = t.sons[0].skipTypes(skipPtrs) proc pushProcCon*(c: PContext; owner: PSym) = rawPushProcCon(c, owner) rawHandleSelf(c, owner) const errCannotInstantiateX = "cannot instantiate: '$1'" iterator instantiateGenericParamList(c: PContext, n: PNode, pt: TIdTable): PSym = internalAssert c.config, n.kind == nkGenericParams for i, a in n.pairs: internalAssert c.config, a.kind == nkSym var q = a.sym if q.typ.kind notin {tyTypeDesc, tyGenericParam, tyStatic}+tyTypeClasses: continue let symKind = if q.typ.kind == tyStatic: skConst else: skType var s = newSym(symKind, q.name, getCurrOwner(c), q.info) s.flags = s.flags + {sfUsed, sfFromGeneric} var t = PType(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 # later by semAsgn in return type inference scenario t = q.typ else: localError(c.config, a.info, errCannotInstantiateX % s.name.s) t = errorType(c) elif t.kind == tyGenericParam: localError(c.config, a.info, errCannotInstantiateX % q.name.s) t = errorType(c) elif t.kind == tyGenericInvocation: #t = instGenericContainer(c, a, t) t = generateTypeInstance(c, pt, a, t) #t = ReplaceTypeVarsT(cl, t) s.typ = t if t.kind == tyStatic: s.ast = t.n yield s proc sameInstantiation(a, b: TInstantiation): bool = if a.concreteTypes.len == b.concreteTypes.len: for i in 0..a.concreteTypes.high: if not compareTypes(a.concreteTypes[i], b.concreteTypes[i], flags = {ExactTypeDescValues, ExactGcSafety}): return result = true proc genericCacheGet(genericSym: PSym, entry: TInstantiation; id: CompilesId): PSym = for inst in genericSym.procInstCache: if inst.compilesId == id and sameInstantiation(entry, inst[]): return inst.sym when false: proc `$`(x: PSym): string = result = x.name.s & " " & " id " &
import strtabs
var tab = newStringTable({"key1": "val1", "key2": "val2"},
modeStyleInsensitive)
for i in 0..80:
tab["key_" & $i] = "value" & $i
for key, val in pairs(tab):
writeLine(stdout, key, ": ", val)
writeLine(stdout, "length of table ", $tab.len)
writeLine(stdout, `%`("$key1 = $key2; ${PATH}", tab, {useEnvironment}))