mirror of
https://github.com/nim-lang/Nim.git
synced 2026-06-08 21:04:20 +00:00
Fix forward declarations in shadow scope contexts (#15386)
* Fix forward declarations in shadow scope contexts * Add testcase for #15385 * Less empty lines * Fix tests * Inline isShadowScope * Add original testcase (with reduced amount of iterations) * Add testcase without forward decl
This commit is contained in:
@@ -39,6 +39,7 @@ true
|
||||
false
|
||||
true
|
||||
false
|
||||
1.0
|
||||
'''
|
||||
"""
|
||||
|
||||
@@ -403,3 +404,79 @@ testEvenOdd5()
|
||||
# it works, because the forward decl and definition share the symbol and the compiler is forgiving here
|
||||
#testEvenOdd6() #Don't test it though, the compiler may become more strict in the future
|
||||
|
||||
# bug #15385
|
||||
var captured_funcs {.compileTime.}: seq[NimNode] = @[]
|
||||
|
||||
macro aad*(fns: varargs[typed]): typed =
|
||||
result = newStmtList()
|
||||
for fn in fns:
|
||||
captured_funcs.add fn[0]
|
||||
result.add fn
|
||||
|
||||
func exp*(x: float): float ## get different error if you remove forward declaration
|
||||
|
||||
func exp*(x: float): float {.aad.} =
|
||||
var x1 = min(max(x, -708.4), 709.8)
|
||||
var result: float ## looks weird because it is taken from template expansion
|
||||
result = x1 + 1.0
|
||||
result
|
||||
|
||||
template check_accuracy(f: untyped, rng: Slice[float], n: int, verbose = false): auto =
|
||||
|
||||
proc check_accuracy: tuple[avg_ulp: float, max_ulp: int] {.gensym.} =
|
||||
let k = (rng.b - rng.a) / (float) n
|
||||
var
|
||||
res, x: float
|
||||
i, max_ulp = 0
|
||||
avg_ulp = 0.0
|
||||
|
||||
x = rng.a
|
||||
while (i < n):
|
||||
res = f(x)
|
||||
i.inc
|
||||
x = x + 0.001
|
||||
(avg_ulp, max_ulp)
|
||||
check_accuracy()
|
||||
|
||||
discard check_accuracy(exp, -730.0..709.4, 4)
|
||||
|
||||
# And without forward decl
|
||||
macro aad2*(fns: varargs[typed]): typed =
|
||||
result = newStmtList()
|
||||
for fn in fns:
|
||||
captured_funcs.add fn[0]
|
||||
result.add fn
|
||||
|
||||
func exp2*(x: float): float {.aad2.} =
|
||||
var x1 = min(max(x, -708.4), 709.8)
|
||||
var result: float ## looks weird because it is taken from template expansion
|
||||
result = x1 + 1.0
|
||||
result
|
||||
|
||||
template check_accuracy2(f: untyped, rng: Slice[float], n: int, verbose = false): auto =
|
||||
|
||||
proc check_accuracy2: tuple[avg_ulp: float, max_ulp: int] {.gensym.} =
|
||||
let k = (rng.b - rng.a) / (float) n
|
||||
var
|
||||
res, x: float
|
||||
i, max_ulp = 0
|
||||
avg_ulp = 0.0
|
||||
|
||||
x = rng.a
|
||||
while (i < n):
|
||||
res = f(x)
|
||||
i.inc
|
||||
x = x + 0.001
|
||||
(avg_ulp, max_ulp)
|
||||
check_accuracy2()
|
||||
|
||||
discard check_accuracy2(exp2, -730.0..709.4, 4)
|
||||
|
||||
# And minimized:
|
||||
macro aadMin(fn: typed): typed = fn
|
||||
|
||||
func expMin: float
|
||||
|
||||
func expMin: float {.aadMin.} = 1
|
||||
|
||||
echo expMin()
|
||||
|
||||
Reference in New Issue
Block a user