-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Term rewriting macros: not working when declared inside template #7214
Comments
Note, changing "template" to macro solves the issue. I suppose the template replacement happens after the term-rewriting pass which is too late. |
I have a new use-case for scoped term-rewriting macro. I'm refactoring Arraymancer backend, by default the new backend assumes that all raw pointer accesses are aligned and hints the compiler as such with:
However when interfacing with external buffers that may not be aligned (Numpy) it is needed to not assume anything. Adding an However by having a term-rewriting scope, we could neatly recursively rewrite all operations in that scope to not assume they are aligned by default: import macros
proc unsafe_raw_data*(x: int, aligned: static bool = true): int {.inline.} =
when aligned:
echo "Aligned"
else:
echo "Unaligned"
macro raw_data_unaligned*(body: untyped): untyped =
## Within this code block, all raw data accesses will not be
## assumed aligned by default.
template rewrite_unsafe_raw_data{unsafe_raw_data(t)}(t): auto =
unsafe_raw_data(t, aligned = false)
body However, while I said that in the previous comment we could use macro instead of template to make the TRM works, once declared it "escapes" its block. Test case: proc addmod[T: SomeInteger](a, b, modulus: T): T {.noSideEffect.}=
## Modular addition
let a_m = if a < modulus: a
else: a mod modulus
if b == 0:
return a_m
let b_m = if b < modulus: b
else: b mod modulus
let b_from_m = modulus - b_m
if a_m >= b_from_m:
result = a_m - b_from_m
else:
result = modulus - b_from_m + a_m
## Notice the TRM in local scope
macro modular[T: SomeInteger](modulus: T, body: untyped): untyped =
block:
template trmAddMod{a + b}(a, b): auto =
addmod(a, b, 12)
body
proc main() =
let
a = 10
b = 3
modular(12):
let u = a + b
echo a + b # Unfortunately this is also rewritten
echo u
echo addmod(a,b,12)
echo u == addmod(a, b, 12)
main() |
… it's applied file-wide at the moment
This works
This doesn't
The text was updated successfully, but these errors were encountered: