diff --git a/compiler/sem.nim b/compiler/sem.nim index 0f26279985..2c65f55a08 100755 --- a/compiler/sem.nim +++ b/compiler/sem.nim @@ -111,21 +111,24 @@ proc semAfterMacroCall(c: PContext, n: PNode, s: PSym): PNode = GlobalError(s.info, errTemplateInstantiationTooNested) result = n - case s.typ.sons[0].kind - of tyExpr: - # BUGFIX: we cannot expect a type here, because module aliases would not - # work then (see the ``tmodulealias`` test) - # semExprWithType(c, result) - result = semExpr(c, result) - of tyStmt: + if s.typ.sons[0] == nil: result = semStmt(c, result) - of tyTypeDesc: - if n.kind == nkStmtList: result.kind = nkStmtListType - result.typ = semTypeNode(c, result, nil) else: - result = semExpr(c, result) - result = fitNode(c, s.typ.sons[0], result) - #GlobalError(s.info, errInvalidParamKindX, typeToString(s.typ.sons[0])) + case s.typ.sons[0].kind + of tyExpr: + # BUGFIX: we cannot expect a type here, because module aliases would not + # work then (see the ``tmodulealias`` test) + # semExprWithType(c, result) + result = semExpr(c, result) + of tyStmt: + result = semStmt(c, result) + of tyTypeDesc: + if n.kind == nkStmtList: result.kind = nkStmtListType + result.typ = semTypeNode(c, result, nil) + else: + result = semExpr(c, result) + result = fitNode(c, s.typ.sons[0], result) + #GlobalError(s.info, errInvalidParamKindX, typeToString(s.typ.sons[0])) dec(evalTemplateCounter) proc semMacroExpr(c: PContext, n, nOrig: PNode, sym: PSym, diff --git a/compiler/seminst.nim b/compiler/seminst.nim index a03f620755..ffda48fba5 100755 --- a/compiler/seminst.nim +++ b/compiler/seminst.nim @@ -74,7 +74,7 @@ proc instantiateBody(c: PContext, n: PNode, result: PSym) = # add it here, so that recursive generic procs are possible: addDecl(c, result) pushProcCon(c, result) - if result.kind in {skProc, skMethod, skConverter}: + if result.kind in {skProc, skMethod, skConverter, skMacro}: addResult(c, result.typ.sons[0], n.info, result.kind) addResultNode(c, n) var b = semStmtScope(c, n.sons[bodyPos]) @@ -184,8 +184,9 @@ proc generateInstance(c: PContext, fn: PSym, pt: TIdTable, pragma(c, result, n.sons[pragmasPos], allRoutinePragmas) if isNil(n.sons[bodyPos]): n.sons[bodyPos] = copyTree(fn.getBody) - instantiateBody(c, n, result) - sideEffectsCheck(c, result) + if fn.kind != skTemplate: + instantiateBody(c, n, result) + sideEffectsCheck(c, result) else: result = oldPrc popInfoContext() diff --git a/lib/pure/collections/sets.nim b/lib/pure/collections/sets.nim index ff2ffec0e5..42b77d427c 100755 --- a/lib/pure/collections/sets.nim +++ b/lib/pure/collections/sets.nim @@ -157,7 +157,7 @@ proc card*[A](s: TOrderedSet[A]): int {.inline.} = ## alias for `len`. result = s.counter -template forAllOrderedPairs(yieldStmt: stmt) {.dirty.} = +template forAllOrderedPairs(yieldStmt: stmt) {.dirty, immediate.} = var h = s.first while h >= 0: var nxt = s.data[h].next diff --git a/lib/pure/collections/tables.nim b/lib/pure/collections/tables.nim index 3ae25d3adc..3b252f1d29 100755 --- a/lib/pure/collections/tables.nim +++ b/lib/pure/collections/tables.nim @@ -202,7 +202,7 @@ proc len*[A, B](t: TOrderedTable[A, B]): int {.inline.} = ## returns the number of keys in `t`. result = t.counter -template forAllOrderedPairs(yieldStmt: stmt) {.dirty.} = +template forAllOrderedPairs(yieldStmt: stmt) {.dirty, immediate.} = var h = t.first while h >= 0: var nxt = t.data[h].next diff --git a/lib/system/channels.nim b/lib/system/channels.nim index 617dddb7e3..13d751d80e 100755 --- a/lib/system/channels.nim +++ b/lib/system/channels.nim @@ -180,12 +180,12 @@ proc rawRecv(q: PRawChannel, data: pointer, typ: PNimType) = storeAux(data, addr(q.data[q.rd * typ.size]), typ, q, mLoad) q.rd = (q.rd + 1) and q.mask -template lockChannel(q: expr, action: stmt) = +template lockChannel(q: expr, action: stmt) {.immediate.} = acquireSys(q.lock) action releaseSys(q.lock) -template sendImpl(q: expr) = +template sendImpl(q: expr) {.immediate.} = if q.mask == ChannelDeadMask: raise newException(EDeadThread, "cannot send message; thread died") acquireSys(q.lock) diff --git a/tests/compile/tgeneric3.nim b/tests/compile/tgeneric3.nim index f4ec59ced9..3c543ecfae 100644 --- a/tests/compile/tgeneric3.nim +++ b/tests/compile/tgeneric3.nim @@ -66,12 +66,12 @@ proc setItem[T,D] (AKey: T, AValue: D, ANode: PNode[T,D]): ref TItem[T,D] {.inli proc cmp[T:Int8|Int16|Int32|Int64|Int] (a,b: T): T {.inline.} = return a-b -template binSearchImpl *(docmp: expr) = +template binSearchImpl *(docmp: expr) {.immediate.} = var bFound = false result = 0 var H = haystack.len -1 while result <= H : - var I = (result + H) shr 1 + var I {.inject.} = (result + H) shr 1 var SW = docmp if SW < 0: result = I + 1 else: diff --git a/tests/compile/tgenerictmpl.nim b/tests/compile/tgenerictmpl.nim index f3bb4b6ee4..a749e65708 100644 --- a/tests/compile/tgenerictmpl.nim +++ b/tests/compile/tgenerictmpl.nim @@ -1,8 +1,12 @@ template tmp[T](x: var seq[T]) = - var yz: T + #var yz: T # XXX doesn't work yet x = @[1, 2, 3] +macro tmp2[T](x: var seq[T]): stmt = + nil + var y: seq[int] tmp(y) +tmp(y) echo y.repr diff --git a/tests/compile/tgensym.nim b/tests/run/tgensym.nim similarity index 56% rename from tests/compile/tgensym.nim rename to tests/run/tgensym.nim index 3c0405136c..3c85b0b832 100644 --- a/tests/compile/tgensym.nim +++ b/tests/run/tgensym.nim @@ -1,6 +1,10 @@ +discard """ + output: "123100" +""" + template hygienic(val: expr) = - var `*x` = val - stdout.write `*x` + var x = val + stdout.write x var x = 100 diff --git a/tests/run/tmacro3.nim b/tests/run/tmacro3.nim index fa2040e92d..1622123269 100755 --- a/tests/run/tmacro3.nim +++ b/tests/run/tmacro3.nim @@ -8,7 +8,7 @@ type TA = tuple[a: int] PA = ref TA -macro test*(a: stmt): stmt = +macro test*(a: stmt): stmt {.immediate.} = var val: PA new(val) val.a = 4 @@ -16,7 +16,7 @@ macro test*(a: stmt): stmt = test: "hi" -macro test2*(a: stmt): stmt = +macro test2*(a: stmt): stmt {.immediate.} = proc testproc(recurse: int) = echo "Thats weird" var o : PNimrodNode = nil diff --git a/tests/run/tmacro4.nim b/tests/run/tmacro4.nim index f90a8a4349..10a23b159b 100755 --- a/tests/run/tmacro4.nim +++ b/tests/run/tmacro4.nim @@ -5,7 +5,7 @@ discard """ import macros, strutils -macro test_macro*(n: stmt): stmt = +macro test_macro*(n: stmt): stmt {.immediate.} = result = newNimNode(nnkStmtList) var ass : PNimrodNode = newNimNode(nnkAsgn) add(ass, newIdentNode("str")) diff --git a/tests/run/tmacros1.nim b/tests/run/tmacros1.nim index a1bb298237..b2fb7240d0 100755 --- a/tests/run/tmacros1.nim +++ b/tests/run/tmacros1.nim @@ -5,7 +5,7 @@ discard """ import macros, strutils -macro outterMacro*(n: stmt): stmt = +macro outterMacro*(n: stmt): stmt {.immediate.} = let n = callsite() var j : string = "hi" proc innerProc(i: int): string = diff --git a/tests/run/tsets2.nim b/tests/run/tsets2.nim index 89935072fe..ac977096ba 100755 --- a/tests/run/tsets2.nim +++ b/tests/run/tsets2.nim @@ -1,6 +1,6 @@ discard """ output: '''true''' - cmd: "nimrod cc --gc:none --hints:on $# $#" + cmd: "nimrod cc --hints:on $# $#" """ import hashes, sets diff --git a/todo.txt b/todo.txt index e31e1cd49c..7ed2872840 100755 --- a/todo.txt +++ b/todo.txt @@ -76,6 +76,7 @@ version 0.9.XX per default? - 'const' objects including case objects - 'export' feature +- from buggymodule import * except optBroken, optBroken2 - think about ``{:}.toTable[int, string]()`` - mocking support with ``tyProxy`` that does: o.p(x) --> p(o, x) --> myMacro(p, o, x)