parent
3fa2e79814
commit
26eae7d00e
10 changed files with 317 additions and 67 deletions
|
|
@ -111,7 +111,7 @@ proc mapSetType(typ: PType): TCTypeKind =
|
|||
else: result = ctArray
|
||||
|
||||
proc mapType(typ: PType): TCTypeKind =
|
||||
## Maps a nimrod type to a C type
|
||||
## Maps a Nim type to a C type
|
||||
case typ.kind
|
||||
of tyNone, tyStmt: result = ctVoid
|
||||
of tyBool: result = ctBool
|
||||
|
|
|
|||
|
|
@ -89,6 +89,10 @@ proc fitNode(c: PContext, formal: PType, arg: PNode): PNode =
|
|||
let x = result.skipConv
|
||||
if x.kind == nkPar and formal.kind != tyExpr:
|
||||
changeType(x, formal, check=true)
|
||||
else:
|
||||
result = skipHiddenSubConv(result)
|
||||
#result.typ = takeType(formal, arg.typ)
|
||||
#echo arg.info, " picked ", result.typ.typeToString
|
||||
|
||||
proc inferWithMetatype(c: PContext, formal: PType,
|
||||
arg: PNode, coerceDistincts = false): PNode
|
||||
|
|
|
|||
|
|
@ -535,44 +535,45 @@ proc semArrayConstr(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
|||
result.sons[i] = fitNode(c, typ, result.sons[i])
|
||||
result.typ.sons[0] = makeRangeType(c, 0, sonsLen(result) - 1, n.info)
|
||||
|
||||
proc fixAbstractType(c: PContext, n: PNode) =
|
||||
# XXX finally rewrite that crap!
|
||||
for i in countup(1, sonsLen(n) - 1):
|
||||
var it = n.sons[i]
|
||||
case it.kind
|
||||
of nkHiddenStdConv, nkHiddenSubConv:
|
||||
if it.sons[1].kind == nkBracket:
|
||||
it.sons[1].typ = arrayConstrType(c, it.sons[1])
|
||||
#it.sons[1] = semArrayConstr(c, it.sons[1])
|
||||
if skipTypes(it.typ, abstractVar).kind in {tyOpenArray, tyVarargs}:
|
||||
#if n.sons[0].kind == nkSym and IdentEq(n.sons[0].sym.name, "[]="):
|
||||
# debug(n)
|
||||
template fixAbstractType(c: PContext, n: PNode) =
|
||||
when false:
|
||||
# XXX finally rewrite that crap!
|
||||
for i in countup(1, sonsLen(n) - 1):
|
||||
var it = n.sons[i]
|
||||
case it.kind
|
||||
of nkHiddenStdConv, nkHiddenSubConv:
|
||||
if it.sons[1].kind == nkBracket:
|
||||
it.sons[1].typ = arrayConstrType(c, it.sons[1])
|
||||
#it.sons[1] = semArrayConstr(c, it.sons[1])
|
||||
if skipTypes(it.typ, abstractVar).kind in {tyOpenArray, tyVarargs}:
|
||||
#if n.sons[0].kind == nkSym and IdentEq(n.sons[0].sym.name, "[]="):
|
||||
# debug(n)
|
||||
|
||||
var s = skipTypes(it.sons[1].typ, abstractVar)
|
||||
if s.kind == tyArrayConstr and s.sons[1].kind == tyEmpty:
|
||||
s = copyType(s, getCurrOwner(), false)
|
||||
skipTypes(s, abstractVar).sons[1] = elemType(
|
||||
skipTypes(it.typ, abstractVar))
|
||||
it.sons[1].typ = s
|
||||
elif s.kind == tySequence and s.sons[0].kind == tyEmpty:
|
||||
s = copyType(s, getCurrOwner(), false)
|
||||
skipTypes(s, abstractVar).sons[0] = elemType(
|
||||
skipTypes(it.typ, abstractVar))
|
||||
it.sons[1].typ = s
|
||||
var s = skipTypes(it.sons[1].typ, abstractVar)
|
||||
if s.kind == tyArrayConstr and s.sons[1].kind == tyEmpty:
|
||||
s = copyType(s, getCurrOwner(), false)
|
||||
skipTypes(s, abstractVar).sons[1] = elemType(
|
||||
skipTypes(it.typ, abstractVar))
|
||||
it.sons[1].typ = s
|
||||
elif s.kind == tySequence and s.sons[0].kind == tyEmpty:
|
||||
s = copyType(s, getCurrOwner(), false)
|
||||
skipTypes(s, abstractVar).sons[0] = elemType(
|
||||
skipTypes(it.typ, abstractVar))
|
||||
it.sons[1].typ = s
|
||||
|
||||
elif skipTypes(it.sons[1].typ, abstractVar).kind in
|
||||
{tyNil, tyArrayConstr, tyTuple, tySet}:
|
||||
var s = skipTypes(it.typ, abstractVar)
|
||||
if s.kind != tyExpr:
|
||||
changeType(it.sons[1], s, check=true)
|
||||
n.sons[i] = it.sons[1]
|
||||
of nkBracket:
|
||||
# an implicitly constructed array (passed to an open array):
|
||||
n.sons[i] = semArrayConstr(c, it, {})
|
||||
else:
|
||||
discard
|
||||
#if (it.typ == nil):
|
||||
# InternalError(it.info, "fixAbstractType: " & renderTree(it))
|
||||
elif skipTypes(it.sons[1].typ, abstractVar).kind in
|
||||
{tyNil, tyArrayConstr, tyTuple, tySet}:
|
||||
var s = skipTypes(it.typ, abstractVar)
|
||||
if s.kind != tyExpr:
|
||||
changeType(it.sons[1], s, check=true)
|
||||
n.sons[i] = it.sons[1]
|
||||
of nkBracket:
|
||||
# an implicitly constructed array (passed to an open array):
|
||||
n.sons[i] = semArrayConstr(c, it, {})
|
||||
else:
|
||||
discard
|
||||
#if (it.typ == nil):
|
||||
# InternalError(it.info, "fixAbstractType: " & renderTree(it))
|
||||
|
||||
proc skipObjConv(n: PNode): PNode =
|
||||
case n.kind
|
||||
|
|
|
|||
|
|
@ -431,7 +431,8 @@ proc evalOp(m: TMagic, n, a, b, c: PNode): PNode =
|
|||
mExit, mInc, ast.mDec, mEcho, mSwap, mAppendStrCh,
|
||||
mAppendStrStr, mAppendSeqElem, mSetLengthStr, mSetLengthSeq,
|
||||
mParseExprToAst, mParseStmtToAst, mExpandToAst, mTypeTrait, mDotDot,
|
||||
mNLen..mNError, mEqRef, mSlurp, mStaticExec, mNGenSym, mSpawn, mParallel:
|
||||
mNLen..mNError, mEqRef, mSlurp, mStaticExec, mNGenSym, mSpawn,
|
||||
mParallel, mPlugin:
|
||||
discard
|
||||
else: internalError(a.info, "evalOp(" & $m & ')')
|
||||
|
||||
|
|
@ -544,7 +545,7 @@ proc foldConv*(n, a: PNode; check = false): PNode =
|
|||
discard
|
||||
else:
|
||||
result = a
|
||||
result.typ = n.typ
|
||||
result.typ = takeType(n.typ, a.typ)
|
||||
|
||||
proc getArrayConstr(m: PSym, n: PNode): PNode =
|
||||
if n.kind == nkBracket:
|
||||
|
|
|
|||
|
|
@ -187,7 +187,9 @@ proc instantiateProcType(c: PContext, pt: TIdTable,
|
|||
let param = copySym(oldParam)
|
||||
param.owner = prc
|
||||
param.typ = result.sons[i]
|
||||
param.ast = oldParam.ast.copyTree
|
||||
if oldParam.ast != nil:
|
||||
param.ast = fitNode(c, param.typ, oldParam.ast)
|
||||
|
||||
# don't be lazy here and call replaceTypeVarsN(cl, originalParams[i])!
|
||||
result.n.sons[i] = newSymNode(param)
|
||||
addDecl(c, param)
|
||||
|
|
|
|||
|
|
@ -1200,15 +1200,6 @@ proc isInlineIterator*(t: PType): bool =
|
|||
result = t.kind == tyIter or
|
||||
(t.kind == tyBuiltInTypeClass and t.base.kind == tyIter)
|
||||
|
||||
proc isEmptyContainer*(t: PType): bool =
|
||||
case t.kind
|
||||
of tyExpr, tyNil: result = true
|
||||
of tyArray, tyArrayConstr: result = t.sons[1].kind == tyEmpty
|
||||
of tySet, tySequence, tyOpenArray, tyVarargs:
|
||||
result = t.sons[0].kind == tyEmpty
|
||||
of tyGenericInst: result = isEmptyContainer(t.lastSon)
|
||||
else: result = false
|
||||
|
||||
proc incMatches(m: var TCandidate; r: TTypeRelation; convMatch = 1) =
|
||||
case r
|
||||
of isConvertible, isIntConv: inc(m.convMatches, convMatch)
|
||||
|
|
@ -1313,7 +1304,7 @@ proc paramTypesMatchAux(m: var TCandidate, f, argType: PType,
|
|||
if arg.typ == nil:
|
||||
result = arg
|
||||
elif skipTypes(arg.typ, abstractVar-{tyTypeDesc}).kind == tyTuple:
|
||||
result = implicitConv(nkHiddenStdConv, f, copyTree(arg), m, c)
|
||||
result = implicitConv(nkHiddenSubConv, f, arg, m, c)
|
||||
elif arg.typ.isEmptyContainer:
|
||||
result = arg.copyTree
|
||||
result.typ = getInstantiatedType(c, arg, m, f)
|
||||
|
|
@ -1328,7 +1319,7 @@ proc paramTypesMatchAux(m: var TCandidate, f, argType: PType,
|
|||
inc(m.exactMatches)
|
||||
result = arg
|
||||
if skipTypes(f, abstractVar-{tyTypeDesc}).kind in {tyTuple}:
|
||||
result = implicitConv(nkHiddenStdConv, f, arg, m, c)
|
||||
result = implicitConv(nkHiddenSubConv, f, arg, m, c)
|
||||
of isNone:
|
||||
# do not do this in ``typeRel`` as it then can't infere T in ``ref T``:
|
||||
if a.kind in {tyProxy, tyUnknown}:
|
||||
|
|
@ -1580,6 +1571,8 @@ proc matchesAux(c: PContext, n, nOrig: PNode,
|
|||
#assert(container == nil)
|
||||
if container.isNil:
|
||||
container = newNodeIT(nkBracket, n.sons[a].info, arrayConstr(c, arg))
|
||||
else:
|
||||
incrIndexType(container.typ)
|
||||
addSon(container, arg)
|
||||
setSon(m.call, formal.position + 1,
|
||||
implicitConv(nkHiddenStdConv, formal.typ, container, m, c))
|
||||
|
|
|
|||
|
|
@ -379,6 +379,9 @@ proc transformConv(c: PTransf, n: PNode): PTransNode =
|
|||
result = transformSons(c, n)
|
||||
of tyOpenArray, tyVarargs:
|
||||
result = transform(c, n.sons[1])
|
||||
PNode(result).typ = takeType(n.typ, n.sons[1].typ)
|
||||
#echo n.info, " came here and produced ", typeToString(PNode(result).typ),
|
||||
# " from ", typeToString(n.typ), " and ", typeToString(n.sons[1].typ)
|
||||
of tyCString:
|
||||
if source.kind == tyString:
|
||||
result = newTransNode(nkStringToCString, n, 1)
|
||||
|
|
|
|||
|
|
@ -1439,3 +1439,45 @@ proc skipConv*(n: PNode): PNode =
|
|||
proc skipConvTakeType*(n: PNode): PNode =
|
||||
result = n.skipConv
|
||||
result.typ = n.typ
|
||||
|
||||
proc isEmptyContainer*(t: PType): bool =
|
||||
case t.kind
|
||||
of tyExpr, tyNil: result = true
|
||||
of tyArray, tyArrayConstr: result = t.sons[1].kind == tyEmpty
|
||||
of tySet, tySequence, tyOpenArray, tyVarargs:
|
||||
result = t.sons[0].kind == tyEmpty
|
||||
of tyGenericInst: result = isEmptyContainer(t.lastSon)
|
||||
else: result = false
|
||||
|
||||
proc takeType*(formal, arg: PType): PType =
|
||||
# param: openArray[string] = []
|
||||
# [] is an array constructor of length 0 of type string!
|
||||
if arg.kind == tyNil:
|
||||
# and not (formal.kind == tyProc and formal.callConv == ccClosure):
|
||||
result = formal
|
||||
elif formal.kind in {tyOpenArray, tyVarargs, tySequence} and
|
||||
arg.isEmptyContainer:
|
||||
let a = copyType(arg.skipTypes({tyGenericInst}), arg.owner, keepId=false)
|
||||
a.sons[ord(arg.kind in {tyArray, tyArrayConstr})] = formal.sons[0]
|
||||
result = a
|
||||
elif formal.kind == tySet and arg.kind == tySet:
|
||||
result = formal
|
||||
else:
|
||||
result = arg
|
||||
|
||||
proc skipHiddenSubConv*(n: PNode): PNode =
|
||||
if n.kind == nkHiddenSubConv:
|
||||
# param: openArray[string] = []
|
||||
# [] is an array constructor of length 0 of type string!
|
||||
let formal = n.typ
|
||||
result = n.sons[1]
|
||||
let arg = result.typ
|
||||
let dest = takeType(formal, arg)
|
||||
if dest == arg and formal.kind != tyExpr:
|
||||
#echo n.info, " came here for ", formal.typeToString
|
||||
result = n
|
||||
else:
|
||||
result = copyTree(result)
|
||||
result.typ = dest
|
||||
else:
|
||||
result = n
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue