Skip to content

Deparse

syntax.Deparse (M1, v0.2.0): what it reproduces of deparse() and print(), its parity with R 4.6.2, and the platform divergences: exp10 and x86-64 long double.

f, err := syntax.ParseAll(src)
lines := syntax.Deparse(f.Exprs[0], nil)   // deparse(), one string per line

syntax.Deparse is in v0.2.0 and completes milestone M1 (parser and deparse).

What it is written from

Deparse is written from the documented behaviour of deparse(): precedence and parenthesisation, the 60-byte line cutoff with its break points and indentation, if/else layout inside braces, structure-free constants, 15-significant-digit numbers, and string escapes with R’s own table of printable characters. That table is generated by the oracle into syntax/print_gen.go, and the list of primitives that deparse as function calls into syntax/prims_gen.go. No R source is copied.

Parity with R 4.6.2

Judged by the oracle: the same input is parsed, then deparsed by R and by Go, for deparse() and print().

CorpusInputsDeparse
R src/library: every .R file of the base packages (7.8 MB)844 (842 parse, 2 rejected)842 / 842
R tests/: 95 files (1 is not UTF-8 and is skipped)94 (90 parse, 4 rejected)90 / 90
our snippets4242 / 42
our deparse cases (parentheses, precedence, line breaking, indentation, constants, names)65 (2 rejected)63 / 63
differential fuzz: 610 000 random edits of lines of R’s sources610 000all
decimal literals, random (up to 20 digits, exponents -330..330)100 00099 995 identical, 5 not

The complete table, with the tree, token and error columns, is on The parser.

Known divergences

Both are platform effects, not semantics.

  • exp10. Numeric constants with a decimal exponent beyond about 200 in magnitude: R takes a power of ten from the C library’s exp10, which on macOS is not always the correctly rounded value. 5 of 100 000 random literals of that kind (1e229, 1e303, 1e-244) deparse with one more digit in Go (1.00000000000000e+229). No such constant occurs in R’s sources or tests.
  • x86-64 long double. On x86-64 Linux, where R parses and formats numbers in 80-bit long double with its own digits routine, 6 of the 90 files of R’s tests/ deparse with a different last digit in some constant (1e-270 against 9.99999999999999e-271, -5152.07935578853 against ...52). The CI lane on Linux reports that verdict and gates the other three columns and all of src/library.

Created on by tannevaled

Modified on by tannevaled