diff --git a/compiler/guards.nim b/compiler/guards.nim index b53365617c..df32cf98c3 100644 --- a/compiler/guards.nim +++ b/compiler/guards.nim @@ -758,10 +758,11 @@ macro `=~`(x: PNode, pat: untyped): bool = of nnkIdent: let c = newTree(nnkStmtListExpr, newLetStmt(pat, x)) conds.add c - if ($pat)[^1] == 'c': c.add(getAst(isVal(pat))) + # XXX why is this 'isVal(pat)' and not 'isVal(x)'? + if ($pat)[^1] == 'c': c.add(getAst(isVal(x))) else: c.add bindSym"true" of nnkIntLit: - conds.add(getAst(isIntVal(pat.intVal))) + conds.add(getAst(isIntVal(x, pat.intVal))) else: error("invalid pattern") diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index 8f1362691d..cf3fe57af7 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -1594,17 +1594,23 @@ proc newAnonSym(c: PContext; kind: TSymKind, info: TLineInfo): PSym = proc semExpandToAst(c: PContext, n: PNode): PNode = let macroCall = n[1] - let expandedSym = expectMacroOrTemplateCall(c, macroCall) - if expandedSym.kind == skError: return n - macroCall.sons[0] = newSymNode(expandedSym, macroCall.info) - markUsed(n.info, expandedSym, c.graph.usageSym) - styleCheckUse(n.info, expandedSym) + when false: + let expandedSym = expectMacroOrTemplateCall(c, macroCall) + if expandedSym.kind == skError: return n - for i in countup(1, macroCall.len-1): - #if macroCall.sons[0].typ.sons[i].kind != tyExpr: - macroCall.sons[i] = semExprWithType(c, macroCall[i], {}) + macroCall.sons[0] = newSymNode(expandedSym, macroCall.info) + markUsed(n.info, expandedSym, c.graph.usageSym) + styleCheckUse(n.info, expandedSym) + if isCallExpr(macroCall): + for i in countup(1, macroCall.len-1): + #if macroCall.sons[0].typ.sons[i].kind != tyExpr: + macroCall.sons[i] = semExprWithType(c, macroCall[i], {}) + # we just perform overloading resolution here: + n.sons[1] = semOverloadedCall(c, macroCall, macroCall, {skTemplate, skMacro}) + else: + localError(n.info, "getAst takes a call, but got " & n.renderTree) # Preserve the magic symbol in order to be handled in evals.nim internalAssert n.sons[0].sym.magic == mExpandToAst #n.typ = getSysSym("NimNode").typ # expandedSym.getReturnType diff --git a/lib/pure/unittest.nim b/lib/pure/unittest.nim index dd7009d638..1163b74408 100644 --- a/lib/pure/unittest.nim +++ b/lib/pure/unittest.nim @@ -324,8 +324,8 @@ macro check*(conditions: untyped): untyped = case checked.kind of nnkCallKinds: - template rewrite(call, lineInfoLit: expr, callLit: string, - argAssgs, argPrintOuts: stmt): stmt = + template rewrite(call, lineInfoLit, callLit, + argAssgs, argPrintOuts) = block: argAssgs #all callables (and assignments) are run here if not call: @@ -345,8 +345,8 @@ macro check*(conditions: untyped): untyped = result.add(newCall(!"check", checked[i])) else: - template rewrite(Exp, lineInfoLit: expr, expLit: string): stmt = - if not Exp: + template rewrite(exp, lineInfoLit, expLit) = + if not exp: checkpoint(lineInfoLit & ": Check failed: " & expLit) fail() diff --git a/tests/macros/tdumpast.nim b/tests/macros/tdumpast.nim index e3388591a4..3a26ffd2f1 100644 --- a/tests/macros/tdumpast.nim +++ b/tests/macros/tdumpast.nim @@ -2,13 +2,13 @@ import macros -template plus(a, b: expr): expr {.dirty} = +template plus(a, b: untyped): untyped {.dirty} = a + b -macro call(e: expr): expr = +macro call(e: untyped): untyped = result = newCall("foo", newStrLitNode("bar")) -macro dumpAST(n: stmt): stmt {.immediate.} = +macro dumpAST(n: untyped): untyped = # dump AST as a side-effect and return the inner node let n = callsite() echo n.lispRepr @@ -17,7 +17,7 @@ macro dumpAST(n: stmt): stmt {.immediate.} = var plusAst = getAst(plus(1, 2)) echo plusAst.lispRepr - var callAst = getAst(call()) + var callAst = getAst(call(4)) echo callAst.lispRepr var e = parseExpr("foo(bar + baz)") diff --git a/tests/template/twrong_getast.nim b/tests/template/twrong_getast.nim new file mode 100644 index 0000000000..236fecdd99 --- /dev/null +++ b/tests/template/twrong_getast.nim @@ -0,0 +1,19 @@ +discard """ + errormsg: "type mismatch" + line: 16 +""" + +import macros + +template grainBlock(proxyTypeName: untyped, proxyProcs: untyped): typed = + discard + +var + proxyTypeName: string + proxyProcs: string + +macro foo(): untyped = + let x = getAst grainBlock(proxyTypeName, proxyProcs, proxyTypeName) + +foo() +