intsets are now a proper module and part of the stdlib

This commit is contained in:
Araq 2011-06-14 01:36:49 +02:00
commit ade67f1abc
25 changed files with 297 additions and 286 deletions

View file

@ -10,7 +10,7 @@
# this module contains routines for accessing and iterating over types
import
ast, astalgo, trees, msgs, strutils, platform
intsets, ast, astalgo, trees, msgs, strutils, platform
proc firstOrd*(t: PType): biggestInt
proc lastOrd*(t: PType): biggestInt
@ -219,7 +219,7 @@ proc iterOverTypeAux(marker: var TIntSet, t: PType, iter: TTypeIter,
if t == nil: return
result = iter(t, closure)
if result: return
if not IntSetContainsOrIncl(marker, t.id):
if not ContainsOrIncl(marker, t.id):
case t.kind
of tyGenericInst, tyGenericBody:
result = iterOverTypeAux(marker, lastSon(t), iter, closure)
@ -230,8 +230,7 @@ proc iterOverTypeAux(marker: var TIntSet, t: PType, iter: TTypeIter,
if t.n != nil: result = iterOverNode(marker, t.n, iter, closure)
proc IterOverType(t: PType, iter: TTypeIter, closure: PObject): bool =
var marker: TIntSet
IntSetInit(marker)
var marker = InitIntSet()
result = iterOverTypeAux(marker, t, iter, closure)
proc searchTypeForAux(t: PType, predicate: TTypePredicate,
@ -263,7 +262,7 @@ proc searchTypeForAux(t: PType, predicate: TTypePredicate, marker: var TIntSet):
# iterates over VALUE types!
result = false
if t == nil: return
if IntSetContainsOrIncl(marker, t.id): return
if ContainsOrIncl(marker, t.id): return
result = Predicate(t)
if result: return
case t.kind
@ -280,8 +279,7 @@ proc searchTypeForAux(t: PType, predicate: TTypePredicate, marker: var TIntSet):
nil
proc searchTypeFor(t: PType, predicate: TTypePredicate): bool =
var marker: TIntSet
IntSetInit(marker)
var marker = InitIntSet()
result = searchTypeForAux(t, predicate, marker)
proc isObjectPredicate(t: PType): bool =
@ -322,8 +320,7 @@ proc analyseObjectWithTypeFieldAux(t: PType, marker: var TIntSet): TTypeFieldRes
nil
proc analyseObjectWithTypeField(t: PType): TTypeFieldResult =
var marker: TIntSet
IntSetInit(marker)
var marker = InitIntSet()
result = analyseObjectWithTypeFieldAux(t, marker)
proc isGBCRef(t: PType): bool =
@ -365,7 +362,7 @@ proc canFormAcycleAux(marker: var TIntSet, typ: PType, startId: int): bool =
if tfAcyclic in t.flags: return
case t.kind
of tyTuple, tyObject, tyRef, tySequence, tyArray, tyArrayConstr, tyOpenArray:
if not IntSetContainsOrIncl(marker, t.id):
if not ContainsOrIncl(marker, t.id):
for i in countup(0, sonsLen(t) - 1):
result = canFormAcycleAux(marker, t.sons[i], startId)
if result: return
@ -376,8 +373,7 @@ proc canFormAcycleAux(marker: var TIntSet, typ: PType, startId: int): bool =
nil
proc canFormAcycle(typ: PType): bool =
var marker: TIntSet
IntSetInit(marker)
var marker = InitIntSet()
result = canFormAcycleAux(marker, typ, typ.id)
proc mutateTypeAux(marker: var TIntSet, t: PType, iter: TTypeMutator,
@ -400,7 +396,7 @@ proc mutateTypeAux(marker: var TIntSet, t: PType, iter: TTypeMutator,
result = nil
if t == nil: return
result = iter(t, closure)
if not IntSetContainsOrIncl(marker, t.id):
if not ContainsOrIncl(marker, t.id):
for i in countup(0, sonsLen(t) - 1):
result.sons[i] = mutateTypeAux(marker, result.sons[i], iter, closure)
if (result.sons[i] == nil) and (result.kind == tyGenericInst):
@ -409,8 +405,7 @@ proc mutateTypeAux(marker: var TIntSet, t: PType, iter: TTypeMutator,
assert(result != nil)
proc mutateType(t: PType, iter: TTypeMutator, closure: PObject): PType =
var marker: TIntSet
IntSetInit(marker)
var marker = InitIntSet()
result = mutateTypeAux(marker, t, iter, closure)
proc rangeToStr(n: PNode): string =
@ -591,17 +586,14 @@ proc equalParam(a, b: PSym): TParamsEquality =
result = paramsNotEqual
proc equalParams(a, b: PNode): TParamsEquality =
var
length: int
m, n: PSym
result = paramsEqual
length = sonsLen(a)
var length = sonsLen(a)
if length != sonsLen(b):
result = paramsNotEqual
else:
for i in countup(1, length - 1):
m = a.sons[i].sym
n = b.sons[i].sym
var m = a.sons[i].sym
var n = b.sons[i].sym
assert((m.kind == skParam) and (n.kind == skParam))
case equalParam(m, n)
of paramsNotEqual:
@ -646,7 +638,6 @@ proc sameTuple(a, b: PType, DistinctOf: bool): bool =
# two tuples are equivalent iff the names, types and positions are the same;
# however, both types may not have any field names (t.n may be nil) which
# complicates the matter a bit.
var x, y: PSym
if sonsLen(a) == sonsLen(b):
result = true
for i in countup(0, sonsLen(a) - 1):
@ -658,8 +649,8 @@ proc sameTuple(a, b: PType, DistinctOf: bool): bool =
# check field names:
if a.n.sons[i].kind != nkSym: InternalError(a.n.info, "sameTuple")
if b.n.sons[i].kind != nkSym: InternalError(b.n.info, "sameTuple")
x = a.n.sons[i].sym
y = b.n.sons[i].sym
var x = a.n.sons[i].sym
var y = b.n.sons[i].sym
result = x.name.id == y.name.id
if not result: break
else:
@ -758,17 +749,16 @@ proc typeAllowedNode(marker: var TIntSet, n: PNode, kind: TSymKind): bool =
if not result: return
proc typeAllowedAux(marker: var TIntSet, typ: PType, kind: TSymKind): bool =
var t, t2: PType
assert(kind in {skVar, skConst, skParam})
# if we have already checked the type, return true, because we stop the
# evaluation if something is wrong:
result = true
if typ == nil:
return # if we have already checked the type, return true, because we stop the
# evaluation if something is wrong:
if IntSetContainsOrIncl(marker, typ.id): return
t = skipTypes(typ, abstractInst)
if typ == nil: return
if ContainsOrIncl(marker, typ.id): return
var t = skipTypes(typ, abstractInst)
case t.kind
of tyVar:
t2 = skipTypes(t.sons[0], abstractInst)
var t2 = skipTypes(t.sons[0], abstractInst)
case t2.kind
of tyVar:
result = false # ``var var`` is always an invalid type:
@ -815,8 +805,7 @@ proc typeAllowedAux(marker: var TIntSet, typ: PType, kind: TSymKind): bool =
if t.n != nil: result = typeAllowedNode(marker, t.n, skVar)
proc typeAllowed(t: PType, kind: TSymKind): bool =
var marker: TIntSet
IntSetInit(marker)
var marker = InitIntSet()
result = typeAllowedAux(marker, t, kind)
proc align(address, alignment: biggestInt): biggestInt =