Nimony

The road to Nim 3

comesfrom

nimony/src/lib/comesfrom.nim

Expansion provenance encoded in a line-info filename.

Code produced by expanding a template does not get its own wrapper node. Instead the tokens carry a forged filename that records what they came from, so a debug backend can emit them as DWARF inlined frames:

__crucial\0setElem.0.foo\1foo.nim\116\0[]=.0.system\1system.nim\134\0system.nim ^prefix ^-------- outermost -------^ ^--------- innermost --------^ ^real file

The chain runs outermost-first, so its length is the inlining depth. Each entry is <sym>\1<declfile>\1<declline>: the symbol names the expanded routine, and the declaration site is carried because it cannot be recovered later - a template declaration does not survive into the backend, and the expanded code's own line info points at wherever the body came from, not at the template. Everything after the last NUL is the real filename, which is what a consumer that does not care about frames should use.

A filename cannot otherwise contain a NUL or a \1, which is what makes the encoding unambiguous - note that | would not do, since Nim lets an operator be named |. nifbuilder.needsEscape covers c < ' ', so both control characters survive text NIF as \00 / \01; bif writes filenames length-prefixed, so binary is fine.

Deliberately free of any NIF dependency: it is plain string handling, so the front end, the C backend and the LLVM backend can all reach it without pulling in a cursor API.