doc/ref/spec: reflect reality w.r.t. octal numbers
0123:
- cue/parser|scanner: not accepted (done)
- cue: accepted if present in AST (done)
- cue/format: accepted but convert
Also added a test for multiline label acceptance.
This is also tested in another package.
Change-Id: If3cf3892e03020528840cedca760dea9552df84c
Reviewed-on: https://cue-review.googlesource.com/c/cue/+/3442
Reviewed-by: Marcel van Lohuizen <mpvl@golang.org>
diff --git a/cue/format/format_test.go b/cue/format/format_test.go
index 7c5ab8d..28dd843 100644
--- a/cue/format/format_test.go
+++ b/cue/format/format_test.go
@@ -226,6 +226,45 @@
}
}
+// TestNodes tests nodes that are that are invalid CUE, but are accepted by
+// format.
+func TestNodes(t *testing.T) {
+ testCases := []struct {
+ name string
+ in ast.Node
+ out string
+ }{{
+ name: "old-style octal numbers",
+ in: &ast.BasicLit{Kind: token.INT, Value: "0123"},
+ out: "0o123",
+ }, {
+ name: "labels with multi-line strings",
+ in: &ast.Field{
+ Label: &ast.BasicLit{
+ Kind: token.STRING,
+ Value: `"""
+ foo
+ bar
+ """`,
+ },
+ Value: ast.NewIdent("goo"),
+ },
+ out: `"foo\nbar": goo`,
+ }}
+ for _, tc := range testCases {
+ t.Run(tc.name, func(t *testing.T) {
+ b, err := Node(tc.in)
+ if err != nil {
+ t.Fatal(err)
+ }
+ if got := string(b); got != tc.out {
+ t.Errorf("\ngot: %v; want: %v", got, tc.out)
+ }
+ })
+ }
+
+}
+
// Verify that the printer doesn't crash if the AST contains BadXXX nodes.
func TestBadNodes(t *testing.T) {
const src = "package p\n("
diff --git a/cue/format/printer.go b/cue/format/printer.go
index 3542310..5ecec0b 100644
--- a/cue/format/printer.go
+++ b/cue/format/printer.go
@@ -107,6 +107,15 @@
case *ast.BasicLit:
data = x.Value
+ switch x.Kind {
+ case token.INT:
+ if len(data) > 1 &&
+ data[0] == '0' &&
+ data[1] >= '0' && data[1] <= '9' {
+ data = "0o" + data[1:]
+ }
+ }
+
isLit = true
impliedComma = true
p.lastTok = x.Kind
diff --git a/doc/ref/spec.md b/doc/ref/spec.md
index aab56f8..2df912c 100644
--- a/doc/ref/spec.md
+++ b/doc/ref/spec.md
@@ -302,7 +302,7 @@
### Integer literals
An integer literal is a sequence of digits representing an integer value.
-An optional prefix sets a non-decimal base: 0 for octal,
+An optional prefix sets a non-decimal base: 0o for octal,
0x or 0X for hexadecimal, and 0b for binary.
In hexadecimal literals, letters a-f and A-F represent values 10 through 15.
All integers allow interstitial underscores "_";
@@ -321,7 +321,7 @@
"." decimals multiplier .
binary_lit = "0b" binary_digit { binary_digit } .
hex_lit = "0" ( "x" | "X" ) hex_digit { [ "_" ] hex_digit } .
-octal_lit = "0" [ "o" ] octal_digit { [ "_" ] octal_digit } .
+octal_lit = "0o" octal_digit { [ "_" ] octal_digit } .
multiplier = ( "K" | "M" | "G" | "T" | "P" | "E" | "Y" | "Z" ) [ "i" ]
float_lit = decimals "." [ decimals ] [ exponent ] |