Ah, I think I found a solution:
    
    
    import macros, strutils
    
    macro typecheckedAst(x: typed): untyped =
      echo "calling typecheck on expression: ", x.repr
      echo "with type: ", x.getType().treeRepr()
      # We can build a type specific AST here:
      let typ = x.getType()
      if sameType(typ, bindSym"int"):
        echo "it's an int"
        result = newStrLitNode("AST for int")
      elif sameType(typ, bindSym"string"):
        echo "it's a string"
        result = newStrLitNode("AST for string")
      else:
        echo "unknown type"
      echo " => resulting type dependent AST: ", result.repr
    
    macro fmt*(fmt: static[string]): untyped =
      let fields = fmt.split(":")
      assert fields.len == 2
      let lhs = fields[0]
      let rhs = fields[1]
      # We probably can't get the type of `e` here, but we can delegate
      # all type specific AST generation into the `typecheckedAst` macro
      let e = parseExpr(lhs)
      result = newCall(ident"typecheckedAst", e)
    
    block:
      let x = 1
      echo fmt"x + x:<format-string>"
    
    block:
      let x = "test"
      echo fmt"x & x:<format-string>"
    

So the trick is to use `parseExpr` in the outer macro and delegate the type 
specific AST generation into a sub-macro which takes a `typed` expression.

Reply via email to