big repo cleanup
This commit is contained in:
parent
46c41e4369
commit
cd292568d7
246 changed files with 28 additions and 74652 deletions
128
compiler/seminst.nim
Executable file
128
compiler/seminst.nim
Executable file
|
|
@ -0,0 +1,128 @@
|
|||
#
|
||||
#
|
||||
# The Nimrod Compiler
|
||||
# (c) Copyright 2011 Andreas Rumpf
|
||||
#
|
||||
# See the file "copying.txt", included in this
|
||||
# distribution, for details about the copyright.
|
||||
#
|
||||
|
||||
# This module implements the instantiation of generic procs.
|
||||
|
||||
proc instantiateGenericParamList(c: PContext, n: PNode, pt: TIdTable) =
|
||||
if (n.kind != nkGenericParams):
|
||||
InternalError(n.info, "instantiateGenericParamList; no generic params")
|
||||
for i in countup(0, sonsLen(n) - 1):
|
||||
var a = n.sons[i]
|
||||
if a.kind != nkSym:
|
||||
InternalError(a.info, "instantiateGenericParamList; no symbol")
|
||||
var q = a.sym
|
||||
if not (q.typ.kind in {tyTypeDesc, tyGenericParam}): continue
|
||||
var s = newSym(skType, q.name, getCurrOwner())
|
||||
var t = PType(IdTableGet(pt, q.typ))
|
||||
if t == nil:
|
||||
LocalError(a.info, errCannotInstantiateX, s.name.s)
|
||||
break
|
||||
if (t.kind == tyGenericParam):
|
||||
InternalError(a.info, "instantiateGenericParamList: " & q.name.s)
|
||||
s.typ = t
|
||||
addDecl(c, s)
|
||||
|
||||
proc GenericCacheGet(c: PContext, genericSym, instSym: PSym): PSym =
|
||||
result = nil
|
||||
for i in countup(0, sonsLen(c.generics) - 1):
|
||||
if c.generics.sons[i].kind != nkExprEqExpr:
|
||||
InternalError(genericSym.info, "GenericCacheGet")
|
||||
var a = c.generics.sons[i].sons[0].sym
|
||||
if genericSym.id == a.id:
|
||||
var b = c.generics.sons[i].sons[1].sym
|
||||
if equalParams(b.typ.n, instSym.typ.n) == paramsEqual:
|
||||
#if gVerbosity > 0 then
|
||||
# MessageOut('found in cache: ' + getProcHeader(instSym));
|
||||
return b
|
||||
|
||||
proc GenericCacheAdd(c: PContext, genericSym, instSym: PSym) =
|
||||
var n = newNode(nkExprEqExpr)
|
||||
addSon(n, newSymNode(genericSym))
|
||||
addSon(n, newSymNode(instSym))
|
||||
addSon(c.generics, n)
|
||||
|
||||
proc removeDefaultParamValues(n: PNode) =
|
||||
# we remove default params, because they cannot be instantiated properly
|
||||
# and they are not needed anyway for instantiation (each param is already
|
||||
# provided).
|
||||
when false:
|
||||
for i in countup(1, sonsLen(n)-1):
|
||||
var a = n.sons[i]
|
||||
if a.kind != nkIdentDefs: IllFormedAst(a)
|
||||
var L = a.len
|
||||
if a.sons[L-1].kind != nkEmpty and a.sons[L-2].kind != nkEmpty:
|
||||
# ``param: typ = defaultVal``.
|
||||
# We don't need defaultVal for semantic checking and it's wrong for
|
||||
# ``cmp: proc (a, b: T): int = cmp``. Hm, for ``cmp = cmp`` that is
|
||||
# not possible... XXX We don't solve this issue here.
|
||||
a.sons[L-1] = ast.emptyNode
|
||||
|
||||
proc generateInstance(c: PContext, fn: PSym, pt: TIdTable,
|
||||
info: TLineInfo): PSym =
|
||||
# generates an instantiated proc
|
||||
var
|
||||
oldPrc, oldMod: PSym
|
||||
n: PNode
|
||||
if c.InstCounter > 1000: InternalError(fn.ast.info, "nesting too deep")
|
||||
inc(c.InstCounter)
|
||||
# NOTE: for access of private fields within generics from a different module
|
||||
# and other identifiers we fake the current module temporarily!
|
||||
# XXX bad hack!
|
||||
oldMod = c.module
|
||||
c.module = getModule(fn)
|
||||
result = copySym(fn, false)
|
||||
incl(result.flags, sfFromGeneric)
|
||||
result.owner = getCurrOwner().owner
|
||||
n = copyTree(fn.ast)
|
||||
result.ast = n
|
||||
pushOwner(result)
|
||||
openScope(c.tab)
|
||||
if (n.sons[genericParamsPos].kind == nkEmpty):
|
||||
InternalError(n.info, "generateInstance")
|
||||
n.sons[namePos] = newSymNode(result)
|
||||
pushInfoContext(info)
|
||||
instantiateGenericParamList(c, n.sons[genericParamsPos], pt)
|
||||
n.sons[genericParamsPos] = ast.emptyNode
|
||||
# semantic checking for the parameters:
|
||||
if n.sons[paramsPos].kind != nkEmpty:
|
||||
removeDefaultParamValues(n.sons[ParamsPos])
|
||||
semParamList(c, n.sons[ParamsPos], nil, result)
|
||||
addParams(c, result.typ.n)
|
||||
else:
|
||||
result.typ = newTypeS(tyProc, c)
|
||||
addSon(result.typ, nil)
|
||||
result.typ.callConv = fn.typ.callConv
|
||||
oldPrc = GenericCacheGet(c, fn, result)
|
||||
if oldPrc == nil:
|
||||
# add it here, so that recursive generic procs are possible:
|
||||
GenericCacheAdd(c, fn, result)
|
||||
addDecl(c, result)
|
||||
if n.sons[codePos].kind != nkEmpty:
|
||||
pushProcCon(c, result)
|
||||
if result.kind in {skProc, skMethod, skConverter}:
|
||||
addResult(c, result.typ.sons[0], n.info)
|
||||
addResultNode(c, n)
|
||||
n.sons[codePos] = semStmtScope(c, n.sons[codePos])
|
||||
popProcCon(c)
|
||||
else:
|
||||
result = oldPrc
|
||||
popInfoContext()
|
||||
closeScope(c.tab) # close scope for parameters
|
||||
popOwner()
|
||||
c.module = oldMod
|
||||
dec(c.InstCounter)
|
||||
|
||||
proc instGenericContainer(c: PContext, n: PNode, header: PType): PType =
|
||||
var cl: TReplTypeVars
|
||||
InitIdTable(cl.symMap)
|
||||
InitIdTable(cl.typeMap)
|
||||
cl.info = n.info
|
||||
cl.c = c
|
||||
result = ReplaceTypeVarsT(cl, header)
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue