support for multiple test variables and var qualifiers in user-defined type classes
This commit is contained in:
parent
9061b8961e
commit
31dd66acbf
6 changed files with 35 additions and 13 deletions
|
|
@ -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:
|
||||||
|
|
|
||||||
|
|
@ -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:
|
||||||
|
|
|
||||||
|
|
@ -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}
|
||||||
|
|
|
||||||
|
|
@ -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]
|
||||||
|
|
|
||||||
|
|
@ -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})
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue