summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAraq <rumpf_a@web.de>2012-12-15 22:35:16 +0100
committerAraq <rumpf_a@web.de>2012-12-15 22:35:16 +0100
commita22c1f444fa76cc06fee1ae31c79986e9c3b459f (patch)
tree2226d8cc4813b7b38988d14309ff603c60ff19c2
parentc98696d7428346b53c8998bf8fab77fe08830e2e (diff)
downloadNim-a22c1f444fa76cc06fee1ae31c79986e9c3b459f.tar.gz
fixes #271
-rwxr-xr-xcompiler/msgs.nim2
-rwxr-xr-xcompiler/sem.nim2
-rwxr-xr-xcompiler/semcall.nim40
-rwxr-xr-xcompiler/semexprs.nim1
-rwxr-xr-xcompiler/sigmatch.nim34
-rwxr-xr-xconfig/nimrod.cfg2
-rwxr-xr-xdoc/lib.txt4
-rw-r--r--tests/run/titer9.nim6
-rwxr-xr-xtodo.txt1
9 files changed, 54 insertions, 38 deletions
diff --git a/compiler/msgs.nim b/compiler/msgs.nim
index 0f795c07d..240115817 100755
--- a/compiler/msgs.nim
+++ b/compiler/msgs.nim
@@ -132,7 +132,7 @@ const
     errNumberOutOfRange: "number $1 out of valid range", 
     errNnotAllowedInCharacter: "\\n not allowed in character literal", 
     errClosingBracketExpected: "closing ']' expected, but end of file reached", 
-    errMissingFinalQuote: "missing final \'", 
+    errMissingFinalQuote: "missing final \' for character literal", 
     errIdentifierExpected: "identifier expected, but found \'$1\'", 
     errNewlineExpected: "newline expected, but found \'$1\'",
     errInvalidModuleName: "invalid module name: '$1'",
diff --git a/compiler/sem.nim b/compiler/sem.nim
index 911eafb08..c8340a139 100755
--- a/compiler/sem.nim
+++ b/compiler/sem.nim
@@ -47,6 +47,8 @@ proc fixImmediateParams(n: PNode): PNode
 proc activate(c: PContext, n: PNode)
 proc semQuoteAst(c: PContext, n: PNode): PNode
 
+proc IndexTypesMatch(c: PContext, f, a: PType, arg: PNode): PNode
+
 proc typeMismatch(n: PNode, formal, actual: PType) = 
   if formal.kind != tyError and actual.kind != tyError: 
     LocalError(n.Info, errGenerated, msgKindToString(errTypeMismatch) &
diff --git a/compiler/semcall.nim b/compiler/semcall.nim
index 962e4d3cc..0a5f19822 100755
--- a/compiler/semcall.nim
+++ b/compiler/semcall.nim
@@ -84,15 +84,34 @@ proc resolveOverloads(c: PContext, n, orig: PNode,
         getProcHeader(best.calleeSym), getProcHeader(alt.calleeSym),
         args])
 
-proc instantiateGenericConverters(c: PContext, n: PNode, x: TCandidate) {.
-                                  noinline.}=
-  for i in 1 .. <n.len:
-    var a = n.sons[i]
-    if a.kind == nkHiddenCallConv and a.sons[0].kind == nkSym and
-        isGenericRoutine(a.sons[0].sym):
-      let finalCallee = generateInstance(c, a.sons[0].sym, x.bindings, n.info)
-      a.sons[0].sym = finalCallee
-      a.sons[0].typ = finalCallee.typ
+
+proc instGenericConvertersArg*(c: PContext, a: PNode, x: TCandidate) =
+  if a.kind == nkHiddenCallConv and a.sons[0].kind == nkSym and
+      isGenericRoutine(a.sons[0].sym):
+    let finalCallee = generateInstance(c, a.sons[0].sym, x.bindings, a.info)
+    a.sons[0].sym = finalCallee
+    a.sons[0].typ = finalCallee.typ
+    #a.typ = finalCallee.typ.sons[0]
+
+proc instGenericConvertersSons*(c: PContext, n: PNode, x: TCandidate) =
+  assert n.kind in nkCallKinds
+  if x.genericConverter:
+    for i in 1 .. <n.len:
+      instGenericConvertersArg(c, n.sons[i], x)
+
+proc IndexTypesMatch(c: PContext, f, a: PType, arg: PNode): PNode = 
+  var m: TCandidate
+  initCandidate(m, f)
+  result = paramTypesMatch(c, m, f, a, arg, nil)
+  if m.genericConverter and result != nil:
+    instGenericConvertersArg(c, result, m)
+
+proc ConvertTo*(c: PContext, f: PType, n: PNode): PNode = 
+  var m: TCandidate
+  initCandidate(m, f)
+  result = paramTypesMatch(c, m, f, n.typ, n, nil)
+  if m.genericConverter and result != nil:
+    instGenericConvertersArg(c, result, m)
 
 proc semResolvedCall(c: PContext, n: PNode, x: TCandidate): PNode =
   assert x.state == csMatch
@@ -111,8 +130,7 @@ proc semResolvedCall(c: PContext, n: PNode, x: TCandidate): PNode =
       if ContainsGenericType(result.typ): result.typ = errorType(c)
       return
   result = x.call
-  if x.genericConverter:
-    instantiateGenericConverters(c, result, x)
+  instGenericConvertersSons(c, result, x)
   result.sons[0] = newSymNode(finalCallee, result.sons[0].info)
   result.typ = finalCallee.typ.sons[0]
 
diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim
index 7b37987ee..d0fbcab6f 100755
--- a/compiler/semexprs.nim
+++ b/compiler/semexprs.nim
@@ -664,6 +664,7 @@ proc semIndirectOp(c: PContext, n: PNode, flags: TExprFlags): PNode =
       result = nil
     else:
       result = m.call
+      instGenericConvertersSons(c, result, m)
     # we assume that a procedure that calls something indirectly 
     # has side-effects:
     if tfNoSideEffect notin t.flags: incl(c.p.owner.flags, sfSideEffect)
diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim
index 1f2511694..2fecda427 100755
--- a/compiler/sigmatch.nim
+++ b/compiler/sigmatch.nim
@@ -594,7 +594,7 @@ proc userConvMatch(c: PContext, m: var TCandidate, f, a: PType,
       addSon(result, copyTree(arg))
       inc(m.convMatches)
       m.genericConverter = srca == isGeneric or destIsGeneric
-      return
+      return result
 
 proc localConvMatch(c: PContext, m: var TCandidate, f, a: PType, 
                     arg: PNode): PNode = 
@@ -705,8 +705,8 @@ proc ParamTypesMatchAux(c: PContext, m: var TCandidate, f, a: PType,
         else:
           result = userConvMatch(c, m, base(f), a, arg)
 
-proc ParamTypesMatch(c: PContext, m: var TCandidate, f, a: PType, 
-                     arg, argOrig: PNode): PNode =
+proc ParamTypesMatch*(c: PContext, m: var TCandidate, f, a: PType, 
+                      arg, argOrig: PNode): PNode =
   if arg == nil or arg.kind notin nkSymChoices:
     result = ParamTypesMatchAux(c, m, f, a, arg, argOrig)
   else: 
@@ -752,27 +752,12 @@ proc ParamTypesMatch(c: PContext, m: var TCandidate, f, a: PType,
       result = ParamTypesMatchAux(c, m, f, arg.sons[best].typ, arg.sons[best],
                                   argOrig)
 
-proc IndexTypesMatch*(c: PContext, f, a: PType, arg: PNode): PNode = 
-  var m: TCandidate
-  initCandidate(m, f)
-  result = paramTypesMatch(c, m, f, a, arg, nil)
-
-proc ConvertTo*(c: PContext, f: PType, n: PNode): PNode = 
-  var m: TCandidate
-  initCandidate(m, f)
-  result = paramTypesMatch(c, m, f, n.typ, n, nil)
-
-proc argtypeMatches*(c: PContext, f, a: PType): bool = 
-  var m: TCandidate
-  initCandidate(m, f)
-  result = paramTypesMatch(c, m, f, a, ast.emptyNode, nil) != nil  
-
 proc setSon(father: PNode, at: int, son: PNode) = 
   if sonsLen(father) <= at: setlen(father.sons, at + 1)
   father.sons[at] = son
 
-proc matchesAux*(c: PContext, n, nOrig: PNode,
-                 m: var TCandidate, marker: var TIntSet) = 
+proc matchesAux(c: PContext, n, nOrig: PNode,
+                m: var TCandidate, marker: var TIntSet) = 
   template checkConstraint(n: expr) {.immediate, dirty.} =
     if not formal.constraint.isNil:
       if matchNodeKinds(formal.constraint, n):
@@ -904,4 +889,13 @@ proc matches*(c: PContext, n, nOrig: PNode, m: var TCandidate) =
         setSon(m.call, formal.position + 1, copyTree(formal.ast))
     inc(f)
 
+proc argtypeMatches*(c: PContext, f, a: PType): bool = 
+  var m: TCandidate
+  initCandidate(m, f)
+  let res = paramTypesMatch(c, m, f, a, ast.emptyNode, nil)
+  #instantiateGenericConverters(c, res, m)
+  # XXX this is used by patterns.nim too; I think it's better to not
+  # instantiate generic converters for that
+  result = res != nil
+
 include suggest
diff --git a/config/nimrod.cfg b/config/nimrod.cfg
index ea3d11a0e..9db13e836 100755
--- a/config/nimrod.cfg
+++ b/config/nimrod.cfg
@@ -33,7 +33,7 @@ path="$lib/ecmas"
 path="$lib/pure/unidecode"
 
 @if nimbabel:
-  babelpath="$home/babeltest/"
+  babelpath="$home/.babel/libs/"
 @end
 
 @if release or quick:
diff --git a/doc/lib.txt b/doc/lib.txt
index f4d3dde30..a429a8289 100755
--- a/doc/lib.txt
+++ b/doc/lib.txt
@@ -38,11 +38,11 @@ Core
 
 * `threads <threads.html>`_
   Nimrod thread support. **Note**: This is part of the system module. Do not
-  import it explicitely.
+  import it explicitly.
 
 * `channels <channels.html>`_
   Nimrod message passing support for threads. **Note**: This is part of the 
-  system module. Do not import it explicitely.
+  system module. Do not import it explicitly.
 
 * `locks <locks.html>`_
   Locks and condition variables for Nimrod.
diff --git a/tests/run/titer9.nim b/tests/run/titer9.nim
index 0d6c466c1..99874e70a 100644
--- a/tests/run/titer9.nim
+++ b/tests/run/titer9.nim
@@ -4,17 +4,17 @@ discard """
 0'''
 """
 
-iterator count(x: int, skip: bool): int {.closure.} =
+iterator count[T](x: T, skip: bool): int {.closure.} =
   if skip: return x+10
   else: yield x+1
 
   if skip: return x+10
   else: yield x+2
 
-proc takeProc(x: iterator (x: int, skip: bool): int) =
+proc takeProc[T](x: iterator (x: T, skip: bool): int) =
   echo x(4, false)
   echo x(4, true)
   echo x(4, false)
 
-takeProc(count)
+takeProc(count[int])
 
diff --git a/todo.txt b/todo.txt
index b162812bc..f5e6d8092 100755
--- a/todo.txt
+++ b/todo.txt
@@ -87,6 +87,7 @@ GC
 Optimizations
 =============
 
+- optimize 'if' with a constant condition
 - escape analysis for string/seq seems to be easy to do too;
   even further write barrier specialization
 - inlining of first class functions