> What's the heck!

The manual is not completely clear AFAIU, but the mistake is very likely that 
your code expects overloading to work with templates as it does with 
procedures, which it doesn't. The first `options` template is an immediate one 
and doesn't overload with the second (see 
[https://nim-lang.org/docs/manual.html#templates-typed-vs-untyped-parameters)](https://nim-lang.org/docs/manual.html#templates-typed-vs-untyped-parameters\)).
 The code can be fixed by giving the first `options` template a typed dummy 
`status` parameter, which makes it non-immediate so that overloading works 
again.

A more elegant solution is to take the first `options` template out of the 
overloading hierarchy like this:
    
    
    import macros
    
    template dsl(dslBody: untyped): untyped =
      block:
        macro options(args: varargs[untyped]): untyped =
          template tpl(postFix: untyped; args: varargs[untyped]) =
            `options postFix`(args)
          
          let postFix = if nnkStmtList == args[0].kind:
            "UT".ident
          else:
            "T".ident
          
          result = getAst(tpl(postFix, args))
        
        template optionsUT(optionsBody: untyped): untyped =
          block:
            template foo(fooBody: untyped): untyped =
              echo "Enter foo"
              fooBody
              echo "Leave foo"
            
            echo "Enter options"
            optionsBody
            echo "Leave options"
        
        template optionsT(status: string; optionsBody: untyped): untyped =
          block:
            echo "Enter options with string " & status
            options(optionsBody)
            echo "Leave options with string " & status
        
        # add other `optionsT` templates with `status: <sometype>` here..
        
        echo "Enter dsl"
        dslBody
        echo "Leave dsl"
    
    
    expandMacros:
      dsl:
        options:
          echo "Youpi!"
          foo:
            echo "1000 $!!!"
        
        options "Oops!":
          echo "I failed"
          foo:
            echo "1000 $!!!"
    
    
    Run

(Term rewriting macros might be able to do this in a more compact way, but they 
are experimental.)

So maybe we add these to your list:

  1. Read all of the manual and experiment where it is not 100% clear.
  2. Believe @Araq when he tells you to look at macros before trying to 
overstretch the power of templates.



;-)

Reply via email to