added system.typeof operation; fixes #9093
This commit is contained in:
parent
e7e75224a2
commit
963292f725
5 changed files with 47 additions and 4 deletions
|
|
@ -27,6 +27,9 @@
|
||||||
|
|
||||||
- Added `or` for `NimNode` in `macros`.
|
- Added `or` for `NimNode` in `macros`.
|
||||||
|
|
||||||
|
- Added `system.typeof` for more control over how `type` expressions
|
||||||
|
can be deduced.
|
||||||
|
|
||||||
### Library changes
|
### Library changes
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -84,6 +84,7 @@ proc initDefines*(symbols: StringTableRef) =
|
||||||
defineSymbol("nimNoNilSeqs2")
|
defineSymbol("nimNoNilSeqs2")
|
||||||
defineSymbol("nimHasUserErrors")
|
defineSymbol("nimHasUserErrors")
|
||||||
defineSymbol("nimUncheckedArrayTyp")
|
defineSymbol("nimUncheckedArrayTyp")
|
||||||
|
defineSymbol("nimHasTypeof")
|
||||||
|
|
||||||
defineSymbol("nimHasNilSeqs")
|
defineSymbol("nimHasNilSeqs")
|
||||||
for f in low(Feature)..high(Feature):
|
for f in low(Feature)..high(Feature):
|
||||||
|
|
|
||||||
|
|
@ -1414,6 +1414,20 @@ proc semTypeof(c: PContext; n: PNode; prev: PType): PType =
|
||||||
fixupTypeOf(c, prev, t)
|
fixupTypeOf(c, prev, t)
|
||||||
result = t.typ
|
result = t.typ
|
||||||
|
|
||||||
|
proc semTypeof2(c: PContext; n: PNode; prev: PType): PType =
|
||||||
|
openScope(c)
|
||||||
|
var m = BiggestInt 1 # typeOfIter
|
||||||
|
if n.len == 3:
|
||||||
|
let mode = semConstExpr(c, n[2])
|
||||||
|
if mode.kind != nkIntLit:
|
||||||
|
localError(c.config, n.info, "typeof: cannot evaluate 'mode' parameter at compile-time")
|
||||||
|
else:
|
||||||
|
m = mode.intVal
|
||||||
|
let t = semExprWithType(c, n[1], if m == 1: {efInTypeof} else: {})
|
||||||
|
closeScope(c)
|
||||||
|
fixupTypeOf(c, prev, t)
|
||||||
|
result = t.typ
|
||||||
|
|
||||||
proc semTypeNode(c: PContext, n: PNode, prev: PType): PType =
|
proc semTypeNode(c: PContext, n: PNode, prev: PType): PType =
|
||||||
result = nil
|
result = nil
|
||||||
inc c.inTypeContext
|
inc c.inTypeContext
|
||||||
|
|
@ -1494,6 +1508,8 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType =
|
||||||
elif op.id == ord(wType):
|
elif op.id == ord(wType):
|
||||||
checkSonsLen(n, 2, c.config)
|
checkSonsLen(n, 2, c.config)
|
||||||
result = semTypeof(c, n[1], prev)
|
result = semTypeof(c, n[1], prev)
|
||||||
|
elif op.s == "typeof" and n[0].kind == nkSym and n[0].sym.magic == mTypeof:
|
||||||
|
result = semTypeOf2(c, n, prev)
|
||||||
else:
|
else:
|
||||||
if c.inGenericContext > 0 and n.kind == nkCall:
|
if c.inGenericContext > 0 and n.kind == nkCall:
|
||||||
result = makeTypeFromExpr(c, n.copyTree)
|
result = makeTypeFromExpr(c, n.copyTree)
|
||||||
|
|
|
||||||
|
|
@ -673,6 +673,12 @@ template mapIt*(s: typed, op: untyped): untyped =
|
||||||
## nums = @[1, 2, 3, 4]
|
## nums = @[1, 2, 3, 4]
|
||||||
## strings = nums.mapIt($(4 * it))
|
## strings = nums.mapIt($(4 * it))
|
||||||
## assert strings == @["4", "8", "12", "16"]
|
## assert strings == @["4", "8", "12", "16"]
|
||||||
|
when defined(nimHasTypeof):
|
||||||
|
type outType = typeof((
|
||||||
|
block:
|
||||||
|
var it{.inject.}: typeof(items(s), typeOfIter);
|
||||||
|
op), typeOfProc)
|
||||||
|
else:
|
||||||
type outType = type((
|
type outType = type((
|
||||||
block:
|
block:
|
||||||
var it{.inject.}: type(items(s));
|
var it{.inject.}: type(items(s));
|
||||||
|
|
@ -1135,5 +1141,13 @@ when isMainModule:
|
||||||
A, B
|
A, B
|
||||||
doAssert mapIt(X, $it) == @["A", "B"]
|
doAssert mapIt(X, $it) == @["A", "B"]
|
||||||
|
|
||||||
|
block:
|
||||||
|
# bug #9093
|
||||||
|
let inp = "a:b,c:d"
|
||||||
|
|
||||||
|
let outp = inp.split(",").mapIt(it.split(":"))
|
||||||
|
doAssert outp == @[@["a", "b"], @["c", "d"]]
|
||||||
|
|
||||||
|
|
||||||
when not defined(testing):
|
when not defined(testing):
|
||||||
echo "Finished doc tests"
|
echo "Finished doc tests"
|
||||||
|
|
|
||||||
|
|
@ -180,6 +180,15 @@ else:
|
||||||
## Cannot be overloaded.
|
## Cannot be overloaded.
|
||||||
discard
|
discard
|
||||||
|
|
||||||
|
when defined(nimHasTypeof):
|
||||||
|
type
|
||||||
|
TypeOfMode* = enum ## Possible modes of `typeof`.
|
||||||
|
typeOfProc, ## Prefer the interpretation that means `x` is a proc call.
|
||||||
|
typeOfIter ## Prefer the interpretation that means `x` is an iterator call.
|
||||||
|
proc typeof*(x: untyped; mode = typeOfIter): typeDesc {.magic: "TypeOf", noSideEffect, compileTime.} =
|
||||||
|
## Builtin 'typeof' operation for accessing the type of an expression. Since version 0.20.0.
|
||||||
|
discard
|
||||||
|
|
||||||
proc `not`*(x: bool): bool {.magic: "Not", noSideEffect.}
|
proc `not`*(x: bool): bool {.magic: "Not", noSideEffect.}
|
||||||
## Boolean not; returns true iff ``x == false``.
|
## Boolean not; returns true iff ``x == false``.
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue