Re: how to get unmodified / uninterpreted source code/AST of expression in macro?

2018-04-03 Thread rpowers
It works when the macro parameter is untyped, I guess constant folding happens 
during the typing process:


import macros

macro mylog(x:untyped): untyped =
result = newNimNode(nnkStmtList, x)
result.add(newCall("write", newIdentNode("stdout"), toStrLit(x)))
result.add(newCall("write", newIdentNode("stdout"), newStrLitNode(":")))
result.add(newCall("writeLine", newIdentNode("stdout"), x))

var x=1
mylog(x+1) # x + 1:2  (OK but I'd rather want exact source code with 
spacing eg: `x+1:2`)
mylog(1+1) # 2:2 (not OK, I want: 1+1: 2)



Re: a proc returning void creates 1 arg, not 0: breaking generic code

2018-03-29 Thread rpowers
Oh, right!  I guess it's testing it on untyped rather than the actual type in 
the macro. Anyways, this one is definitely working, it just tests for 
void-typed arguments:


import macros
import typetraits
import strformat

macro fun*(n: varargs[typed]): typed =
result = newNimNode(nnkStmtList, n)
var echoedCount = 0
for x in n:
if x.getTypeInst.typeKind != ntyVoid:
result.add(newCall("echo", x))
echoedCount += 1

result.add(newCall("echo", newStrLitNode($(echoedCount

proc bar() = echo "ok"

fun(1+1) # n.len=1
fun() # n.len=0
# comment this to make it work
fun(bar())



> isn't that a better behavior? if not what would be downsides of that?

No, I think automatically filtering void arguments in a macro is not a better 
or intuitive behavior. What if you remove a return type from a function and the 
compiler just silently starts ignoring it in argument lists instead of 
producing a type mismatch error? That seems like it could be an interesting 
source of bugs.

I guess what you're asking for is not SFINAE, but it feels similar -- it's a 
hack used to make template systems have some limited metaprogramming. I think 
that you'll find that sort of thing is not necessary with Nim, you can just 
write a macro that does what you want. Is there something specific that you're 
trying to do that requires the argument-ignoring approach used in D? Maybe we 
could help you come up with a good solution for it in Nim. 


Re: How to call a macro from a template with a constructed identifier argument?

2018-03-23 Thread rpowers
Thanks for the suggestions.

@mratsim I had no idea you could put a template inside a macro and get its 
evaluated AST. Cool! This will be very useful.

@Lando Interesting, I guess this works because quote doesn't touch the passed 
in backticked identifier and this is then returned intact to the template? 
Maybe I should treat identifiers-like NimNodes as more of a black box in the 
future to allow this sort of thing.


Re: How to call a macro from a template with a constructed identifier argument?

2018-03-22 Thread rpowers
Yes, that compiles, but the macro produces the code


let x = 1000


instead of the code


let xExtra = 1000


I'm trying to get the identifier to be constructed before passing it into the 
macro, but I'm not sure if that's possible.


How to call a macro from a template with a constructed identifier argument?

2018-03-21 Thread rpowers
I have a macro that creates a type and associated functions, and I'm calling 
that from a template. I want to use identifier construction to append a suffix 
to the template parameter, but the whole backticked AST (instead of the 
constructed identifier) gets passed in to the macro. Is there some way to 
generate an identifier before the macro is evaluated? I've included a 
simplified example below.


macro defthing(name: untyped): untyped =
return parseStmt("let $1 = 1000".format($name.ident))

template calldefthing(name: untyped): untyped {.dirty.} =
defthing name # argument is an identifier
defthing `name Extra` # argument is not an identifier, I'd like to 
evaluate the `name Extra` before the macro is called

calldefthing x



Re: Emscripten/WebAssembly GC considerations?

2018-03-20 Thread rpowers
@yglukhov Thanks, that makes sense, I can just call GC_step at the start of 
each emscripten_set_main_loop callback. By the way, thanks for writing jsbind, 
it has been very helpful! 

@mashingan I copied most of the nim.cfg from here: 
[https://forum.nim-lang.org/t/2991](https://forum.nim-lang.org/t/2991). Then 
follow the Emscripten installation instructions: 
[https://kripken.github.io/emscripten-site/docs/getting_started/downloads.html](https://kripken.github.io/emscripten-site/docs/getting_started/downloads.html)
 (be sure to source ./emsdk_env.sh in the console before using the Nim 
compiler).

To compile, run something like nim c -d:emscripten -d:wasm -d:release 
-o:main-wasm.html main.nim and it will just.. work. If I have time, I'll put 
together a simple example repo.

FYI, I could only get it to work on Linux (or Windows Linux), the Windows 
command prompt had some issues.


Emscripten/WebAssembly GC considerations?

2018-03-19 Thread rpowers
I've been using Nim to generate WebAssembly using Emscripten and everything 
seems to be working very well. Are there any special considerations I should 
make for the GC? I know that it's impossible to scan the stack in WASM, but 
that shouldn't be much of a problem for Nim due to reference counting. However, 
cycle detection also has to run, which (I'm assuming) does need to scan the 
stack to find roots. Will that be called automatically? Or do I need to call it 
manually? I imagine I could occasionally call it on Emscripten's frame callback 
emscripten_set_main_loop when the Nim stack is basically empty.