summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAndreas Rumpf <andreas@andreas-desktop>2010-03-10 16:33:55 +0100
committerAndreas Rumpf <andreas@andreas-desktop>2010-03-10 16:33:55 +0100
commit96b828a3863c28680e8a5b0165c5e0bbcca7a46c (patch)
tree6ab8e58da5bf2dde1c0c865f60ef9ecf1a55ba15
parent2e280eafa8b13802980cf0e2f309342742e61347 (diff)
downloadNim-96b828a3863c28680e8a5b0165c5e0bbcca7a46c.tar.gz
bugfix: len openarray
-rwxr-xr-xlib/pure/strutils.nim18
-rwxr-xr-xrod/sem.nim5
-rwxr-xr-xrod/semfold.nim36
-rwxr-xr-xtests/accept/compile/tmodulealias.nim17
-rwxr-xr-xtests/accept/run/spec.csv1
-rwxr-xr-xtests/accept/run/tlenopenarray.nim5
-rwxr-xr-xtests/accept/run/tstrutil.nim4
-rwxr-xr-xweb/news.txt1
8 files changed, 74 insertions, 13 deletions
diff --git a/lib/pure/strutils.nim b/lib/pure/strutils.nim
index 724d00ee9..11ba14aa1 100755
--- a/lib/pure/strutils.nim
+++ b/lib/pure/strutils.nim
@@ -748,6 +748,24 @@ proc toBin*(x: BiggestInt, len: int): string =
     shift = shift + 1
     mask = mask shl 1
 
+proc insertSep*(s: string, sep = '_', digits = 3): string = 
+  ## inserts the separator `sep` after `digits` digits from right to left.
+  ## Even though the algorithm works with any string `s`, it is only useful 
+  ## if `s` contains a number.
+  ## Example: ``insertSep("1000000") == "1_000_000"`` 
+  var L = (s.len-1) div digits + s.len
+  result = newString(L)
+  var j = 0
+  dec(L)
+  for i in countdown(len(s)-1, 0): 
+    if j == digits: 
+      result[L] = sep
+      dec(L)
+      j = 0
+    result[L] = s[i]
+    inc(j)
+    dec(L)
+
 proc escape*(s: string, prefix = "\"", suffix = "\""): string =
   ## Escapes a string `s`. This does these operations (at the same time):
   ## * replaces any ``\`` by ``\\``
diff --git a/rod/sem.nim b/rod/sem.nim
index 7ea6338a2..ac2f21857 100755
--- a/rod/sem.nim
+++ b/rod/sem.nim
@@ -85,7 +85,10 @@ proc semAndEvalConstExpr(c: PContext, n: PNode): PNode =
 proc semAfterMacroCall(c: PContext, n: PNode, s: PSym): PNode = 
   result = n
   case s.typ.sons[0].kind
-  of tyExpr: result = semExprWithType(c, result)
+  of tyExpr: 
+    # BUGFIX: we cannot expect a type here, because module aliases would not 
+    # work then (see the ``tmodulealias`` test)
+    result = semExpr(c, result) # semExprWithType(c, result)
   of tyStmt: result = semStmt(c, result)
   of tyTypeDesc: result.typ = semTypeNode(c, result, nil)
   else: liMessage(s.info, errInvalidParamKindX, typeToString(s.typ.sons[0]))
diff --git a/rod/semfold.nim b/rod/semfold.nim
index fddf47398..95710af75 100755
--- a/rod/semfold.nim
+++ b/rod/semfold.nim
@@ -256,6 +256,21 @@ proc leValueConv(a, b: PNode): bool =
     else: InternalError(a.info, "leValueConv")
   else: InternalError(a.info, "leValueConv")
   
+proc magicCall(m: PSym, n: PNode): PNode =
+  var s = n.sons[0].sym
+  var a = getConstExpr(m, n.sons[1])
+  var b, c: PNode
+  if a == nil: return 
+  if sonsLen(n) > 2: 
+    b = getConstExpr(m, n.sons[2])
+    if b == nil: return 
+    if sonsLen(n) > 3: 
+      c = getConstExpr(m, n.sons[3])
+      if c == nil: return 
+  else: 
+    b = nil
+  result = evalOp(s.magic, n, a, b, c)
+  
 proc getConstExpr(m: PSym, n: PNode): PNode = 
   result = nil
   case n.kind
@@ -308,19 +323,16 @@ proc getConstExpr(m: PSym, n: PNode): PNode =
         if not (skipTypes(n.sons[1].typ, abstractVar).kind in
             {tyOpenArray, tySequence, tyString}): 
           result = newIntNodeT(lastOrd(skipTypes(n.sons[1].typ, abstractVar)), n)
+      of mLengthOpenArray:
+        var a = n.sons[1]
+        if a.kind == nkPassAsOpenArray: a = a.sons[0]
+        if a.kind == nkBracket: 
+          # we can optimize it away! This fixes the bug ``len(134)``. 
+          result = newIntNodeT(sonsLen(a), n)
+        else:
+          result = magicCall(m, n)
       else: 
-        var a = getConstExpr(m, n.sons[1])
-        var b, c: PNode
-        if a == nil: return 
-        if sonsLen(n) > 2: 
-          b = getConstExpr(m, n.sons[2])
-          if b == nil: return 
-          if sonsLen(n) > 3: 
-            c = getConstExpr(m, n.sons[3])
-            if c == nil: return 
-        else: 
-          b = nil
-        result = evalOp(s.magic, n, a, b, c)
+        result = magicCall(m, n)
     except EOverflow: 
       liMessage(n.info, errOverOrUnderflow)
     except EDivByZero: 
diff --git a/tests/accept/compile/tmodulealias.nim b/tests/accept/compile/tmodulealias.nim
new file mode 100755
index 000000000..1154cb99d
--- /dev/null
+++ b/tests/accept/compile/tmodulealias.nim
@@ -0,0 +1,17 @@
+
+
+when defined(windows):
+  import winlean
+else:
+  import posix
+
+when defined(Windows):
+  template orig: expr = 
+    winlean
+else:
+  template orig: expr = 
+    posix
+
+proc socket(domain, typ, protocol: int): int =
+  result = orig.socket(ord(domain), ord(typ), ord(protocol)))
+
diff --git a/tests/accept/run/spec.csv b/tests/accept/run/spec.csv
index 79a03776a..0dc9a4baa 100755
--- a/tests/accept/run/spec.csv
+++ b/tests/accept/run/spec.csv
@@ -27,6 +27,7 @@ tisopr.nim;falsetrue
 titer2.nim;123
 titer3.nim;1231
 titer5.nim;abcxyz
+tlenopenarray.nim;1
 tlowhigh.nim;10
 tmatrix.nim;111
 tmultim1.nim;7
diff --git a/tests/accept/run/tlenopenarray.nim b/tests/accept/run/tlenopenarray.nim
new file mode 100755
index 000000000..9731cb4f2
--- /dev/null
+++ b/tests/accept/run/tlenopenarray.nim
@@ -0,0 +1,5 @@
+
+# len(x) --> len([x]) --> match!
+echo len(1_000_000) #OUT 1
+
+
diff --git a/tests/accept/run/tstrutil.nim b/tests/accept/run/tstrutil.nim
index 0468dfa0c..affe6e58d 100755
--- a/tests/accept/run/tstrutil.nim
+++ b/tests/accept/run/tstrutil.nim
@@ -11,6 +11,10 @@ proc main() =
   for p in split("/home/a1:xyz:/usr/bin", {':'}):

     write(stdout, p)

     

+assert(insertSep($1000_000) == "1_000_000")
+assert(insertSep($232) == "232")
+assert(insertSep($12345, ',') == "12,345")
+assert(insertSep($0) == "0")
 

 assert(editDistance("prefix__hallo_suffix", "prefix__hallo_suffix") == 0)

 assert(editDistance("prefix__hallo_suffix", "prefix__hallo_suffi1") == 1)

diff --git a/web/news.txt b/web/news.txt
index 1c31849c4..4ceaea6e7 100755
--- a/web/news.txt
+++ b/web/news.txt
@@ -35,6 +35,7 @@ Additions
 - Added ``system./`` for int.
 - Exported ``system.newException`` template.
 - Added ``cgi.decodeData(data: string): tuple[key, value: string]``.
+- Added ``strutils.insertSep``.
 - Added ``math.trunc``.
 - Added ``ropes`` module.
 - Added ``sockets`` module.