support for multiple test variables and var qualifiers in user-defined type classes

This commit is contained in:
Zahary Karadjov
2013-11-13 02:24:08 +02:00
parent 9061b8961e
commit 31dd66acbf
6 changed files with 35 additions and 13 deletions

View File

@@ -712,7 +712,6 @@ type
# -1 means that the size is unkwown
align*: int # the type's alignment requirements
loc*: TLoc
testeeName*: PIdent # the test variable in user-defined type classes
TPair*{.final.} = object
key*, val*: PObject
@@ -1088,7 +1087,6 @@ proc assignType(dest, src: PType) =
dest.size = src.size
dest.align = src.align
dest.destructor = src.destructor
dest.testeeName = src.testeeName
# this fixes 'type TLock = TSysLock':
if src.sym != nil:
if dest.sym != nil:

View File

@@ -1624,10 +1624,23 @@ proc parseObject(p: var TParser): PNode =
return
addSon(result, parseObjectPart(p))
proc parseTypeClassParam(p: var TParser): PNode =
if p.tok.tokType == tkVar:
getTok(p)
result = newNode(nkVarTy)
result.addSon(p.parseSymbol)
else:
result = p.parseSymbol
proc parseTypeClass(p: var TParser): PNode =
result = newNodeP(nkTypeClassTy, p)
getTok(p)
addSon(result, p.parseSymbol)
var args = newNode(nkArgList)
addSon(result, args)
addSon(args, p.parseTypeClassParam)
while p.tok.TokType == tkComma:
getTok(p)
addSon(args, p.parseTypeClassParam)
if p.tok.tokType == tkCurlyDotLe and p.validInd:
addSon(result, parsePragma(p))
else:

View File

@@ -299,7 +299,7 @@ proc semOf(c: PContext, n: PNode): PNode =
n.typ = getSysType(tyBool)
result = n
proc IsOpImpl(c: PContext, n: PNode): PNode =
proc isOpImpl(c: PContext, n: PNode): PNode =
InternalAssert n.sonsLen == 3 and
n[1].kind == nkSym and n[1].sym.kind == skType and
n[2].kind in {nkStrLit..nkTripleStrLit, nkType}
@@ -353,7 +353,7 @@ proc semIs(c: PContext, n: PNode): PNode =
let t1 = n[1].typ.sons[0]
# BUGFIX: don't evaluate this too early: ``T is void``
if not containsGenericType(t1): result = IsOpImpl(c, n)
if not containsGenericType(t1): result = isOpImpl(c, n)
proc semOpAux(c: PContext, n: PNode) =
const flags = {efDetermineType}

View File

@@ -876,8 +876,7 @@ proc freshType(res, prev: PType): PType {.inline.} =
proc semTypeClass(c: PContext, n: PNode, prev: PType): PType =
# if n.sonsLen == 0: return newConstraint(c, tyTypeClass)
result = newOrPrevType(tyTypeClass, prev, c)
result.testeeName = considerAcc(n[0])
result.n = n[3]
result.n = n
let
pragmas = n[1]

View File

@@ -751,11 +751,24 @@ proc matchUserTypeClass*(c: PContext, m: var TCandidate,
# pushInfoContext(arg.info)
openScope(c)
var testee = newSym(skParam, f.testeeName, f.sym, f.sym.info)
testee.typ = a
addDecl(c, testee)
for param in f.n[0]:
var
dummyName: PNode
dummyType: PType
if param.kind == nkVarTy:
dummyName = param[0]
dummyType = makeVarType(c, a)
else:
dummyName = param
dummyType = a
for stmt in f.n:
InternalAssert dummyName.kind == nkIdent
var dummyParam = newSym(skParam, dummyName.ident, f.sym, f.sym.info)
dummyParam.typ = dummyType
addDecl(c, dummyParam)
for stmt in f.n[3]:
var e = c.semTryExpr(c, copyTree(stmt))
if e == nil:
let expStr = renderTree(stmt, {renderNoComments})

View File

@@ -387,8 +387,7 @@ template `--`(rc: TRefCount): expr =
rc <% rcIncrement
template `--` (rc: TRefCount, heapType: THeapType): expr =
(when heapType == SharedHeap: atomicDec(rc, rcIncrement) <% rcIncrement
else: --rc)
(when heapType == SharedHeap: atomicDec(rc, rcIncrement) <% rcIncrement else: --rc)
template doDecRef(cc: PCell,
heapType = LocalHeap,