expr params implemented for procs; paving the way for type classes

This commit is contained in:
Zahary Karadjov 2012-03-21 23:48:03 +02:00
commit 3a5cf3d63a
6 changed files with 88 additions and 29 deletions

View file

@ -8,6 +8,7 @@
#
# This module implements the instantiation of generic procs.
# included from sem.nim
proc instantiateGenericParamList(c: PContext, n: PNode, pt: TIdTable,
entry: var TInstantiatedSymbol) =
@ -106,6 +107,35 @@ proc sideEffectsCheck(c: PContext, s: PSym) =
s.ast.sons[genericParamsPos].kind == nkEmpty:
c.threadEntries.add(s)
template nimdbg: expr = c.filename.endsWith"nimdbg.nim"
proc applyConcreteTypesToSig(genericProc: PSym, concTypes: seq[PType]): PType =
# XXX: This is intended to replace the use of semParamList in generateInstance.
# The results of semParamList's analysis are already encoded in the original
# proc type and any concrete types may be aplied directly over it.
# Besides being more efficient, it will remove the awkward case of
# genericParams == nil in semParamList.
# Currenly, it fails in some cases such as:
# proc inc2*[T](x: var ordinal[T], y = 1) {.magic: "Inc", noSideEffect.}
let sig = genericProc.typ
result = copyType(sig, getCurrOwner(), false)
result.n = sig.n.shallowCopy
for i in countup(0, sig.len - 1):
let tOrig = sig.sons[i]
if tOrig == nil: continue
let oGenParams = genericProc.ast.sons[genericParamsPos]
if skipTypes(tOrig, skipPtrs).kind in {tyGenericParam}:
var tConcrete = concTypes[tOrig.sym.position]
if i > 0:
let param = sig.n.sons[i].sym.copySym
param.typ = tConcrete
result.n.sons[i] = newSymNode(param)
result.sons[i] = tConcrete
else:
result.sons[i] = tOrig
if i > 0: result.n.sons[i] = sig.n.sons[i]
proc generateInstance(c: PContext, fn: PSym, pt: TIdTable,
info: TLineInfo): PSym =
# generates an instantiated proc
@ -133,12 +163,14 @@ proc generateInstance(c: PContext, fn: PSym, pt: TIdTable,
instantiateGenericParamList(c, n.sons[genericParamsPos], pt, entry)
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)
# XXX: obsoleted - happens in semParamList #
# addParams(c, result.typ.n)
else:
if n.sons[paramsPos].kind != nkEmpty:
if false and nimdbg:
result.typ = applyConcreteTypesToSig(fn, entry.concreteTypes)
addParams(c, result.typ.n, fn.kind)
else:
removeDefaultParamValues(n.sons[ParamsPos])
semParamList(c, n.sons[ParamsPos], nil, result)
else:
result.typ = newTypeS(tyProc, c)
addSon(result.typ, nil)
result.typ.callConv = fn.typ.callConv