Pretty: do not wrap non-compound if/while/for bodies in braces#109
Open
jkoppel wants to merge 1 commit into
Open
Pretty: do not wrap non-compound if/while/for bodies in braces#109jkoppel wants to merge 1 commit into
jkoppel wants to merge 1 commit into
Conversation
`prettyBody nonCompound` synthesizes a `CCompound` around the body before
printing, so e.g.
if (x) return 1;
is pretty-printed as
if (x) {
return 1;
}
The output is semantically equivalent C but diverges from the parsed
AST: a `CReturn` becomes a `CCompound [CBlockStmt (CReturn …)]` on
the trip through `pretty`. Any consumer that needs `parse >> pretty`
to round-trip fails on every `if`/`else`/`while`/`for` that has a
single non-compound body in the source. The synthesised node also
uses `undefined` for its `NodeInfo`, which is a footgun for anything
that touches it.
This commit just prints the body as-is, leaving brace wrapping in
the hands of whoever constructed the AST (i.e., the parser, which
already wraps with `CCompound` whenever the source did).
Originally authored on a downstream fork by dvekeman in 2016
(https://github.com/jkoppel/language-c — fix for fork issue #1).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Language.C.Prettysynthesizes aCCompoundaround any non-compoundif/while/forbody before printing it. This commit removes thatsynthesis and prints the body as-is.
Example
The output has braces around
return 1;that weren't in the source — those braces are introduced entirely by the pretty-printer. With this fix, the second-from-bottom line is justif (x) return 1;.Why
parse >> prettydoesn't round-trip on anyif/while/for/elsewhose body is a single non-compound statement, which is a very common
shape in real-world C. The current behavior at
Pretty.hs:128is:It wraps the body in a fresh
CCompound(withundefinedas itsNodeInfo, which is also a footgun if any downstream consumerlater inspects the synthesized node).
The fix:
prettyBody nonCompound = pretty nonCompoundBrace wrapping stays in the hands of whoever built the AST — the
parser already wraps with
CCompoundwhenever the source did, socompound bodies still print with braces.
Credit
Originally written by @dvekeman in 2016 against the downstream
jkoppel/language-cfork(issue #1 there); never submitted upstream. The commit is preserved
intact with its original author.
Tested
Cherry-picked onto current upstream
master(00db59a); cubix'sparametric-syntax test suite (~100 tests including round-trip checks
on a real C corpus) passes against the resulting
language-c. Happyto add a targeted test inside
language-citself if helpful.