mirror of
https://github.com/nim-lang/Nim.git
synced 2025-12-29 01:14:41 +00:00
merge macros tests (#9367)
This commit is contained in:
@@ -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()
|
||||
@@ -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
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -1,13 +0,0 @@
|
||||
discard """
|
||||
output: '''x = 10
|
||||
x + y = 30
|
||||
'''
|
||||
"""
|
||||
|
||||
import future
|
||||
|
||||
let
|
||||
x = 10
|
||||
y = 20
|
||||
dump x
|
||||
dump(x + y)
|
||||
@@ -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
|
||||
@@ -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()
|
||||
@@ -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>
|
||||
"""
|
||||
@@ -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
241
tests/macros/tissues.nim
Normal 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)
|
||||
@@ -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"
|
||||
@@ -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
|
||||
@@ -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
111
tests/macros/tvarious.nim
Normal 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)
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user