I solved this problem with a two layer macro. The outer macro had an untyped 
argument and an inner macro with a typed argument. The outer macro was the 
macro that the user of the dsl would call and it has the nice syntax to call 
it. The outer macro transforms the untyped ast in an ast that then can be type 
checked. I did this by adding some function calls that didn't do anything, they 
were just there, so that the type checker could do it's job. The now 
typecheckable ast is then passed to the inner macro that has a typed argument. 
Now you can do whatever you want from here on. In your case the outer macro 
would generate the let expression you talked about.

over simplifiled example:
    
    
    proc decoration[T](arg: T): int = 1
    
    macro inner(arg: typed): untyped = [...]
    
    macro outer*(arg: untyped) =
      result = quote do:
        inner:
          decoration(`arg`)
    

Reply via email to