Skip to content

Commit

Permalink
allow dots in defined() (nim-lang#20010)
Browse files Browse the repository at this point in the history
* allow dots in defined()

refs nim-lang/RFCs#181

* mention accents in older versions
  • Loading branch information
metagn authored and capocasa committed Mar 31, 2023
1 parent c6688ee commit bdf236d
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 3 deletions.
3 changes: 3 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,9 @@ becomes an alias for `addr`.
- Full command syntax and block arguments i.e. `foo a, b: c` are now allowed
for the right-hand side of type definitions in type sections. Previously
they would error with "invalid indentation".
- `defined` now accepts identifiers separated by dots, i.e. `defined(a.b.c)`.
In the command line, this is defined as `-d:a.b.c`. Older versions can
use accents as in ``defined(`a.b.c`)`` to access such defines.

## Compiler changes

Expand Down
14 changes: 13 additions & 1 deletion compiler/semexprs.nim
Original file line number Diff line number Diff line change
Expand Up @@ -1938,11 +1938,23 @@ proc semYield(c: PContext, n: PNode): PNode =
elif c.p.owner.typ[0] != nil:
localError(c.config, n.info, errGenerated, "yield statement must yield a value")

proc considerQuotedIdentOrDot(c: PContext, n: PNode, origin: PNode = nil): PIdent =
if n.kind == nkDotExpr:
let a = considerQuotedIdentOrDot(c, n[0], origin).s
let b = considerQuotedIdentOrDot(c, n[1], origin).s
var s = newStringOfCap(a.len + b.len + 1)
s.add(a)
s.add('.')
s.add(b)
result = getIdent(c.cache, s)
else:
result = considerQuotedIdent(c, n, origin)

proc semDefined(c: PContext, n: PNode): PNode =
checkSonsLen(n, 2, c.config)
# we replace this node by a 'true' or 'false' node:
result = newIntNode(nkIntLit, 0)
result.intVal = ord isDefined(c.config, considerQuotedIdent(c, n[1], n).s)
result.intVal = ord isDefined(c.config, considerQuotedIdentOrDot(c, n[1], n).s)
result.info = n.info
result.typ = getSysType(c.graph, n.info, tyBool)

Expand Down
19 changes: 17 additions & 2 deletions tests/misc/tdefine.nim
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
discard """
joinable: false
cmd: "nim c -d:booldef -d:booldef2=false -d:intdef=2 -d:strdef=foobar -r $file"
cmd: "nim c -d:booldef -d:booldef2=false -d:intdef=2 -d:strdef=foobar -d:namespaced.define=false -d:double.namespaced.define -r $file"
"""

const booldef {.booldefine.} = false
Expand All @@ -27,4 +27,19 @@ type T = object
when intdef2 == 1:
field2: int
when strdef2 == "abc":
field3: int
field3: int

doAssert not defined(booldef3)
doAssert not defined(intdef2)
doAssert not defined(strdef2)
discard T(field1: 1, field2: 2, field3: 3)

doAssert defined(namespaced.define)
const `namespaced.define` {.booldefine.} = true
doAssert not `namespaced.define`

doAssert defined(double.namespaced.define)
const `double.namespaced.define` {.booldefine.} = false
doAssert `double.namespaced.define`

doAssert not defined(namespaced.butnotdefined)

0 comments on commit bdf236d

Please sign in to comment.