diff options
-rw-r--r-- | compiler/ccgexprs.nim | 14 | ||||
-rw-r--r-- | compiler/condsyms.nim | 2 | ||||
-rw-r--r-- | compiler/vmgen.nim | 1 | ||||
-rw-r--r-- | lib/impure/nre.nim | 1 | ||||
-rw-r--r-- | lib/system.nim | 11 | ||||
-rw-r--r-- | lib/system/sysstr.nim | 29 | ||||
-rw-r--r-- | tests/system/toString.nim | 56 |
7 files changed, 91 insertions, 23 deletions
diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim index dde3d6e70..562d6d165 100644 --- a/compiler/ccgexprs.nim +++ b/compiler/ccgexprs.nim @@ -980,10 +980,10 @@ proc genEcho(p: BProc, n: PNode) = var a: TLoc for it in n.sons: if it.skipConv.kind == nkNilLit: - add(args, ", \"nil\"") + add(args, ", \"\"") else: initLocExpr(p, it, a) - addf(args, ", $1? ($1)->data:\"nil\"", [rdLoc(a)]) + addf(args, ", $1? ($1)->data:\"\"", [rdLoc(a)]) p.module.includeHeader("<base/log.h>") linefmt(p, cpsStmts, """Genode::log(""$1);$n""", args) else: @@ -1755,16 +1755,14 @@ proc genStrEquals(p: BProc, e: PNode, d: var TLoc) = var x: TLoc var a = e.sons[1] var b = e.sons[2] - if (a.kind == nkNilLit) or (b.kind == nkNilLit): - binaryExpr(p, e, d, "($1 == $2)") - elif (a.kind in {nkStrLit..nkTripleStrLit}) and (a.strVal == ""): + if a.kind in {nkStrLit..nkTripleStrLit} and a.strVal == "": initLocExpr(p, e.sons[2], x) putIntoDest(p, d, e, - rfmt(nil, "(($1) && ($1)->$2 == 0)", rdLoc(x), lenField(p))) - elif (b.kind in {nkStrLit..nkTripleStrLit}) and (b.strVal == ""): + rfmt(nil, "(!($1) || ($1)->$2 == 0)", rdLoc(x), lenField(p))) + elif b.kind in {nkStrLit..nkTripleStrLit} and b.strVal == "": initLocExpr(p, e.sons[1], x) putIntoDest(p, d, e, - rfmt(nil, "(($1) && ($1)->$2 == 0)", rdLoc(x), lenField(p))) + rfmt(nil, "(!($1) || ($1)->$2 == 0)", rdLoc(x), lenField(p))) else: binaryExpr(p, e, d, "#eqStrings($1, $2)") diff --git a/compiler/condsyms.nim b/compiler/condsyms.nim index 028aedb5b..08dda9b6a 100644 --- a/compiler/condsyms.nim +++ b/compiler/condsyms.nim @@ -82,7 +82,6 @@ proc countDefinedSymbols*(): int = proc initDefines*() = gSymbols = newStringTable(modeStyleInsensitive) - defineSymbol("nimrod") # 'nimrod' is always defined # for bootstrapping purposes and old code: defineSymbol("nimhygiene") defineSymbol("niminheritable") @@ -115,3 +114,4 @@ proc initDefines*() = defineSymbol("nimHasNilChecks") defineSymbol("nimSymKind") defineSymbol("nimVmEqIdent") + defineSymbol("nimNoNil") diff --git a/compiler/vmgen.nim b/compiler/vmgen.nim index c3eaf8946..0544dc311 100644 --- a/compiler/vmgen.nim +++ b/compiler/vmgen.nim @@ -1553,6 +1553,7 @@ proc getNullValue(typ: PType, info: TLineInfo): PNode = result = newNodeIT(nkFloatLit, info, t) of tyCString, tyString: result = newNodeIT(nkStrLit, info, t) + result.strVal = "" of tyVar, tyLent, tyPointer, tyPtr, tySequence, tyExpr, tyStmt, tyTypeDesc, tyStatic, tyRef, tyNil: result = newNodeIT(nkNilLit, info, t) diff --git a/lib/impure/nre.nim b/lib/impure/nre.nim index 3d4afc0ae..582f5ab3b 100644 --- a/lib/impure/nre.nim +++ b/lib/impure/nre.nim @@ -645,7 +645,6 @@ template replaceImpl(str: string, pattern: Regex, let bounds = match.matchBounds result.add(str.substr(lastIdx, bounds.a - 1)) let nextVal = replacement - assert(nextVal != nil) result.add(nextVal) lastIdx = bounds.b + 1 diff --git a/lib/system.nim b/lib/system.nim index 523a25d64..5c0970f85 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -2412,8 +2412,9 @@ proc `==` *[T](x, y: seq[T]): bool {.noSideEffect.} = if seqToPtr(x) == seqToPtr(y): return true - if x.isNil or y.isNil: - return false + when not defined(nimNoNil): + if x.isNil or y.isNil: + return false if x.len != y.len: return false @@ -4010,18 +4011,18 @@ proc addQuoted*[T](s: var string, x: T) = when hasAlloc: # XXX: make these the default (or implement the NilObject optimization) - proc safeAdd*[T](x: var seq[T], y: T) {.noSideEffect.} = + proc safeAdd*[T](x: var seq[T], y: T) {.noSideEffect, deprecated.} = ## Adds ``y`` to ``x`` unless ``x`` is not yet initialized; in that case, ## ``x`` becomes ``@[y]`` if x == nil: x = @[y] else: x.add(y) - proc safeAdd*(x: var string, y: char) = + proc safeAdd*(x: var string, y: char) {.noSideEffect, deprecated.} = ## Adds ``y`` to ``x``. If ``x`` is ``nil`` it is initialized to ``""`` if x == nil: x = "" x.add(y) - proc safeAdd*(x: var string, y: string) = + proc safeAdd*(x: var string, y: string) {.noSideEffect, deprecated.} = ## Adds ``y`` to ``x`` unless ``x`` is not yet initalized; in that ## case, ``x`` becomes ``y`` if x == nil: x = y diff --git a/lib/system/sysstr.nim b/lib/system/sysstr.nim index 9e7ee903f..bba59e930 100644 --- a/lib/system/sysstr.nim +++ b/lib/system/sysstr.nim @@ -22,21 +22,34 @@ proc resize(old: int): int {.inline.} = proc cmpStrings(a, b: NimString): int {.inline, compilerProc.} = if a == b: return 0 - if a == nil: return -1 - if b == nil: return 1 - let minlen = min(a.len, b.len) + when defined(nimNoNil): + let alen = if a == nil: 0 else: a.len + let blen = if b == nil: 0 else: b.len + else: + if a == nil: return -1 + if b == nil: return 1 + let alen = a.len + let blen = b.len + let minlen = min(alen, blen) if minlen > 0: result = c_memcmp(addr a.data, addr b.data, minlen.csize) if result == 0: - result = a.len - b.len + result = alen - blen else: - result = a.len - b.len + result = alen - blen proc eqStrings(a, b: NimString): bool {.inline, compilerProc.} = if a == b: return true - if a == nil or b == nil: return false - return a.len == b.len and - equalMem(addr(a.data), addr(b.data), a.len) + when defined(nimNoNil): + let alen = if a == nil: 0 else: a.len + let blen = if b == nil: 0 else: b.len + else: + if a == nil or b == nil: return false + let alen = a.len + let blen = b.len + if alen == blen: + if alen == 0: return true + return equalMem(addr(a.data), addr(b.data), alen) when declared(allocAtomic): template allocStr(size: untyped): untyped = diff --git a/tests/system/toString.nim b/tests/system/toString.nim index ea9d6b05b..37c678a74 100644 --- a/tests/system/toString.nim +++ b/tests/system/toString.nim @@ -51,3 +51,59 @@ import strutils let arr = ['H','e','l','l','o',' ','W','o','r','l','d','!','\0'] doAssert $arr == "['H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd', '!', '\\x00']" doAssert $cstring(unsafeAddr arr) == "Hello World!" + +proc takes(c: cstring) = + doAssert c == "" + +proc testm() = + var x: string + # nil is mapped to "": + takes(x) + +testm() + +# nil tests +var xx: seq[string] +var yy: string +doAssert xx == @[] +doAssert yy == "" + +proc bar(arg: cstring): void = + doAssert arg[0] == '\0' + +proc baz(arg: openarray[char]): void = + doAssert arg.len == 0 + +proc stringCompare(): void = + var a,b,c,d,e,f,g: string + a.add 'a' + doAssert a == "a" + b.add "bee" + doAssert b == "bee" + b.add g + doAssert b == "bee" + c.add 123.456 + doAssert c == "123.456" + d.add 123456 + doAssert d == "123456" + + doAssert e == "" + doAssert "" == e + doAssert nil == e + doAssert e == nil + doAssert f == g + doAssert "" == "" + doAssert "" == nil + doAssert nil == "" + + g.setLen(10) + doAssert g == "\0\0\0\0\0\0\0\0\0\0" + doAssert "" != "\0\0\0\0\0\0\0\0\0\0" + + var nilstring: string + bar(nilstring) + baz(nilstring) + +stringCompare() +static: + stringCompare() \ No newline at end of file |