big repo cleanup
This commit is contained in:
parent
46c41e4369
commit
cd292568d7
246 changed files with 28 additions and 74652 deletions
151
compiler/semtypinst.nim
Executable file
151
compiler/semtypinst.nim
Executable file
|
|
@ -0,0 +1,151 @@
|
|||
#
|
||||
#
|
||||
# The Nimrod Compiler
|
||||
# (c) Copyright 2011 Andreas Rumpf
|
||||
#
|
||||
# See the file "copying.txt", included in this
|
||||
# distribution, for details about the copyright.
|
||||
#
|
||||
|
||||
# This module does the instantiation of generic procs and types.
|
||||
|
||||
import ast, astalgo, msgs, types, semdata
|
||||
|
||||
proc checkConstructedType*(info: TLineInfo, t: PType) =
|
||||
if tfAcyclic in t.flags and skipTypes(t, abstractInst).kind != tyObject:
|
||||
LocalError(info, errInvalidPragmaX, "acyclic")
|
||||
elif computeSize(t) < 0:
|
||||
LocalError(info, errIllegalRecursionInTypeX, typeToString(t))
|
||||
elif t.kind == tyVar and t.sons[0].kind == tyVar:
|
||||
LocalError(info, errVarVarTypeNotAllowed)
|
||||
when false:
|
||||
if t.kind == tyObject and t.sons[0] != nil:
|
||||
if t.sons[0].kind != tyObject or tfFinal in t.sons[0].flags:
|
||||
localError(info, errInheritanceOnlyWithNonFinalObjects)
|
||||
|
||||
proc containsGenericTypeIter(t: PType, closure: PObject): bool =
|
||||
result = t.kind in GenericTypes
|
||||
|
||||
proc containsGenericType*(t: PType): bool =
|
||||
result = iterOverType(t, containsGenericTypeIter, nil)
|
||||
|
||||
proc searchInstTypes(tab: TIdTable, key: PType): PType =
|
||||
# returns nil if we need to declare this type
|
||||
result = PType(IdTableGet(tab, key))
|
||||
if (result == nil) and (tab.counter > 0):
|
||||
# we have to do a slow linear search because types may need
|
||||
# to be compared by their structure:
|
||||
for h in countup(0, high(tab.data)):
|
||||
var t = PType(tab.data[h].key)
|
||||
if t != nil:
|
||||
if key.containerId == t.containerID:
|
||||
var match = true
|
||||
for j in countup(0, sonsLen(t) - 1):
|
||||
# XXX sameType is not really correct for nested generics?
|
||||
if not sameType(t.sons[j], key.sons[j]):
|
||||
match = false
|
||||
break
|
||||
if match:
|
||||
return PType(tab.data[h].val)
|
||||
|
||||
type
|
||||
TReplTypeVars* {.final.} = object
|
||||
c*: PContext
|
||||
typeMap*: TIdTable # map PType to PType
|
||||
symMap*: TIdTable # map PSym to PSym
|
||||
info*: TLineInfo
|
||||
|
||||
proc ReplaceTypeVarsT*(cl: var TReplTypeVars, t: PType): PType
|
||||
proc ReplaceTypeVarsS(cl: var TReplTypeVars, s: PSym): PSym
|
||||
proc ReplaceTypeVarsN(cl: var TReplTypeVars, n: PNode): PNode =
|
||||
if n != nil:
|
||||
result = copyNode(n)
|
||||
result.typ = ReplaceTypeVarsT(cl, n.typ)
|
||||
case n.kind
|
||||
of nkNone..pred(nkSym), succ(nkSym)..nkNilLit:
|
||||
nil
|
||||
of nkSym:
|
||||
result.sym = ReplaceTypeVarsS(cl, n.sym)
|
||||
else:
|
||||
var length = sonsLen(n)
|
||||
if length > 0:
|
||||
newSons(result, length)
|
||||
for i in countup(0, length - 1):
|
||||
result.sons[i] = ReplaceTypeVarsN(cl, n.sons[i])
|
||||
|
||||
proc ReplaceTypeVarsS(cl: var TReplTypeVars, s: PSym): PSym =
|
||||
if s == nil: return nil
|
||||
result = PSym(idTableGet(cl.symMap, s))
|
||||
if result == nil:
|
||||
result = copySym(s, false)
|
||||
incl(result.flags, sfFromGeneric)
|
||||
idTablePut(cl.symMap, s, result)
|
||||
result.typ = ReplaceTypeVarsT(cl, s.typ)
|
||||
result.owner = s.owner
|
||||
result.ast = ReplaceTypeVarsN(cl, s.ast)
|
||||
|
||||
proc lookupTypeVar(cl: TReplTypeVars, t: PType): PType =
|
||||
result = PType(idTableGet(cl.typeMap, t))
|
||||
if result == nil:
|
||||
GlobalError(t.sym.info, errCannotInstantiateX, typeToString(t))
|
||||
elif result.kind == tyGenericParam:
|
||||
InternalError(cl.info, "substitution with generic parameter")
|
||||
|
||||
proc ReplaceTypeVarsT*(cl: var TReplTypeVars, t: PType): PType =
|
||||
var body, newbody, x, header: PType
|
||||
result = t
|
||||
if t == nil: return
|
||||
case t.kind
|
||||
of tyGenericParam:
|
||||
result = lookupTypeVar(cl, t)
|
||||
of tyGenericInvokation:
|
||||
body = t.sons[0]
|
||||
if body.kind != tyGenericBody: InternalError(cl.info, "no generic body")
|
||||
header = nil
|
||||
for i in countup(1, sonsLen(t) - 1):
|
||||
if t.sons[i].kind == tyGenericParam:
|
||||
x = lookupTypeVar(cl, t.sons[i])
|
||||
if header == nil: header = copyType(t, t.owner, false)
|
||||
header.sons[i] = x
|
||||
else:
|
||||
x = t.sons[i]
|
||||
idTablePut(cl.typeMap, body.sons[i - 1], x)
|
||||
if header == nil: header = t
|
||||
result = searchInstTypes(gInstTypes, header)
|
||||
if result != nil: return
|
||||
result = newType(tyGenericInst, t.sons[0].owner)
|
||||
for i in countup(0, sonsLen(t) - 1):
|
||||
# if one of the params is not concrete, we cannot do anything
|
||||
# but we already raised an error!
|
||||
addSon(result, header.sons[i])
|
||||
idTablePut(gInstTypes, header, result)
|
||||
newbody = ReplaceTypeVarsT(cl, lastSon(body))
|
||||
newbody.n = ReplaceTypeVarsN(cl, lastSon(body).n)
|
||||
addSon(result, newbody)
|
||||
#writeln(output, ropeToStr(Typetoyaml(newbody)));
|
||||
checkConstructedType(cl.info, newbody)
|
||||
of tyGenericBody:
|
||||
InternalError(cl.info, "ReplaceTypeVarsT: tyGenericBody")
|
||||
result = ReplaceTypeVarsT(cl, lastSon(t))
|
||||
else:
|
||||
if containsGenericType(t):
|
||||
result = copyType(t, t.owner, false)
|
||||
for i in countup(0, sonsLen(result) - 1):
|
||||
result.sons[i] = ReplaceTypeVarsT(cl, result.sons[i])
|
||||
result.n = ReplaceTypeVarsN(cl, result.n)
|
||||
if result.Kind in GenericTypes:
|
||||
LocalError(cl.info, errCannotInstantiateX, TypeToString(t, preferName))
|
||||
#writeln(output, ropeToStr(Typetoyaml(result)))
|
||||
#checkConstructedType(cl.info, result)
|
||||
|
||||
proc generateTypeInstance*(p: PContext, pt: TIdTable, arg: PNode,
|
||||
t: PType): PType =
|
||||
var cl: TReplTypeVars
|
||||
InitIdTable(cl.symMap)
|
||||
copyIdTable(cl.typeMap, pt)
|
||||
cl.info = arg.info
|
||||
cl.c = p
|
||||
pushInfoContext(arg.info)
|
||||
result = ReplaceTypeVarsT(cl, t)
|
||||
popInfoContext()
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue