merge macros tests (#9367)

This commit is contained in:
Miran
2018-10-14 17:08:42 +02:00
committed by narimiran
parent ae80f763b3
commit ee18699609
15 changed files with 352 additions and 333 deletions

View File

@@ -1,21 +0,0 @@
discard """
output: '''0
0
'''
"""
import macros
macro varargsLen(args:varargs[untyped]): untyped =
doAssert args.kind == nnkArglist
doAssert args.len == 0
result = newLit(args.len)
template bar(a0:varargs[untyped]): untyped =
varargsLen(a0)
template foo(x: int, a0:varargs[untyped]): untyped =
bar(a0)
echo foo(42)
echo bar()

View File

@@ -1,20 +0,0 @@
discard """
output: '''
range[0 .. 100]
array[0 .. 100, int]
'''
"""
import macros
type
Foo1 = range[0 .. 100]
Foo2 = array[0 .. 100, int]
macro get(T: typedesc): untyped =
# Get the X out of typedesc[X]
let tmp = getTypeImpl(T)
result = newStrLitNode(getTypeImpl(tmp[1]).repr)
echo Foo1.get
echo Foo2.get

View File

@@ -1,106 +0,0 @@
discard """
msg: '''a
s
d
f
TTaa
TTaa
TTaa
TTaa
true
true
nil
42
false
true'''
output: '''test
2'''
"""
type
Foo = object
s: char
iterator test2(f: string): Foo =
for i in f:
yield Foo(s: i)
macro test(): untyped =
for i in test2("asdf"):
echo i.s
test()
# bug 1297
import macros
type TType = tuple[s: string]
macro echotest(): untyped =
var t: TType
t.s = ""
t.s.add("test")
result = newCall(newIdentNode("echo"), newStrLitNode(t.s))
echotest()
# bug #1103
type
Td = tuple
a:string
b:int
proc get_data(d: Td) : string {.compileTime.} =
result = d.a # Works if a literal string is used here.
# Bugs if line A or B is active. Works with C
result &= "aa" # A
#result.add("aa") # B
#result = result & "aa" # C
macro m(s:static[Td]) : untyped =
echo get_data(s)
echo get_data(s)
result = newEmptyNode()
const s=("TT", 3)
m(s)
m(s)
# bug #933
proc nilcheck(): NimNode {.compileTime.} =
echo(result == nil) # true
echo(result.isNil) # true
echo(repr(result)) # nil
macro testnilcheck(): untyped =
result = newNimNode(nnkStmtList)
discard nilcheck()
testnilcheck()
# bug #1323
proc calc(): array[1, int] =
result[0].inc()
result[0].inc()
const c = calc()
echo c[0]
# bug #3046
macro sampleMacroInt(i: int): untyped =
echo i.intVal
macro sampleMacroBool(b: bool): untyped =
echo b.boolVal
sampleMacroInt(42)
sampleMacroBool(false)
sampleMacroBool(system.true)

View File

@@ -1,29 +0,0 @@
discard """
output: '''a[0]: 42
a[1]: 45
x: some string'''
"""
import macros
macro debug(n: varargs[untyped]): untyped =
# `n` is a Nim AST that contains the whole macro invocation
# this macro returns a list of statements:
result = newNimNode(nnkStmtList, n)
# iterate over any argument that is passed to this macro:
for i in 0..n.len-1:
# add a call to the statement list that writes the expression;
# `toStrLit` converts an AST to its string representation:
add(result, newCall("write", newIdentNode("stdout"), toStrLit(n[i])))
# add a call to the statement list that writes ": "
add(result, newCall("write", newIdentNode("stdout"), newStrLitNode(": ")))
# add a call to the statement list that writes the expressions value:
add(result, newCall("writeLine", newIdentNode("stdout"), n[i]))
var
a: array[0..10, int]
x = "some string"
a[0] = 42
a[1] = 45
debug(a[0], a[1], x)

View File

@@ -1,13 +0,0 @@
discard """
output: '''x = 10
x + y = 30
'''
"""
import future
let
x = 10
y = 20
dump x
dump(x + y)

View File

@@ -1,19 +0,0 @@
discard """
msg: '''
Infix
Ident !"=>"
Call
Ident !"name"
Ident !"a"
ExprColonExpr
Ident !"b"
Ident !"cint"
NilLit nil
'''
"""
import macros
macro def(x): untyped =
echo treeRepr(x)
def name(a, b:cint) => nil

View File

@@ -1,13 +0,0 @@
discard """
output: '''proc foo[T, N: static[int]]()
proc foo[T; N: static[int]]()'''
"""
import macros
macro test():string =
let expr0 = "proc foo[T, N: static[int]]()"
let expr1 = "proc foo[T; N: static[int]]()"
$toStrLit(parseExpr(expr0)) & "\n" & $toStrLit(parseExpr(expr1))
echo test()

View File

@@ -1,35 +0,0 @@
# bug #1140
import parseutils, macros
proc parse_until_symbol(node: NimNode, value: string, index: var int): bool {.compiletime.} =
var splitValue: string
var read = value.parseUntil(splitValue, '$', index)
# when false:
if false:
var identifier: string
read = value.parseWhile(identifier, {}, index)
node.add newCall("add", ident("result"), newCall("$", ident(identifier)))
if splitValue.len > 0:
node.insert node.len, newCall("add", ident("result"), newStrLitNode(splitValue))
proc parse_template(node: NimNode, value: string) {.compiletime.} =
var index = 0
while index < value.len and
parse_until_symbol(node, value, index): discard
macro tmpli*(body: untyped): typed =
result = newStmtList()
result.add parseExpr("result = \"\"")
result.parse_template body[1].strVal
proc actual: string = tmpli html"""
<p>Test!</p>
"""
proc another: string = tmpli html"""
<p>what</p>
"""

View File

@@ -1,19 +0,0 @@
discard """
output: "3 4"
"""
import macros
# Test compile-time state in same module
var gid {.compileTime.} = 3
macro genId(): int =
result = newIntLitNode(gid)
inc gid
proc Id1(): int {.compileTime.} = return genId()
proc Id2(): int {.compileTime.} = return genId()
echo Id1(), " ", Id2()

241
tests/macros/tissues.nim Normal file
View File

@@ -0,0 +1,241 @@
discard """
msg: '''
proc init(foo129050: int; bar129052: typedesc[int]): int =
foo129050
IntLit 5
proc (x: int): string => typeDesc[proc[string, int]]
proc (x: int): void => typeDesc[proc[void, int]]
proc (x: int) => typeDesc[proc[void, int]]
x => uncheckedArray[int]
a
s
d
f
TTaa
TTaa
TTaa
TTaa
true
true
nil
42
false
true
'''
output: '''
range[0 .. 100]
array[0 .. 100, int]
10
test
'''
"""
import macros, parseutils
block t7723:
macro foo1(): untyped =
result = newStmtList()
result.add quote do:
proc init(foo: int, bar: typedesc[int]): int =
foo
expandMacros:
foo1()
doAssert init(1, int) == 1
block t8706:
macro varargsLen(args:varargs[untyped]): untyped =
doAssert args.kind == nnkArglist
doAssert args.len == 0
result = newLit(args.len)
template bar(a0:varargs[untyped]): untyped =
varargsLen(a0)
template foo(x: int, a0:varargs[untyped]): untyped =
bar(a0)
doAssert foo(42) == 0
doAssert bar() == 0
block t9194:
type
Foo1 = range[0 .. 100]
Foo2 = array[0 .. 100, int]
macro get(T: typedesc): untyped =
# Get the X out of typedesc[X]
let tmp = getTypeImpl(T)
result = newStrLitNode(getTypeImpl(tmp[1]).repr)
echo Foo1.get
echo Foo2.get
block t1944:
template t(e: untyped): untyped =
macro m(eNode: untyped): untyped =
echo eNode.treeRepr
m e
t 5
block t926:
proc test(f: var NimNode) {.compileTime.} =
f = newNimNode(nnkStmtList)
f.add newCall(newIdentNode("echo"), newLit(10))
macro blah(prc: untyped): untyped =
result = prc
test(result)
proc test() {.blah.} =
echo 5
block t2211:
macro showType(t:typed): untyped =
let ty = t.getType
echo t.repr, " => ", ty.repr
showType(proc(x:int): string)
showType(proc(x:int): void)
showType(proc(x:int))
var x: UncheckedArray[int]
showType(x)
block t1140:
proc parse_until_symbol(node: NimNode, value: string, index: var int): bool {.compiletime.} =
var splitValue: string
var read = value.parseUntil(splitValue, '$', index)
# when false:
if false:
var identifier: string
read = value.parseWhile(identifier, {}, index)
node.add newCall("add", ident("result"), newCall("$", ident(identifier)))
if splitValue.len > 0:
node.insert node.len, newCall("add", ident("result"), newStrLitNode(splitValue))
proc parse_template(node: NimNode, value: string) {.compiletime.} =
var index = 0
while index < value.len and
parse_until_symbol(node, value, index): discard
macro tmpli(body: untyped): typed =
result = newStmtList()
result.add parseExpr("result = \"\"")
result.parse_template body[1].strVal
proc actual: string = tmpli html"""
<p>Test!</p>
"""
proc another: string = tmpli html"""
<p>what</p>
"""
block tbugs:
type
Foo = object
s: char
iterator test2(f: string): Foo =
for i in f:
yield Foo(s: i)
macro test(): untyped =
for i in test2("asdf"):
echo i.s
test()
# bug 1297
type TType = tuple[s: string]
macro echotest(): untyped =
var t: TType
t.s = ""
t.s.add("test")
result = newCall(newIdentNode("echo"), newStrLitNode(t.s))
echotest()
# bug #1103
type
Td = tuple
a:string
b:int
proc get_data(d: Td) : string {.compileTime.} =
result = d.a # Works if a literal string is used here.
# Bugs if line A or B is active. Works with C
result &= "aa" # A
#result.add("aa") # B
#result = result & "aa" # C
macro m(s:static[Td]) : untyped =
echo get_data(s)
echo get_data(s)
result = newEmptyNode()
const s = ("TT", 3)
m(s)
m(s)
# bug #933
proc nilcheck(): NimNode {.compileTime.} =
echo(result == nil) # true
echo(result.isNil) # true
echo(repr(result)) # nil
macro testnilcheck(): untyped =
result = newNimNode(nnkStmtList)
discard nilcheck()
testnilcheck()
# bug #1323
proc calc(): array[1, int] =
result[0].inc()
result[0].inc()
const c = calc()
doAssert c[0] == 2
# bug #3046
macro sampleMacroInt(i: int): untyped =
echo i.intVal
macro sampleMacroBool(b: bool): untyped =
echo b.boolVal
sampleMacroInt(42)
sampleMacroBool(false)
sampleMacroBool(system.true)

View File

@@ -1,15 +0,0 @@
import macros
macro match*(s: cstring|string; pos: int; sections: varargs[untyped]): untyped =
for sec in sections:
expectKind sec, nnkOfBranch
expectLen sec, 2
result = newStmtList()
when isMainModule:
var input = "the input"
var pos = 0
match input, pos:
of r"[a-zA-Z_]\w+": echo "an identifier"
of r"\d+": echo "an integer"
of r".": echo "something else"

View File

@@ -1,14 +0,0 @@
# issue #5617, feature request
# Ability to set a NimNode's lineinfo
import macros
type
Test = object
macro mixer(n: typed): untyped =
let x = newIdentNode("echo")
x.copyLineInfo(n)
result = newLit(x.lineInfo == n.lineInfo)
var z = mixer(Test)
doAssert z

View File

@@ -1,10 +0,0 @@
# bug #1944
import macros
template t(e: untyped): untyped =
macro m(eNode: untyped): untyped =
echo eNode.treeRepr
m e
t 5

111
tests/macros/tvarious.nim Normal file
View File

@@ -0,0 +1,111 @@
discard """
msg: '''
range[0 .. 100]
array[0 .. 100, int]
10
test
'''
output: '''
x = 10
x + y = 30
proc foo[T, N: static[int]]()
proc foo[T; N: static[int]]()
a[0]: 42
a[1]: 45
x: some string
'''
"""
import macros, sugar
block tdump:
let
x = 10
y = 20
dump x
dump(x + y)
block texprcolonexpr:
macro def(x): untyped =
echo treeRepr(x)
def name(a, b:cint) => nil
block tgenericparams:
macro test():string =
let expr0 = "proc foo[T, N: static[int]]()"
let expr1 = "proc foo[T; N: static[int]]()"
$toStrLit(parseExpr(expr0)) & "\n" & $toStrLit(parseExpr(expr1))
echo test()
block tidgen:
# Test compile-time state in same module
var gid {.compileTime.} = 3
macro genId(): int =
result = newIntLitNode(gid)
inc gid
proc Id1(): int {.compileTime.} = return genId()
proc Id2(): int {.compileTime.} = return genId()
doAssert Id1() == 3
doAssert Id2() == 4
block tlexerex:
macro match(s: cstring|string; pos: int; sections: varargs[untyped]): untyped =
for sec in sections:
expectKind sec, nnkOfBranch
expectLen sec, 2
result = newStmtList()
var input = "the input"
var pos = 0
match input, pos:
of r"[a-zA-Z_]\w+": echo "an identifier"
of r"\d+": echo "an integer"
of r".": echo "something else"
block tlineinfo:
# issue #5617, feature request
type Test = object
macro mixer(n: typed): untyped =
let x = newIdentNode("echo")
x.copyLineInfo(n)
result = newLit(x.lineInfo == n.lineInfo)
var z = mixer(Test)
doAssert z
block tdebugstmt:
macro debug(n: varargs[untyped]): untyped =
result = newNimNode(nnkStmtList, n)
for i in 0..n.len-1:
add(result, newCall("write", newIdentNode("stdout"), toStrLit(n[i])))
add(result, newCall("write", newIdentNode("stdout"), newStrLitNode(": ")))
add(result, newCall("writeLine", newIdentNode("stdout"), n[i]))
var
a: array[0..10, int]
x = "some string"
a[0] = 42
a[1] = 45
debug(a[0], a[1], x)

View File

@@ -1,19 +0,0 @@
discard """
output: 10
"""
#bug #926
import macros
proc test(f: var NimNode) {.compileTime.} =
f = newNimNode(nnkStmtList)
f.add newCall(newIdentNode("echo"), newLit(10))
macro blah(prc: untyped): untyped =
result = prc
test(result)
proc test() {.blah.} =
echo 5