In many cases such as exception and logging messages its beneficial to have compile time access to the calling site source file and line number similar to the the C preprocessor __FILE__ and __LINE__ macros. Is there a similar mechanism available in NIM?
The best solution I have constructed is given in the source listing below. Is there a more direct way to accomplish this in NIM?
import macros
macro srcLocMcr*(n:expr): string =
if n.kind != nnkNilLit:
quit "Invalid node:" & n.lispRepr
lineinfo(n)
template srcLoc*: expr = srcLocMcr(nil)
template newExceptionSl*(srcLocStr: string, exceptn: typedesc, message: string): expr =
## creates an exception object of type ``exceptn`` and sets its ``msg`` field
## to `message`. Returns the new exception object.
var
e: ref exceptn
new(e)
e.msg = srcLocStr & ": " & message
e
template newExc*(exceptn: typedesc, message: string): expr =
newExceptionSl(srcLoc,exceptn,message)
when isMainModule:
raise newExceptionSl(srcLoc,ValueError,"Value Error")
Here is the output from the source above
Traceback (most recent call last)
lineno.nim(25) lineno
Error: unhandled exception: lineno.nim(25,23): Value Error [ValueError]
template info: expr = instantiationInfo()
# At runtime
echo info
echo info.filename
echo info.line
static: # At compiletime
echo info
echo info.filename
echo info.line
Hi def,
What type signature should be used in place of "sourceLoc: string" in my newExceptionSl() template if I intend to send "info" as a argument? I can't seem to work this out.
See the type here: http://nim-lang.org/docs/system.html#instantiationInfo,. But you can make your template easier:
import strutils
template newExceptionSl*(exceptn: typedesc, message: string): expr =
## creates an exception object of type ``exceptn`` and sets its ``msg`` field
## to `message`. Returns the new exception object.
let (file, line) = instantiationInfo()
(ref exceptn)(msg: "$#($#): $#".format(file, line, message))
when isMainModule:
raise newExceptionSl(ValueError, "Value Error")