Hi,
I receive untyped expression as the macro argument. Expression refers to variables that are not currently scope, hence it is truly untyped expression. However, in the macro I am generating a new let section which defines all missing variables and makes expression valid and now I want to know expression's type, however getType fails with 'Node has no type'
Btw, I managed to get a type of expression in the outer function, but I need it in the macro, because there are still a lot to be generated in macro based on the type of expression.
I want to do something like this:
macro exprInTuple(ctx : typed, expr : untyped) : typed =
let ctxType = ctx.getTypeImpl
if ctxType.typeKind != ntyTuple: error("Tuple is expected as first argument")
var letSection = newNimNode(nnkLetSection)
for field in ctxType:
let dotExpr = newDotExpr(ctx, newIdentNode($field[0]))
letSection.add(newIdentDefs(ident($field[0]), newEmptyNode(),newDotExpr))
result = newStmtList(letSection, expr)
getType(result) ## currently fails
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`)