Allow void macro result (#11286)
* allow void macro result * add test for void macro result type
This commit is contained in:
parent
68b5e3e3fe
commit
f94ec363ab
25 changed files with 143 additions and 60 deletions
|
|
@ -32,7 +32,7 @@ proc foo(): seq[NimNode] {.compiletime.} =
|
|||
result.add test()
|
||||
result.add parseExpr("echo(5+56)")
|
||||
|
||||
macro bar(): typed =
|
||||
macro bar() =
|
||||
result = newNimNode(nnkStmtList)
|
||||
let x = foo()
|
||||
for xx in x:
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ proc symToIdent(x: NimNode): NimNode =
|
|||
result.add symToIdent(c)
|
||||
|
||||
# check getTypeInst and getTypeImpl for given symbol x
|
||||
macro testX(x,inst0: typed; recurse: static[bool]; implX: typed): typed =
|
||||
macro testX(x,inst0: typed; recurse: static[bool]; implX: typed) =
|
||||
# check that getTypeInst(x) equals inst0
|
||||
let inst = x.getTypeInst
|
||||
let instr = inst.symToIdent.treeRepr
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ macro importImpl_forward(name, returns: untyped): untyped =
|
|||
decls.add res
|
||||
echo(repr(res))
|
||||
|
||||
macro importImpl(name, returns, body: untyped): typed =
|
||||
macro importImpl(name, returns, body: untyped) =
|
||||
#var res = getAST(importImpl_forward(name, returns))
|
||||
discard getAST(importImpl_forward(name, returns))
|
||||
var res = copyNimTree(decls[decls.high])
|
||||
|
|
@ -46,7 +46,7 @@ macro importImpl(name, returns, body: untyped): typed =
|
|||
echo repr(res)
|
||||
impls.add res
|
||||
|
||||
macro okayy: typed =
|
||||
macro okayy() =
|
||||
result = newNimNode(nnkStmtList)
|
||||
for node in decls: result.add node
|
||||
for node in impls: result.add node
|
||||
|
|
|
|||
75
tests/macros/tmacro6.nim
Normal file
75
tests/macros/tmacro6.nim
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
discard """
|
||||
errormsg: "expression '123' is of type 'int literal(123)' and has to be discarded"
|
||||
line: 71
|
||||
"""
|
||||
|
||||
import macros
|
||||
|
||||
proc foo(a,b,c: int): int =
|
||||
result += a
|
||||
result += b
|
||||
result += c
|
||||
|
||||
macro bar(a,b,c: int): int =
|
||||
result = newCall(ident"echo")
|
||||
result.add a
|
||||
result.add b
|
||||
result.add c
|
||||
|
||||
macro baz(a,b,c: int): int =
|
||||
let stmt = nnkStmtListExpr.newTree()
|
||||
stmt.add newCall(ident"echo", a)
|
||||
stmt.add newCall(ident"echo", b)
|
||||
stmt.add newCall(ident"echo", c)
|
||||
stmt.add newLit(123)
|
||||
return c
|
||||
|
||||
# test no result type with explicit return
|
||||
|
||||
macro baz2(a,b,c: int) =
|
||||
let stmt = nnkStmtListExpr.newTree()
|
||||
stmt.add newCall(ident"echo", a)
|
||||
stmt.add newCall(ident"echo", b)
|
||||
stmt.add newCall(ident"echo", c)
|
||||
return stmt
|
||||
|
||||
# test explicit void type with explicit return
|
||||
|
||||
macro baz3(a,b,c: int): void =
|
||||
let stmt = nnkStmtListExpr.newTree()
|
||||
stmt.add newCall(ident"echo", a)
|
||||
stmt.add newCall(ident"echo", b)
|
||||
stmt.add newCall(ident"echo", c)
|
||||
return stmt
|
||||
|
||||
# test no result type with result variable
|
||||
|
||||
macro baz4(a,b,c: int) =
|
||||
result = nnkStmtListExpr.newTree()
|
||||
result.add newCall(ident"echo", a)
|
||||
result.add newCall(ident"echo", b)
|
||||
result.add newCall(ident"echo", c)
|
||||
|
||||
# test explicit void type with result variable
|
||||
|
||||
macro baz5(a,b,c: int): void =
|
||||
let result = nnkStmtListExpr.newTree()
|
||||
result.add newCall(ident"echo", a)
|
||||
result.add newCall(ident"echo", b)
|
||||
result.add newCall(ident"echo", c)
|
||||
|
||||
macro foobar1(): int =
|
||||
result = quote do:
|
||||
echo "Hello World"
|
||||
1337
|
||||
|
||||
echo foobar1()
|
||||
|
||||
# this should create an error message, because 123 has to be discarded.
|
||||
|
||||
macro foobar2() =
|
||||
result = quote do:
|
||||
echo "Hello World"
|
||||
123
|
||||
|
||||
echo foobar2()
|
||||
|
|
@ -18,15 +18,16 @@ case_token: inc i
|
|||
|
||||
#bug #488
|
||||
|
||||
macro foo: typed =
|
||||
macro foo() =
|
||||
var exp = newCall("whatwhat", newIntLitNode(1))
|
||||
if compiles(getAst(exp)): return exp
|
||||
if compiles(getAst(exp)):
|
||||
return exp
|
||||
else: echo "Does not compute! (test OK)"
|
||||
|
||||
foo()
|
||||
|
||||
#------------------------------------
|
||||
# bug #8287
|
||||
# bug #8287
|
||||
type MyString = distinct string
|
||||
|
||||
proc `$` (c: MyString): string {.borrow.}
|
||||
|
|
@ -37,7 +38,7 @@ proc `!!` (c: cstring): int =
|
|||
proc f(name: MyString): int =
|
||||
!! $ name
|
||||
|
||||
macro repr_and_parse(fn: typed): typed =
|
||||
macro repr_and_parse(fn: typed) =
|
||||
let fn_impl = fn.getImpl
|
||||
fn_impl.name = genSym(nskProc, $fn_impl.name)
|
||||
echo fn_impl.repr
|
||||
|
|
@ -51,7 +52,7 @@ repr_and_parse(f)
|
|||
|
||||
|
||||
#------------------------------------
|
||||
# bugs #8343 and #8344
|
||||
# bugs #8343 and #8344
|
||||
proc one_if_proc(x, y : int): int =
|
||||
if x < y: result = x
|
||||
else: result = y
|
||||
|
|
@ -76,7 +77,7 @@ proc test_cond_stmtlist(x, y: int): int =
|
|||
|
||||
#------------------------------------
|
||||
# bug #8762
|
||||
proc t2(a, b: int): int =
|
||||
proc t2(a, b: int): int =
|
||||
`+`(a, b)
|
||||
|
||||
|
||||
|
|
@ -92,23 +93,23 @@ proc fn2(x, y: float): float =
|
|||
proc fn3(x, y: int): bool =
|
||||
(((x and 3) div 4) or (x mod (y xor -1))) == 0 or y notin [1,2]
|
||||
|
||||
proc fn4(x: int): int =
|
||||
proc fn4(x: int): int =
|
||||
if x mod 2 == 0: return x + 2
|
||||
else: return 0
|
||||
|
||||
#------------------------------------
|
||||
# bug #10807
|
||||
proc fn_unsafeaddr(x: int): int =
|
||||
proc fn_unsafeaddr(x: int): int =
|
||||
cast[int](unsafeAddr(x))
|
||||
|
||||
static:
|
||||
echo fn_unsafeaddr.repr_to_string
|
||||
echo fn_unsafeaddr.repr_to_string
|
||||
let fn1s = "proc fn1(x, y: int): int =\n result = 2 * (x + y)\n"
|
||||
let fn2s = "proc fn2(x, y: float): float =\n result = (y + 2 * x) / (x - y)\n"
|
||||
let fn3s = "proc fn3(x, y: int): bool =\n result = ((x and 3) div 4 or x mod (y xor -1)) == 0 or not contains([1, 2], y)\n"
|
||||
let fn4s = "proc fn4(x: int): int =\n if x mod 2 == 0:\n return x + 2\n else:\n return 0\n"
|
||||
let fnAddr = "proc fn_unsafeaddr(x: int): int =\n result = cast[int](unsafeAddr(x))\n"
|
||||
|
||||
|
||||
doAssert fn1.repr_to_string == fn1s
|
||||
doAssert fn2.repr_to_string == fn2s
|
||||
doAssert fn3.repr_to_string == fn3s
|
||||
|
|
@ -134,4 +135,3 @@ repr_and_parse(test_block)
|
|||
repr_and_parse(test_cond_stmtlist)
|
||||
repr_and_parse(t2)
|
||||
repr_and_parse(test_pure_enums)
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue