Re: Procedure overloading with explicit parameters
I'm surprised noone answered OP's question so far. So going back: proc fac(0): int = 1 proc fac(n: int): int = n*fac(n-1) Run Since Nim is not a functional, but imperative language, you would use runtime flow control in this case: proc fac(n: int): int = if n == 0: 1 else: n * fac(n - 1) Run
Re: Compiling problem
Nim requires you to use consistent spacing around binary expressions. So you can do no spaces on both sides, `a+b`, one space, `a + b`, two spaces `a + b` but you can't do one space on the left and no spaces on the right, `a +b`. As people said, this is a quirk of the command syntax `someProc arg1, arg2`.
Re: Why does typechecking of generic procs only occur when used?
This is a side effect of how generics are implemented. I don't know the exact details, but an obvious implementation would be to just store the AST of the generic proc until it needs to be instantiated; later, when the proc is called, we know the generic params passed to the proc, so we can easily inject the passed params into the current scope as typedescs. You can imagine something like this happening: # our proc is this: proc f[T](a: T): T = result = a # the following statement might yield in this echo f[int](1) # because f[int] wasn't instantiated yet, we declare it. # keep in mind that this proc is not visible to the user. block: type T = int # the passed generic param, now as a typedesc # this proc actually gets semchecked, instead of the original generic proc proc f_int(a: T): T = result = a # the generic proc is "substituted" echo f_int(1) Run Keep in mind that the above explanation is an oversimplification. This was probably a sane design decision. Consider this example: proc add[T](a, b: T): T = a + b Run When the semchecker checks the proc, how does it know if what's done is legit? Some person may pass a seq here, which would obviously not work. Checking all the generic types, etc. right where the proc is declared would only add to the complexity of the compiler. Simply instantiating the proc when needed and checking it then is a much simpler and much faster approach.
Re: Practical examples showing how macros lead to better code?
[euwren](https://github.com/liquid600pgm/euwren) uses macros to create a DSL that allows its users to easily add scripting support to their programs. import euwren type Greeter = object target*: string proc newGreeter(target: string): Greeter = Greeter(target: target) proc greet(greeter: Greeter) = echo "Hello, " & greeter.target & "!" var wren = newWren() wren.foreign("greeter"): Greeter: [new] newGreeter greet wren.ready() Run Then, scripts like this can be executed using `wren.run(sourceCode)`: import "greeter" for Greeter var greeter = Greeter.new("world") greeter.greet() // -> Hello, world! greeter.target = "Nim" greeter.greet() // -> Hello, Nim! Run Because Wren is a C library, you'd normally have to deal with a low-level, verbose API full of passing pointers around and other unsafe things. euwren abstracts that away, and provides a much more user friendly API that doesn't require non-idiomatic code to be used. euwren's `foreign()` is a prime example of how macros can lead to cleaner and more maintainable code: reading a list of names is much easier than reading through a bunch of `addProc` and `addClass` calls with low level procs mixed inbetween. This makes every proc you bind consistently the same, no matter what it is, which embraces the DRY rule.
Re: euwren – a high-level wrapper for the Wren scripting language with a user-friendly DSL
I've been working on this project a lot, and I'm finally able to say it's (almost) feature complete. Since the last release, I have added things like: * name aliasing * enum support * automatic Wren glue code generation * exception handling and much more quality of life improvements. Feel free to check out the [changelog](https://github.com/liquid600pgm/euwren/releases).
Re: euwren – a high-level wrapper for the Wren scripting language with a user-friendly DSL
euwren 0.3.0 is out! This release introduces the ability to interact with Wren from Nim. Changelog: [https://github.com/liquid600pgm/euwren/releases/tag/0.3.0](https://github.com/liquid600pgm/euwren/releases/tag/0.3.0)
Re: Advent of Nim 2019 megathread
I'm kind of late to the party, but here goes. [https://github.com/liquid600pgm/aoc-2019](https://github.com/liquid600pgm/aoc-2019)
euwren – a high-level wrapper for the Wren scripting language with a user-friendly DSL
Recently, I have been working on euwren, a high level wrapper for [Wren](http://wren.io/). The idea behind euwren is to be _the king of Wren wrappers_ , one that uses a user-friendly DSL and that makes wrapping Nim procs a piece of cake. All you have to do is list the things you need in the VM, and voila! The VM is ready to execute some Nim code. The wrapper is highly WIP, but the most essential things are ready to be used. You can find the wrapper [here](https://github.com/liquid600pgm/euwren). Feel free to suggest any features you'd like to see, or any bugs you find. I'll be happy to take care of them.
Re: How to avoid recursive module dependency ?
When you have types that depend on each other, you must place them under one `type` section—there's no way of avoiding that.
Re: _MEM.RECALL();, a game for Open Jam 2019 written in Nim
It's probably a problem with shader linking, I'll try adding the `#version 330` core directive into all shaders.
Re: _MEM.RECALL();, a game for Open Jam 2019 written in Nim
This is a weird thing that started happening recently, I guess it said The futex facility returned an unexpected error code. It's bothering me too, but it doesn't affect the actual gameplay, it only occurs when you close the window or ^C.
Re: _MEM.RECALL();, a game for Open Jam 2019 written in Nim
Exactly, rapid links _all_ libraries statically to avoid dependency hell.
Re: _MEM.RECALL();, a game for Open Jam 2019 written in Nim
Indeed, the game was inspired by VV quite a lot ;) Apart from that, my inspirations were Hollow Knight and maybe a few others.
_MEM.RECALL();, a game for Open Jam 2019 written in Nim
Hi everyone, I just wanted to announce the release of _MEM.RECALL();, a game I made for Open Jam 2019. You can find the game here: * [itch.io](https://lqdev.itch.io/memrecall) * [GitHub](https://github.com/liquid600pgm/memrecall) Keep in mind that the game _may_ be buggy at times, especially in the audio department. My audio library is still unfinished, so please report any issues you find [here](https://github.com/liquid600pgm/rapid/). Hope you enjoy the game!
Re: 1.0.0 is here
Congratulations to all Nim developers! So happy that 1.0 is finally here. I'd also like to thank the community for being such a warm welcoming group. You're all awesome :)
Re: Where is nimbase.h ?
nimbase.h is located in your Nim installation, under the `lib` directory. If you installed using choosenim, you .can find your installations in `~/.choosenim`.
Re: pibench2 – A multi-threaded performance benchmark written in Nim
Hmm, strange. My CPU load is 100% during the benchmark, almost constantly (with tiny fluctuations to 99%).
pibench2 – A multi-threaded performance benchmark written in Nim
Hello! I'd like to announce a new small project of mine – pibench2. It's a multi-threaded performance benchmark, written in Nim. [https://github.com/liquid600pgm/pibench2](https://github.com/liquid600pgm/pibench2) Feel free to share your scores. Mine is 5.9649s with the default settings, on an AMD Ryzen 5 1600 (overclocked to 3.8GHz).
Is it possible to add a proc after a proc in a macro?
I don't know how to put this into the right words, so let me give you an example: macro someTransformation(proc1: NimNode): NimNode = # create a "wrapper" proc for proc1 proc someProc(a, b: float): float = result = a * 2 + a / b someTransformation(someProc) # this should create a new proc based off of someProc Run Is this possible? AFAIK `someProc` will be passed as an `nnkIdent` to `someTransformation`, but I need to pass the AST of the proc itself.
Re: Wrapping an object without generics
I think the `variant` package is exactly what I need. I can't really use object variants, since I don't know what kind of data is going to be stored within the object declaration itself (the user declares their own type and stores it within the object).
Re: Odd behavior with pairs on string and runeAt
I'm fairly certain `runeAt` is supposed to be used alongside the `unicode` module's `runes` iterator and all the other procs, for Rune indexing in a plain string (not a `seq[Rune]`).
Wrapping an object without generics
Hello, I need to store some user data in an object, but I don't know what is the object's type at compile time. I need to store those wrappers in a `seq`, but I don't know a wrapper's generic type, as it's specified by the user. What would be the best, safest solution to achieve this? I'd like to point out that I know what kind of user data is stored in the wrapper, so the user won't even notice the wrapper – plain data will be passed to them. Example: type Wrapper[T] = object userData: T # this won't work, as ``Wrapper`` has to have a generic type annotation var wrappers: seq[Wrapper] Run Should a `pointer` be used in this situation? Or is there a safer alternative?
Re: Fuzzy matching on table keys
Well, it sort of did. When implementing the `hash` method however, I realized it's not that simple, and decided to use something like this: import tables type FnSignatureTable = ref object signatures: TableRef[string, seq[FnSignature]] Run Then I store all signatures in the table with their names as keys, and use an index operator with a signature as the key. I then compare the inputted signature with all the others in the seq, to see if any one matches.
Fuzzy matching on table keys
Hello, I want to perform fuzzy matching on table keys. What I mean by that, is: import tables type Fn = proc (args: varargs[string]): int FnSignature = tuple name: string arity: int argTypes: seq[string] var signatures = newTable[FnSignature, Fn]() signatures.add(("print", 1, @["any"])) do (args: varargs[string]) -> int: discard echo signatures[("print", 1, @["string"])] # should return the first added element, because ``any`` describes any type Run >From what I know about hash tables, it's not as simple as adding an equality >operator overload to `FnSignature`. How do I achieve what I'm talking about?
Re: Buggy concepts
I wasn't able to create a MCVE, that's why I didn't include it in the post.
Buggy concepts
Hello, I have been trying out Nim's concepts for the past few days, and I have to say: they're far from stable. In simple use cases they work, but when you add advanced OOP techniques into the mix, you get an amalgamate of compiler errors and meaningless exit codes. So far, concepts are very unpredictable, take my current project as an example: [https://github.com/liquid600pgm/rod](https://github.com/liquid600pgm/rod) I tried to create an interface for a proper `RodVM`, to avoid cyclic imports (and add some modularity). Unfortunately, it didn't work out, because for some reason, the compiler crashed with exit code 1 without any reason on compilation. I wasn't able to trace down where the issue is, so I went for a different model: I decided to use a `RodBaseVM` class, which didn't help at all. I still needed concepts to define a meta-type, that would describe a type that implements the required methods of a VM, but failed miserably, with a cryptic compiler error: Error: internal error: getTypeDescAux(tyProxy) No stack traceback available To create a stacktrace, rerun compilation with ./koch temp c Run I get that concepts are still in development, but I expected that the compiler would at least give me some line numbers, but no. That never happened. Overall, I think the overall idea behind concepts is brilliant: they're much more powerful and modular than interfaces, however, they still need a lot of work to be considered stable. TL;DR: Don't use concepts. Not yet, at least.
Re: Concatenate identifiers in template
Thank you!
Concatenate identifiers in template
Hello, I would like to concatenate two identifiers in a template, like so: template myTemplate(id: untyped, body: untyped): untyped = proc r##id() = # I've seen it done this way in C body Run Is this possible without the use of macros?
Re: Convert float to its corresponding bytes?
Thank you very much, this is exactly what I need. I was thinking about using casts but wasn't really sure if it's safe.
Convert float to its corresponding bytes?
Hello, I was wondering if it's possible to convert a `float64` into 8 `uint8` s. To be more precise, I need to add the `float64` into a `seq[uint8]`, and then have a way of converting the corresponding bytes back to a `float64`. Can this be achieved? If so, how?
Re: Use continue statement on parent loop
I just solved my issue by adding another variable. Thanks anyway
Use continue statement on parent loop
Hello, I'm trying to use a continue statement in the following fashion: block first: for i in 0..<10: for j in 0..<5: if j == 3: continue first Run However, the compiler reports that `continue` cannot have a label. How can I achieve this?
Global procedure access?
I don't know if I titled my problem correctly, but this is what I'm trying to achieve: proc a(n: int) = b() proc b() = a(42) Run I know this example would recur infinitely, but my actual use case breaks `a` on a condition. I already tried using tables, but it's not really possible since my procedures have different signatures: import tables var myProcs = initTable[string, proc ()]() # this is where the plan fails myProcs.add("a") do (n: int): myProcs["b"]() myProcs.add("b") do (): myProcs["a"](42) Run Is there any way for me to achieve this?
Enum is undefined in template scope?
Hello, I'm currently doing some more advanced "macro magic", and have stumbled upon a weird error: type TokenKind* = enum rtLParen, rtRParen # () rtLBracket, rtRBracket # [] rtLBrace, rtRBrace # {} Token* = object kind: TokenKind template token(name: untyped, stmts: untyped): untyped {.dirty.} = proc name(input: string): Token = stmts template literal(lit: string, kind: untyped): untyped {.dirty.} = if input == lit: result = Token(kind: kind) token lParen: literal("(", rtLParen) Run For some reason the compiler fails: ../src/rod/tokenizer.nim(24, 39) Error: undeclared field: 'rtLParen' Run Even though `rtLParen` clearly is defined. I want to achieve a template that expands like so: literal("(", rtLParen) # into: if input == "(": result = Token(kind: rtLParen) literal(")" rtRParen) # into: if input == ")": result = Token(kind: rtRParen) # etc Run What am I doing wrong?
Re: Compiling with GCC optimizations disabled
Oh, I just forgot the `-g` flag. Thank you anyways!
Compiling with GCC optimizations disabled
Is it possible to pass `-O0` to C in order to disable all optimizations? I have a problem with a C library I'm compiling and accessing from Nim, and I want to see what I'm doing wrong more clearly. I tried to pass `--passC:"-O0"` and `passC="-O0"` but both seem to have no effect on debugging information in Valgrind.
Re: Use GC_ref on a pointer
Oh, of course! That was a mistake on my behalf, but also part of what I wanted to do – I wanted to allocate some memory to store a pointer, but storing the struct itself seems like a better idea.
Re: Use GC_ref on a pointer
Well, maybe instead of asking you to solve my problem let me ask a more general question about pointers: From what I understand, `ptr T` is untracked by the GC. So can I just do something like this? type MyObj = object x: int proc newMyObj(): MyObj = result = MyObj(x: 42) proc allocMyObj(): ptr MyObj = result = cast[ptr MyObj](alloc(sizeof(ptr MyObj))) result[] = newMyObj() Run Or will this cause some sort of memory problems? I'm asking this question because I'm not very experienced with such low-level programming, and my application uses pretty much what I've shown in the example (except `alloc()` isn't used directly, but it more or less resembles what I'm doing in my code)
Re: Use GC_ref on a pointer
I need to pass around some data between Nim and C, and this `someCAllocFunction` returns a void pointer. I tried casting it to a `ptr MyType` and setting its value using `point[] = MyType()` (in reality I'm using an object with some fields, and the object is initialized in a separate function). But then, in a callback I passed to C, I'm trying to access my data again, but a `SIGSEGV` is raised. instance of TestAutowrenType Traceback (most recent call last) autowren.nim(143)autowren autowren.nim(136)w_data= autowren.nim(130)data= gc.nim(289) unsureAsgnRef gc.nim(185) decRef SIGSEGV: Illegal storage access. (Attempt to read from nil?) Run Here's the source code of my program: [https://github.com/liquid600pgm/rapid/blob/master/src/scripting/autowren.nim](https://github.com/liquid600pgm/rapid/blob/master/src/scripting/autowren.nim) I understood this as the GC removing my object while it's passed around in C code, and that's why I wanted to mark it as referenced.
Use GC_ref on a pointer
I have a type stored in C, that's a pointer to a type. type MyType = object var point = cast[ptr MyType](someCAllocFunction(sizeof(ptr MyType))) GC_ref(point) # this doesn't work, because GC_ref expects a ``ref T``, ``seq[T]``, or ``string`` Run How can I achieve this?
Re: Convincing my friend about Nim
First, I'd like to thank you for all the answers. You really gave me some good knowledge about how I could approach my friend. However, he's found another argument I really can't beat with my own knowledge. He says Nim's unreadable for programmers coming from other languages. My main contr-argument was that you can always read the documentation; heck, the tutorial for the language is well-written and easy to understand. But he keeps bragging that he doesn't want to read any docs; he just wants to understand code in any language. For me, that really shows his ignorance and lazyness. It's not really hard to deduce Nim's language features, some may be easier to deduce than others, but if I wouldn't know Nim and read the codebase of, for example, `nimforum`, as @Araq suggested, I'd at least try to understand the code using my knowledge from other languages. I probably wouldn't understand what `proc` means, or ``*`, or how generics are written, but by looking at more source code I'd be able to deduce what at least 2 of those 3 examples do (can you guess which is the hardest to deduce?). But the fact is, every developer is different, some may be too lazy to even look at something's source code, or too lazy to try and deduce the functions of different operators. You cannot develop software without the use of documentation, and that's what he doesn't understand and keeps bragging about. Again, thank you for all the answers, and happy new year!
Re: Could not load libwren.so
So I decided to link the lib statically, doing the following steps: 1. In my `nim.cfg` I added `--dynlibOverride:wren` 2. In my source code I added this: when sizeof(int) == 4: when defined(windows): const wrenDynlib = "libwren-32.dll" elif defined(macosx): const wrenDynlib = "libwren-32.dylib" else: const wrenDynlib = "libwren-32.so" elif sizeof(int) == 8: when defined(windows): const wrenDynlib = "libwren-64.dll" elif defined(macosx): const wrenDynlib = "libwren-64.dylib" else: const wrenDynlib = "libwren-64.so" {.link: currentSourcePath.splitPath.head / wrenDynlib .} Run There's probably a cleaner way btw, but I did this for testing. ld doesn't return any errors, but my application itself does: /home/[user]/Coding/Nim/rapid/src/rapid: error while loading shared libraries: libwren.so: cannot open shared object file: No such file or directory Error: execution of an external program failed: '/home/[user]/Coding/Nim/rapid/src/rapid ' Run
Convincing my friend about Nim
Hello, First of all, I don't want to hate on other languages, or anything. I don't have anything against other languages' syntaxes, and I'm OK with people using them. But I have a friend who has recently "turned against me" – when I started using Nim, he started being really angry (no, really, he just started saying I'm stupid, etc) that I'm not using a normal (multiple quotes intentional) language. His main argument is Nim's syntax, even though he's never really tried to code in the language. He's pretty much a C# fanboy, he says the syntax is perfect and "it can run on many platforms" (I strongly disagree with that). My main argument is that if he'd finally start coding in an ergonomic language like Python or Nim, he'd finally feel how easy it is to write and read code in it. What he dislikes the most, is the indentation-based syntax, and a few other "weirdnesses" you don't see in typical languages. First of all, he states that not having such an indentation-based syntax allows for more freedom, even though he doesn't indent his code badly. I think this argument is just stupid, taking into account all of his programming practices. But the main deal is about the syntax features themselves. I'm going to use this code sample to describe the problems he has with the syntax: type Box[T] = object value: T proc box*[T](value: T): Box[T] = result = Box(value: value) Run First of all, he really dislikes the lack of brackets, and the "misuse" of them. As I said, he's really used to C#, and thinks the generics syntax is stupid. His problem with it is the use of squared brackets `[T]` instead of angled brackets ``. I thought it was a weird decision too, but later found out it didn't really clash with the rest of the language and worked really well. Pretty much all of his jokes now rely on this argument, even though it's a preference and he shouldn't hate the language just because his preferences are different. Next up, an "invalid" argument. He says macros are dumb, and you could just write code normally without them. I sort of agree with him, but no. Macros are really useful, especially when you have to write a ton of repetitive code when you want to embed a scripting language for your application, or something similar. His last argument is that Nim is not very popular. I left it for last, because it's not an argument – you can't judge something by how popular it is. I tried approaching him with a quote from Araq: > Nim's target audience is the enlightened/misguided programmer who doesn't > understand why there should be more than one programming language. And yet, he keeps being stubborn about his opinion. How can I convince him to at least stop hating the language so much, or to change his decision and try out the language?
Re: Could not load libwren.so
I don't want to rely on the end-user to compile and install `libwren.so` themselves, that's why I wanted to provide the lib with my application. Could static linking work there? If so, how can I achieve it with a wrapper that uses the `dynlib` pragma everywhere?
Could not load libwren.so
Hello, I'm trying to use @geotre's Wren wrapper for Nim, but I can't get dynamic linking to work. Here's my folder structure with the relevant files: . └── src ├── lib │ └── wren │ ├── info.txt │ ├── LICENSE │ ├── readme.md │ ├── src │ │ ├── wren │ │ │ └── libwren.nim │ │ └── wren.nim │ └── wren.nimble ├── libwren.so └── rapid.nim Run The wrapper's `libwren.nim` file depends on the `libwren.(dll|dylib|so)` dynamic library, and I'm putting it into my `src` folder, as you can see above. The wrapper unfortunately isn't available on Nimble, so I had to include it in my `lib` folder. `libwren.so` has been compiled from the official repo: [https://github.com/wren-lang/wren](https://github.com/wren-lang/wren), using the command `make shared`, on a 64-bit machine. Now, the problem is, my application runs into an error: libwren.so: cannot open shared object file: No such file or directory could not load: libwren.so Run This is the program's output when compiled with the `-d:nimDebugDlOpen` switch (Nim also says `libpcre.so.3` is missing, but I'm not going to use PCRE in my final application so I stripped it from the output).
Re: PEG.js-like API for the pegs module
That's not an option, I'm not using the JavaScript backend.
PEG.js-like API for the pegs module
Hello, I'm looking for an easier API for `pegs` that would for easy AST building. PEG.js allows for something like this: Method = ident:Ident args:CallArgs { return { type: "call_method", ident, args } } Run Unfortunately I don't see anything similar for Nim's built-in `pegs` module, is something like this possible with macros, or something like this?
Find all procs annotated with a pragma
Hello, I'm trying to achieve something like this: proc someProc() {.script.} = # do stuff # then use each proc annotated with {.script.} as a proc argument Run I was thinking I could use pragmas to build a compile-time sequence of procs with the script pragma, but I don't know how to do so. Is what I'm trying to do possible, and if it is, how can I achieve it?
Re: Using var object in a proc that is the object's property
Oh wait, it's a pointer! Mistook it as a reference (those are what I never used, I use pointers on a daily basis because of OpenGL).
Re: Using var object in a proc that is the object's property
How do I pass the `ptr SomeWrapper` to `registerEvents`? I never used pointers in Nim before.
Using var object in a proc that is the object's property
Hello, I'm trying to do something like this: type Events = object onload, onfail: proc (name: string) type SomeWrapper = object events: Events onload, onfail: proc (name: string) proc registerEvents(wrapper: var SomeWrapper) = wrapper.events.onload = proc (name: string) = echo "loaded " & name; wrapper.onload(name) wrapper.events.onfail = proc (name: string) = echo "failed to load " & name; wrapper.onfail(name) Run But the following error is thrown: $ nim c mutability.nim Hint: used config file '/home/daknus/.choosenim/toolchains/nim-0.19.0/config/nim.cfg' [Conf] Hint: system [Processing] Hint: mutability [Processing] mutability.nim(11, 65) Error: illegal capture 'wrapper' of type which is declared here: mutability.nim(10, 20) Run So far I understand the problem (when `wrapper` is destroyed, `events` may still persist as a reference somewhere, and then the implementations of `events.onload` and `events.onfail` would access illegal memory, and cause a segmentation fault, which in my real use case is very unlikely as the lifetime of the hypothetical `events` never exceeds the lifetime of the `wrapper`), but I don't know how to fix it.
Re: Undefined reference to proc with {.importc.}
Cool! However, I wanted to make one myself to learn the Nim FFI capabilities.
Re: Undefined reference to proc with {.importc.}
I tried that, same error thrown by ld.
Undefined reference to proc with {.importc.}
Hello, I'm trying to make a [Wren](http://wren.io/) wrapper for Nim, but I have trouble understanding Nim's FFI. So far I've got a folder structure like this: src/ - wren.nim - wren/ - incl/ - wren.h - wrapper.nim - vm/(...) Run The `src/wren/vm` folder's contents can be found here: [https://github.com/wren-lang/wren/tree/master/src/vm](https://github.com/wren-lang/wren/tree/master/src/vm) I tried using the `importc` macro in `wrapper.nim` like this: # tell the C compiler to look for the wren header # unfortunately this must be done as Nim doesn't copy the .h filed from the header pragma to its compile cache from os import splitPath {.passC: "-I" & currentSourcePath.splitPath.head.} const h = "wren.h" type WrenConfiguration* {.importc, header: h.} = object proc wrenInitConfiguration*(cfg: ptr WrenConfiguration) {.importc: "wrenInitConfiguration", nodecl.} Run However, when I try and test if the `wrenInitConfiguration` proc works, I get this error: /usr/bin/ld: /home/[username]/.cache/nim/test1_d/wren_test1.c.o: in function `NimMainModule': wren_test1.c:(.text+0x95e): undefined reference to `wrenInitConfiguration' collect2: error: ld returned 1 exit status Run What am I doing wrong, and how can I make a wrapper properly?
Cross-compiling from Linux to Windows using the -d:mingw flag
Hello, I am trying to cross-compile to Windows using the MinGW toolchain. Here's what I'm doing: $ nim c -d:mingw --cpu:amd64 src/uitest.nim Run However, a regular Linux executable is produced. How can I compile an exe file for Windows?