refactor cmpIgnoreStyle and cmpIgnoreCase (#16399)

* init

* support strutils

* more

* better

* Call len once per string/cstring

* Change var to let

* Compare ternary on first char

* More appropriate param name

* fix

* better

* one test

* impl

* more efficient

* minor

Co-authored-by: Clyybber <darkmine956@gmail.com>
This commit is contained in:
flywind 2020-12-31 04:54:40 -06:00 • committed by GitHub
commit 5fb56a3b2c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 141 additions and 147 deletions

View file

@ -1389,25 +1389,10 @@ when defined(nimVmEqIdent):
## these nodes will be unwrapped.
else:
from std/private/strimpl import cmpIgnoreStyleImpl
# this procedure is optimized for native code, it should not be compiled to nimVM bytecode.
proc cmpIgnoreStyle(a, b: cstring): int {.noSideEffect.} =
proc toLower(c: char): char {.inline.} =
if c in {'A'..'Z'}: result = chr(ord(c) + (ord('a') - ord('A')))
else: result = c
var i = 0
var j = 0
# first char is case sensitive
if a[0] != b[0]: return 1
while true:
while a[i] == '_': inc(i)
while b[j] == '_': inc(j) # BUGFIX: typo
var aa = toLower(a[i])
var bb = toLower(b[j])
result = ord(aa) - ord(bb)
if result != 0 or aa == '\0': break
inc(i)
inc(j)
cmpIgnoreStyleImpl(a, b, true)
proc eqIdent*(a, b: string): bool = cmpIgnoreStyle(a, b) == 0
## Check if two idents are equal.

View file

@ -91,6 +91,8 @@ when not defined(gcDestructors):
else:
include system/seqs_v2_reimpl
from std/private/strimpl import cmpIgnoreStyleImpl
when not defined(js):
template rawType(x: Any): PNimType =
cast[PNimType](x.rawTypePtr)
@ -366,36 +368,22 @@ iterator fields*(x: Any): tuple[name: string, any: Any] =
for name, any in items(ret):
yield ($name, any)
proc cmpIgnoreStyle(a, b: cstring): int {.noSideEffect.} =
proc toLower(c: char): char {.inline.} =
if c in {'A'..'Z'}: result = chr(ord(c) + (ord('a') - ord('A')))
else: result = c
var i = 0
var j = 0
if a[0] != b[0]: return 1
while true:
while a[i] == '_': inc(i)
while b[j] == '_': inc(j) # BUGFIX: typo
var aa = toLower(a[i])
var bb = toLower(b[j])
result = ord(aa) - ord(bb)
if result != 0 or aa == '\0': break
inc(i)
inc(j)
proc cmpNimIdentifier(a, b: cstring): int {.noSideEffect.} =
cmpIgnoreStyleImpl(a, b, true)
proc getFieldNode(p: pointer, n: ptr TNimNode,
name: cstring): ptr TNimNode =
case n.kind
of nkNone: assert(false)
of nkSlot:
if cmpIgnoreStyle(n.name, name) == 0:
if cmpNimIdentifier(n.name, name) == 0:
result = n
of nkList:
for i in 0..n.len-1:
result = getFieldNode(p, n.sons[i], name)
if result != nil: break
of nkCase:
if cmpIgnoreStyle(n.name, name) == 0:
if cmpNimIdentifier(n.name, name) == 0:
result = n
else:
var m = selectBranch(p, n)
@ -599,7 +587,7 @@ proc getEnumOrdinal*(x: Any, name: string): int =
var n = typ.node
var s = n.sons
for i in 0 .. n.len-1:
if cmpIgnoreStyle($s[i].name, name) == 0:
if cmpNimIdentifier($s[i].name, name) == 0:
if ntfEnumHole notin typ.flags:
return i
else: