remove the old tester
This commit is contained in:
commit
efcbaa965e
21 changed files with 523 additions and 348 deletions
|
|
@ -336,26 +336,52 @@ type
|
|||
tyConst, tyMutable, tyVarargs,
|
||||
tyIter, # unused
|
||||
tyProxy # used as errornous type (for idetools)
|
||||
tyTypeClass
|
||||
tyParametricTypeClass # structured similarly to tyGenericInst
|
||||
# lastSon is the body of the type class
|
||||
|
||||
tyBuiltInTypeClass # Type such as the catch-all object, tuple, seq, etc
|
||||
tyBuiltInTypeClass #\
|
||||
# Type such as the catch-all object, tuple, seq, etc
|
||||
|
||||
tyCompositeTypeClass #
|
||||
tyUserTypeClass #\
|
||||
# the body of a user-defined type class
|
||||
|
||||
tyUserTypeClassInst #\
|
||||
# Instance of a parametric user-defined type class.
|
||||
# Structured similarly to tyGenericInst.
|
||||
# tyGenericInst represents concrete types, while
|
||||
# this is still a "generic param" that will bind types
|
||||
# and resolves them during sigmatch and instantiation.
|
||||
|
||||
tyAnd, tyOr, tyNot # boolean type classes such as `string|int`,`not seq`,
|
||||
# `Sortable and Enumable`, etc
|
||||
tyCompositeTypeClass #\
|
||||
# Type such as seq[Number]
|
||||
# The notes for tyUserTypeClassInst apply here as well
|
||||
# sons[0]: the original expression used by the user.
|
||||
# sons[1]: fully expanded and instantiated meta type
|
||||
# (potentially following aliases)
|
||||
|
||||
tyAnything # a type class matching any type
|
||||
tyAnd, tyOr, tyNot #\
|
||||
# boolean type classes such as `string|int`,`not seq`,
|
||||
# `Sortable and Enumable`, etc
|
||||
|
||||
tyStatic # a value known at compile type (the underlying type is .base)
|
||||
tyAnything #\
|
||||
# a type class matching any type
|
||||
|
||||
tyFromExpr # This is a type representing an expression that depends
|
||||
# on generic parameters (the exprsesion is stored in t.n)
|
||||
# It will be converted to a real type only during generic
|
||||
# instantiation and prior to this it has the potential to
|
||||
# be any type.
|
||||
tyStatic #\
|
||||
# a value known at compile type (the underlying type is .base)
|
||||
|
||||
tyFromExpr #\
|
||||
# This is a type representing an expression that depends
|
||||
# on generic parameters (the exprsesion is stored in t.n)
|
||||
# It will be converted to a real type only during generic
|
||||
# instantiation and prior to this it has the potential to
|
||||
# be any type.
|
||||
|
||||
tyFieldAccessor #\
|
||||
# Expressions such as Type.field (valid in contexts such
|
||||
# as the `is` operator and magics like `high` and `low`).
|
||||
# Could be lifted to a single argument proc returning the
|
||||
# field value.
|
||||
# sons[0]: type of containing object or tuple
|
||||
# sons[1]: field type
|
||||
# .n: nkDotExpr storing the field name
|
||||
|
||||
const
|
||||
tyPureObject* = tyTuple
|
||||
|
|
@ -364,8 +390,9 @@ const
|
|||
|
||||
tyUnknownTypes* = {tyError, tyFromExpr}
|
||||
|
||||
tyTypeClasses* = {tyTypeClass, tyBuiltInTypeClass, tyCompositeTypeClass,
|
||||
tyParametricTypeClass, tyAnd, tyOr, tyNot, tyAnything}
|
||||
tyTypeClasses* = {tyBuiltInTypeClass, tyCompositeTypeClass,
|
||||
tyUserTypeClass, tyUserTypeClassInst,
|
||||
tyAnd, tyOr, tyNot, tyAnything}
|
||||
|
||||
tyMetaTypes* = {tyGenericParam, tyTypeDesc, tyStatic, tyExpr} + tyTypeClasses
|
||||
|
||||
|
|
|
|||
|
|
@ -87,7 +87,7 @@ proc getUniqueType*(key: PType): PType =
|
|||
gCanonicalTypes[k] = key
|
||||
result = key
|
||||
of tyTypeDesc, tyTypeClasses, tyGenericParam,
|
||||
tyFromExpr, tyStatic:
|
||||
tyFromExpr, tyStatic, tyFieldAccessor:
|
||||
internalError("GetUniqueType")
|
||||
of tyGenericInst, tyDistinct, tyOrdinal, tyMutable, tyConst, tyIter:
|
||||
result = getUniqueType(lastSon(key))
|
||||
|
|
|
|||
|
|
@ -130,7 +130,7 @@ proc mapType(typ: PType): TJSTypeKind =
|
|||
result = etyObject
|
||||
of tyNil: result = etyNull
|
||||
of tyGenericInst, tyGenericParam, tyGenericBody, tyGenericInvokation,
|
||||
tyNone, tyFromExpr, tyForward, tyEmpty,
|
||||
tyNone, tyFromExpr, tyForward, tyEmpty, tyFieldAccessor,
|
||||
tyExpr, tyStmt, tyStatic, tyTypeDesc, tyTypeClasses:
|
||||
result = etyNone
|
||||
of tyProc: result = etyProc
|
||||
|
|
|
|||
|
|
@ -239,7 +239,8 @@ proc semLowHigh(c: PContext, n: PNode, m: TMagic): PNode =
|
|||
localError(n.info, errXExpectsTypeOrValue, opToStr[m])
|
||||
else:
|
||||
n.sons[1] = semExprWithType(c, n.sons[1], {efDetermineType})
|
||||
var typ = skipTypes(n.sons[1].typ, abstractVarRange+{tyTypeDesc})
|
||||
var typ = skipTypes(n.sons[1].typ, abstractVarRange +
|
||||
{tyTypeDesc, tyFieldAccessor})
|
||||
case typ.kind
|
||||
of tySequence, tyString, tyOpenArray, tyVarargs:
|
||||
n.typ = getSysType(tyInt)
|
||||
|
|
@ -247,7 +248,7 @@ proc semLowHigh(c: PContext, n: PNode, m: TMagic): PNode =
|
|||
n.typ = typ.sons[0] # indextype
|
||||
of tyInt..tyInt64, tyChar, tyBool, tyEnum, tyUInt8, tyUInt16, tyUInt32:
|
||||
# do not skip the range!
|
||||
n.typ = n.sons[1].typ.skipTypes(abstractVar)
|
||||
n.typ = n.sons[1].typ.skipTypes(abstractVar + {tyFieldAccessor})
|
||||
of tyGenericParam:
|
||||
# prepare this for resolving in semtypinst:
|
||||
# we must use copyTree here in order to avoid creating a cycle
|
||||
|
|
@ -306,7 +307,7 @@ proc isOpImpl(c: PContext, n: PNode): PNode =
|
|||
n[1].typ != nil and n[1].typ.kind == tyTypeDesc and
|
||||
n[2].kind in {nkStrLit..nkTripleStrLit, nkType}
|
||||
|
||||
let t1 = n[1].typ.skipTypes({tyTypeDesc})
|
||||
let t1 = n[1].typ.skipTypes({tyTypeDesc, tyFieldAccessor})
|
||||
|
||||
if n[2].kind in {nkStrLit..nkTripleStrLit}:
|
||||
case n[2].strVal.normalize
|
||||
|
|
@ -321,24 +322,13 @@ proc isOpImpl(c: PContext, n: PNode): PNode =
|
|||
t.callConv == ccClosure and
|
||||
tfIterator in t.flags))
|
||||
else:
|
||||
var match: bool
|
||||
let t2 = n[2].typ
|
||||
case t2.kind
|
||||
of tyTypeClasses:
|
||||
var m: TCandidate
|
||||
initCandidate(c, m, t2)
|
||||
match = matchUserTypeClass(c, m, emptyNode, t2, t1) != nil
|
||||
of tyOrdinal:
|
||||
var m: TCandidate
|
||||
initCandidate(c, m, t2)
|
||||
match = isOrdinalType(t1)
|
||||
of tySequence, tyArray, tySet:
|
||||
var m: TCandidate
|
||||
initCandidate(c, m, t2)
|
||||
match = typeRel(m, t2, t1) != isNone
|
||||
else:
|
||||
match = sameType(t1, t2)
|
||||
|
||||
var t2 = n[2].typ.skipTypes({tyTypeDesc})
|
||||
let lifted = liftParamType(c, skType, newNodeI(nkArgList, n.info),
|
||||
t2, ":anon", n.info)
|
||||
if lifted != nil: t2 = lifted
|
||||
var m: TCandidate
|
||||
initCandidate(c, m, t2)
|
||||
let match = typeRel(m, t2, t1) != isNone
|
||||
result = newIntNode(nkIntLit, ord(match))
|
||||
|
||||
result.typ = n.typ
|
||||
|
|
@ -948,6 +938,13 @@ proc builtinFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
|||
let foundTyp = makeTypeDesc(c, rawTyp)
|
||||
return newSymNode(copySym(tParam.sym).linkTo(foundTyp), n.info)
|
||||
return
|
||||
of tyObject, tyTuple:
|
||||
if ty.n.kind == nkRecList:
|
||||
for field in ty.n.sons:
|
||||
if field.sym.name == i:
|
||||
n.typ = newTypeWithSons(c, tyFieldAccessor, @[ty, field.sym.typ])
|
||||
n.typ.n = copyTree(n)
|
||||
return n
|
||||
else:
|
||||
# echo "TYPE FIELD ACCESS"
|
||||
# debug ty
|
||||
|
|
|
|||
|
|
@ -252,8 +252,7 @@ proc evalIs(n, a: PNode): PNode =
|
|||
else:
|
||||
# XXX semexprs.isOpImpl is slightly different and requires a context. yay.
|
||||
let t2 = n[2].typ
|
||||
var match = if t2.kind == tyTypeClass: true
|
||||
else: sameType(t1, t2)
|
||||
var match = sameType(t1, t2)
|
||||
result = newIntNode(nkIntLit, ord(match))
|
||||
result.typ = n.typ
|
||||
|
||||
|
|
|
|||
|
|
@ -1247,7 +1247,7 @@ proc semStmtList(c: PContext, n: PNode): PNode =
|
|||
if n.sons[i].typ == enforceVoidContext or usesResult(n.sons[i]):
|
||||
voidContext = true
|
||||
n.typ = enforceVoidContext
|
||||
if i != last or voidContext:
|
||||
if i != last or voidContext or c.inTypeClass > 0:
|
||||
discardCheck(c, n.sons[i])
|
||||
else:
|
||||
n.typ = n.sons[i].typ
|
||||
|
|
|
|||
|
|
@ -710,6 +710,11 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode,
|
|||
result = addImplicitGeneric(result)
|
||||
|
||||
of tyGenericInst:
|
||||
if paramType.lastSon.kind == tyUserTypeClass:
|
||||
var cp = copyType(paramType, getCurrOwner(), false)
|
||||
cp.kind = tyUserTypeClassInst
|
||||
return addImplicitGeneric(cp)
|
||||
|
||||
for i in 1 .. (paramType.sons.len - 2):
|
||||
var lifted = liftingWalk(paramType.sons[i])
|
||||
if lifted != nil:
|
||||
|
|
@ -731,7 +736,7 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode,
|
|||
allowMetaTypes = true)
|
||||
result = liftingWalk(expanded)
|
||||
|
||||
of tyTypeClass, tyBuiltInTypeClass, tyAnd, tyOr, tyNot:
|
||||
of tyUserTypeClass, tyBuiltInTypeClass, tyAnd, tyOr, tyNot:
|
||||
result = addImplicitGeneric(copyType(paramType, getCurrOwner(), true))
|
||||
|
||||
of tyExpr:
|
||||
|
|
@ -866,7 +871,7 @@ proc semGenericParamInInvokation(c: PContext, n: PNode): PType =
|
|||
proc semGeneric(c: PContext, n: PNode, s: PSym, prev: PType): PType =
|
||||
result = newOrPrevType(tyGenericInvokation, prev, c)
|
||||
addSonSkipIntLit(result, s.typ)
|
||||
|
||||
|
||||
template addToResult(typ) =
|
||||
if typ.isNil:
|
||||
internalAssert false
|
||||
|
|
@ -923,7 +928,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 = newOrPrevType(tyUserTypeClass, prev, c)
|
||||
result.n = n
|
||||
|
||||
let
|
||||
|
|
|
|||
|
|
@ -360,7 +360,10 @@ proc replaceTypeVarsTAux(cl: var TReplTypeVars, t: PType): PType =
|
|||
if tfUnresolved in t.flags: result = result.base
|
||||
elif t.sonsLen > 0:
|
||||
result = makeTypeDesc(cl.c, replaceTypeVarsT(cl, t.sons[0]))
|
||||
|
||||
|
||||
of tyUserTypeClass:
|
||||
result = t
|
||||
|
||||
of tyGenericInst:
|
||||
result = instCopyType(cl, t)
|
||||
for i in 1 .. <result.sonsLen:
|
||||
|
|
|
|||
|
|
@ -140,7 +140,7 @@ proc sumGeneric(t: PType): int =
|
|||
result = ord(t.kind == tyGenericInvokation)
|
||||
for i in 0 .. <t.len: result += t.sons[i].sumGeneric
|
||||
break
|
||||
of tyGenericParam, tyExpr, tyStatic, tyStmt, tyTypeDesc, tyTypeClass: break
|
||||
of tyGenericParam, tyExpr, tyStatic, tyStmt, tyTypeDesc: break
|
||||
else: return 0
|
||||
|
||||
proc complexDisambiguation(a, b: PType): int =
|
||||
|
|
@ -399,6 +399,70 @@ proc typeRangeRel(f, a: PType): TTypeRelation {.noinline.} =
|
|||
else:
|
||||
result = isNone
|
||||
|
||||
proc matchUserTypeClass*(c: PContext, m: var TCandidate,
|
||||
ff, a: PType): TTypeRelation =
|
||||
#if f.n == nil:
|
||||
# let r = typeRel(m, f, a)
|
||||
# return if r == isGeneric: arg else: nil
|
||||
|
||||
var body = ff.skipTypes({tyUserTypeClassInst})
|
||||
|
||||
# var prev = PType(idTableGet(m.bindings, f))
|
||||
# if prev != nil:
|
||||
# if sameType(prev, a): return arg
|
||||
# else: return nil
|
||||
|
||||
# pushInfoContext(arg.info)
|
||||
openScope(c)
|
||||
inc c.inTypeClass
|
||||
|
||||
finally:
|
||||
dec c.inTypeClass
|
||||
closeScope(c)
|
||||
|
||||
if ff.kind == tyUserTypeClassInst:
|
||||
for i in 1 .. <(ff.len - 1):
|
||||
var
|
||||
typeParamName = ff.base.sons[i-1].sym.name
|
||||
typ = ff.sons[i]
|
||||
param = newSym(skType, typeParamName, body.sym, body.sym.info)
|
||||
|
||||
param.typ = makeTypeDesc(c, typ)
|
||||
addDecl(c, param)
|
||||
|
||||
for param in body.n[0]:
|
||||
var
|
||||
dummyName: PNode
|
||||
dummyType: PType
|
||||
|
||||
if param.kind == nkVarTy:
|
||||
dummyName = param[0]
|
||||
dummyType = makeVarType(c, a)
|
||||
else:
|
||||
dummyName = param
|
||||
dummyType = a
|
||||
|
||||
internalAssert dummyName.kind == nkIdent
|
||||
var dummyParam = newSym(skType, dummyName.ident, body.sym, body.sym.info)
|
||||
dummyParam.typ = dummyType
|
||||
addDecl(c, dummyParam)
|
||||
|
||||
var checkedBody = c.semTryExpr(c, copyTree(body.n[3]), bufferErrors = false)
|
||||
m.errors = bufferedMsgs
|
||||
clearBufferedMsgs()
|
||||
if checkedBody == nil: return isNone
|
||||
|
||||
if checkedBody.kind == nkStmtList:
|
||||
for stmt in checkedBody:
|
||||
case stmt.kind
|
||||
of nkReturnStmt: discard
|
||||
of nkTypeSection: discard
|
||||
of nkConstDef: discard
|
||||
else: discard
|
||||
|
||||
return isGeneric
|
||||
# put(m.bindings, f, a)
|
||||
|
||||
proc typeRel(c: var TCandidate, f, aOrig: PType, doBind = true): TTypeRelation =
|
||||
# typeRel can be used to establish various relationships between types:
|
||||
#
|
||||
|
|
@ -418,6 +482,11 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, doBind = true): TTypeRelation =
|
|||
|
||||
result = isNone
|
||||
assert(f != nil)
|
||||
|
||||
if f.kind == tyExpr:
|
||||
put(c.bindings, f, aOrig)
|
||||
return isGeneric
|
||||
|
||||
assert(aOrig != nil)
|
||||
|
||||
# var and static arguments match regular modifier-free types
|
||||
|
|
@ -751,6 +820,12 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, doBind = true): TTypeRelation =
|
|||
else:
|
||||
return isNone
|
||||
|
||||
of tyUserTypeClass, tyUserTypeClassInst:
|
||||
considerPreviousT:
|
||||
result = matchUserTypeClass(c.c, c, f, a)
|
||||
if result == isGeneric:
|
||||
put(c.bindings, f, a)
|
||||
|
||||
of tyCompositeTypeClass:
|
||||
considerPreviousT:
|
||||
if typeRel(c, f.sons[1], a) != isNone:
|
||||
|
|
@ -759,7 +834,7 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, doBind = true): TTypeRelation =
|
|||
else:
|
||||
return isNone
|
||||
|
||||
of tyGenericParam, tyTypeClass:
|
||||
of tyGenericParam:
|
||||
var x = PType(idTableGet(c.bindings, f))
|
||||
if x == nil:
|
||||
if c.calleeSym != nil and c.calleeSym.kind == skType and
|
||||
|
|
@ -822,7 +897,7 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, doBind = true): TTypeRelation =
|
|||
else: a.sons[0]
|
||||
result = typeRel(c, prev.sons[0], toMatch)
|
||||
|
||||
of tyExpr, tyStmt:
|
||||
of tyStmt:
|
||||
result = isGeneric
|
||||
|
||||
of tyProxy:
|
||||
|
|
@ -904,57 +979,6 @@ proc localConvMatch(c: PContext, m: var TCandidate, f, a: PType,
|
|||
result.typ = getInstantiatedType(c, arg, m, base(f))
|
||||
m.baseTypeMatch = true
|
||||
|
||||
proc matchUserTypeClass*(c: PContext, m: var TCandidate,
|
||||
arg: PNode, f, a: PType): PNode =
|
||||
if f.n == nil:
|
||||
let r = typeRel(m, f, a)
|
||||
return if r == isGeneric: arg else: nil
|
||||
|
||||
var prev = PType(idTableGet(m.bindings, f))
|
||||
if prev != nil:
|
||||
if sameType(prev, a): return arg
|
||||
else: return nil
|
||||
|
||||
# pushInfoContext(arg.info)
|
||||
openScope(c)
|
||||
inc c.inTypeClass
|
||||
|
||||
finally:
|
||||
dec c.inTypeClass
|
||||
closeScope(c)
|
||||
|
||||
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
|
||||
|
||||
internalAssert dummyName.kind == nkIdent
|
||||
var dummyParam = newSym(skType, 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), bufferErrors = false)
|
||||
m.errors = bufferedMsgs
|
||||
clearBufferedMsgs()
|
||||
if e == nil: return nil
|
||||
|
||||
case e.kind
|
||||
of nkReturnStmt: discard
|
||||
of nkTypeSection: discard
|
||||
of nkConstDef: discard
|
||||
else: discard
|
||||
|
||||
result = arg
|
||||
put(m.bindings, f, a)
|
||||
|
||||
proc paramTypesMatchAux(m: var TCandidate, f, argType: PType,
|
||||
argSemantized, argOrig: PNode): PNode =
|
||||
var
|
||||
|
|
@ -975,25 +999,9 @@ proc paramTypesMatchAux(m: var TCandidate, f, argType: PType,
|
|||
argType = arg.typ
|
||||
|
||||
var
|
||||
r: TTypeRelation
|
||||
a = if c.inTypeClass > 0: argType.skipTypes({tyTypeDesc})
|
||||
else: argType
|
||||
|
||||
case fMaybeStatic.kind
|
||||
of tyTypeClass, tyParametricTypeClass:
|
||||
if fMaybeStatic.n != nil:
|
||||
let match = matchUserTypeClass(c, m, arg, fMaybeStatic, a)
|
||||
if match != nil:
|
||||
r = isGeneric
|
||||
arg = match
|
||||
else:
|
||||
r = isNone
|
||||
else:
|
||||
r = typeRel(m, f, a)
|
||||
of tyExpr:
|
||||
r = isGeneric
|
||||
put(m.bindings, f, arg.typ)
|
||||
else:
|
||||
r = typeRel(m, f, a)
|
||||
|
||||
case r
|
||||
|
|
|
|||
|
|
@ -389,7 +389,7 @@ proc transformConv(c: PTransf, n: PNode): PTransNode =
|
|||
result[0] = transform(c, n.sons[1])
|
||||
else:
|
||||
result = transform(c, n.sons[1])
|
||||
of tyGenericParam, tyOrdinal, tyTypeClass:
|
||||
of tyGenericParam, tyOrdinal:
|
||||
result = transform(c, n.sons[1])
|
||||
# happens sometimes for generated assignments, etc.
|
||||
else:
|
||||
|
|
|
|||
|
|
@ -404,9 +404,10 @@ const
|
|||
"float", "float32", "float64", "float128",
|
||||
"uint", "uint8", "uint16", "uint32", "uint64",
|
||||
"bignum", "const ",
|
||||
"!", "varargs[$1]", "iter[$1]", "Error Type", "TypeClass",
|
||||
"ParametricTypeClass", "BuiltInTypeClass", "CompositeTypeClass",
|
||||
"and", "or", "not", "any", "static", "TypeFromExpr"]
|
||||
"!", "varargs[$1]", "iter[$1]", "Error Type",
|
||||
"BuiltInTypeClass", "UserTypeClass",
|
||||
"UserTypeClassInst", "CompositeTypeClass",
|
||||
"and", "or", "not", "any", "static", "TypeFromExpr", "FieldAccessor"]
|
||||
|
||||
proc typeToString(typ: PType, prefer: TPreferedDesc = preferName): string =
|
||||
var t = typ
|
||||
|
|
@ -434,11 +435,30 @@ proc typeToString(typ: PType, prefer: TPreferedDesc = preferName): string =
|
|||
of tyStatic:
|
||||
internalAssert t.len > 0
|
||||
result = "static[" & typeToString(t.sons[0]) & "]"
|
||||
of tyTypeClass:
|
||||
of tyUserTypeClass:
|
||||
internalAssert t.sym != nil and t.sym.owner != nil
|
||||
return t.sym.owner.name.s
|
||||
of tyBuiltInTypeClass:
|
||||
return "TypeClass"
|
||||
result = case t.base.kind:
|
||||
of tyVar: "var"
|
||||
of tyRef: "ref"
|
||||
of tyPtr: "ptr"
|
||||
of tySequence: "seq"
|
||||
of tyArray: "array"
|
||||
of tySet: "set"
|
||||
of tyRange: "range"
|
||||
of tyDistinct: "distinct"
|
||||
of tyProc: "proc"
|
||||
of tyObject: "object"
|
||||
of tyTuple: "tuple"
|
||||
else: (internalAssert(false); "")
|
||||
of tyUserTypeClassInst:
|
||||
let body = t.base
|
||||
result = body.sym.name.s & "["
|
||||
for i in countup(1, sonsLen(t) - 2):
|
||||
if i > 1: add(result, ", ")
|
||||
add(result, typeToString(t.sons[i]))
|
||||
result.add "]"
|
||||
of tyAnd:
|
||||
result = typeToString(t.sons[0]) & " and " & typeToString(t.sons[1])
|
||||
of tyOr:
|
||||
|
|
@ -448,7 +468,7 @@ proc typeToString(typ: PType, prefer: TPreferedDesc = preferName): string =
|
|||
of tyExpr:
|
||||
internalAssert t.len == 0
|
||||
result = "expr"
|
||||
of tyFromExpr:
|
||||
of tyFromExpr, tyFieldAccessor:
|
||||
result = renderTree(t.n)
|
||||
of tyArray:
|
||||
if t.sons[0].kind == tyRange:
|
||||
|
|
@ -546,7 +566,8 @@ proc firstOrd(t: PType): BiggestInt =
|
|||
else:
|
||||
assert(t.n.sons[0].kind == nkSym)
|
||||
result = t.n.sons[0].sym.position
|
||||
of tyGenericInst, tyDistinct, tyConst, tyMutable, tyTypeDesc:
|
||||
of tyGenericInst, tyDistinct, tyConst, tyMutable,
|
||||
tyTypeDesc, tyFieldAccessor:
|
||||
result = firstOrd(lastSon(t))
|
||||
else:
|
||||
internalError("invalid kind for first(" & $t.kind & ')')
|
||||
|
|
@ -579,7 +600,8 @@ proc lastOrd(t: PType): BiggestInt =
|
|||
of tyEnum:
|
||||
assert(t.n.sons[sonsLen(t.n) - 1].kind == nkSym)
|
||||
result = t.n.sons[sonsLen(t.n) - 1].sym.position
|
||||
of tyGenericInst, tyDistinct, tyConst, tyMutable, tyTypeDesc:
|
||||
of tyGenericInst, tyDistinct, tyConst, tyMutable,
|
||||
tyTypeDesc, tyFieldAccessor:
|
||||
result = lastOrd(lastSon(t))
|
||||
of tyProxy: result = 0
|
||||
else:
|
||||
|
|
@ -875,9 +897,9 @@ proc sameTypeAux(x, y: PType, c: var TSameTypeClosure): bool =
|
|||
of tyGenericInvokation, tyGenericBody, tySequence,
|
||||
tyOpenArray, tySet, tyRef, tyPtr, tyVar, tyArrayConstr,
|
||||
tyArray, tyProc, tyConst, tyMutable, tyVarargs, tyIter,
|
||||
tyOrdinal, tyTypeClasses:
|
||||
tyOrdinal, tyTypeClasses, tyFieldAccessor:
|
||||
cycleCheck()
|
||||
if a.kind == tyTypeClass and a.n != nil: return a.n == b.n
|
||||
if a.kind == tyUserTypeClass and a.n != nil: return a.n == b.n
|
||||
result = sameChildrenAux(a, b, c) and sameFlags(a, b)
|
||||
if result and a.kind == tyProc:
|
||||
result = ((IgnoreCC in c.flags) or a.callConv == b.callConv) and
|
||||
|
|
@ -1021,7 +1043,7 @@ proc typeAllowedAux(marker: var TIntSet, typ: PType, kind: TSymKind,
|
|||
of tyTypeClasses:
|
||||
result = true
|
||||
of tyGenericBody, tyGenericParam, tyGenericInvokation,
|
||||
tyNone, tyForward, tyFromExpr:
|
||||
tyNone, tyForward, tyFromExpr, tyFieldAccessor:
|
||||
result = false
|
||||
of tyNil:
|
||||
result = kind == skConst
|
||||
|
|
@ -1231,8 +1253,15 @@ proc getSize(typ: PType): BiggestInt =
|
|||
if result < 0: internalError("getSize: " & $typ.kind)
|
||||
|
||||
proc containsGenericTypeIter(t: PType, closure: PObject): bool =
|
||||
result = t.kind in GenericTypes + tyTypeClasses + {tyTypeDesc,tyFromExpr} or
|
||||
t.kind == tyStatic and t.n == nil
|
||||
if t.kind in GenericTypes + tyTypeClasses + {tyFromExpr}:
|
||||
return true
|
||||
|
||||
if t.kind == tyTypeDesc:
|
||||
if t.sonsLen == 0: return true
|
||||
if containsGenericTypeIter(t.base, closure): return true
|
||||
return false
|
||||
|
||||
return t.kind == tyStatic and t.n == nil
|
||||
|
||||
proc containsGenericType*(t: PType): bool =
|
||||
result = iterOverType(t, containsGenericTypeIter, nil)
|
||||
|
|
|
|||
|
|
@ -812,7 +812,7 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): PNode =
|
|||
let t1 = regs[rb].typ.skipTypes({tyTypeDesc})
|
||||
let t2 = c.types[regs[rc].intVal.int]
|
||||
# XXX: This should use the standard isOpImpl
|
||||
let match = if t2.kind == tyTypeClass: true
|
||||
let match = if t2.kind == tyUserTypeClass: true
|
||||
else: sameType(t1, t2)
|
||||
regs[ra].intVal = ord(match)
|
||||
of opcSetLenSeq:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue