Allow tyOr,tyAnd and tyNot to be constructed in more contexts
This commit is contained in:
parent
3e52bb6535
commit
bc01835091
3 changed files with 53 additions and 18 deletions
|
|
@ -277,6 +277,10 @@ proc makeTypeFromExpr*(c: PContext, n: PNode): PType =
|
||||||
assert n != nil
|
assert n != nil
|
||||||
result.n = n
|
result.n = n
|
||||||
|
|
||||||
|
proc newTypeWithSons2*(kind: TTypeKind, owner: PSym, sons: seq[PType]): PType =
|
||||||
|
result = newType(kind, owner)
|
||||||
|
result.sons = sons
|
||||||
|
|
||||||
proc newTypeWithSons*(c: PContext, kind: TTypeKind,
|
proc newTypeWithSons*(c: PContext, kind: TTypeKind,
|
||||||
sons: seq[PType]): PType =
|
sons: seq[PType]): PType =
|
||||||
result = newType(kind, getCurrOwner(c))
|
result = newType(kind, getCurrOwner(c))
|
||||||
|
|
|
||||||
|
|
@ -89,9 +89,9 @@ proc semInstantiationInfo(c: PContext, n: PNode): PNode =
|
||||||
proc toNode(t: PType, i: TLineInfo): PNode =
|
proc toNode(t: PType, i: TLineInfo): PNode =
|
||||||
result = newNodeIT(nkType, i, t)
|
result = newNodeIT(nkType, i, t)
|
||||||
|
|
||||||
const
|
const
|
||||||
# these are types that use the bracket syntax for instantiation
|
# these are types that use the bracket syntax for instantiation
|
||||||
# they can be subjected to the type traits `genericHead` and
|
# they can be subjected to the type traits `genericHead` and
|
||||||
# `Uninstantiated`
|
# `Uninstantiated`
|
||||||
tyUserDefinedGenerics* = {tyGenericInst, tyGenericInvocation,
|
tyUserDefinedGenerics* = {tyGenericInst, tyGenericInvocation,
|
||||||
tyUserTypeClassInst}
|
tyUserTypeClassInst}
|
||||||
|
|
@ -109,27 +109,43 @@ proc uninstantiate(t: PType): PType =
|
||||||
of tyCompositeTypeClass: uninstantiate t.sons[1]
|
of tyCompositeTypeClass: uninstantiate t.sons[1]
|
||||||
else: t
|
else: t
|
||||||
|
|
||||||
proc evalTypeTrait(trait: PNode, operand: PType, context: PSym): PNode =
|
proc evalTypeTrait(traitCall: PNode, operand: PType, context: PSym): PNode =
|
||||||
var typ = operand.skipTypes({tyTypeDesc})
|
const skippedTypes = {tyTypeDesc}
|
||||||
|
let trait = traitCall[0]
|
||||||
|
internalAssert trait.kind == nkSym
|
||||||
|
var operand = operand.skipTypes(skippedTypes)
|
||||||
|
|
||||||
|
template operand2: PType =
|
||||||
|
traitCall.sons[2].typ.skipTypes({tyTypeDesc})
|
||||||
|
|
||||||
|
template typeWithSonsResult(kind, sons): PNode =
|
||||||
|
newTypeWithSons2(kind, context, sons).toNode(traitCall.info)
|
||||||
|
|
||||||
case trait.sym.name.s
|
case trait.sym.name.s
|
||||||
|
of "or", "|":
|
||||||
|
return typeWithSonsResult(tyOr, @[operand, operand2])
|
||||||
|
of "and":
|
||||||
|
return typeWithSonsResult(tyAnd, @[operand, operand2])
|
||||||
|
of "not":
|
||||||
|
return typeWithSonsResult(tyNot, @[operand])
|
||||||
of "name":
|
of "name":
|
||||||
result = newStrNode(nkStrLit, typ.typeToString(preferName))
|
result = newStrNode(nkStrLit, operand.typeToString(preferName))
|
||||||
result.typ = newType(tyString, context)
|
result.typ = newType(tyString, context)
|
||||||
result.info = trait.info
|
result.info = traitCall.info
|
||||||
of "arity":
|
of "arity":
|
||||||
result = newIntNode(nkIntLit, typ.len - ord(typ.kind==tyProc))
|
result = newIntNode(nkIntLit, operand.len - ord(operand.kind==tyProc))
|
||||||
result.typ = newType(tyInt, context)
|
result.typ = newType(tyInt, context)
|
||||||
result.info = trait.info
|
result.info = traitCall.info
|
||||||
of "genericHead":
|
of "genericHead":
|
||||||
var res = uninstantiate(typ)
|
var res = uninstantiate(operand)
|
||||||
if res == typ and res.kind notin tyMagicGenerics:
|
if res == operand and res.kind notin tyMagicGenerics:
|
||||||
localError(trait.info,
|
localError(traitCall.info,
|
||||||
"genericHead expects a generic type. The given type was " &
|
"genericHead expects a generic type. The given type was " &
|
||||||
typeToString(typ))
|
typeToString(operand))
|
||||||
return newType(tyError, context).toNode(trait.info)
|
return newType(tyError, context).toNode(traitCall.info)
|
||||||
result = res.base.toNode(trait.info)
|
result = res.base.toNode(traitCall.info)
|
||||||
of "stripGenericParams":
|
of "stripGenericParams":
|
||||||
result = uninstantiate(typ).toNode(trait.info)
|
result = uninstantiate(operand).toNode(traitCall.info)
|
||||||
else:
|
else:
|
||||||
internalAssert false
|
internalAssert false
|
||||||
|
|
||||||
|
|
@ -140,7 +156,7 @@ proc semTypeTraits(c: PContext, n: PNode): PNode =
|
||||||
if t.sonsLen > 0:
|
if t.sonsLen > 0:
|
||||||
# This is either a type known to sem or a typedesc
|
# This is either a type known to sem or a typedesc
|
||||||
# param to a regular proc (again, known at instantiation)
|
# param to a regular proc (again, known at instantiation)
|
||||||
result = evalTypeTrait(n[0], t, getCurrOwner(c))
|
result = evalTypeTrait(n, t, getCurrOwner(c))
|
||||||
else:
|
else:
|
||||||
# a typedesc variable, pass unmodified to evals
|
# a typedesc variable, pass unmodified to evals
|
||||||
result = n
|
result = n
|
||||||
|
|
|
||||||
|
|
@ -49,6 +49,9 @@ type
|
||||||
cstring* {.magic: Cstring.} ## built-in cstring (*compatible string*) type
|
cstring* {.magic: Cstring.} ## built-in cstring (*compatible string*) type
|
||||||
pointer* {.magic: Pointer.} ## built-in pointer type, use the ``addr``
|
pointer* {.magic: Pointer.} ## built-in pointer type, use the ``addr``
|
||||||
## operator to get a pointer to a variable
|
## operator to get a pointer to a variable
|
||||||
|
|
||||||
|
typedesc* {.magic: TypeDesc.} ## meta type to denote a type description
|
||||||
|
|
||||||
const
|
const
|
||||||
on* = true ## alias for ``true``
|
on* = true ## alias for ``true``
|
||||||
off* = false ## alias for ``false``
|
off* = false ## alias for ``false``
|
||||||
|
|
@ -56,6 +59,18 @@ const
|
||||||
{.push warning[GcMem]: off, warning[Uninit]: off.}
|
{.push warning[GcMem]: off, warning[Uninit]: off.}
|
||||||
{.push hints: off.}
|
{.push hints: off.}
|
||||||
|
|
||||||
|
proc `|` *(a, b: typedesc): typedesc {.magic: "TypeTrait", noSideEffect.}
|
||||||
|
## Constructs an `or` meta class
|
||||||
|
|
||||||
|
proc `or` *(a, b: typedesc): typedesc {.magic: "TypeTrait", noSideEffect.}
|
||||||
|
## Constructs an `or` meta class
|
||||||
|
|
||||||
|
proc `and` *(a, b: typedesc): typedesc {.magic: "TypeTrait", noSideEffect.}
|
||||||
|
## Constructs an `and` meta class
|
||||||
|
|
||||||
|
proc `not` *(a: typedesc): typedesc {.magic: "TypeTrait", noSideEffect.}
|
||||||
|
## Constructs an `not` meta class
|
||||||
|
|
||||||
type
|
type
|
||||||
Ordinal* {.magic: Ordinal.}[T] ## Generic ordinal type. Includes integer,
|
Ordinal* {.magic: Ordinal.}[T] ## Generic ordinal type. Includes integer,
|
||||||
## bool, character, and enumeration types
|
## bool, character, and enumeration types
|
||||||
|
|
@ -66,11 +81,11 @@ type
|
||||||
`ref`* {.magic: Pointer.}[T] ## built-in generic traced pointer type
|
`ref`* {.magic: Pointer.}[T] ## built-in generic traced pointer type
|
||||||
|
|
||||||
`nil` {.magic: "Nil".}
|
`nil` {.magic: "Nil".}
|
||||||
|
|
||||||
expr* {.magic: Expr, deprecated.} ## meta type to denote an expression (for templates)
|
expr* {.magic: Expr, deprecated.} ## meta type to denote an expression (for templates)
|
||||||
## **Deprecated** since version 0.15. Use ``untyped`` instead.
|
## **Deprecated** since version 0.15. Use ``untyped`` instead.
|
||||||
stmt* {.magic: Stmt, deprecated.} ## meta type to denote a statement (for templates)
|
stmt* {.magic: Stmt, deprecated.} ## meta type to denote a statement (for templates)
|
||||||
## **Deprecated** since version 0.15. Use ``typed`` instead.
|
## **Deprecated** since version 0.15. Use ``typed`` instead.
|
||||||
typedesc* {.magic: TypeDesc.} ## meta type to denote a type description
|
|
||||||
void* {.magic: "VoidType".} ## meta type to denote the absence of any type
|
void* {.magic: "VoidType".} ## meta type to denote the absence of any type
|
||||||
auto* {.magic: Expr.} ## meta type for automatic type determination
|
auto* {.magic: Expr.} ## meta type for automatic type determination
|
||||||
any* = distinct auto ## meta type for any supported type
|
any* = distinct auto ## meta type for any supported type
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue