cue/scanner: allow $ as a letter in identifies
This brings CUE identifiers in line with JavaScript,
and more importantly, JSON style.
It is common in JSON to have identifiers with a $.
With the restriction that string labels can no longer
be referenced, and with the elimination of quoted
identifiers, this has become a bit awkward.
Also, unlike Go, CUE cannot enforce a certain
capitalization style as this is often enforced by the
given APIs. Allowing `$` in addition to `_` gives users
a bit more flexibility in using identifiers that stand out
from other conventions used within an API.
Change-Id: If6253d1e353729aad07ccd665ccd04018ab2ccce
Reviewed-on: https://cue-review.googlesource.com/c/cue/+/3982
Reviewed-by: Jonathan Amsterdam <jba@google.com>
diff --git a/cue/ast/ident.go b/cue/ast/ident.go
index 8760c7b..22e3762 100644
--- a/cue/ast/ident.go
+++ b/cue/ast/ident.go
@@ -35,7 +35,7 @@
// IsValidIdent reports whether str is a valid identifier.
func IsValidIdent(ident string) bool {
for i, r := range ident {
- if isLetter(r) || r == '_' {
+ if isLetter(r) || r == '_' || r == '$' {
continue
}
if i > 0 && isDigit(r) {
@@ -65,7 +65,7 @@
// }
for _, r := range ident {
- if isLetter(r) || isDigit(r) || r == '_' {
+ if isLetter(r) || isDigit(r) || r == '_' || r == '$' {
continue
}
if r == '-' {
diff --git a/cue/scanner/scanner.go b/cue/scanner/scanner.go
index 07817f9..29cb0cf 100644
--- a/cue/scanner/scanner.go
+++ b/cue/scanner/scanner.go
@@ -282,7 +282,7 @@
func (s *Scanner) scanIdentifier() string {
offs := s.offset
- for isLetter(s.ch) || isDigit(s.ch) || s.ch == '_' {
+ for isLetter(s.ch) || isDigit(s.ch) || s.ch == '_' || s.ch == '$' {
s.next()
}
return string(s.src[offs:s.offset])
@@ -798,7 +798,7 @@
// lit = string(rune(ch))
// s.next()
// fallthrough
- case isLetter(ch):
+ case isLetter(ch), ch == '$':
lit = s.scanIdentifier()
if len(lit) > 1 {
// keywords are longer than one letter - avoid lookup otherwise
diff --git a/cue/scanner/scanner_test.go b/cue/scanner/scanner_test.go
index bcbca81..11a377b 100644
--- a/cue/scanner/scanner_test.go
+++ b/cue/scanner/scanner_test.go
@@ -74,6 +74,7 @@
{token.BOTTOM, "_|_", literal},
{token.IDENT, "foobar", literal},
+ {token.IDENT, "$foobar", literal},
{token.IDENT, "`foobar`", literal},
{token.IDENT, "a۰۱۸", literal},
{token.IDENT, "foo६४", literal},
diff --git a/doc/ref/spec.md b/doc/ref/spec.md
index 22fc29c..2fe4864 100644
--- a/doc/ref/spec.md
+++ b/doc/ref/spec.md
@@ -177,8 +177,9 @@
### Identifiers
Identifiers name entities such as fields and aliases.
-An identifier is a sequence of one or more letters (which includes `_`) and digits.
-It may not be `_`.
+An identifier is a sequence of one or more letters (which includes `_` and `$`)
+and digits.
+It may not be `_` or `$`.
The first character in an identifier must be a letter.
<!--