summary refs log tree commit diff stats
path: root/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'compiler')
-rwxr-xr-xcompiler/sem.nim4
-rwxr-xr-xcompiler/seminst.nim5
-rwxr-xr-xcompiler/semstmts.nim11
-rwxr-xr-xcompiler/semtempl.nim36
-rwxr-xr-xcompiler/sigmatch.nim4
5 files changed, 36 insertions, 24 deletions
diff --git a/compiler/sem.nim b/compiler/sem.nim
index 0f9cb1d16..34b6f1f78 100755
--- a/compiler/sem.nim
+++ b/compiler/sem.nim
@@ -86,8 +86,6 @@ proc semMacroExpr(c: PContext, n: PNode, sym: PSym,
 
 proc semWhen(c: PContext, n: PNode, semCheck: bool = true): PNode
 
-include semtempl
-
 proc evalTypedExpr(c: PContext, e: PNode): PNode =
   result = getConstExpr(c.module, e)
   if result == nil:
@@ -154,7 +152,7 @@ proc semConstBoolExpr(c: PContext, n: PNode): PNode =
     LocalError(n.info, errConstExprExpected)
     result = nn
 
-include semtypes, semexprs, semgnrc, semstmts
+include semtypes, semtempl, semexprs, semgnrc, semstmts
 
 proc addCodeForGenerics(c: PContext, n: PNode) = 
   for i in countup(c.generics.lastGenericIdx, Len(c.generics.generics) - 1):
diff --git a/compiler/seminst.nim b/compiler/seminst.nim
index 8e4cb086d..2d1f68d5d 100755
--- a/compiler/seminst.nim
+++ b/compiler/seminst.nim
@@ -133,7 +133,10 @@ proc applyConcreteTypesToSig(genericProc: PSym, concTypes: seq[PType]): PType =
       if i > 0: result.n.sons[i] = sig.n.sons[i]
 
 proc generateInstance(c: PContext, fn: PSym, pt: TIdTable, 
-                      info: TLineInfo): PSym = 
+                      info: TLineInfo): PSym =
+  # no need to instantiate generic templates/macros:
+  if fn.kind in {skTemplate, skMacro}: return fn
+  
   # generates an instantiated proc
   if c.InstCounter > 1000: InternalError(fn.ast.info, "nesting too deep")
   inc(c.InstCounter)
diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim
index b8bf9e970..d12ad23cf 100755
--- a/compiler/semstmts.nim
+++ b/compiler/semstmts.nim
@@ -517,13 +517,12 @@ proc semTry(c: PContext, n: PNode): PNode =
     a.sons[length - 1] = semStmtScope(c, a.sons[length - 1])
   dec c.p.inTryStmt
 
-proc addGenericParamListToScope(c: PContext, n: PNode) = 
-  if n.kind != nkGenericParams: 
-    InternalError(n.info, "addGenericParamListToScope")
-  for i in countup(0, sonsLen(n)-1): 
+proc addGenericParamListToScope(c: PContext, n: PNode) =
+  if n.kind != nkGenericParams: illFormedAst(n)
+  for i in countup(0, sonsLen(n)-1):
     var a = n.sons[i]
     if a.kind == nkSym: addDecl(c, a.sym)
-    else: internalError(a.info, "addGenericParamListToScope")
+    else: illFormedAst(a)
 
 proc typeSectionLeftSidePass(c: PContext, n: PNode) = 
   # process the symbols on the left side for the whole type section, before
@@ -635,7 +634,7 @@ proc semParamList(c: PContext, n, genericParams: PNode, s: PSym) =
 proc addParams(c: PContext, n: PNode, kind: TSymKind) = 
   for i in countup(1, sonsLen(n)-1): 
     if n.sons[i].kind == nkSym: addParamOrResult(c, n.sons[i].sym, kind)
-    else: InternalError(n.info, "addParams")
+    else: illFormedAst(n)
 
 proc semBorrow(c: PContext, n: PNode, s: PSym) = 
   # search for the correct alias:
diff --git a/compiler/semtempl.nim b/compiler/semtempl.nim
index c16f4ce09..440fac6cc 100755
--- a/compiler/semtempl.nim
+++ b/compiler/semtempl.nim
@@ -183,8 +183,9 @@ 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 s.owner == c.owner:
-        InternalAssert sfGenSym in s.flags
+      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)
   of nkBind:
@@ -364,21 +365,32 @@ proc semTemplateDef(c: PContext, n: PNode): PNode =
   n.sons[namePos] = newSymNode(s, n.sons[namePos].info)
   if n.sons[pragmasPos].kind != nkEmpty:
     pragma(c, s, n.sons[pragmasPos], templatePragmas)
-  # check that no generic parameters exist:
+
+  var gp: PNode
   if n.sons[genericParamsPos].kind != nkEmpty: 
-    LocalError(n.info, errNoGenericParamsAllowedForX, "template")
-  if n.sons[paramsPos].kind == nkEmpty: 
-    # use ``stmt`` as implicit result type
-    s.typ = newTypeS(tyProc, c)
-    s.typ.n = newNodeI(nkFormalParams, n.info)
-    rawAddSon(s.typ, newTypeS(tyStmt, c))
-    addSon(s.typ.n, newNodeIT(nkType, n.info, s.typ.sons[0]))
+    n.sons[genericParamsPos] = semGenericParamList(c, n.sons[genericParamsPos])
+    gp = n.sons[genericParamsPos]
   else: 
-    semParamList(c, n.sons[ParamsPos], nil, s)
-    if n.sons[paramsPos].sons[0].kind == nkEmpty: 
+    gp = newNodeI(nkGenericParams, n.info)
+  # process parameters:
+  if n.sons[paramsPos].kind != nkEmpty:
+    semParamList(c, n.sons[ParamsPos], gp, s)
+    if sonsLen(gp) > 0:
+      if n.sons[genericParamsPos].kind == nkEmpty:
+        # we have a list of implicit type parameters:
+        n.sons[genericParamsPos] = gp
+    # no explicit return type? -> use tyStmt
+    if n.sons[paramsPos].sons[0].kind == nkEmpty:
       # use ``stmt`` as implicit result type
       s.typ.sons[0] = newTypeS(tyStmt, c)
       s.typ.n.sons[0] = newNodeIT(nkType, n.info, s.typ.sons[0])
+  else:
+    s.typ = newTypeS(tyProc, c)
+    # XXX why do we need tyStmt as a return type again?
+    s.typ.n = newNodeI(nkFormalParams, n.info)
+    rawAddSon(s.typ, newTypeS(tyStmt, c))
+    addSon(s.typ.n, newNodeIT(nkType, n.info, s.typ.sons[0]))
+      
   var ctx: TemplCtx
   ctx.toBind = initIntSet()
   ctx.c = c
diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim
index 5057883c7..a113696fe 100755
--- a/compiler/sigmatch.nim
+++ b/compiler/sigmatch.nim
@@ -138,8 +138,8 @@ proc NotFoundError*(c: PContext, n: PNode) =
   var candidates = ""
   var o: TOverloadIter
   var sym = initOverloadIter(o, c, n.sons[0])
-  while sym != nil: 
-    if sym.kind in {skProc, skMethod, skIterator, skConverter}: 
+  while sym != nil:
+    if sym.kind in RoutineKinds:
       add(candidates, getProcHeader(sym))
       add(candidates, "\n")
       #debug(sym.typ)