tyOrdinal now means "integral types". tyTypeClass created to take care of type constraints

This commit is contained in:
Zahary Karadjov 2012-03-22 16:24:12 +02:00
commit 296ef07955
7 changed files with 43 additions and 30 deletions

View file

@ -259,7 +259,7 @@ type
tyGenericParam, # ``a`` in the above patterns tyGenericParam, # ``a`` in the above patterns
tyDistinct, tyDistinct,
tyEnum, tyEnum,
tyOrdinal, # misnamed: should become 'tyConstraint' tyOrdinal, # integer types (including enums and boolean)
tyArray, tyArray,
tyObject, tyObject,
tyTuple, tyTuple,
@ -278,6 +278,7 @@ type
tyConst, tyMutable, tyVarargs, tyConst, tyMutable, tyVarargs,
tyIter, # unused tyIter, # unused
tyProxy # currently unused tyProxy # currently unused
tyTypeClass,
const const
tyPureObject* = tyTuple tyPureObject* = tyTuple

View file

@ -82,9 +82,11 @@ proc GetUniqueType*(key: PType): PType =
if result == nil: if result == nil:
gCanonicalTypes[k] = key gCanonicalTypes[k] = key
result = key result = key
of tyGenericParam, tyTypeClass:
InternalError("GetUniqueType")
of tyGenericInst, tyDistinct, tyOrdinal, tyMutable, tyConst, tyIter: of tyGenericInst, tyDistinct, tyOrdinal, tyMutable, tyConst, tyIter:
result = GetUniqueType(lastSon(key)) result = GetUniqueType(lastSon(key))
of tyArrayConstr, tyGenericInvokation, tyGenericBody, tyGenericParam, of tyArrayConstr, tyGenericInvokation, tyGenericBody,
tyOpenArray, tyArray, tyTuple, tySet, tyRange, tyOpenArray, tyArray, tyTuple, tySet, tyRange,
tyPtr, tyRef, tySequence, tyForward, tyVarargs, tyProxy, tyVar: tyPtr, tyRef, tySequence, tyForward, tyVarargs, tyProxy, tyVar:
# we have to do a slow linear search because types may need # we have to do a slow linear search because types may need

View file

@ -111,7 +111,7 @@ proc mapType(typ: PType): TEcmasTypeKind =
result = etyObject result = etyObject
of tyNil: result = etyNull of tyNil: result = etyNull
of tyGenericInst, tyGenericParam, tyGenericBody, tyGenericInvokation, tyNone, of tyGenericInst, tyGenericParam, tyGenericBody, tyGenericInvokation, tyNone,
tyForward, tyEmpty, tyExpr, tyStmt, tyTypeDesc: tyForward, tyEmpty, tyExpr, tyStmt, tyTypeDesc, tyTypeClass:
result = etyNone result = etyNone
of tyProc: result = etyProc of tyProc: result = etyProc
of tyCString: result = etyString of tyCString: result = etyString

View file

@ -520,8 +520,12 @@ proc addParamOrResult(c: PContext, param: PSym, kind: TSymKind) =
else: else:
addDecl(c, param) addDecl(c, param)
proc isTypeClass(c: PContext, t: PType): bool = proc paramTypeClass(c: PContext, paramType: PType, procKind: TSymKind): PType =
return t.kind in {tyExpr} case paramType.kind:
of tyExpr:
if procKind notin {skTemplate, skMacro}:
result = newTypeS(tyGenericParam, c)
else: nil
proc semProcTypeNode(c: PContext, n, genericParams: PNode, proc semProcTypeNode(c: PContext, n, genericParams: PNode,
prev: PType, kind: TSymKind): PType = prev: PType, kind: TSymKind): PType =
@ -552,6 +556,11 @@ proc semProcTypeNode(c: PContext, n, genericParams: PNode,
if hasType: if hasType:
typ = paramType(c, a.sons[length-2], genericParams, cl) typ = paramType(c, a.sons[length-2], genericParams, cl)
if c.filename.endsWith"nimdbg.nim" and typ != nil:
echo("PARAM TYPE ", typ.kind, " ")
if genericParams != nil:
echo genericParams.info.toFileLineCol
debug typ
#if matchType(typ, [(tyVar, 0)], tyGenericInvokation): #if matchType(typ, [(tyVar, 0)], tyGenericInvokation):
# debug a.sons[length-2][0][1] # debug a.sons[length-2][0][1]
if hasDefault: if hasDefault:
@ -571,9 +580,9 @@ proc semProcTypeNode(c: PContext, n, genericParams: PNode,
if skipTypes(typ, {tyGenericInst}).kind == tyEmpty: continue if skipTypes(typ, {tyGenericInst}).kind == tyEmpty: continue
for j in countup(0, length-3): for j in countup(0, length-3):
var arg = newSymS(skParam, a.sons[j], c) var arg = newSymS(skParam, a.sons[j], c)
arg.typ = typ let typeClass = paramTypeClass(c, typ, kind)
if kind notin {skTemplate, skMacro} and isTypeClass(c, typ): if typeClass != nil:
let typeClassParamId = getIdent(":tcls_" & $i & "_" & $j) let typeClassParamId = getIdent(arg.name.s & ":type")
if genericParams == nil: if genericParams == nil:
# genericParams is nil when the proc is being instantiated # genericParams is nil when the proc is being instantiated
# the resolved type will be in scope then # the resolved type will be in scope then
@ -581,11 +590,13 @@ proc semProcTypeNode(c: PContext, n, genericParams: PNode,
arg.typ = s.typ arg.typ = s.typ
else: else:
var s = newSym(skType, typeClassParamId, getCurrOwner()) var s = newSym(skType, typeClassParamId, getCurrOwner())
s.typ = newTypeS(tyGenericParam, c) s.typ = typeClass
s.typ.sym = s s.typ.sym = s
s.position = genericParams.len s.position = genericParams.len
genericParams.addSon(newSymNode(s)) genericParams.addSon(newSymNode(s))
arg.typ = s.typ arg.typ = s.typ
else:
arg.typ = typ
arg.position = counter arg.position = counter
inc(counter) inc(counter)
@ -799,7 +810,7 @@ proc processMagicType(c: PContext, m: PSym) =
else: GlobalError(m.info, errTypeExpected) else: GlobalError(m.info, errTypeExpected)
proc newConstraint(c: PContext, k: TTypeKind): PType = proc newConstraint(c: PContext, k: TTypeKind): PType =
result = newTypeS(tyOrdinal, c) result = newTypeS(tyTypeClass, c)
result.addSon(newTypeS(k, c)) result.addSon(newTypeS(k, c))
proc semGenericConstraints(c: PContext, n: PNode, result: PType) = proc semGenericConstraints(c: PContext, n: PNode, result: PType) =

View file

@ -340,11 +340,10 @@ proc typeRel(mapping: var TIdTable, f, a: PType): TTypeRelation =
result = typeRel(mapping, f.sons[0], a.sons[0]) result = typeRel(mapping, f.sons[0], a.sons[0])
if result < isGeneric: result = isNone if result < isGeneric: result = isNone
else: nil else: nil
of tyTypeClass:
result = constraintRel(mapping, f.sons[0], a)
of tyOrdinal: of tyOrdinal:
if f.sons[0].kind != tyGenericParam: if isOrdinalType(a):
# some constraint:
result = constraintRel(mapping, f.sons[0], a)
elif isOrdinalType(a):
var x = if a.kind == tyOrdinal: a.sons[0] else: a var x = if a.kind == tyOrdinal: a.sons[0] else: a
result = typeRel(mapping, f.sons[0], x) result = typeRel(mapping, f.sons[0], x)
if result < isGeneric: result = isNone if result < isGeneric: result = isNone

View file

@ -437,7 +437,7 @@ proc transformConv(c: PTransf, n: PNode): PTransNode =
result = generateThunk(c, x, dest).ptransnode result = generateThunk(c, x, dest).ptransnode
else: else:
result = transformSons(c, n) result = transformSons(c, n)
of tyGenericParam, tyOrdinal: of tyGenericParam, tyOrdinal, tyTypeClass:
result = transform(c, n.sons[1]) result = transform(c, n.sons[1])
# happens sometimes for generated assignments, etc. # happens sometimes for generated assignments, etc.
else: else:

View file

@ -48,15 +48,15 @@ proc equalParams*(a, b: PNode): TParamsEquality
proc isOrdinalType*(t: PType): bool proc isOrdinalType*(t: PType): bool
proc enumHasHoles*(t: PType): bool proc enumHasHoles*(t: PType): bool
const const
abstractPtrs* = {tyVar, tyPtr, tyRef, tyGenericInst, tyDistinct, tyOrdinal, abstractPtrs* = {tyVar, tyPtr, tyRef, tyGenericInst, tyDistinct,
tyConst, tyMutable} tyConst, tyMutable}
abstractVar* = {tyVar, tyGenericInst, tyDistinct, tyOrdinal, abstractVar* = {tyVar, tyGenericInst, tyDistinct,
tyConst, tyMutable} tyConst, tyMutable}
abstractRange* = {tyGenericInst, tyRange, tyDistinct, tyOrdinal, abstractRange* = {tyGenericInst, tyRange, tyDistinct,
tyConst, tyMutable} tyConst, tyMutable}
abstractVarRange* = {tyGenericInst, tyRange, tyVar, tyDistinct, tyOrdinal, abstractVarRange* = {tyGenericInst, tyRange, tyVar, tyDistinct,
tyConst, tyMutable} tyConst, tyMutable}
abstractInst* = {tyGenericInst, tyDistinct, tyOrdinal, tyConst, tyMutable} abstractInst* = {tyGenericInst, tyDistinct, tyConst, tyMutable}
skipPtrs* = {tyVar, tyPtr, tyRef, tyGenericInst, tyConst, tyMutable} skipPtrs* = {tyVar, tyPtr, tyRef, tyGenericInst, tyConst, tyMutable}
@ -142,7 +142,7 @@ proc skipTypes(t: PType, kinds: TTypeKinds): PType =
proc isOrdinalType(t: PType): bool = proc isOrdinalType(t: PType): bool =
assert(t != nil) assert(t != nil)
result = (t.Kind in {tyChar, tyInt..tyInt64, tyBool, tyEnum}) or result = (t.Kind in {tyChar, tyInt..tyInt64, tyBool, tyEnum}) or
(t.Kind in {tyRange, tyOrdinal, tyConst, tyMutable, tyGenericInst}) and (t.Kind in {tyRange, tyConst, tyMutable, tyGenericInst}) and
isOrdinalType(t.sons[0]) isOrdinalType(t.sons[0])
proc enumHasHoles(t: PType): bool = proc enumHasHoles(t: PType): bool =
@ -383,7 +383,7 @@ proc TypeToString(typ: PType, prefer: TPreferedDesc = preferName): string =
"int16", "int32", "int64", "float", "float32", "float64", "float128", "int16", "int32", "int64", "float", "float32", "float64", "float128",
"uint", "uint8", "uint16", "uint32", "uint64", "bignum", "const ", "uint", "uint8", "uint16", "uint32", "uint64", "bignum", "const ",
"!", "varargs[$1]", "iter[$1]", "proxy[$1]"] "!", "varargs[$1]", "iter[$1]", "proxy[$1]", "TypeClass" ]
var t = typ var t = typ
result = "" result = ""
if t == nil: return if t == nil: return
@ -409,7 +409,7 @@ proc TypeToString(typ: PType, prefer: TPreferedDesc = preferName): string =
of tySequence: of tySequence:
result = "seq[" & typeToString(t.sons[0]) & ']' result = "seq[" & typeToString(t.sons[0]) & ']'
of tyOrdinal: of tyOrdinal:
result = "ordinal[" & typeToString(t.sons[0]) & ']' result = "ordinal"
of tySet: of tySet:
result = "set[" & typeToString(t.sons[0]) & ']' result = "set[" & typeToString(t.sons[0]) & ']'
of tyOpenArray: of tyOpenArray:
@ -730,7 +730,7 @@ proc SameTypeAux(x, y: PType, c: var TSameTypeClosure): bool =
if a.kind != b.kind: return false if a.kind != b.kind: return false
case a.Kind case a.Kind
of tyEmpty, tyChar, tyBool, tyNil, tyPointer, tyString, tyCString, of tyEmpty, tyChar, tyBool, tyNil, tyPointer, tyString, tyCString,
tyInt..tyBigNum, tyExpr, tyStmt, tyTypeDesc: tyInt..tyBigNum, tyExpr, tyStmt, tyTypeDesc, tyOrdinal:
result = true result = true
of tyObject: of tyObject:
IfFastObjectTypeCheckFailed(a, b): IfFastObjectTypeCheckFailed(a, b):
@ -740,7 +740,7 @@ proc SameTypeAux(x, y: PType, c: var TSameTypeClosure): bool =
CycleCheck() CycleCheck()
if c.cmp == dcEq: result = sameDistinctTypes(a, b) if c.cmp == dcEq: result = sameDistinctTypes(a, b)
else: result = sameTypeAux(a.sons[0], b.sons[0], c) else: result = sameTypeAux(a.sons[0], b.sons[0], c)
of tyEnum, tyForward, tyProxy: of tyEnum, tyForward, tyProxy, tyTypeClass:
# XXX generic enums do not make much sense, but require structural checking # XXX generic enums do not make much sense, but require structural checking
result = a.id == b.id result = a.id == b.id
of tyTuple: of tyTuple:
@ -748,7 +748,7 @@ proc SameTypeAux(x, y: PType, c: var TSameTypeClosure): bool =
result = sameTuple(a, b, c) result = sameTuple(a, b, c)
of tyGenericInst: result = sameTypeAux(lastSon(a), lastSon(b), c) of tyGenericInst: result = sameTypeAux(lastSon(a), lastSon(b), c)
of tyGenericParam, tyGenericInvokation, tyGenericBody, tySequence, of tyGenericParam, tyGenericInvokation, tyGenericBody, tySequence,
tyOrdinal, tyOpenArray, tySet, tyRef, tyPtr, tyVar, tyArrayConstr, tyOpenArray, tySet, tyRef, tyPtr, tyVar, tyArrayConstr,
tyArray, tyProc, tyConst, tyMutable, tyVarargs, tyIter: tyArray, tyProc, tyConst, tyMutable, tyVarargs, tyIter:
if sonsLen(a) == sonsLen(b): if sonsLen(a) == sonsLen(b):
CycleCheck() CycleCheck()
@ -845,7 +845,7 @@ proc typeAllowedAux(marker: var TIntSet, typ: PType, kind: TSymKind): bool =
result = typeAllowedAux(marker, t.sons[0], skResult) result = typeAllowedAux(marker, t.sons[0], skResult)
of tyExpr, tyStmt, tyTypeDesc: of tyExpr, tyStmt, tyTypeDesc:
result = true result = true
of tyGenericBody, tyGenericParam, tyForward, tyNone, tyGenericInvokation: of tyGenericBody, tyGenericParam, tyForward, tyNone, tyGenericInvokation, tyTypeClass:
result = false #InternalError('shit found'); result = false #InternalError('shit found');
of tyEmpty, tyNil: of tyEmpty, tyNil:
result = kind == skConst result = kind == skConst