Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

lenVarargs: number of varargs elements #12907

Merged
merged 7 commits into from
Dec 23, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions lib/system.nim
Original file line number Diff line number Diff line change
Expand Up @@ -4198,6 +4198,11 @@ type
NimNode* {.magic: "PNimrodNode".} = ref NimNodeObj
## Represents a Nim AST node. Macros operate on this type.

macro lenVarargs*(x: varargs[untyped]): int {.since: (1, 1).} =
## returns number of variadic arguments in `x`
proc lenVarargsImpl(x: NimNode): NimNode {.magic: "LengthOpenArray", noSideEffect.}
lenVarargsImpl(x)

when false:
template eval*(blk: typed): typed =
## Executes a block of code at compile time just as if it was a macro.
Expand Down
59 changes: 59 additions & 0 deletions tests/system/tlenvarargs.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
discard """
output: '''
tlenvarargs.nim:35:9 (1, 2)
tlenvarargs.nim:36:9 12
tlenvarargs.nim:37:9 1
tlenvarargs.nim:38:8
done
'''
"""
## line 10

template myecho*(a: varargs[untyped]) =
## shows a useful debugging echo-like proc that is dependency-free (no dependency
## on macros.nim) so can be used in more contexts
const info = instantiationInfo(-1, false)
const loc = info.filename & ":" & $info.line & ":" & $info.column & " "
when lenVarargs(a) > 0:
echo(loc, a)
else:
echo(loc)

template fun*(a: varargs[untyped]): untyped =
lenVarargs(a)

template fun2*(a: varargs[typed]): untyped =
a.lenVarargs

template fun3*(a: varargs[int]): untyped =
a.lenVarargs

template fun4*(a: varargs[untyped]): untyped =
len(a)

proc main()=
myecho (1, 2)
myecho 1, 2
myecho 1
myecho()

doAssert fun() == 0
doAssert fun('a') == 1
doAssert fun("asdf", 1) == 2

doAssert fun2() == 0
doAssert fun2('a') == 1
doAssert fun2("asdf", 1) == 2

doAssert fun3() == 0
doAssert fun3(10) == 1
doAssert fun3(10, 11) == 2

## shows why `lenVarargs` can't be named `len`
doAssert fun4("abcdef") == len("abcdef")

## workaround for BUG:D20191218T171447 whereby if testament expected output ends
## in space, testament strips it from expected output but not actual output,
## which leads to a mismatch when running test via megatest
echo "done"
main()