From b5d34242ca7156ec702f8e63a01c9cd059d28e5f Mon Sep 17 00:00:00 2001 From: Araq Date: Tue, 26 Jun 2012 01:00:32 +0200 Subject: added proc annotations: macros invoked as pragmas --- compiler/astalgo.nim | 7 +++++++ compiler/pragmas.nim | 11 +++++++---- compiler/seminst.nim | 4 ++-- compiler/semstmts.nim | 36 ++++++++++++++++++++++++++++++++++++ doc/manual.txt | 23 ++++++++++++++++++++++- todo.txt | 1 + web/news.txt | 1 + 7 files changed, 76 insertions(+), 7 deletions(-) diff --git a/compiler/astalgo.nim b/compiler/astalgo.nim index 41fbd3cf1..70cb8653e 100755 --- a/compiler/astalgo.nim +++ b/compiler/astalgo.nim @@ -91,6 +91,7 @@ type proc InitSymTab*(tab: var TSymTab) proc DeinitSymTab*(tab: var TSymTab) proc SymTabGet*(tab: TSymTab, s: PIdent): PSym +proc SymTabGet*(tab: TSymTab, s: PIdent, filter: TSymKinds): PSym proc SymTabLocalGet*(tab: TSymTab, s: PIdent): PSym proc SymTabAdd*(tab: var TSymTab, e: PSym) proc SymTabAddAt*(tab: var TSymTab, e: PSym, at: Natural) @@ -703,6 +704,12 @@ proc SymTabGet(tab: TSymTab, s: PIdent): PSym = if result != nil: return result = nil +proc SymTabGet*(tab: TSymTab, s: PIdent, filter: TSymKinds): PSym = + for i in countdown(tab.tos - 1, 0): + result = StrTableGet(tab.stack[i], s) + if result != nil and result.kind in filter: return + result = nil + proc SymTabAddAt(tab: var TSymTab, e: PSym, at: Natural) = StrTableAdd(tab.stack[at], e) diff --git a/compiler/pragmas.nim b/compiler/pragmas.nim index d4a635058..348bf9bc6 100755 --- a/compiler/pragmas.nim +++ b/compiler/pragmas.nim @@ -431,17 +431,20 @@ proc processPragma(c: PContext, n: PNode, i: int) = for j in i+1 .. sonsLen(n)-1: addSon(body, n.sons[j]) userPragma.ast = body StrTableAdd(c.userPragmas, userPragma) - -proc pragma(c: PContext, sym: PSym, n: PNode, validPragmas: TSpecialWords) = - if n == nil: return + +proc pragma(c: PContext, sym: PSym, n: PNode, validPragmas: TSpecialWords) = + if n == nil: return for i in countup(0, sonsLen(n) - 1): var it = n.sons[i] var key = if it.kind == nkExprColonExpr: it.sons[0] else: it if key.kind == nkIdent: var userPragma = StrTableGet(c.userPragmas, key.ident) if userPragma != nil: + inc c.InstCounter + if c.InstCounter > 100: + GlobalError(it.info, errRecursiveDependencyX, userPragma.name.s) pragma(c, sym, userPragma.ast, validPragmas) - # XXX BUG: possible infinite recursion! + dec c.InstCounter else: var k = whichKeyword(key.ident) if k in validPragmas: diff --git a/compiler/seminst.nim b/compiler/seminst.nim index f44b80223..a2f4129ea 100755 --- a/compiler/seminst.nim +++ b/compiler/seminst.nim @@ -139,6 +139,8 @@ proc generateInstance(c: PContext, fn: PSym, pt: TIdTable, # generates an instantiated proc if c.InstCounter > 1000: InternalError(fn.ast.info, "nesting too deep") inc(c.InstCounter) + # careful! we copy the whole AST including the possibly nil body! + var n = copyTree(fn.ast) # NOTE: for access of private fields within generics from a different module # we set the friend module: var oldFriend = c.friendModule @@ -148,8 +150,6 @@ proc generateInstance(c: PContext, fn: PSym, pt: TIdTable, # keep the owner if it's an inner proc (for proper closure transformations): if fn.owner.kind == skModule: result.owner = getCurrOwner().owner - # careful! we copy the whole AST including the possibly nil body! - var n = copyTree(fn.ast) result.ast = n pushOwner(result) openScope(c.tab) diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim index eb7660dd6..bc7f00c87 100755 --- a/compiler/semstmts.nim +++ b/compiler/semstmts.nim @@ -644,8 +644,42 @@ proc addResult(c: PContext, t: PType, info: TLineInfo, owner: TSymKind) = proc addResultNode(c: PContext, n: PNode) = if c.p.resultSym != nil: addSon(n, newSymNode(c.p.resultSym)) + +proc copyExcept(n: PNode, i: int): PNode = + result = copyNode(n) + for j in 0..