Skip to content

A binops minus sign ("-") split across rows is parsed as negation when the right operand happens to start at the column immediately after the minus sign #35

Description

@gilramir

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 -.

broken =
    10 -
        3

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:

sameRow =
    10 - 3
"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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions