diff options
author | Andreas Rumpf <andreas@andreas-desktop> | 2010-03-10 16:33:55 +0100 |
---|---|---|
committer | Andreas Rumpf <andreas@andreas-desktop> | 2010-03-10 16:33:55 +0100 |
commit | 96b828a3863c28680e8a5b0165c5e0bbcca7a46c (patch) | |
tree | 6ab8e58da5bf2dde1c0c865f60ef9ecf1a55ba15 | |
parent | 2e280eafa8b13802980cf0e2f309342742e61347 (diff) | |
download | Nim-96b828a3863c28680e8a5b0165c5e0bbcca7a46c.tar.gz |
bugfix: len openarray
-rwxr-xr-x | lib/pure/strutils.nim | 18 | ||||
-rwxr-xr-x | rod/sem.nim | 5 | ||||
-rwxr-xr-x | rod/semfold.nim | 36 | ||||
-rwxr-xr-x | tests/accept/compile/tmodulealias.nim | 17 | ||||
-rwxr-xr-x | tests/accept/run/spec.csv | 1 | ||||
-rwxr-xr-x | tests/accept/run/tlenopenarray.nim | 5 | ||||
-rwxr-xr-x | tests/accept/run/tstrutil.nim | 4 | ||||
-rwxr-xr-x | web/news.txt | 1 |
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. |