summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAraq <rumpf_a@web.de>2014-01-19 01:25:23 +0100
committerAraq <rumpf_a@web.de>2014-01-19 01:25:23 +0100
commit6df259f15b8507b1d7be6f72759daeb537ff7ac5 (patch)
treebde0df9349faf368a27443368267f95cfe621a77
parentd986a5adb5014e1dedf3427399f933f1b898a554 (diff)
downloadNim-6df259f15b8507b1d7be6f72759daeb537ff7ac5.tar.gz
'inject' for the new symbol binding rules in templates
-rw-r--r--compiler/semtempl.nim26
1 files changed, 19 insertions, 7 deletions
diff --git a/compiler/semtempl.nim b/compiler/semtempl.nim
index 569d92d33..5abc3ef33 100644
--- a/compiler/semtempl.nim
+++ b/compiler/semtempl.nim
@@ -1,7 +1,7 @@
 #
 #
 #           The Nimrod Compiler
-#        (c) Copyright 2013 Andreas Rumpf
+#        (c) Copyright 2014 Andreas Rumpf
 #
 #    See the file "copying.txt", included in this
 #    distribution, for details about the copyright.
@@ -38,7 +38,7 @@ proc symBinding(n: PNode): TSymBinding =
       case whichKeyword(key.ident)
       of wGensym: return spGenSym
       of wInject: return spInject
-      else: nil
+      else: discard
 
 type
   TSymChoiceRule = enum
@@ -106,7 +106,7 @@ proc replaceIdentBySym(n: var PNode, s: PNode) =
 type
   TemplCtx {.pure, final.} = object
     c: PContext
-    toBind, toMixin: TIntSet
+    toBind, toMixin, toInject: TIntSet
     owner: PSym
 
 proc getIdentNode(c: var TemplCtx, n: PNode): PNode =
@@ -145,7 +145,18 @@ proc newGenSym(kind: TSymKind, n: PNode, c: var TemplCtx): PSym =
 
 proc addLocalDecl(c: var TemplCtx, n: var PNode, k: TSymKind) =
   # locals default to 'gensym':
-  if n.kind != nkPragmaExpr or symBinding(n.sons[1]) != spInject:
+  if n.kind == nkPragmaExpr and symBinding(n.sons[1]) == spInject:
+    # even if injected, don't produce a sym choice here:
+    #n = semTemplBody(c, n)
+    var x = n[0]
+    while true:
+      case x.kind
+      of nkPostfix: x = x[1]
+      of nkPragmaExpr: x = x[0]
+      of nkIdent: break
+      else: illFormedAst(x)
+    c.toInject.incl(x.ident.id)
+  else:
     let ident = getIdentNode(c, n)
     if not isTemplParam(c, ident):
       let local = newGenSym(k, ident, c)
@@ -153,8 +164,6 @@ proc addLocalDecl(c: var TemplCtx, n: var PNode, k: TSymKind) =
       replaceIdentBySym(n, newSymNode(local, n.info))
     else:
       replaceIdentBySym(n, ident)
-  else:
-    n = semTemplBody(c, n)
 
 proc semTemplSymbol(c: PContext, n: PNode, s: PSym): PNode = 
   incl(s.flags, sfUsed)
@@ -224,6 +233,7 @@ proc semTemplBody(c: var TemplCtx, n: PNode): PNode =
   result = n
   case n.kind
   of nkIdent:
+    if n.ident.id in c.toInject: return n
     let s = qualifiedLookUp(c.c, n, {})
     if s != nil:
       if s.owner == c.owner and s.kind == skParam:
@@ -247,7 +257,7 @@ proc semTemplBody(c: var TemplCtx, n: PNode): PNode =
   of nkMixinStmt:
     result = semMixinStmt(c.c, n, c.toMixin)
   of nkEmpty, nkSym..nkNilLit:
-    nil
+    discard
   of nkIfStmt:
     for i in countup(0, sonsLen(n)-1):
       var it = n.sons[i]
@@ -457,6 +467,7 @@ proc semTemplateDef(c: PContext, n: PNode): PNode =
   var ctx: TemplCtx
   ctx.toBind = initIntSet()
   ctx.toMixin = initIntSet()
+  ctx.toInject = initIntSet()
   ctx.c = c
   ctx.owner = s
   if sfDirty in s.flags:
@@ -598,6 +609,7 @@ proc semPattern(c: PContext, n: PNode): PNode =
   var ctx: TemplCtx
   ctx.toBind = initIntSet()
   ctx.toMixin = initIntSet()
+  ctx.toInject = initIntSet()
   ctx.c = c
   ctx.owner = getCurrOwner()
   result = flattenStmts(semPatternBody(ctx, n))