Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

how to get file/line of a function's caller? cf in D: void fun(string file=__FILE__) #7406

Closed
timotheecour opened this issue Mar 24, 2018 · 5 comments

Comments

@timotheecour
Copy link
Member

timotheecour commented Mar 24, 2018

how to get file/line of a function's caller?

in D this works:

void fun(string file=__FILE__, int line=__LINE__){import std.stdio; writeln(file, ":", line);}
fun(); // main.d:2
fun(); // main.d:3

in D we can get the file/line of a function caller using __FILE__, __LINE__ (__MODULE__, etc)

how would we do that in nim proc's ?

proc fun(line:int = instantiationInfo(-1, true).line): auto=
    echo $("fun:line", line) # this is -1
    return
fun() # expecting:2
fun() # expecting:3

NOTE: this also doesn't work:

template currentSourceLine*: int = instantiationInfo(-1, true).line
proc fun(line:int = currentSourceLine):auto=
  echo $("fun:line", line) # this is 2
  return
fun() # expecting:5
fun() # expecting:6

NOTE: looking for a solution that works with proc (eg, no template bloat)

@timotheecour timotheecour changed the title equivalent of D's void fun(string file=__FILE__)? how to get file/line of a function's caller? cf equivalent of D's void fun(string file=__FILE__) Mar 24, 2018
@timotheecour timotheecour changed the title how to get file/line of a function's caller? cf equivalent of D's void fun(string file=__FILE__) how to get file/line of a function's caller? cf in D: void fun(string file=__FILE__) Mar 24, 2018
@cooldome
Copy link
Member

check instantiationInfo(-2) and callsite

@timotheecour
Copy link
Member Author

timotheecour commented Mar 26, 2018

sorry could you please post a working test case?

proc fun1():auto=
    echo instantiationInfo(-2)
fun1() #(filename: "???", line: -1)

proc fun2():auto=
    let e = callsite() #Error: 'callsite' can only be used in compile-time context
    echo e
fun2()

@zah
Copy link
Member

zah commented Mar 27, 2018

instantiationInfo is available only in macros and templates because different code needs to be expanded on each call-site. You can introduce a helper template that will forward the filename and line to a regular proc:

type
  FileInfo = tuple[filename: string, line: int]

proc fooImpl(callerInfo: FileInfo) =
  echo callerInfo.filename, ":", callerInfo.line

template foo(): untyped =
  fooImpl(instantiationInfo())

foo()
foo()

Since my particular file is called "test.nim", the output is the following:

test.nim:10
test.nim:11

@timotheecour
Copy link
Member Author

timotheecour commented Mar 27, 2018

thanks, so it confirms what I was afraid of which is that this isnt' possible without introducing template bloat.

Could nim implement this feature just like it's done in D? in D, optional arguments (eg __FILE__, __LINE__, __MODULE__, __FUNC__ etc) get instantiated at caller-site, not callee site, and it works with regular functions (no need for templates).

otherwise, what are (objectively) the downsides of using template instead of proc (so that instantiationInfo() works) ?

@Araq
Copy link
Member

Araq commented Mar 27, 2018

There is no template bloat.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants