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

View file

@ -1624,10 +1624,23 @@ proc parseObject(p: var TParser): PNode =
return return
addSon(result, parseObjectPart(p)) 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 = proc parseTypeClass(p: var TParser): PNode =
result = newNodeP(nkTypeClassTy, p) result = newNodeP(nkTypeClassTy, p)
getTok(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: if p.tok.tokType == tkCurlyDotLe and p.validInd:
addSon(result, parsePragma(p)) addSon(result, parsePragma(p))
else: else:

View file

@ -299,7 +299,7 @@ proc semOf(c: PContext, n: PNode): PNode =
n.typ = getSysType(tyBool) n.typ = getSysType(tyBool)
result = n result = n
proc IsOpImpl(c: PContext, n: PNode): PNode = proc isOpImpl(c: PContext, n: PNode): PNode =
InternalAssert n.sonsLen == 3 and InternalAssert n.sonsLen == 3 and
n[1].kind == nkSym and n[1].sym.kind == skType and n[1].kind == nkSym and n[1].sym.kind == skType and
n[2].kind in {nkStrLit..nkTripleStrLit, nkType} 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] let t1 = n[1].typ.sons[0]
# BUGFIX: don't evaluate this too early: ``T is void`` # 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) = proc semOpAux(c: PContext, n: PNode) =
const flags = {efDetermineType} 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 = proc semTypeClass(c: PContext, n: PNode, prev: PType): PType =
# if n.sonsLen == 0: return newConstraint(c, tyTypeClass) # if n.sonsLen == 0: return newConstraint(c, tyTypeClass)
result = newOrPrevType(tyTypeClass, prev, c) result = newOrPrevType(tyTypeClass, prev, c)
result.testeeName = considerAcc(n[0]) result.n = n
result.n = n[3]
let let
pragmas = n[1] pragmas = n[1]

View file

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

View file

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