Re: What's wrong with this simple macro?
@dawkot To put it simply, what Araq says is: in the first case, the macro operates directly on procA at compile time so it behaves as expected but in the second case, it actually operates on p argument (which has no implementation as it's not an actual procedure, therefore its implementation is nil) and then you provide procA as a value of p argument at runtime. But what was done at compile time remains the same so the runtime argument passing is irrelevant. What you need is a template, as templates' arguments are passed at compile time rather than runtime: import macros macro procImplRepr(p: proc): string = p.symbol.getImpl.repr proc procA = discard template procB(p: proc): string = p.procImplRepr echo procA.procImplRepr echo procB(procA) # both print the same value
Re: Macros: How to parse a string and get the type of the expression?
@Jehan The fact that an arbitrary string is ambiguous without a context is probably the reason a context is passed as a separate parameter in Rust macros, I guess. I sometimes miss that possibility in Nim, it would makes tricks unnecessary and macros would be less of magic, I guess.
Re: Can I somehow show context-specific information in an {.error.} ?
Mmh there is an error proc in macros that I _think_ does that: [https://nim-lang.org/docs/macros.html#error,string,NimNode](https://nim-lang.org/docs/macros.html#error,string,NimNode)
Re: Can I tell Nim to NOT use *reference* for a var parameter?
@Araq Here is a minimal example. This is compiled with "vcc". It compiles to C, but not to C++. type VolatilePtr*[T] = distinct ptr T proc toVolatilePtr*[T](t: var T): VolatilePtr[T] = cast[VolatilePtr[T]](addr t) # Pretend we're actually checking it's volatile, which is apparently not possible to do. var my_vbyte {.volatile.}: byte = 42'u8 var my_vbyte_ptr = toVolatilePtr[byte](my_vbyte) type AtomType* = SomeNumber|pointer|ptr|char|bool when defined(cpp): proc interlockedOr8(p: pointer; value: int8): int8 {.importcpp: "_InterlockedOr8(static_cast(#), #)", header: "".} else: proc interlockedOr8(p: pointer; value: int8): int8 {.importc: "_InterlockedOr8", header: "".} proc atomicLoadFull*[T: AtomType](p: VolatilePtr[T]): T {.inline.} = let pp = cast[pointer](p) when sizeof(T) == 1: cast[T](interlockedOr8(pp, 0'i8)) else: # TODO, sizeof(T) == (2|4|8) static: assert(false, "invalid parameter size: " & $sizeof(T)) assert(atomicLoadFull(my_vbyte_ptr) == 42'u8) src\nimcache\abc_volatile2.cpp(306): error C2664: 'NU8 *toVolatilePtr_EP8VL8ilqAQ1Zz9bJAA4rwQ(NU8 &)': cannot convert argument 1 from 'volatile NU8' to 'NU8 &' src\nimcache\abc_volatile2.cpp(306): note: Conversion loses qualifiers I've had the issue that the error doesn't always come, if I don't delete the nimcache, but I think it's caused by VS Code compiling automatically as well, using a different configuration.
Re: Can I somehow show context-specific information in an {.error.} ?
@stisa Actually, I meant "when sizeof(T) == 1" rather than "if sizeof(T) == 1" (now corrected). But the problem is, that in the real code I want to support multiple paramter sizes, and get a compile time error if the size is unexpected. The example you gave me compiles, but fails at runtime. OTOH, this led me to find that I can has static asserts (static: assert(false, "invalid parameter size: " & $sizeof(T))), and that does the trick. Still, it would be nice if the error pragma supported that too.
Re: nim-lang ui not working with vcc on windows
I have the solution. It was a silly mistake. I had placed libui library at the wrong place. Thanks for the response.
Re: Can I somehow show context-specific information in an {.error.} ?
You can use asserts: let b: byte = 42'u8 let c = 42'u16 proc test*[T](t: T): bool = assert(sizeof(T) == 1, "invalid parameter size: " & $sizeof(T)) result = true echo test(b) echo test(c)
Can I somehow show context-specific information in an {.error.} ?
I'm trying to debug a compilation problem: the generic parameter of a proc doesn't seem to match my expectation, so I'd like to write something like this: let b: byte = 42'u8 proc test*[T](t: T): bool = if sizeof(T) == 1: result = true # ... else: {.error: "invalid parameter size: " & $sizeof(T).} test(b) But the compiler returns this: Error: invalid pragma: error: "invalid parameter size: " & $ sizeof(T) I tried searching in the Nim codebase, but found no example. So is it impossible? find . -name "*.nim" | xargs fgrep "{.error"
Re: Arraymancer - A n-dimensional array / tensor library
@mratsim Would you mind if I make a reference to your lib in my bachelor thesis about optimization?
Re: nim-lang ui not working with vcc on windows
To which folder did u copy the libui.h file? I have cloned the libui from git completely into my repository and it exists in the UI folder.