summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rwxr-xr-xcompiler/ccgutils.nim14
-rw-r--r--compiler/lambdalifting.nim4
-rwxr-xr-xcompiler/msgs.nim8
-rwxr-xr-xcompiler/semexprs.nim12
-rwxr-xr-xcompiler/semstmts.nim2
-rwxr-xr-xlib/system/arithm.nim3
-rw-r--r--tests/run/tfilter.nim28
7 files changed, 58 insertions, 13 deletions
diff --git a/compiler/ccgutils.nim b/compiler/ccgutils.nim
index de49897c5..ad7f22bbc 100755
--- a/compiler/ccgutils.nim
+++ b/compiler/ccgutils.nim
@@ -124,8 +124,18 @@ proc GetUniqueType*(key: PType): PType =
       result = key
   of tyProc:
     # tyVar is not 100% correct, but would speeds things up a little:
-    result = key
-
+    if key.callConv != ccClosure:
+      result = key
+    else:
+      # ugh, we need the canon here:
+      if IdTableHasObjectAsKey(gTypeTable[k], key): return key 
+      for h in countup(0, high(gTypeTable[k].data)): 
+        var t = PType(gTypeTable[k].data[h].key)
+        if t != nil and sameBackendType(t, key): 
+          return t
+      IdTablePut(gTypeTable[k], key, key)
+      result = key
+      
 proc TableGetType*(tab: TIdTable, key: PType): PObject = 
   # returns nil if we need to declare this type
   result = IdTableGet(tab, key)
diff --git a/compiler/lambdalifting.nim b/compiler/lambdalifting.nim
index 219fead2c..2bf6ac57e 100644
--- a/compiler/lambdalifting.nim
+++ b/compiler/lambdalifting.nim
@@ -366,14 +366,17 @@ proc searchForInnerProcs(o: POuterContext, n: PNode) =
       var it = n.sons[i]
       if it.kind == nkCommentStmt: nil
       elif it.kind == nkIdentDefs:
+        var L = sonsLen(it)
         if it.sons[0].kind != nkSym: InternalError(it.info, "transformOuter")
         #echo "set: ", it.sons[0].sym.name.s, " ", o.currentBlock == nil
         IdTablePut(o.localsToEnv, it.sons[0].sym, o.currentEnv)
+        searchForInnerProcs(o, it.sons[L-1])
       elif it.kind == nkVarTuple:
         var L = sonsLen(it)
         for j in countup(0, L-3):
           #echo "set: ", it.sons[j].sym.name.s, " ", o.currentBlock == nil
           IdTablePut(o.localsToEnv, it.sons[j].sym, o.currentEnv)
+        searchForInnerProcs(o, it.sons[L-1])
       else:
         InternalError(it.info, "transformOuter")
   of nkProcDef, nkMethodDef, nkConverterDef, nkMacroDef, nkTemplateDef, 
@@ -493,7 +496,6 @@ proc liftLambdas(fn: PSym, body: PNode): PNode =
     searchForInnerProcs(o, body)
     let a = transformOuterProc(o, body)
     result = ex
-    #echo renderTree(result)
   
 # XXX should 's' be replaced by a tuple ('s', env)?
 
diff --git a/compiler/msgs.nim b/compiler/msgs.nim
index 2af512af7..0b79a68a2 100755
--- a/compiler/msgs.nim
+++ b/compiler/msgs.nim
@@ -596,14 +596,14 @@ proc rawMessage*(msg: TMsgKind, args: openarray[string]) =
     writeContext(unknownLineInfo())
     frmt = rawErrorFormat
   of warnMin..warnMax: 
-    if not (optWarns in gOptions): return 
-    if not (msg in gNotes): return 
+    if optWarns notin gOptions: return 
+    if msg notin gNotes: return 
     writeContext(unknownLineInfo())
     frmt = rawWarningFormat
     inc(gWarnCounter)
   of hintMin..hintMax: 
-    if not (optHints in gOptions): return 
-    if not (msg in gNotes): return 
+    if optHints notin gOptions: return 
+    if msg notin gNotes: return 
     frmt = rawHintFormat
     inc(gHintCounter)
   let s = `%`(frmt, `%`(msgKindToString(msg), args))
diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim
index cd97e74b1..00acbbe65 100755
--- a/compiler/semexprs.nim
+++ b/compiler/semexprs.nim
@@ -135,9 +135,9 @@ proc checkConvertible(info: TLineInfo, castDest, src: PType) =
     IntegralTypes = {tyBool, tyEnum, tyChar, tyInt..tyUInt64}
   if sameType(castDest, src) and castDest.sym == src.sym: 
     # don't annoy conversions that may be needed on another processor:
-    if not (castDest.kind in {tyInt..tyUInt64, tyNil}): 
+    if castDest.kind notin {tyInt..tyUInt64, tyNil}:
       Message(info, hintConvFromXtoItselfNotNeeded, typeToString(castDest))
-    return 
+    return
   var d = skipTypes(castDest, abstractVar)
   var s = skipTypes(src, abstractVar)
   while (d != nil) and (d.Kind in {tyPtr, tyRef}) and (d.Kind == s.Kind): 
@@ -538,9 +538,11 @@ proc semOverloadedCallAnalyseEffects(c: PContext, n: PNode, nOrig: PNode,
     result = semOverloadedCall(c, n, nOrig, {skIterator})
   elif efInTypeOf in flags:
     # for ``type(countup(1,3))``, see ``tests/ttoseq``.
-    result = semOverloadedCall(c, n, nOrig, {skIterator, skProc, skMethod, skConverter, skMacro, skTemplate})
+    result = semOverloadedCall(c, n, nOrig, 
+      {skProc, skMethod, skConverter, skMacro, skTemplate, skIterator})
   else:
-    result = semOverloadedCall(c, n, nOrig, {skProc, skMethod, skConverter, skMacro, skTemplate})
+    result = semOverloadedCall(c, n, nOrig, 
+      {skProc, skMethod, skConverter, skMacro, skTemplate})
   if result != nil:
     if result.sons[0].kind != nkSym: 
       InternalError("semDirectCallAnalyseEffects")
@@ -838,7 +840,7 @@ proc semFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode =
       # if f != nil and f.kind == skStub: loadStub(f)
       # ``loadStub`` is not correct here as we don't care for ``f`` really
       if f != nil: 
-        # BUGFIX: do not check for (f.kind in [skProc, skMethod, skIterator]) here
+        # BUGFIX: do not check for (f.kind in {skProc, skMethod, skIterator}) here
         # This special node kind is to merge with the call handler in `semExpr`.
         result = newNodeI(nkDotCall, n.info)
         addSon(result, newIdentNode(i, n.info))
diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim
index 53b8951e8..fd3ac7891 100755
--- a/compiler/semstmts.nim
+++ b/compiler/semstmts.nim
@@ -767,7 +767,7 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind,
       pushProcCon(c, s)
       if s.typ.sons[0] != nil and kind != skIterator: 
         addResult(c, s.typ.sons[0], n.info, kind)
-      if sfImportc notin s.flags: 
+      if sfImportc notin s.flags:
         # no semantic checking for importc:
         n.sons[bodyPos] = semStmtScope(c, n.sons[bodyPos])
       if s.typ.sons[0] != nil and kind != skIterator: addResultNode(c, n)
diff --git a/lib/system/arithm.nim b/lib/system/arithm.nim
index 54407c04e..8f036caa5 100755
--- a/lib/system/arithm.nim
+++ b/lib/system/arithm.nim
@@ -184,6 +184,9 @@ elif false: # asmVersion and (defined(gcc) or defined(llvm_gcc)):
       :"=a"(`result`)
       :"a"(`a`), "c"(`b`)
     """
+    #".intel_syntax noprefix"
+    #/* Intel syntax here */
+    #".att_syntax"
 
   proc subInt(a, b: int): int {.compilerProc, inline.} =
     asm """ "subl %%ecx,%%eax\n"
diff --git a/tests/run/tfilter.nim b/tests/run/tfilter.nim
new file mode 100644
index 000000000..e82d05742
--- /dev/null
+++ b/tests/run/tfilter.nim
@@ -0,0 +1,28 @@
+discard """
+  output: "02468101214161820"
+"""
+
+proc filter[T](list: seq[T], f: proc (item: T): bool {.closure.}): seq[T] =
+  result = @[]
+  for i in items(list):
+    if f(i):
+      result.add(i)
+
+let nums = @[0, 1, 2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]
+
+when true:
+  let nums2 = filter(nums,
+               (proc (item: int): bool =
+                 result = (item mod 2) == 0)
+               )
+
+proc outer =
+  # lets use a proper closure this time:
+  var modulo = 2
+  let nums2 = filter(nums,
+               (proc (item: int): bool = result = (item mod modulo) == 0)
+               )
+
+  for n in nums2: stdout.write(n)
+
+outer()