From 04b16fded342cc006390d95c7c856c7c20a32cf4 Mon Sep 17 00:00:00 2001 From: Timothee Cour Date: Mon, 16 Dec 2019 02:24:37 +0000 Subject: [PATCH 1/7] lenVarargs: number of varargs elements --- lib/system.nim | 6 ++++ tests/system/tlenvarargs.nim | 55 ++++++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+) create mode 100644 tests/system/tlenvarargs.nim diff --git a/lib/system.nim b/lib/system.nim index 05029b9d75082..efe038f89620e 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -4198,6 +4198,12 @@ type NimNode* {.magic: "PNimrodNode".} = ref NimNodeObj ## Represents a Nim AST node. Macros operate on this type. +proc lenVarargsImpl(x: NimNode): NimNode {.magic: "LengthOpenArray", noSideEffect.} + +macro lenVarargs*(x: varargs[untyped]): int {.magic: "LengthOpenArray", noSideEffect.} = + ## returns number of variadic arguments in `x` + lenVarargsImpl(x) + when false: template eval*(blk: typed): typed = ## Executes a block of code at compile time just as if it was a macro. diff --git a/tests/system/tlenvarargs.nim b/tests/system/tlenvarargs.nim new file mode 100644 index 0000000000000..c3025506fa0ed --- /dev/null +++ b/tests/system/tlenvarargs.nim @@ -0,0 +1,55 @@ +discard """ + output: ''' +tlenvarargs.nim:35:9 (1, 2) +tlenvarargs.nim:36:9 12 +tlenvarargs.nim:37:9 1 +tlenvarargs.nim:38:8''' +""" + + +## 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") + +main() From 067328604a71dae100bde0b306097812631c42fe Mon Sep 17 00:00:00 2001 From: Timothee Cour Date: Mon, 16 Dec 2019 03:35:54 +0000 Subject: [PATCH 2/7] tlenvarargs.nim: workaround #12908 --- tests/system/tlenvarargs.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/system/tlenvarargs.nim b/tests/system/tlenvarargs.nim index c3025506fa0ed..34c7066b83c7f 100644 --- a/tests/system/tlenvarargs.nim +++ b/tests/system/tlenvarargs.nim @@ -4,9 +4,9 @@ tlenvarargs.nim:35:9 (1, 2) tlenvarargs.nim:36:9 12 tlenvarargs.nim:37:9 1 tlenvarargs.nim:38:8''' + joinable: "false" """ - ## line 10 template myecho*(a: varargs[untyped]) = From 4648d3453247573908ef2779f3bd85ca268aacea Mon Sep 17 00:00:00 2001 From: Timothee Cour Date: Wed, 18 Dec 2019 08:39:52 +0000 Subject: [PATCH 3/7] fixup --- lib/system.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/system.nim b/lib/system.nim index efe038f89620e..004154ecd57cb 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -4200,7 +4200,7 @@ type proc lenVarargsImpl(x: NimNode): NimNode {.magic: "LengthOpenArray", noSideEffect.} -macro lenVarargs*(x: varargs[untyped]): int {.magic: "LengthOpenArray", noSideEffect.} = +macro lenVarargs*(x: varargs[untyped]): int = ## returns number of variadic arguments in `x` lenVarargsImpl(x) From 851f1f1b3bbde9e6bc2e7017c4dfd18eb251c2a5 Mon Sep 17 00:00:00 2001 From: Timothee Cour Date: Wed, 18 Dec 2019 17:19:45 +0000 Subject: [PATCH 4/7] workaround testament megatest BUG:D20191218T171447: make test joinable --- tests/system/tlenvarargs.nim | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/tests/system/tlenvarargs.nim b/tests/system/tlenvarargs.nim index 34c7066b83c7f..ca12c8171b652 100644 --- a/tests/system/tlenvarargs.nim +++ b/tests/system/tlenvarargs.nim @@ -3,10 +3,10 @@ discard """ tlenvarargs.nim:35:9 (1, 2) tlenvarargs.nim:36:9 12 tlenvarargs.nim:37:9 1 -tlenvarargs.nim:38:8''' - joinable: "false" +tlenvarargs.nim:38:8 +done +''' """ - ## line 10 template myecho*(a: varargs[untyped]) = @@ -52,4 +52,8 @@ proc main()= ## 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() From 682568583fe2126d5a2777a307932e30c5bd8308 Mon Sep 17 00:00:00 2001 From: Timothee Cour Date: Thu, 19 Dec 2019 22:51:01 +0100 Subject: [PATCH 5/7] fixup --- lib/system.nim | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/system.nim b/lib/system.nim index 004154ecd57cb..8e208ce0e50c5 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -4198,10 +4198,9 @@ type NimNode* {.magic: "PNimrodNode".} = ref NimNodeObj ## Represents a Nim AST node. Macros operate on this type. -proc lenVarargsImpl(x: NimNode): NimNode {.magic: "LengthOpenArray", noSideEffect.} - macro lenVarargs*(x: varargs[untyped]): int = ## returns number of variadic arguments in `x` + proc lenVarargsImpl(x: NimNode): NimNode {.magic: "LengthOpenArray", noSideEffect.} lenVarargsImpl(x) when false: From f371a43073a033c2097e357616851a31803b641a Mon Sep 17 00:00:00 2001 From: Timothee Cour Date: Sat, 21 Dec 2019 15:10:19 +0100 Subject: [PATCH 6/7] fixup --- lib/system.nim | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/lib/system.nim b/lib/system.nim index 8e208ce0e50c5..a0addd59a3694 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -4198,10 +4198,11 @@ type NimNode* {.magic: "PNimrodNode".} = ref NimNodeObj ## Represents a Nim AST node. Macros operate on this type. -macro lenVarargs*(x: varargs[untyped]): int = - ## returns number of variadic arguments in `x` - proc lenVarargsImpl(x: NimNode): NimNode {.magic: "LengthOpenArray", noSideEffect.} - lenVarargsImpl(x) +when (NimMajor, NimMinor) >= (1, 1): + macro lenVarargs*(x: varargs[untyped]): int = + ## returns number of variadic arguments in `x` + proc lenVarargsImpl(x: NimNode): NimNode {.magic: "LengthOpenArray", noSideEffect.} + lenVarargsImpl(x) when false: template eval*(blk: typed): typed = From c026df029bec7bd6cf06ac71f3d5a9c8e2c6e12c Mon Sep 17 00:00:00 2001 From: Timothee Cour Date: Sat, 21 Dec 2019 15:12:02 +0100 Subject: [PATCH 7/7] use since --- lib/system.nim | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/lib/system.nim b/lib/system.nim index a0addd59a3694..a1f94218eb100 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -4198,11 +4198,10 @@ type NimNode* {.magic: "PNimrodNode".} = ref NimNodeObj ## Represents a Nim AST node. Macros operate on this type. -when (NimMajor, NimMinor) >= (1, 1): - macro lenVarargs*(x: varargs[untyped]): int = - ## returns number of variadic arguments in `x` - proc lenVarargsImpl(x: NimNode): NimNode {.magic: "LengthOpenArray", noSideEffect.} - lenVarargsImpl(x) +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 =