summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--compiler/ccgcalls.nim2
-rw-r--r--compiler/semtempl.nim47
-rw-r--r--lib/pure/sockets.nim2
-rw-r--r--lib/system.nim3
-rw-r--r--todo.txt3
5 files changed, 49 insertions, 8 deletions
diff --git a/compiler/ccgcalls.nim b/compiler/ccgcalls.nim
index b8b7f4c44..1d6df3c15 100644
--- a/compiler/ccgcalls.nim
+++ b/compiler/ccgcalls.nim
@@ -163,7 +163,7 @@ proc genClosureCall(p: BProc, le, ri: PNode, d: var TLoc) =
       app(pl, genArgNoParam(p, ri.sons[i]))
     if i < length - 1: app(pl, ~", ")
   
-  template genCallPattern =
+  template genCallPattern {.dirty.} =
     lineF(p, cpsStmts, CallPattern & ";$n", op.r, pl, pl.addComma, rawProc)
 
   let rawProc = getRawProcType(p, typ)
diff --git a/compiler/semtempl.nim b/compiler/semtempl.nim
index 68abc9aa6..66cc3a983 100644
--- a/compiler/semtempl.nim
+++ b/compiler/semtempl.nim
@@ -14,7 +14,7 @@ discard """
   
     template `||` (a, b: expr): expr =
       let aa = a
-      (if aa: aa else: b)
+      if aa: aa else: b
     
     var
       a, b: T
@@ -156,6 +156,37 @@ proc addLocalDecl(c: var TemplCtx, n: var PNode, k: TSymKind) =
   else:
     n = semTemplBody(c, n)
 
+proc semTemplSymbol(c: PContext, n: PNode, s: PSym): PNode = 
+  incl(s.flags, sfUsed)
+  case s.kind
+  of skUnknown: 
+    # Introduced in this pass! Leave it as an identifier.
+    result = n
+  of skProc, skMethod, skIterator, skConverter, skTemplate, skMacro:
+    result = symChoice(c, n, s, scOpen)
+  of skGenericParam: 
+    result = newSymNodeTypeDesc(s, n.info)
+  of skParam: 
+    result = n
+  of skType: 
+    if (s.typ != nil) and (s.typ.kind != tyGenericParam): 
+      result = newSymNodeTypeDesc(s, n.info)
+    else: 
+      result = n
+  else: result = newSymNode(s, n.info)
+
+proc semRoutineInTemplName(c: var TemplCtx, n: PNode): PNode =
+  result = n
+  if n.kind == nkIdent:
+    let s = QualifiedLookUp(c.c, n, {})
+    if s != nil:
+      if s.owner == c.owner and (s.kind == skParam or sfGenSym in s.flags):
+        incl(s.flags, sfUsed)
+        result = newSymNode(s, n.info)
+  else:
+    for i in countup(0, safeLen(n) - 1):
+      result.sons[i] = semRoutineInTemplName(c, n.sons[i])
+
 proc semRoutineInTemplBody(c: var TemplCtx, n: PNode, k: TSymKind): PNode =
   result = n
   checkSonsLen(n, bodyPos + 1)
@@ -170,14 +201,14 @@ proc semRoutineInTemplBody(c: var TemplCtx, n: PNode, k: TSymKind): PNode =
     else:
       n.sons[namePos] = ident
   else:
-    n.sons[namePos] = semTemplBody(c, n.sons[namePos])
+    n.sons[namePos] = semRoutineInTemplName(c, n.sons[namePos])
   openScope(c)
   for i in patternPos..bodyPos:
     n.sons[i] = semTemplBody(c, n.sons[i])
   closeScope(c)
 
 proc semTemplSomeDecl(c: var TemplCtx, n: PNode, symKind: TSymKind) =
-  for i in countup(ord(symkind == skConditional), sonsLen(n) - 1):
+  for i in countup(0, sonsLen(n) - 1):
     var a = n.sons[i]
     if a.kind == nkCommentStmt: continue
     if (a.kind != nkIdentDefs) and (a.kind != nkVarTuple): IllFormedAst(a)
@@ -200,11 +231,15 @@ proc semTemplBody(c: var TemplCtx, n: PNode): PNode =
         result = newSymNode(s, n.info)
       elif Contains(c.toBind, s.id):
         result = symChoice(c.c, n, s, scClosed)
+      elif Contains(c.toMixin, s.name.id):
+        result = symChoice(c.c, n, s, scForceOpen)
       elif s.owner == c.owner and sfGenSym in s.flags:
         # template tmp[T](x: var seq[T]) =
         # var yz: T
         incl(s.flags, sfUsed)
         result = newSymNode(s, n.info)
+      else:
+        result = semTemplSymbol(c.c, n, s)
   of nkBind:
     result = semTemplBody(c, n.sons[0])
   of nkBindStmt:
@@ -310,6 +345,10 @@ proc semTemplBody(c: var TemplCtx, n: PNode): PNode =
     result = semRoutineInTemplBody(c, n, skMacro)
   of nkConverterDef:
     result = semRoutineInTemplBody(c, n, skConverter)
+  of nkPragmaExpr:
+    result.sons[0] = semTemplBody(c, n.sons[0])
+  of nkPragma:
+    discard
   else:
     # dotExpr is ambiguous: note that we explicitely allow 'x.TemplateParam',
     # so we use the generic code for nkDotExpr too
@@ -318,6 +357,8 @@ proc semTemplBody(c: var TemplCtx, n: PNode): PNode =
       if s != nil:
         if Contains(c.toBind, s.id):
           return symChoice(c.c, n, s, scClosed)
+        elif Contains(c.toMixin, s.name.id):
+          return symChoice(c.c, n, s, scForceOpen)
     result = n
     for i in countup(0, sonsLen(n) - 1):
       result.sons[i] = semTemplBody(c, n.sons[i])
diff --git a/lib/pure/sockets.nim b/lib/pure/sockets.nim
index 2d602c86e..17e4d3118 100644
--- a/lib/pure/sockets.nim
+++ b/lib/pure/sockets.nim
@@ -1028,7 +1028,7 @@ proc readIntoBuf(socket: TSocket, flags: int32): int =
   socket.bufLen = result
   socket.currPos = 0
 
-template retRead(flags, readBytes: int) =
+template retRead(flags, readBytes: int) {.dirty.} =
   let res = socket.readIntoBuf(flags.int32)
   if res <= 0:
     if readBytes > 0:
diff --git a/lib/system.nim b/lib/system.nim
index 4cdc212b9..1e284f68a 100644
--- a/lib/system.nim
+++ b/lib/system.nim
@@ -194,7 +194,8 @@ when not defined(JS) and not defined(NimrodVM):
       data: array[0..100_000_000, char]
     NimString = ptr NimStringDesc
     
-  template space(s: PGenericSeq): int = s.reserved and not seqShallowFlag
+  template space(s: PGenericSeq): int {.dirty.} =
+    s.reserved and not seqShallowFlag
 
   include "system/hti"
 
diff --git a/todo.txt b/todo.txt
index d1dbf8b74..f18bdc585 100644
--- a/todo.txt
+++ b/todo.txt
@@ -1,8 +1,7 @@
 version 0.9.2
 =============
 
-- make 'bind' default for templates and introduce 'mixin';
-  special rule for ``[]=``
+- special rule for ``[]=``
 - ``=`` should be overloadable; requires specialization for ``=``; general
   lift mechanism in the compiler is already implemented for 'fields'
 - mocking support with ``tyProxy`` that does: fallback for ``.`` operator