I've been playing with the idea of a simple MUD server in Nim. To make homebrew "I want to add this one thing" hacking with it easier, I've been looking at taking in-game commands ("look", "say", "punch monster", etc), and turning the implementation of each one into its own file.
However, to go with this line of thought, is there a way to import or include all .nim files in a given folder automatically, or would each need to be explicitly listed?
There are two principal solutions I see.
The first one is cleaner and results in faster recompilation times. You basically write a separate program (in Nim or your favorite scripting language or as a shell script) to generate a file. E.g. something like this:
import os
proc main() =
for i in 1..paramCount():
let dir = paramStr(i)
let module = open(dir & ".nim", fmWrite)
for file in walkFiles(dir & "/*.nim"):
module.write("import " & file[0..^5] & "\n")
module.close
main()
You can then include the generated module, which will import all the modules in that directory.
Alternatively, you can write a macro to do the job for you.
import macros, strutils
macro importFolder(s: string): expr =
let s = staticExec "find " & s.toStrLit.strVal & " -name '*.nim' -maxdepth 1"
let files = s.splitLines
result = newStmtList()
for file in files:
result.add(parseStmt("import " & file[0..^5]))
The use of staticExec in a macro to execute an external program is slightly hackish, but it seems to do its job. This macro will generate and execute an import statement for each file in the folder. Note that because of the need to execute an external program, this can cause a bit of overhead and may be slow if you repeatedly recompile code.
#In Commands.nim
include look, say, travel, punch_monster
#In Room.nim or whatever name you put
import Commands
case command
of "look": look(playerEntity)
of "say": say(playerEntity, command)
else: echo "This command does not exist!"