some work to make 'opt' a first class type
This commit is contained in:
parent
e5cb1a2dd5
commit
e879da5791
13 changed files with 52 additions and 71 deletions
|
|
@ -404,14 +404,8 @@ type
|
||||||
# instantiation and prior to this it has the potential to
|
# instantiation and prior to this it has the potential to
|
||||||
# be any type.
|
# be any type.
|
||||||
|
|
||||||
tyFieldAccessor
|
tyOpt
|
||||||
# Expressions such as Type.field (valid in contexts such
|
# Builtin optional type
|
||||||
# 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
|
|
||||||
|
|
||||||
tyVoid
|
tyVoid
|
||||||
# now different from tyEmpty, hurray!
|
# now different from tyEmpty, hurray!
|
||||||
|
|
@ -624,7 +618,7 @@ type
|
||||||
mSwap, mIsNil, mArrToSeq, mCopyStr, mCopyStrLast,
|
mSwap, mIsNil, mArrToSeq, mCopyStr, mCopyStrLast,
|
||||||
mNewString, mNewStringOfCap, mParseBiggestFloat,
|
mNewString, mNewStringOfCap, mParseBiggestFloat,
|
||||||
mReset,
|
mReset,
|
||||||
mArray, mOpenArray, mRange, mSet, mSeq, mVarargs,
|
mArray, mOpenArray, mRange, mSet, mSeq, mOpt, mVarargs,
|
||||||
mRef, mPtr, mVar, mDistinct, mVoid, mTuple,
|
mRef, mPtr, mVar, mDistinct, mVoid, mTuple,
|
||||||
mOrdinal,
|
mOrdinal,
|
||||||
mInt, mInt8, mInt16, mInt32, mInt64,
|
mInt, mInt8, mInt16, mInt32, mInt64,
|
||||||
|
|
|
||||||
|
|
@ -130,7 +130,7 @@ proc hashType(c: var MD5Context, t: PType) =
|
||||||
c.hashSym body.sym
|
c.hashSym body.sym
|
||||||
for i in countup(1, sonsLen(t) - 2):
|
for i in countup(1, sonsLen(t) - 2):
|
||||||
c.hashType t.sons[i]
|
c.hashType t.sons[i]
|
||||||
of tyFromExpr, tyFieldAccessor:
|
of tyFromExpr:
|
||||||
c.hashTree(t.n)
|
c.hashTree(t.n)
|
||||||
of tyArray:
|
of tyArray:
|
||||||
c.hashTree(t.sons[0].n)
|
c.hashTree(t.sons[0].n)
|
||||||
|
|
|
||||||
|
|
@ -100,7 +100,7 @@ proc getUniqueType*(key: PType): PType =
|
||||||
if result == nil:
|
if result == nil:
|
||||||
gCanonicalTypes[k] = key
|
gCanonicalTypes[k] = key
|
||||||
result = key
|
result = key
|
||||||
of tyTypeDesc, tyTypeClasses, tyGenericParam, tyFromExpr, tyFieldAccessor:
|
of tyTypeDesc, tyTypeClasses, tyGenericParam, tyFromExpr:
|
||||||
if key.isResolvedUserTypeClass:
|
if key.isResolvedUserTypeClass:
|
||||||
return getUniqueType(lastSon(key))
|
return getUniqueType(lastSon(key))
|
||||||
if key.sym != nil:
|
if key.sym != nil:
|
||||||
|
|
@ -126,7 +126,7 @@ proc getUniqueType*(key: PType): PType =
|
||||||
result = slowSearch(key, k)
|
result = slowSearch(key, k)
|
||||||
of tyGenericInvocation, tyGenericBody,
|
of tyGenericInvocation, tyGenericBody,
|
||||||
tyOpenArray, tyArray, tySet, tyRange, tyTuple,
|
tyOpenArray, tyArray, tySet, tyRange, tyTuple,
|
||||||
tySequence, tyForward, tyVarargs, tyProxy:
|
tySequence, tyForward, tyVarargs, tyProxy, tyOpt:
|
||||||
# we have to do a slow linear search because types may need
|
# we have to do a slow linear search because types may need
|
||||||
# to be compared by their structure:
|
# to be compared by their structure:
|
||||||
result = slowSearch(key, k)
|
result = slowSearch(key, k)
|
||||||
|
|
|
||||||
|
|
@ -187,12 +187,12 @@ proc mapType(typ: PType): TJSTypeKind =
|
||||||
of tyBool: result = etyBool
|
of tyBool: result = etyBool
|
||||||
of tyFloat..tyFloat128: result = etyFloat
|
of tyFloat..tyFloat128: result = etyFloat
|
||||||
of tySet: result = etyObject # map a set to a table
|
of tySet: result = etyObject # map a set to a table
|
||||||
of tyString, tySequence: result = etySeq
|
of tyString, tySequence, tyOpt: result = etySeq
|
||||||
of tyObject, tyArray, tyTuple, tyOpenArray, tyVarargs:
|
of tyObject, tyArray, tyTuple, tyOpenArray, tyVarargs:
|
||||||
result = etyObject
|
result = etyObject
|
||||||
of tyNil: result = etyNull
|
of tyNil: result = etyNull
|
||||||
of tyGenericInst, tyGenericParam, tyGenericBody, tyGenericInvocation,
|
of tyGenericInst, tyGenericParam, tyGenericBody, tyGenericInvocation,
|
||||||
tyNone, tyFromExpr, tyForward, tyEmpty, tyFieldAccessor,
|
tyNone, tyFromExpr, tyForward, tyEmpty,
|
||||||
tyExpr, tyStmt, tyTypeDesc, tyTypeClasses, tyVoid, tyAlias:
|
tyExpr, tyStmt, tyTypeDesc, tyTypeClasses, tyVoid, tyAlias:
|
||||||
result = etyNone
|
result = etyNone
|
||||||
of tyInferred:
|
of tyInferred:
|
||||||
|
|
@ -927,7 +927,7 @@ proc genAsgnAux(p: PProc, x, y: PNode, noCopyNeeded: bool) =
|
||||||
|
|
||||||
# we don't care if it's an etyBaseIndex (global) of a string, it's
|
# we don't care if it's an etyBaseIndex (global) of a string, it's
|
||||||
# still a string that needs to be copied properly:
|
# still a string that needs to be copied properly:
|
||||||
if x.typ.skipTypes(abstractInst).kind in {tySequence, tyString}:
|
if x.typ.skipTypes(abstractInst).kind in {tySequence, tyOpt, tyString}:
|
||||||
xtyp = etySeq
|
xtyp = etySeq
|
||||||
case xtyp
|
case xtyp
|
||||||
of etySeq:
|
of etySeq:
|
||||||
|
|
@ -971,7 +971,7 @@ proc genFastAsgn(p: PProc, n: PNode) =
|
||||||
# See bug #5933. So we try to be more compatible with the C backend semantics
|
# See bug #5933. So we try to be more compatible with the C backend semantics
|
||||||
# here for 'shallowCopy'. This is an educated guess and might require further
|
# here for 'shallowCopy'. This is an educated guess and might require further
|
||||||
# changes later:
|
# changes later:
|
||||||
let noCopy = n[0].typ.skipTypes(abstractInst).kind in {tySequence, tyString}
|
let noCopy = n[0].typ.skipTypes(abstractInst).kind in {tySequence, tyOpt, tyString}
|
||||||
genAsgnAux(p, n.sons[0], n.sons[1], noCopyNeeded=noCopy)
|
genAsgnAux(p, n.sons[0], n.sons[1], noCopyNeeded=noCopy)
|
||||||
|
|
||||||
proc genSwap(p: PProc, n: PNode) =
|
proc genSwap(p: PProc, n: PNode) =
|
||||||
|
|
@ -1550,7 +1550,7 @@ proc createVar(p: PProc, typ: PType, indirect: bool): Rope =
|
||||||
result = putToSeq("[null, 0]", indirect)
|
result = putToSeq("[null, 0]", indirect)
|
||||||
else:
|
else:
|
||||||
result = putToSeq("null", indirect)
|
result = putToSeq("null", indirect)
|
||||||
of tySequence, tyString, tyCString, tyPointer, tyProc:
|
of tySequence, tyOpt, tyString, tyCString, tyPointer, tyProc:
|
||||||
result = putToSeq("null", indirect)
|
result = putToSeq("null", indirect)
|
||||||
of tyStatic:
|
of tyStatic:
|
||||||
if t.n != nil:
|
if t.n != nil:
|
||||||
|
|
|
||||||
|
|
@ -185,7 +185,7 @@ proc liftBodyAux(c: var TLiftCtx; t: PType; body, x, y: PNode) =
|
||||||
case t.kind
|
case t.kind
|
||||||
of tyNone, tyEmpty, tyVoid: discard
|
of tyNone, tyEmpty, tyVoid: discard
|
||||||
of tyPointer, tySet, tyBool, tyChar, tyEnum, tyInt..tyUInt64, tyCString,
|
of tyPointer, tySet, tyBool, tyChar, tyEnum, tyInt..tyUInt64, tyCString,
|
||||||
tyPtr, tyString, tyRef:
|
tyPtr, tyString, tyRef, tyOpt:
|
||||||
defaultOp(c, t, body, x, y)
|
defaultOp(c, t, body, x, y)
|
||||||
of tyArray, tySequence:
|
of tyArray, tySequence:
|
||||||
if tfHasAsgn in t.flags:
|
if tfHasAsgn in t.flags:
|
||||||
|
|
@ -227,7 +227,7 @@ proc liftBodyAux(c: var TLiftCtx; t: PType; body, x, y: PNode) =
|
||||||
tyTypeDesc, tyGenericInvocation, tyForward:
|
tyTypeDesc, tyGenericInvocation, tyForward:
|
||||||
internalError(c.info, "assignment requested for type: " & typeToString(t))
|
internalError(c.info, "assignment requested for type: " & typeToString(t))
|
||||||
of tyOrdinal, tyRange, tyInferred,
|
of tyOrdinal, tyRange, tyInferred,
|
||||||
tyGenericInst, tyFieldAccessor, tyStatic, tyVar, tyAlias:
|
tyGenericInst, tyStatic, tyVar, tyAlias:
|
||||||
liftBodyAux(c, lastSon(t), body, x, y)
|
liftBodyAux(c, lastSon(t), body, x, y)
|
||||||
of tyUnused, tyUnused0, tyUnused1, tyUnused2: internalError("liftBodyAux")
|
of tyUnused, tyUnused0, tyUnused1, tyUnused2: internalError("liftBodyAux")
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -246,8 +246,7 @@ proc semLowHigh(c: PContext, n: PNode, m: TMagic): PNode =
|
||||||
localError(n.info, errXExpectsTypeOrValue, opToStr[m])
|
localError(n.info, errXExpectsTypeOrValue, opToStr[m])
|
||||||
else:
|
else:
|
||||||
n.sons[1] = semExprWithType(c, n.sons[1], {efDetermineType})
|
n.sons[1] = semExprWithType(c, n.sons[1], {efDetermineType})
|
||||||
var typ = skipTypes(n.sons[1].typ, abstractVarRange +
|
var typ = skipTypes(n.sons[1].typ, abstractVarRange + {tyTypeDesc})
|
||||||
{tyTypeDesc, tyFieldAccessor})
|
|
||||||
case typ.kind
|
case typ.kind
|
||||||
of tySequence, tyString, tyCString, tyOpenArray, tyVarargs:
|
of tySequence, tyString, tyCString, tyOpenArray, tyVarargs:
|
||||||
n.typ = getSysType(tyInt)
|
n.typ = getSysType(tyInt)
|
||||||
|
|
@ -255,7 +254,7 @@ proc semLowHigh(c: PContext, n: PNode, m: TMagic): PNode =
|
||||||
n.typ = typ.sons[0] # indextype
|
n.typ = typ.sons[0] # indextype
|
||||||
of tyInt..tyInt64, tyChar, tyBool, tyEnum, tyUInt8, tyUInt16, tyUInt32:
|
of tyInt..tyInt64, tyChar, tyBool, tyEnum, tyUInt8, tyUInt16, tyUInt32:
|
||||||
# do not skip the range!
|
# do not skip the range!
|
||||||
n.typ = n.sons[1].typ.skipTypes(abstractVar + {tyFieldAccessor})
|
n.typ = n.sons[1].typ.skipTypes(abstractVar)
|
||||||
of tyGenericParam:
|
of tyGenericParam:
|
||||||
# prepare this for resolving in semtypinst:
|
# prepare this for resolving in semtypinst:
|
||||||
# we must use copyTree here in order to avoid creating a cycle
|
# we must use copyTree here in order to avoid creating a cycle
|
||||||
|
|
@ -279,7 +278,7 @@ proc isOpImpl(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
||||||
n[1].typ != nil and n[1].typ.kind == tyTypeDesc and
|
n[1].typ != nil and n[1].typ.kind == tyTypeDesc and
|
||||||
n[2].kind in {nkStrLit..nkTripleStrLit, nkType}
|
n[2].kind in {nkStrLit..nkTripleStrLit, nkType}
|
||||||
|
|
||||||
let t1 = n[1].typ.skipTypes({tyTypeDesc, tyFieldAccessor})
|
let t1 = n[1].typ.skipTypes({tyTypeDesc})
|
||||||
|
|
||||||
if n[2].kind in {nkStrLit..nkTripleStrLit}:
|
if n[2].kind in {nkStrLit..nkTripleStrLit}:
|
||||||
case n[2].strVal.normalize
|
case n[2].strVal.normalize
|
||||||
|
|
@ -1087,9 +1086,6 @@ proc builtinFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
||||||
if field != nil:
|
if field != nil:
|
||||||
n.typ = makeTypeDesc(c, field.typ)
|
n.typ = makeTypeDesc(c, field.typ)
|
||||||
return n
|
return n
|
||||||
#n.typ = newTypeWithSons(c, tyFieldAccessor, @[ty, field.typ])
|
|
||||||
#n.typ.n = copyTree(n)
|
|
||||||
#return n
|
|
||||||
else:
|
else:
|
||||||
tryReadingGenericParam(ty)
|
tryReadingGenericParam(ty)
|
||||||
return
|
return
|
||||||
|
|
|
||||||
|
|
@ -1234,7 +1234,7 @@ proc semInferredLambda(c: PContext, pt: TIdTable, n: PNode): PNode =
|
||||||
s.typ = n.typ
|
s.typ = n.typ
|
||||||
for i in 1..<params.len:
|
for i in 1..<params.len:
|
||||||
if params[i].typ.kind in {tyTypeDesc, tyGenericParam,
|
if params[i].typ.kind in {tyTypeDesc, tyGenericParam,
|
||||||
tyFromExpr, tyFieldAccessor}+tyTypeClasses:
|
tyFromExpr}+tyTypeClasses:
|
||||||
localError(params[i].info, "cannot infer type of parameter: " &
|
localError(params[i].info, "cannot infer type of parameter: " &
|
||||||
params[i].sym.name.s)
|
params[i].sym.name.s)
|
||||||
#params[i].sym.owner = s
|
#params[i].sym.owner = s
|
||||||
|
|
|
||||||
|
|
@ -1592,6 +1592,8 @@ proc processMagicType(c: PContext, m: PSym) =
|
||||||
setMagicType(m, tySet, 0)
|
setMagicType(m, tySet, 0)
|
||||||
of mSeq:
|
of mSeq:
|
||||||
setMagicType(m, tySequence, 0)
|
setMagicType(m, tySequence, 0)
|
||||||
|
of mOpt:
|
||||||
|
setMagicType(m, tyOpt, 0)
|
||||||
of mOrdinal:
|
of mOrdinal:
|
||||||
setMagicType(m, tyOrdinal, 0)
|
setMagicType(m, tyOrdinal, 0)
|
||||||
rawAddSon(m.typ, newTypeS(tyNone, c))
|
rawAddSon(m.typ, newTypeS(tyNone, c))
|
||||||
|
|
|
||||||
|
|
@ -201,7 +201,7 @@ proc hashType(c: var MD5Context, t: PType; flags: set[ConsiderFlag]) =
|
||||||
of tyRef, tyPtr, tyGenericBody, tyVar:
|
of tyRef, tyPtr, tyGenericBody, tyVar:
|
||||||
c.hashType t.lastSon, flags
|
c.hashType t.lastSon, flags
|
||||||
if tfVarIsPtr in t.flags: c &= ".varisptr"
|
if tfVarIsPtr in t.flags: c &= ".varisptr"
|
||||||
of tyFromExpr, tyFieldAccessor:
|
of tyFromExpr:
|
||||||
c.hashTree(t.n)
|
c.hashTree(t.n)
|
||||||
of tyTuple:
|
of tyTuple:
|
||||||
if t.n != nil and CoType notin flags:
|
if t.n != nil and CoType notin flags:
|
||||||
|
|
|
||||||
|
|
@ -936,7 +936,7 @@ proc typeRelImpl(c: var TCandidate, f, aOrig: PType,
|
||||||
tfExplicit notin aOrig.flags
|
tfExplicit notin aOrig.flags
|
||||||
|
|
||||||
aOrig = if useTypeLoweringRuleInTypeClass:
|
aOrig = if useTypeLoweringRuleInTypeClass:
|
||||||
aOrig.skipTypes({tyTypeDesc, tyFieldAccessor})
|
aOrig.skipTypes({tyTypeDesc})
|
||||||
else:
|
else:
|
||||||
aOrig
|
aOrig
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,9 +12,6 @@
|
||||||
import
|
import
|
||||||
intsets, ast, astalgo, trees, msgs, strutils, platform, renderer
|
intsets, ast, astalgo, trees, msgs, strutils, platform, renderer
|
||||||
|
|
||||||
proc firstOrd*(t: PType): BiggestInt
|
|
||||||
proc lastOrd*(t: PType): BiggestInt
|
|
||||||
proc lengthOrd*(t: PType): BiggestInt
|
|
||||||
type
|
type
|
||||||
TPreferedDesc* = enum
|
TPreferedDesc* = enum
|
||||||
preferName, preferDesc, preferExported, preferModuleInfo, preferGenericArg
|
preferName, preferDesc, preferExported, preferModuleInfo, preferGenericArg
|
||||||
|
|
@ -70,17 +67,6 @@ const
|
||||||
typedescPtrs* = abstractPtrs + {tyTypeDesc}
|
typedescPtrs* = abstractPtrs + {tyTypeDesc}
|
||||||
typedescInst* = abstractInst + {tyTypeDesc}
|
typedescInst* = abstractInst + {tyTypeDesc}
|
||||||
|
|
||||||
proc containsObject*(t: PType): bool
|
|
||||||
proc containsGarbageCollectedRef*(typ: PType): bool
|
|
||||||
proc containsHiddenPointer*(typ: PType): bool
|
|
||||||
proc canFormAcycle*(typ: PType): bool
|
|
||||||
proc isCompatibleToCString*(a: PType): bool
|
|
||||||
proc getOrdValue*(n: PNode): BiggestInt
|
|
||||||
proc computeSize*(typ: PType): BiggestInt
|
|
||||||
proc getSize*(typ: PType): BiggestInt
|
|
||||||
proc isPureObject*(typ: PType): bool
|
|
||||||
proc invalidGenericInst*(f: PType): bool
|
|
||||||
# for debugging
|
|
||||||
type
|
type
|
||||||
TTypeFieldResult* = enum
|
TTypeFieldResult* = enum
|
||||||
frNone, # type has no object type field
|
frNone, # type has no object type field
|
||||||
|
|
@ -92,16 +78,16 @@ proc analyseObjectWithTypeField*(t: PType): TTypeFieldResult
|
||||||
# made or intializing of the type field suffices or if there is no type field
|
# made or intializing of the type field suffices or if there is no type field
|
||||||
# at all in this type.
|
# at all in this type.
|
||||||
|
|
||||||
proc invalidGenericInst(f: PType): bool =
|
proc invalidGenericInst*(f: PType): bool =
|
||||||
result = f.kind == tyGenericInst and lastSon(f) == nil
|
result = f.kind == tyGenericInst and lastSon(f) == nil
|
||||||
|
|
||||||
proc isPureObject(typ: PType): bool =
|
proc isPureObject*(typ: PType): bool =
|
||||||
var t = typ
|
var t = typ
|
||||||
while t.kind == tyObject and t.sons[0] != nil:
|
while t.kind == tyObject and t.sons[0] != nil:
|
||||||
t = t.sons[0].skipTypes(skipPtrs)
|
t = t.sons[0].skipTypes(skipPtrs)
|
||||||
result = t.sym != nil and sfPure in t.sym.flags
|
result = t.sym != nil and sfPure in t.sym.flags
|
||||||
|
|
||||||
proc getOrdValue(n: PNode): BiggestInt =
|
proc getOrdValue*(n: PNode): BiggestInt =
|
||||||
case n.kind
|
case n.kind
|
||||||
of nkCharLit..nkUInt64Lit: result = n.intVal
|
of nkCharLit..nkUInt64Lit: result = n.intVal
|
||||||
of nkNilLit: result = 0
|
of nkNilLit: result = 0
|
||||||
|
|
@ -116,14 +102,6 @@ proc isIntLit*(t: PType): bool {.inline.} =
|
||||||
proc isFloatLit*(t: PType): bool {.inline.} =
|
proc isFloatLit*(t: PType): bool {.inline.} =
|
||||||
result = t.kind == tyFloat and t.n != nil and t.n.kind == nkFloatLit
|
result = t.kind == tyFloat and t.n != nil and t.n.kind == nkFloatLit
|
||||||
|
|
||||||
proc isCompatibleToCString(a: PType): bool =
|
|
||||||
if a.kind == tyArray:
|
|
||||||
if (firstOrd(a.sons[0]) == 0) and
|
|
||||||
(skipTypes(a.sons[0], {tyRange, tyGenericInst, tyAlias}).kind in
|
|
||||||
{tyInt..tyInt64, tyUInt..tyUInt64}) and
|
|
||||||
(a.sons[1].kind == tyChar):
|
|
||||||
result = true
|
|
||||||
|
|
||||||
proc getProcHeader*(sym: PSym; prefer: TPreferedDesc = preferName): string =
|
proc getProcHeader*(sym: PSym; prefer: TPreferedDesc = preferName): string =
|
||||||
result = sym.owner.name.s & '.' & sym.name.s & '('
|
result = sym.owner.name.s & '.' & sym.name.s & '('
|
||||||
var n = sym.typ.n
|
var n = sym.typ.n
|
||||||
|
|
@ -252,7 +230,7 @@ proc searchTypeFor(t: PType, predicate: TTypePredicate): bool =
|
||||||
proc isObjectPredicate(t: PType): bool =
|
proc isObjectPredicate(t: PType): bool =
|
||||||
result = t.kind == tyObject
|
result = t.kind == tyObject
|
||||||
|
|
||||||
proc containsObject(t: PType): bool =
|
proc containsObject*(t: PType): bool =
|
||||||
result = searchTypeFor(t, isObjectPredicate)
|
result = searchTypeFor(t, isObjectPredicate)
|
||||||
|
|
||||||
proc isObjectWithTypeFieldPredicate(t: PType): bool =
|
proc isObjectWithTypeFieldPredicate(t: PType): bool =
|
||||||
|
|
@ -297,7 +275,7 @@ proc isGCRef(t: PType): bool =
|
||||||
result = t.kind in GcTypeKinds or
|
result = t.kind in GcTypeKinds or
|
||||||
(t.kind == tyProc and t.callConv == ccClosure)
|
(t.kind == tyProc and t.callConv == ccClosure)
|
||||||
|
|
||||||
proc containsGarbageCollectedRef(typ: PType): bool =
|
proc containsGarbageCollectedRef*(typ: PType): bool =
|
||||||
# returns true if typ contains a reference, sequence or string (all the
|
# returns true if typ contains a reference, sequence or string (all the
|
||||||
# things that are garbage-collected)
|
# things that are garbage-collected)
|
||||||
result = searchTypeFor(typ, isGCRef)
|
result = searchTypeFor(typ, isGCRef)
|
||||||
|
|
@ -312,7 +290,7 @@ proc containsTyRef*(typ: PType): bool =
|
||||||
proc isHiddenPointer(t: PType): bool =
|
proc isHiddenPointer(t: PType): bool =
|
||||||
result = t.kind in {tyString, tySequence}
|
result = t.kind in {tyString, tySequence}
|
||||||
|
|
||||||
proc containsHiddenPointer(typ: PType): bool =
|
proc containsHiddenPointer*(typ: PType): bool =
|
||||||
# returns true if typ contains a string, table or sequence (all the things
|
# returns true if typ contains a string, table or sequence (all the things
|
||||||
# that need to be copied deeply)
|
# that need to be copied deeply)
|
||||||
result = searchTypeFor(typ, isHiddenPointer)
|
result = searchTypeFor(typ, isHiddenPointer)
|
||||||
|
|
@ -355,7 +333,7 @@ proc canFormAcycleAux(marker: var IntSet, typ: PType, startId: int): bool =
|
||||||
of tyProc: result = typ.callConv == ccClosure
|
of tyProc: result = typ.callConv == ccClosure
|
||||||
else: discard
|
else: discard
|
||||||
|
|
||||||
proc canFormAcycle(typ: PType): bool =
|
proc canFormAcycle*(typ: PType): bool =
|
||||||
var marker = initIntSet()
|
var marker = initIntSet()
|
||||||
result = canFormAcycleAux(marker, typ, typ.id)
|
result = canFormAcycleAux(marker, typ, typ.id)
|
||||||
|
|
||||||
|
|
@ -521,7 +499,7 @@ proc typeToString(typ: PType, prefer: TPreferedDesc = preferName): string =
|
||||||
of tyExpr:
|
of tyExpr:
|
||||||
internalAssert t.len == 0
|
internalAssert t.len == 0
|
||||||
result = "untyped"
|
result = "untyped"
|
||||||
of tyFromExpr, tyFieldAccessor:
|
of tyFromExpr:
|
||||||
result = renderTree(t.n)
|
result = renderTree(t.n)
|
||||||
of tyArray:
|
of tyArray:
|
||||||
if t.sons[0].kind == tyRange:
|
if t.sons[0].kind == tyRange:
|
||||||
|
|
@ -532,6 +510,8 @@ proc typeToString(typ: PType, prefer: TPreferedDesc = preferName): string =
|
||||||
typeToString(t.sons[1]) & ']'
|
typeToString(t.sons[1]) & ']'
|
||||||
of tySequence:
|
of tySequence:
|
||||||
result = "seq[" & typeToString(t.sons[0]) & ']'
|
result = "seq[" & typeToString(t.sons[0]) & ']'
|
||||||
|
of tyOpt:
|
||||||
|
result = "opt[" & typeToString(t.sons[0]) & ']'
|
||||||
of tyOrdinal:
|
of tyOrdinal:
|
||||||
result = "ordinal[" & typeToString(t.sons[0]) & ']'
|
result = "ordinal[" & typeToString(t.sons[0]) & ']'
|
||||||
of tySet:
|
of tySet:
|
||||||
|
|
@ -605,7 +585,7 @@ proc typeToString(typ: PType, prefer: TPreferedDesc = preferName): string =
|
||||||
result = typeToStr[t.kind]
|
result = typeToStr[t.kind]
|
||||||
result.addTypeFlags(t)
|
result.addTypeFlags(t)
|
||||||
|
|
||||||
proc firstOrd(t: PType): BiggestInt =
|
proc firstOrd*(t: PType): BiggestInt =
|
||||||
case t.kind
|
case t.kind
|
||||||
of tyBool, tyChar, tySequence, tyOpenArray, tyString, tyVarargs, tyProxy:
|
of tyBool, tyChar, tySequence, tyOpenArray, tyString, tyVarargs, tyProxy:
|
||||||
result = 0
|
result = 0
|
||||||
|
|
@ -630,7 +610,7 @@ proc firstOrd(t: PType): BiggestInt =
|
||||||
else:
|
else:
|
||||||
assert(t.n.sons[0].kind == nkSym)
|
assert(t.n.sons[0].kind == nkSym)
|
||||||
result = t.n.sons[0].sym.position
|
result = t.n.sons[0].sym.position
|
||||||
of tyGenericInst, tyDistinct, tyTypeDesc, tyFieldAccessor, tyAlias:
|
of tyGenericInst, tyDistinct, tyTypeDesc, tyAlias:
|
||||||
result = firstOrd(lastSon(t))
|
result = firstOrd(lastSon(t))
|
||||||
of tyOrdinal:
|
of tyOrdinal:
|
||||||
if t.len > 0: result = firstOrd(lastSon(t))
|
if t.len > 0: result = firstOrd(lastSon(t))
|
||||||
|
|
@ -639,7 +619,7 @@ proc firstOrd(t: PType): BiggestInt =
|
||||||
internalError("invalid kind for first(" & $t.kind & ')')
|
internalError("invalid kind for first(" & $t.kind & ')')
|
||||||
result = 0
|
result = 0
|
||||||
|
|
||||||
proc lastOrd(t: PType): BiggestInt =
|
proc lastOrd*(t: PType): BiggestInt =
|
||||||
case t.kind
|
case t.kind
|
||||||
of tyBool: result = 1
|
of tyBool: result = 1
|
||||||
of tyChar: result = 255
|
of tyChar: result = 255
|
||||||
|
|
@ -666,7 +646,7 @@ proc lastOrd(t: PType): BiggestInt =
|
||||||
of tyEnum:
|
of tyEnum:
|
||||||
assert(t.n.sons[sonsLen(t.n) - 1].kind == nkSym)
|
assert(t.n.sons[sonsLen(t.n) - 1].kind == nkSym)
|
||||||
result = t.n.sons[sonsLen(t.n) - 1].sym.position
|
result = t.n.sons[sonsLen(t.n) - 1].sym.position
|
||||||
of tyGenericInst, tyDistinct, tyTypeDesc, tyFieldAccessor, tyAlias:
|
of tyGenericInst, tyDistinct, tyTypeDesc, tyAlias:
|
||||||
result = lastOrd(lastSon(t))
|
result = lastOrd(lastSon(t))
|
||||||
of tyProxy: result = 0
|
of tyProxy: result = 0
|
||||||
of tyOrdinal:
|
of tyOrdinal:
|
||||||
|
|
@ -676,7 +656,7 @@ proc lastOrd(t: PType): BiggestInt =
|
||||||
internalError("invalid kind for last(" & $t.kind & ')')
|
internalError("invalid kind for last(" & $t.kind & ')')
|
||||||
result = 0
|
result = 0
|
||||||
|
|
||||||
proc lengthOrd(t: PType): BiggestInt =
|
proc lengthOrd*(t: PType): BiggestInt =
|
||||||
case t.kind
|
case t.kind
|
||||||
of tyInt64, tyInt32, tyInt: result = lastOrd(t)
|
of tyInt64, tyInt32, tyInt: result = lastOrd(t)
|
||||||
of tyDistinct: result = lengthOrd(t.sons[0])
|
of tyDistinct: result = lengthOrd(t.sons[0])
|
||||||
|
|
@ -689,6 +669,14 @@ proc lengthOrd(t: PType): BiggestInt =
|
||||||
else:
|
else:
|
||||||
result = lastOrd(t) - firstOrd(t) + 1
|
result = lastOrd(t) - firstOrd(t) + 1
|
||||||
|
|
||||||
|
proc isCompatibleToCString*(a: PType): bool =
|
||||||
|
if a.kind == tyArray:
|
||||||
|
if (firstOrd(a.sons[0]) == 0) and
|
||||||
|
(skipTypes(a.sons[0], {tyRange, tyGenericInst, tyAlias}).kind in
|
||||||
|
{tyInt..tyInt64, tyUInt..tyUInt64}) and
|
||||||
|
(a.sons[1].kind == tyChar):
|
||||||
|
result = true
|
||||||
|
|
||||||
# -------------- type equality -----------------------------------------------
|
# -------------- type equality -----------------------------------------------
|
||||||
|
|
||||||
type
|
type
|
||||||
|
|
@ -989,7 +977,7 @@ proc sameTypeAux(x, y: PType, c: var TSameTypeClosure): bool =
|
||||||
result = a.sym.position == b.sym.position
|
result = a.sym.position == b.sym.position
|
||||||
of tyGenericInvocation, tyGenericBody, tySequence,
|
of tyGenericInvocation, tyGenericBody, tySequence,
|
||||||
tyOpenArray, tySet, tyRef, tyPtr, tyVar,
|
tyOpenArray, tySet, tyRef, tyPtr, tyVar,
|
||||||
tyArray, tyProc, tyVarargs, tyOrdinal, tyTypeClasses, tyFieldAccessor:
|
tyArray, tyProc, tyVarargs, tyOrdinal, tyTypeClasses, tyOpt:
|
||||||
cycleCheck()
|
cycleCheck()
|
||||||
if a.kind == tyUserTypeClass 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)
|
result = sameChildrenAux(a, b, c) and sameFlags(a, b)
|
||||||
|
|
@ -1144,7 +1132,7 @@ proc typeAllowedAux(marker: var IntSet, typ: PType, kind: TSymKind,
|
||||||
of tyTypeClasses:
|
of tyTypeClasses:
|
||||||
if not (tfGenericTypeParam in t.flags or taField notin flags): result = t
|
if not (tfGenericTypeParam in t.flags or taField notin flags): result = t
|
||||||
of tyGenericBody, tyGenericParam, tyGenericInvocation,
|
of tyGenericBody, tyGenericParam, tyGenericInvocation,
|
||||||
tyNone, tyForward, tyFromExpr, tyFieldAccessor:
|
tyNone, tyForward, tyFromExpr:
|
||||||
result = t
|
result = t
|
||||||
of tyNil:
|
of tyNil:
|
||||||
if kind != skConst: result = t
|
if kind != skConst: result = t
|
||||||
|
|
@ -1160,7 +1148,7 @@ proc typeAllowedAux(marker: var IntSet, typ: PType, kind: TSymKind,
|
||||||
of tyOpenArray, tyVarargs:
|
of tyOpenArray, tyVarargs:
|
||||||
if kind != skParam: result = t
|
if kind != skParam: result = t
|
||||||
else: result = typeAllowedAux(marker, t.sons[0], skVar, flags)
|
else: result = typeAllowedAux(marker, t.sons[0], skVar, flags)
|
||||||
of tySequence:
|
of tySequence, tyOpt:
|
||||||
if t.sons[0].kind != tyEmpty:
|
if t.sons[0].kind != tyEmpty:
|
||||||
result = typeAllowedAux(marker, t.sons[0], skVar, flags+{taHeap})
|
result = typeAllowedAux(marker, t.sons[0], skVar, flags+{taHeap})
|
||||||
of tyArray:
|
of tyArray:
|
||||||
|
|
@ -1359,7 +1347,7 @@ proc computeSizeAux(typ: PType, a: var BiggestInt): BiggestInt =
|
||||||
typ.size = result
|
typ.size = result
|
||||||
typ.align = int16(a)
|
typ.align = int16(a)
|
||||||
|
|
||||||
proc computeSize(typ: PType): BiggestInt =
|
proc computeSize*(typ: PType): BiggestInt =
|
||||||
var a: BiggestInt = 1
|
var a: BiggestInt = 1
|
||||||
result = computeSizeAux(typ, a)
|
result = computeSizeAux(typ, a)
|
||||||
|
|
||||||
|
|
@ -1368,7 +1356,7 @@ proc getReturnType*(s: PSym): PType =
|
||||||
assert s.kind in skProcKinds
|
assert s.kind in skProcKinds
|
||||||
result = s.typ.sons[0]
|
result = s.typ.sons[0]
|
||||||
|
|
||||||
proc getSize(typ: PType): BiggestInt =
|
proc getSize*(typ: PType): BiggestInt =
|
||||||
result = computeSize(typ)
|
result = computeSize(typ)
|
||||||
if result < 0: internalError("getSize: " & $typ.kind)
|
if result < 0: internalError("getSize: " & $typ.kind)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -250,6 +250,7 @@ proc mapTypeToAstX(t: PType; info: TLineInfo;
|
||||||
result = mapTypeToBracket("ref", mRef, t, info)
|
result = mapTypeToBracket("ref", mRef, t, info)
|
||||||
of tyVar: result = mapTypeToBracket("var", mVar, t, info)
|
of tyVar: result = mapTypeToBracket("var", mVar, t, info)
|
||||||
of tySequence: result = mapTypeToBracket("seq", mSeq, t, info)
|
of tySequence: result = mapTypeToBracket("seq", mSeq, t, info)
|
||||||
|
of tyOpt: result = mapTypeToBracket("opt", mOpt, t, info)
|
||||||
of tyProc:
|
of tyProc:
|
||||||
if inst:
|
if inst:
|
||||||
result = newNodeX(nkProcTy)
|
result = newNodeX(nkProcTy)
|
||||||
|
|
@ -304,7 +305,7 @@ proc mapTypeToAstX(t: PType; info: TLineInfo;
|
||||||
of tyNot: result = mapTypeToBracket("not", mNot, t, info)
|
of tyNot: result = mapTypeToBracket("not", mNot, t, info)
|
||||||
of tyAnything: result = atomicType("anything", mNone)
|
of tyAnything: result = atomicType("anything", mNone)
|
||||||
of tyInferred: internalAssert false
|
of tyInferred: internalAssert false
|
||||||
of tyStatic, tyFromExpr, tyFieldAccessor:
|
of tyStatic, tyFromExpr:
|
||||||
if inst:
|
if inst:
|
||||||
if t.n != nil: result = t.n.copyTree
|
if t.n != nil: result = t.n.copyTree
|
||||||
else: result = atomicType("void", mVoid)
|
else: result = atomicType("void", mVoid)
|
||||||
|
|
|
||||||
|
|
@ -97,7 +97,7 @@ type
|
||||||
ntyError,
|
ntyError,
|
||||||
ntyBuiltinTypeClass, ntyUserTypeClass, ntyUserTypeClassInst,
|
ntyBuiltinTypeClass, ntyUserTypeClass, ntyUserTypeClassInst,
|
||||||
ntyCompositeTypeClass, ntyInferred, ntyAnd, ntyOr, ntyNot,
|
ntyCompositeTypeClass, ntyInferred, ntyAnd, ntyOr, ntyNot,
|
||||||
ntyAnything, ntyStatic, ntyFromExpr, ntyFieldAccessor, ntyVoid
|
ntyAnything, ntyStatic, ntyFromExpr, ntyOpt, ntyVoid
|
||||||
|
|
||||||
TNimTypeKinds* {.deprecated.} = set[NimTypeKind]
|
TNimTypeKinds* {.deprecated.} = set[NimTypeKind]
|
||||||
NimSymKind* = enum
|
NimSymKind* = enum
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue