Skip to content

Commit

Permalink
backtick and export marker handling in eqIdent (nim-lang#12574)
Browse files Browse the repository at this point in the history
  • Loading branch information
krux02 authored and Araq committed Nov 7, 2019
1 parent 372b017 commit 94675c2
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 12 deletions.
4 changes: 3 additions & 1 deletion changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,9 @@
This is more consistent with the other asyncdispatch apis, and allows
`asyncdispatch.drain` to be more efficient.
- `base64.encode` and `base64.decode` was made faster by about 50%.
- `htmlgen` adds [MathML](https://wikipedia.org/wiki/MathML) support (ISO 40314).
- `htmlgen` adds [MathML](https://wikipedia.org/wiki/MathML) support
(ISO 40314).
- `macros.eqIdent` is now invariant to export markers and backtick quotes.



Expand Down
21 changes: 16 additions & 5 deletions compiler/vm.nim
Original file line number Diff line number Diff line change
Expand Up @@ -1644,10 +1644,22 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
of opcEqIdent:
decodeBC(rkInt)
# aliases for shorter and easier to understand code below
let aNode = regs[rb].node
let bNode = regs[rc].node
# these are cstring to prevent string copy, and cmpIgnoreStyle from
# takes cstring arguments
var aNode = regs[rb].node
var bNode = regs[rc].node
# Skipping both, `nkPostfix` and `nkAccQuoted` for both
# arguments. `nkPostfix` exists only to tag exported symbols
# and therefor it can be safely skipped. Nim has no postfix
# operator. `nkAccQuoted` is used to quote an identifier that
# wouldn't be allowed to use in an unquoted context.
if aNode.kind == nkPostfix:
aNode = aNode[1]
if aNode.kind == nkAccQuoted:
aNode = aNode[0]
if bNode.kind == nkPostfix:
bNode = bNode[1]
if bNode.kind == nkAccQuoted:
bNode = bNode[0]
# These vars are of type `cstring` to prevent unnecessary string copy.
var aStrVal: cstring = nil
var bStrVal: cstring = nil
# extract strVal from argument ``a``
Expand All @@ -1674,7 +1686,6 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
bStrVal = bNode[0].sym.name.s.cstring
else:
discard
# set result
regs[ra].intVal =
if aStrVal != nil and bStrVal != nil:
ord(idents.cmpIgnoreStyle(aStrVal, bStrVal, high(int)) == 0)
Expand Down
18 changes: 12 additions & 6 deletions lib/core/macros.nim
Original file line number Diff line number Diff line change
Expand Up @@ -1378,16 +1378,22 @@ when defined(nimVmEqIdent):
## Style insensitive comparison.

proc eqIdent*(a: NimNode; b: string): bool {.magic: "EqIdent", noSideEffect.}
## Style insensitive comparison.
## ``a`` can be an identifier or a symbol.
## Style insensitive comparison. ``a`` can be an identifier or a
## symbol. ``a`` may be wrapped in an export marker
## (``nnkPostfix``) or quoted with backticks (``nnkAccQuoted``),
## these nodes will be unwrapped.

proc eqIdent*(a: string; b: NimNode): bool {.magic: "EqIdent", noSideEffect.}
## Style insensitive comparison.
## ``b`` can be an identifier or a symbol.
## Style insensitive comparison. ``b`` can be an identifier or a
## symbol. ``b`` may be wrapped in an export marker
## (``nnkPostfix``) or quoted with backticks (``nnkAccQuoted``),
## these nodes will be unwrapped.

proc eqIdent*(a: NimNode; b: NimNode): bool {.magic: "EqIdent", noSideEffect.}
## Style insensitive comparison.
## ``a`` and ``b`` can be an identifier or a symbol.
## Style insensitive comparison. ``a`` and ``b`` can be an
## identifier or a symbol. Both may be wrapped in an export marker
## (``nnkPostfix``) or quoted with backticks (``nnkAccQuoted``),
## these nodes will be unwrapped.

else:
# this procedure is optimized for native code, it should not be compiled to nimVM bytecode.
Expand Down
16 changes: 16 additions & 0 deletions tests/macros/tmacro1.nim
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,22 @@ static:
assert fooSym.eqIdent("fOO")
assertNot fooSym.eqIdent("bar")

# eqIdent on exported and backtick quoted identifiers
let procName = ident("proc")
let quoted = nnkAccQuoted.newTree(procName)
let exported = nnkPostfix.newTree(ident"*", procName)
let exportedQuoted = nnkPostfix.newTree(ident"*", quoted)

let nodes = @[procName, quoted, exported, exportedQuoted]

for i in 0 ..< nodes.len:
for j in 0 ..< nodes.len:
doAssert eqIdent(nodes[i], nodes[j])

for node in nodes:
doAssert eqIdent(node, "proc")


var empty: NimNode
var myLit = newLit("str")

Expand Down

0 comments on commit 94675c2

Please sign in to comment.