/
02.05.2025 at 10:28 pm
Cuttings

Nim / Exercise - Make a double(x) macro

Take an identifier and generate code that doubles its value in-place.
var x = 10
double(x)
echo x  # Output: 20

quote do: builds an AST, but lets you write Nim code as if it were regular code.

  1. quote do: builds an AST, but lets you write Nim code as if it were regular code. Use quote do: to turn your code into the corresponding NimNode structure.

  2. Backticks (x):

    • refer to the original identifier within the quoted block;

    • inject the original identifier (not a value) into that generated code.

  3. Backticks work differently with templates/macros in Nim:

    • Templates don't use backticks. The parameter name (expr) is used directly, because you're not working with the AST - you're doing code substitution.

    • Macros use backticks. With macros, you're working with ASTs. Also, parameters like expr are not variables - they are NimNodes.

  4. The resulting code (x = x * 2) is generated and inserted at the macro call site.

  5. This 'works', but it's not using the NimNode itself!

    x = x * 2
    
  6. If I write this:

    template double(expr: untyped): untyped = 
      expr = expr * 2
    echo m, " ", double(m), " ", m
    

    See the resulting error, because of how/where the generated code appears (due to substitution): m = m *2

Code (SolutiON)
     import macros

macro double(expr: untyped): untyped =
  result = quote do:
    `expr` = `expr` *2

var x = 10
double(x)
echo x # Output: 20

                    
Filed under:
#
#
Words: 201 words approx.
Time to read: 0.80 mins (at 250 wpm)
Keywords:
, , , , , , , , ,

Potentially related: Nim / Exercise - Make a `logvars(a, b, c)` macro

Latest Comments

© Wan Zafran. See disclaimer.