How to debug print a variable (name) and its value in Nim?
Asked Answered
I

2

5

During quick and dirty debugging, I often use expressions like:

echo "variable1: ", variable1, " variable2: ", variable2

How can I leverage Nim's macro system to avoid repeating the variable name?

Idyllist answered 22/11, 2017 at 20:14 Comment(0)
I
7

You can use a varargs macro that iterates over the arguments, and generates an AST which prints both the node's string literal as well as its value. Something like this:

import macros

macro debug*(n: varargs[typed]): untyped =
  result = newNimNode(nnkStmtList, n)
  for i in 0..n.len-1:
    if n[i].kind == nnkStrLit:
      # pure string literals are written directly
      result.add(newCall("write", newIdentNode("stdout"), n[i]))
    else:
      # other expressions are written in <expression>: <value> syntax
      result.add(newCall("write", newIdentNode("stdout"), toStrLit(n[i])))
      result.add(newCall("write", newIdentNode("stdout"), newStrLitNode(": ")))
      result.add(newCall("write", newIdentNode("stdout"), n[i]))
    if i != n.len-1:
      # separate by ", "
      result.add(newCall("write", newIdentNode("stdout"), newStrLitNode(", ")))
    else:
      # add newline
      result.add(newCall("writeLine", newIdentNode("stdout"), newStrLitNode("")))

Example usage:

let x = 2
let y = 3
debug("hello", x, y, x*y)

Output:

hello, x: 1, y: 2, x * y: 6
Idyllist answered 22/11, 2017 at 20:14 Comment(0)
F
1

The best way to achieve this is the fmt macro:

let x = "hello"
echo fmt"{x = }" # prints "x = hello"

Also see the debugging-strings section in the manual.

Freehearted answered 5/5, 2023 at 19:55 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.