summary refs log tree commit diff stats
path: root/compiler
diff options
context:
space:
mode:
authorAraq <rumpf_a@web.de>2012-10-05 12:10:01 +0200
committerAraq <rumpf_a@web.de>2012-10-05 12:10:01 +0200
commit350e178d837a212755b729bb82225193acef5734 (patch)
treebd94d64c55eeccdf8479c967bc77bac2500336af /compiler
parent01dfcf63106fb18239a1c6dabf551405c33b6e7e (diff)
parentf28b7be6a37d566df64cb944c1687e014be8d083 (diff)
downloadNim-350e178d837a212755b729bb82225193acef5734.tar.gz
Merge branch 'master' of github.com:Araq/Nimrod
Diffstat (limited to 'compiler')
-rwxr-xr-xcompiler/ast.nim13
-rwxr-xr-xcompiler/c2nim/cparse.nim2
-rwxr-xr-xcompiler/evals.nim2
-rwxr-xr-xcompiler/idents.nim4
-rwxr-xr-xcompiler/msgs.nim19
-rwxr-xr-xcompiler/options.nim6
-rwxr-xr-xcompiler/parser.nim59
-rwxr-xr-xcompiler/renderer.nim1
-rwxr-xr-xcompiler/sem.nim9
-rwxr-xr-xcompiler/semexprs.nim85
-rwxr-xr-xcompiler/semgnrc.nim13
-rwxr-xr-xcompiler/semstmts.nim44
-rwxr-xr-xcompiler/semtypinst.nim3
-rwxr-xr-xcompiler/sigmatch.nim8
-rwxr-xr-xcompiler/suggest.nim3
15 files changed, 124 insertions, 147 deletions
diff --git a/compiler/ast.nim b/compiler/ast.nim
index aa94644aa..340a14888 100755
--- a/compiler/ast.nim
+++ b/compiler/ast.nim
@@ -145,7 +145,6 @@ type
     nkElifBranch,         # used in if statements
     nkExceptBranch,       # an except section
     nkElse,               # an else part
-    nkMacroStmt,          # a macro statement
     nkAsmStmt,            # an assembler block
     nkPragma,             # a pragma statement
     nkPragmaBlock,        # a pragma with a block
@@ -911,6 +910,18 @@ proc newMetaNodeIT*(tree: PNode, info: TLineInfo, typ: PType): PNode =
   result = newNodeIT(nkMetaNode, info, typ)
   result.add(tree)
 
+var emptyParams = newNode(nkFormalParams)
+emptyParams.addSon(emptyNode)
+
+proc newProcNode*(kind: TNodeKind, info: TLineInfo, body: PNode,
+                 params = emptyParams,
+                 name, pattern, genericParams,
+                 pragmas, exceptions = ast.emptyNode): PNode =
+  result = newNodeI(kind, info)
+  result.sons = @[name, pattern, genericParams, params,
+                  pragmas, exceptions, body]
+
+
 proc NewType(kind: TTypeKind, owner: PSym): PType = 
   new(result)
   result.kind = kind
diff --git a/compiler/c2nim/cparse.nim b/compiler/c2nim/cparse.nim
index cb023411d..9f7a7bf36 100755
--- a/compiler/c2nim/cparse.nim
+++ b/compiler/c2nim/cparse.nim
@@ -1382,7 +1382,7 @@ proc nestedStatement(p: var TParser): PNode =
   # Nimrod requires complex statements to be nested in whitespace!
   const
     complexStmt = {nkProcDef, nkMethodDef, nkConverterDef, nkMacroDef,
-      nkTemplateDef, nkIteratorDef, nkMacroStmt, nkIfStmt,
+      nkTemplateDef, nkIteratorDef, nkIfStmt,
       nkWhenStmt, nkForStmt, nkWhileStmt, nkCaseStmt, nkVarSection, 
       nkConstSection, nkTypeSection, nkTryStmt, nkBlockStmt, nkStmtList,
       nkCommentStmt, nkStmtListExpr, nkBlockExpr, nkStmtListType, nkBlockType}
diff --git a/compiler/evals.nim b/compiler/evals.nim
index e72231bf5..c6248e823 100755
--- a/compiler/evals.nim
+++ b/compiler/evals.nim
@@ -1296,7 +1296,7 @@ proc evalAux(c: PEvalContext, n: PNode, flags: TEvalFlags): PNode =
   of nkEmpty: result = n
   of nkSym: result = evalSym(c, n, flags)
   of nkType..nkNilLit: result = copyNode(n) # end of atoms
-  of nkCall, nkHiddenCallConv, nkMacroStmt, nkCommand, nkCallStrLit, nkInfix,
+  of nkCall, nkHiddenCallConv, nkCommand, nkCallStrLit, nkInfix,
      nkPrefix, nkPostfix: 
     result = evalMagicOrCall(c, n)
   of nkCurly, nkBracket, nkRange: 
diff --git a/compiler/idents.nim b/compiler/idents.nim
index f6df3ba93..838d445d3 100755
--- a/compiler/idents.nim
+++ b/compiler/idents.nim
@@ -101,4 +101,6 @@ proc getIdent*(identifier: string, h: THash): PIdent =
 
 proc IdentEq*(id: PIdent, name: string): bool = 
   result = id.id == getIdent(name).id
-  
+
+let idAnon* = getIdent":anonymous"
+
diff --git a/compiler/msgs.nim b/compiler/msgs.nim
index e29142e4f..0d9a05240 100755
--- a/compiler/msgs.nim
+++ b/compiler/msgs.nim
@@ -585,22 +585,25 @@ proc inCheckpoint*(current: TLineInfo): TCheckPointResult =
 type
   TErrorHandling = enum doNothing, doAbort, doRaise
 
-proc handleError(msg: TMsgKind, eh: TErrorHandling, s: string) = 
-  if msg == errInternal: 
-    assert(false)             # we want a stack trace here
+proc handleError(msg: TMsgKind, eh: TErrorHandling, s: string) =
+  template maybeTrace =
+    if defined(debug) or gVerbosity >= 3:
+      writeStackTrace()
+
+  if msg == errInternal:
+    writeStackTrace() # we always want a stack trace here
   if msg >= fatalMin and msg <= fatalMax: 
-    if gVerbosity >= 3: assert(false)
+    maybeTrace()
     quit(1)
   if msg >= errMin and msg <= errMax: 
-    if gVerbosity >= 3: assert(false)
+    maybeTrace()
     inc(gErrorCounter)
     options.gExitcode = 1'i8
     if gErrorCounter >= gErrorMax or eh == doAbort: 
-      if gVerbosity >= 3: assert(false)
-      quit(1)                 # one error stops the compiler
+      quit(1)                        # one error stops the compiler
     elif eh == doRaise:
       raiseRecoverableError(s)
-  
+
 proc `==`*(a, b: TLineInfo): bool = 
   result = a.line == b.line and a.fileIndex == b.fileIndex
 
diff --git a/compiler/options.nim b/compiler/options.nim
index c6b2053b1..316ec2b14 100755
--- a/compiler/options.nim
+++ b/compiler/options.nim
@@ -227,5 +227,7 @@ proc binaryStrSearch*(x: openarray[string], y: string): int =
   result = - 1
 
 # Can we keep this? I'm using it all the time
-template nimdbg*: expr = c.filename.endsWith"nimdbg.nim"
-template cnimdbg*: expr = p.module.filename.endsWith"nimdbg.nim"
+template nimdbg*: expr = c.filename.endsWith"hallo.nim"
+template cnimdbg*: expr = p.module.filename.endsWith"hallo.nim"
+template enimdbg*: expr = c.module.name.s == "hallo"
+template pnimdbg*: expr = p.lex.fileIdx.ToFilename.endsWith"hallo.nim"
diff --git a/compiler/parser.nim b/compiler/parser.nim
index 7612980c5..095252d59 100755
--- a/compiler/parser.nim
+++ b/compiler/parser.nim
@@ -693,20 +693,15 @@ proc optPragmas(p: var TParser): PNode =
   else: result = ast.emptyNode
 
 proc parseDoBlock(p: var TParser): PNode =
-  var info = parLineInfo(p)
+  let info = parLineInfo(p)
   getTok(p)
-  var params = parseParamList(p, retColon=false)
-  var pragmas = optPragmas(p)
+  let params = parseParamList(p, retColon=false)
+  let pragmas = optPragmas(p)
   eat(p, tkColon)
-  result = newNodeI(nkDo, info)
-  addSon(result, ast.emptyNode)       # no name part
-  addSon(result, ast.emptyNode)       # no pattern part
-  addSon(result, ast.emptyNode)       # no generic parameters
-  addSon(result, params)
-  addSon(result, pragmas)
   skipComment(p, result)
-  addSon(result, ast.emptyNode)       # no exception list
-  addSon(result, parseStmt(p))
+  result = newProcNode(nkDo, info, parseStmt(p),
+                       params = params,
+                       pragmas = pragmas)
 
 proc parseDoBlocks(p: var TParser, call: PNode) =
   while p.tok.tokType == tkDo:
@@ -723,16 +718,11 @@ proc parseProcExpr(p: var TParser, isExpr: bool): PNode =
   params = parseParamList(p)
   pragmas = optPragmas(p)
   if p.tok.tokType == tkEquals and isExpr: 
-    result = newNodeI(nkLambda, info)
-    addSon(result, ast.emptyNode)       # no name part
-    addSon(result, ast.emptyNode)       # no pattern
-    addSon(result, ast.emptyNode)       # no generic parameters
-    addSon(result, params)
-    addSon(result, pragmas)
     getTok(p)
     skipComment(p, result)
-    addSon(result, ast.emptyNode)       # no exception list
-    addSon(result, parseStmt(p))
+    result = newProcNode(nkLambda, info, parseStmt(p),
+                         params = params,
+                         pragmas = pragmas)
   else: 
     result = newNodeI(nkProcTy, info)
     if hasSignature:
@@ -822,7 +812,7 @@ proc primary(p: var TParser, skipSuffix = false): PNode =
 proc parseTypeDesc(p: var TParser): PNode = 
   if p.tok.toktype == tkProc: result = parseProcExpr(p, false)
   else: result = parseExpr(p)
-  
+
 proc parseExprStmt(p: var TParser): PNode = 
   var a = lowestExpr(p)
   if p.tok.tokType == tkEquals: 
@@ -832,32 +822,29 @@ proc parseExprStmt(p: var TParser): PNode =
     result = newNodeI(nkAsgn, a.info)
     addSon(result, a)
     addSon(result, b)
-  else: 
-    result = newNodeP(nkCommand, p)
-    result.info = a.info
-    addSon(result, a)
-    while true: 
+  else:
+    var call = if a.kind == nkCall: a
+               else: newNode(nkCommand, a.info, @[a])
+    while true:
       if not isExprStart(p): break 
       var e = parseExpr(p)
-      addSon(result, e)
+      addSon(call, e)
       if p.tok.tokType != tkComma: break 
       getTok(p)
       optInd(p, a)
     if p.tok.tokType == tkDo:
-      parseDoBlocks(p, result)
+      parseDoBlocks(p, call)
       return    
-    if sonsLen(result) <= 1: result = a
-    else: a = result
+    result = if call.sonsLen <= 1: a
+             else: call
     if p.tok.tokType == tkColon:
-      # macro statement
-      result = newNodeP(nkMacroStmt, p)
-      result.info = a.info
-      addSon(result, a)
+      result = call
       getTok(p)
       skipComment(p, result)
       if p.tok.tokType == tkSad: getTok(p)
-      if not (p.tok.TokType in {tkOf, tkElif, tkElse, tkExcept}): 
-        addSon(result, parseStmt(p))
+      if not (p.tok.TokType in {tkOf, tkElif, tkElse, tkExcept}):
+        let body = parseStmt(p)
+        addSon(result, newProcNode(nkDo, body.info, body))
       while true: 
         if p.tok.tokType == tkSad: getTok(p)
         var b: PNode
@@ -882,7 +869,7 @@ proc parseExprStmt(p: var TParser): PNode =
         else: break 
         addSon(b, parseStmt(p))
         addSon(result, b)
-        if b.kind == nkElse: break 
+        if b.kind == nkElse: break
     
 proc parseImportOrIncludeStmt(p: var TParser, kind: TNodeKind): PNode = 
   var a: PNode
diff --git a/compiler/renderer.nim b/compiler/renderer.nim
index 5199e234d..de642eccb 100755
--- a/compiler/renderer.nim
+++ b/compiler/renderer.nim
@@ -1051,7 +1051,6 @@ proc gsub(g: var TSrcGen, n: PNode, c: TContext) =
   of nkWhileStmt: gwhile(g, n)
   of nkPragmaBlock: gpragmaBlock(g, n)
   of nkCaseStmt, nkRecCase: gcase(g, n)
-  of nkMacroStmt: gmacro(g, n)
   of nkTryStmt: gtry(g, n)
   of nkForStmt, nkParForStmt: gfor(g, n)
   of nkBlockStmt, nkBlockExpr: gblock(g, n)
diff --git a/compiler/sem.nim b/compiler/sem.nim
index 0a6159dfa..9289df61c 100755
--- a/compiler/sem.nim
+++ b/compiler/sem.nim
@@ -22,8 +22,7 @@ proc semPass*(): TPass
 
 type 
   TExprFlag = enum 
-    efLValue, efWantIterator, efInTypeof, efWantStmt, 
-    efMacroStmt # expr to semcheck is a macro statement
+    efLValue, efWantIterator, efInTypeof, efWantStmt, efDetermineType
   TExprFlags = set[TExprFlag]
 
 proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode
@@ -35,7 +34,7 @@ proc semProcBody(c: PContext, n: PNode): PNode
 proc fitNode(c: PContext, formal: PType, arg: PNode): PNode
 proc changeType(n: PNode, newType: PType)
 
-proc semLambda(c: PContext, n: PNode): PNode
+proc semLambda(c: PContext, n: PNode, flags: TExprFlags): PNode
 proc semTypeNode(c: PContext, n: PNode, prev: PType): PType
 proc semStmt(c: PContext, n: PNode): PNode
 proc semParamList(c: PContext, n, genericParams: PNode, s: PSym)
@@ -44,6 +43,8 @@ proc addResult(c: PContext, t: PType, info: TLineInfo, owner: TSymKind)
 proc addResultNode(c: PContext, n: PNode)
 proc instGenericContainer(c: PContext, n: PNode, header: PType): PType
 proc tryExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode
+proc fixImmediateParams(n: PNode): PNode
+proc activate(c: PContext, n: PNode)
 
 proc typeMismatch(n: PNode, formal, actual: PType) = 
   if formal.kind != tyError and actual.kind != tyError: 
@@ -91,8 +92,6 @@ proc semTemplateExpr(c: PContext, n: PNode, s: PSym, semCheck = true): PNode
 
 proc semMacroExpr(c: PContext, n, nOrig: PNode, sym: PSym, 
                   semCheck: bool = true): PNode
-proc semMacroStmt(c: PContext, n: PNode, flags: TExprFlags,
-                  semCheck = true): PNode
 proc semDirectOp(c: PContext, n: PNode, flags: TExprFlags): PNode
 
 proc semWhen(c: PContext, n: PNode, semCheck: bool = true): PNode
diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim
index e9dc5a8e9..adcd67ea3 100755
--- a/compiler/semexprs.nim
+++ b/compiler/semexprs.nim
@@ -304,16 +304,17 @@ proc semIs(c: PContext, n: PNode): PNode =
     # BUGFIX: don't evaluate this too early: ``T is void``
     if not containsGenericType(t1): result = evalIsOp(n)
   
-proc semOpAux(c: PContext, n: PNode, tailToExclude = 1) =
-  for i in countup(1, sonsLen(n) - tailToExclude):
+proc semOpAux(c: PContext, n: PNode) =
+  let flags = {efDetermineType}
+  for i in countup(1, n.sonsLen- 1):
     var a = n.sons[i]
     if a.kind == nkExprEqExpr and sonsLen(a) == 2: 
       var info = a.sons[0].info
       a.sons[0] = newIdentNode(considerAcc(a.sons[0]), info)
-      a.sons[1] = semExprWithType(c, a.sons[1])
+      a.sons[1] = semExprWithType(c, a.sons[1], flags)
       a.typ = a.sons[1].typ
     else:
-      n.sons[i] = semExprWithType(c, a)
+      n.sons[i] = semExprWithType(c, a, flags)
     
 proc overloadedCallOpr(c: PContext, n: PNode): PNode = 
   # quick check if there is *any* () operator overloaded:
@@ -668,8 +669,7 @@ proc semIndirectOp(c: PContext, n: PNode, flags: TExprFlags): PNode =
 proc semDirectOp(c: PContext, n: PNode, flags: TExprFlags): PNode = 
   # this seems to be a hotspot in the compiler!
   let nOrig = n.copyTree
-  semOpAux(c, n, 1 + ord(efMacroStmt in flags))
-  let flags = flags - {efMacroStmt}
+  semOpAux(c, n)
   result = semOverloadedCallAnalyseEffects(c, n, nOrig, flags)
   if result == nil:
     result = overloadedCallOpr(c, n)
@@ -679,8 +679,9 @@ proc semDirectOp(c: PContext, n: PNode, flags: TExprFlags): PNode =
   let callee = result.sons[0].sym
   case callee.kind
   of skMacro: result = semMacroExpr(c, result, nOrig, callee)
-  of skTemplate: result = semTemplateExpr(c, nOrig, callee)
+  of skTemplate: result = semTemplateExpr(c, result, callee)
   else:
+    activate(c, n)
     fixAbstractType(c, result)
     analyseIfAddressTakenInCall(c, result)
     if callee.magic != mNone:
@@ -1281,7 +1282,7 @@ proc semCompiles(c: PContext, n: PNode, flags: TExprFlags): PNode =
   # we replace this node by a 'true' or 'false' node:
   if sonsLen(n) != 2: return semDirectOp(c, n, flags)
   
-  result = newIntNode(nkIntLit, ord(tryExpr(c, n, flags) != nil))
+  result = newIntNode(nkIntLit, ord(tryExpr(c, n[1], flags) != nil))
   result.info = n.info
   result.typ = getSysType(tyBool)
 
@@ -1496,52 +1497,6 @@ proc buildCall(n: PNode): PNode =
   else:
     result = n
 
-proc semMacroStmt(c: PContext, n: PNode, flags: TExprFlags, 
-                  semCheck = true): PNode =
-  checkMinSonsLen(n, 2)
-  var a: PNode
-  if isCallExpr(n.sons[0]): a = n.sons[0].sons[0]
-  else: a = n.sons[0]
-  var s = qualifiedLookup(c, a, {checkUndeclared})
-  if s != nil: 
-    # transform
-    # nkMacroStmt(nkCall(a...), stmt, b...)
-    # to
-    # nkCall(a..., stmt, b...)
-    result = newNodeI(nkCall, n.info)
-    addSon(result, a)
-    if isCallExpr(n.sons[0]):
-      for i in countup(1, sonsLen(n.sons[0]) - 1):
-        addSon(result, n.sons[0].sons[i])
-    # for sigmatch this need to have a type; we use 'void':
-    for i in countup(1, sonsLen(n) - 1):
-      n.sons[i].typ = newTypeS(tyEmpty, c)
-      addSon(result, n.sons[i])
-
-    case s.kind
-    of skMacro:
-      if sfImmediate notin s.flags:
-        result = semDirectOp(c, result, flags+{efMacroStmt})
-      else:
-        result = semMacroExpr(c, result, n, s, semCheck)
-    of skTemplate: 
-      if sfImmediate notin s.flags:
-        result = semDirectOp(c, result, flags+{efMacroStmt})
-      else:
-        result = semTemplateExpr(c, result, s, semCheck)
-    else:
-      LocalError(n.info, errXisNoMacroOrTemplate, s.name.s)
-      result = errorNode(c, n)
-  elif a.kind == nkDotExpr:
-    # 'x.m(y): stmt' ==  nkMacroStmt(nkCall(nkDotExpr(x, m), y), stmt)
-    # -->                nkMacroStmt(nkCall(m, x, y), stmt)
-    n.sons[0] = buildCall(n.sons[0])
-    result = semMacroStmt(c, n, flags, semCheck)
-  else:
-    LocalError(n.info, errInvalidExpressionX, 
-               renderTree(a, {renderNoComments}))
-    result = errorNode(c, n)
-
 proc semCaseExpr(c: PContext, caseStmt: PNode): PNode =
   # The case expression is simply rewritten to a StmtListExpr:
   #   var res {.noInit, genSym.}: type(values)
@@ -1553,7 +1508,7 @@ proc semCaseExpr(c: PContext, caseStmt: PNode): PNode =
   #   res
   var
     info = caseStmt.info
-    resVar = newSym(skVar, getIdent":res", getCurrOwner(), info)
+    resVar = newSym(skVar, idAnon, getCurrOwner(), info)
     resNode = newSymNode(resVar, info)
     resType: PType
 
@@ -1592,7 +1547,15 @@ proc semCaseExpr(c: PContext, caseStmt: PNode): PNode =
     resNode])
 
   result = semStmtListExpr(c, result)
-    
+
+proc fixImmediateParams(n: PNode): PNode =
+  # XXX: Temporary work-around until we carry out
+  # the planned overload resolution reforms
+  for i in 1 .. <n.len:
+    if n[i].kind == nkDo: n.sons[i] = n[i][bodyPos]
+  
+  result = n
+
 proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode = 
   result = n
   if gCmd == cmdIdeTools: suggestExpr(c, n)
@@ -1670,12 +1633,14 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
         if sfImmediate notin s.flags:
           result = semDirectOp(c, n, flags)
         else:
-          result = semMacroExpr(c, n, n, s)
+          var p = fixImmediateParams(n)
+          result = semMacroExpr(c, p, p, s)
       of skTemplate:
         if sfImmediate notin s.flags:
           result = semDirectOp(c, n, flags)
         else:
-          result = semTemplateExpr(c, n, s)
+          var p = fixImmediateParams(n)
+          result = semTemplateExpr(c, p, s)
       of skType:
         # XXX think about this more (``set`` procs)
         if n.len == 2:
@@ -1695,8 +1660,6 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
       result = semDirectOp(c, n, flags)
     else:
       result = semIndirectOp(c, n, flags)
-  of nkMacroStmt: 
-    result = semMacroStmt(c, n, flags)
   of nkWhen:
     if efWantStmt in flags:
       result = semWhen(c, n, true)
@@ -1725,7 +1688,7 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
     of paSingle: result = semExpr(c, n.sons[0], flags)
   of nkCurly: result = semSetConstr(c, n)
   of nkBracket: result = semArrayConstr(c, n)
-  of nkLambdaKinds: result = semLambda(c, n)
+  of nkLambdaKinds: result = semLambda(c, n, flags)
   of nkDerefExpr: result = semDeref(c, n)
   of nkAddr: 
     result = n
diff --git a/compiler/semgnrc.nim b/compiler/semgnrc.nim
index bffa8ad8e..4b0c81433 100755
--- a/compiler/semgnrc.nim
+++ b/compiler/semgnrc.nim
@@ -53,6 +53,7 @@ proc semGenericStmtSymbol(c: PContext, n: PNode, s: PSym): PNode =
     result = symChoice(c, n, s, scOpen)
   of skTemplate:
     if macroToExpand(s):
+      let n = fixImmediateParams(n)
       result = semTemplateExpr(c, n, s, false)
     else:
       result = symChoice(c, n, s, scOpen)
@@ -123,6 +124,7 @@ proc semGenericStmt(c: PContext, n: PNode,
           result = n
       of skTemplate: 
         if macroToExpand(s):
+          let n = fixImmediateParams(n)
           result = semTemplateExpr(c, n, s, false)
         else:
           n.sons[0] = symChoice(c, n.sons[0], s, scOpen)
@@ -151,17 +153,6 @@ proc semGenericStmt(c: PContext, n: PNode,
     let flags = if isDefinedMagic: flags+{withinMixin} else: flags
     for i in countup(first, sonsLen(result) - 1):
       result.sons[i] = semGenericStmt(c, result.sons[i], flags, toBind)
-  of nkMacroStmt: 
-    checkMinSonsLen(n, 2)
-    var a: PNode
-    if isCallExpr(n.sons[0]): a = n.sons[0].sons[0]
-    else: a = n.sons[0]
-    let luf = if withinMixin notin flags: {checkUndeclared} else: {}
-    var s = qualifiedLookup(c, a, luf)
-    if s != nil and macroToExpand(s):
-      result = semMacroStmt(c, n, {}, false)
-    for i in countup(0, sonsLen(result)-1): 
-      result.sons[i] = semGenericStmt(c, result.sons[i], flags, toBind)
   of nkIfStmt: 
     for i in countup(0, sonsLen(n)-1): 
       n.sons[i] = semGenericStmtScope(c, n.sons[i], flags, toBind)
diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim
index 2dad56272..0a2275229 100755
--- a/compiler/semstmts.nim
+++ b/compiler/semstmts.nim
@@ -623,9 +623,9 @@ proc semProcAnnotation(c: PContext, prc: PNode): PNode =
     var key = if it.kind == nkExprColonExpr: it.sons[0] else: it
     let m = lookupMacro(c, key)
     if m == nil: continue
-    # we transform ``proc p {.m, rest.}`` into ``m: proc p {.rest.}`` and
+    # we transform ``proc p {.m, rest.}`` into ``m(proc p {.rest.})`` and
     # let the semantic checker deal with it:
-    var x = newNodeI(nkMacroStmt, n.info)
+    var x = newNodeI(nkCall, n.info)
     x.add(newSymNode(m))
     prc.sons[pragmasPos] = copyExcept(n, i)
     if it.kind == nkExprColonExpr:
@@ -634,15 +634,19 @@ proc semProcAnnotation(c: PContext, prc: PNode): PNode =
     x.add(prc)
     # recursion assures that this works for multiple macro annotations too:
     return semStmt(c, x)
-  
-proc semLambda(c: PContext, n: PNode): PNode = 
+
+proc semLambda(c: PContext, n: PNode, flags: TExprFlags): PNode =
   result = semProcAnnotation(c, n)
   if result != nil: return result
   result = n
   checkSonsLen(n, bodyPos + 1)
-  var s = newSym(skProc, getIdent":anonymous", getCurrOwner(), n.info)
-  s.ast = n
-  n.sons[namePos] = newSymNode(s)
+  var s: PSym
+  if n[namePos].kind != nkSym:
+    s = newSym(skProc, idAnon, getCurrOwner(), n.info)
+    s.ast = n
+    n.sons[namePos] = newSymNode(s)
+  else:
+    s = n[namePos].sym
   pushOwner(s)
   openScope(c.tab)
   if n.sons[genericParamsPos].kind != nkEmpty:
@@ -659,19 +663,31 @@ proc semLambda(c: PContext, n: PNode): PNode =
   if n.sons[bodyPos].kind != nkEmpty: 
     if sfImportc in s.flags: 
       LocalError(n.sons[bodyPos].info, errImplOfXNotAllowed, s.name.s)
-    pushProcCon(c, s)
-    addResult(c, s.typ.sons[0], n.info, skProc)
-    let semBody = hloBody(c, semProcBody(c, n.sons[bodyPos]))
-    n.sons[bodyPos] = transformBody(c.module, semBody, s)
-    addResultNode(c, n)
-    popProcCon(c)
+    if efDetermineType notin flags:
+      pushProcCon(c, s)
+      addResult(c, s.typ.sons[0], n.info, skProc)
+      let semBody = hloBody(c, semProcBody(c, n.sons[bodyPos]))
+      n.sons[bodyPos] = transformBody(c.module, semBody, s)
+      addResultNode(c, n)
+      popProcCon(c)
+      sideEffectsCheck(c, s)
   else:
     LocalError(n.info, errImplOfXexpected, s.name.s)
-  sideEffectsCheck(c, s)
   closeScope(c.tab)           # close scope for parameters
   popOwner()
   result.typ = s.typ
 
+proc activate(c: PContext, n: PNode) =
+  # XXX: This proc is part of my plan for getting rid of
+  # forward declarations. stay tuned.
+  case n.kind
+  of nkLambdaKinds:
+    discard semLambda(c, n, {})
+  of nkCallKinds:
+    for i in 1 .. <n.len: activate(c, n[i])
+  else:
+    nil
+
 proc instantiateDestructor*(c: PContext, typ: PType): bool
 
 proc doDestructorStuff(c: PContext, s: PSym, n: PNode) =
diff --git a/compiler/semtypinst.nim b/compiler/semtypinst.nim
index 70453c6db..d51e24c89 100755
--- a/compiler/semtypinst.nim
+++ b/compiler/semtypinst.nim
@@ -64,10 +64,11 @@ proc ReplaceTypeVarsN(cl: var TReplTypeVars, n: PNode): PNode
 proc prepareNode(cl: var TReplTypeVars, n: PNode): PNode =
   result = copyNode(n)
   result.typ = ReplaceTypeVarsT(cl, n.typ)
+  if result.kind == nkSym: result.sym = ReplaceTypeVarsS(cl, n.sym)
   for i in 0 .. safeLen(n)-1: 
     # XXX HACK: ``f(a, b)``, avoid to instantiate `f` 
     if i == 0: result.add(n[i])
-    else: result.add(ReplaceTypeVarsN(cl, n[i]))
+    else: result.add(prepareNode(cl, n[i]))
 
 proc ReplaceTypeVarsN(cl: var TReplTypeVars, n: PNode): PNode =
   if n == nil: return
diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim
index 8f1ca5f36..cfae74119 100755
--- a/compiler/sigmatch.nim
+++ b/compiler/sigmatch.nim
@@ -637,8 +637,12 @@ proc ParamTypesMatchAux(c: PContext, m: var TCandidate, f, a: PType,
   of isGeneric:
     inc(m.genericMatches)
     if m.calleeSym != nil and m.calleeSym.kind in {skMacro, skTemplate}:
-      if f.kind == tyTypeDesc: result = arg
-      else: result = argOrig
+      if f.kind == tyStmt and argOrig.kind == nkDo:
+        result = argOrig[bodyPos]
+      elif f.kind == tyTypeDesc:
+        result = arg
+      else:
+        result = argOrig
     else:
       result = copyTree(arg)
       result.typ = getInstantiatedType(c, arg, m, f) 
diff --git a/compiler/suggest.nim b/compiler/suggest.nim
index 719d0aa42..51f250251 100755
--- a/compiler/suggest.nim
+++ b/compiler/suggest.nim
@@ -175,8 +175,7 @@ proc findClosestDot(n: PNode): PNode =
       if result != nil: return
 
 const
-  CallNodes = {nkCall, nkInfix, nkPrefix, nkPostfix, nkCommand, nkCallStrLit,
-               nkMacroStmt}
+  CallNodes = {nkCall, nkInfix, nkPrefix, nkPostfix, nkCommand, nkCallStrLit}
 
 proc findClosestCall(n: PNode): PNode = 
   if n.kind in callNodes and msgs.inCheckpoint(n.info) == cpExact: