tyOrdinal now means "integral types". tyTypeClass created to take care of type constraints
This commit is contained in:
parent
3a5cf3d63a
commit
296ef07955
7 changed files with 43 additions and 30 deletions
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -520,9 +520,13 @@ 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 =
|
||||||
var
|
var
|
||||||
|
|
@ -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) =
|
||||||
|
|
|
||||||
|
|
@ -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 tyOrdinal:
|
of tyTypeClass:
|
||||||
if f.sons[0].kind != tyGenericParam:
|
result = constraintRel(mapping, f.sons[0], a)
|
||||||
# some constraint:
|
of tyOrdinal:
|
||||||
result = constraintRel(mapping, f.sons[0], a)
|
if isOrdinalType(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
|
||||||
|
|
|
||||||
|
|
@ -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:
|
||||||
|
|
|
||||||
|
|
@ -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:
|
||||||
|
|
@ -729,8 +729,8 @@ proc SameTypeAux(x, y: PType, c: var TSameTypeClosure): bool =
|
||||||
while a.kind == tyDistinct: a = a.sons[0]
|
while a.kind == tyDistinct: a = a.sons[0]
|
||||||
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
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue