Summary
When a subtraction is written with the right operand on a later row, the parser
reads the - as a unary negation and the whole expression as a function
call — but only when the right operand happens to start at the column
immediately after the -.
is parsed as 10 (-3) — a call of 10 with the argument -3 — rather than
10 - 3.
The Haskell-based Gren compiler and elm-format both read it as subtraction, unlike
the compiler-common.
The parse
gren-formt --pre-ast on the module above shows:
"body": {
"value": {
"type": "call",
"fn": { "value": { "type": "number", "value": { "type": "int", "value": 10 } } },
"args": [
{ "value": { "type": "negate",
"expr": { "value": { "type": "number",
"value": { "type": "int", "value": 3 } } } } }
]
}
}
Written on one row, the same expression parses correctly:
"body": { "value": { "type": "binops",
"left": { "value": { "type": "number", … 10 } },
"operator": { "value": "-" },
"right": { "value": { "type": "number", … 3 } } } }
The Haskell-based compiler parses this correctly
Both of these examples compile cleanly with the Haskell-based Gren compiler:
module T exposing (..)
broken : Int
broken =
10 -
3
withComment : Int
withComment =
10 - -- c
3
$ gren make T
Success! Compiled 1 module.
Diagnosis - it is the column, and nothing else
The trigger is the right operand starting at the column one past the - on a
later row. Nothing about the first operand kinds matters; shifting the operand one
column either way flips the parse.
A blank line between the two rows makes no difference; it is still parsed as a
call.
Summary
When a subtraction is written with the right operand on a later row, the parser
reads the
-as a unary negation and the whole expression as a functioncall — but only when the right operand happens to start at the column
immediately after the
-.is parsed as
10 (-3)— a call of10with the argument-3— rather than10 - 3.The Haskell-based Gren compiler and
elm-formatboth read it as subtraction, unlikethe compiler-common.
The parse
gren-formt --pre-aston the module above shows:Written on one row, the same expression parses correctly:
The Haskell-based compiler parses this correctly
Both of these examples compile cleanly with the Haskell-based Gren compiler:
Diagnosis - it is the column, and nothing else
The trigger is the right operand starting at the column one past the
-on alater row. Nothing about the first operand kinds matters; shifting the operand one
column either way flips the parse.
A blank line between the two rows makes no difference; it is still parsed as a
call.