pigpigyyy / Yuescript

A Moonscript dialect compiles to Lua.
http://yuescript.org
MIT License
424 stars 35 forks source link

Precedence of pipeline operator with list syntax w/o explicit line continuation #138

Open refi64 opened 1 year ago

refi64 commented 1 year ago

Right now, if I compile this code:

f
  * a
    |> b

the resulting Lua is:

return b(f({ -- 2
  a -- 2
})) -- 2

This is the opposite of what I'd expect: based on the indentation, I would've thought it would be parsed as f({ a|> b }), not f({ a }) |> b. If I use an explicit slash:

f
  * a \
    |> b

then it compiles like I'd expect:

return f({ -- 2
  b(a) -- 2
}) -- 3

I'm not sure if this is intentional? But it was certainly rather confusing :sweat_smile:

pigpigyyy commented 1 year ago

It is a syntax precedence problem. To support syntax like:

readFile "example.txt"
  |> extract language, {}
  |> parse language
  |> emit
  |> render
  |> print

The multiline pipes are parsed as statements instead of parts of an expression for the moment. So that the newline characters are breaking the expression in the end of function call argument. If we make pipe syntax a higher precedence, the example codes above will be parsed as:

readFile("example.txt" |> extract(language, {} |> parse(language |> emit |> render |> print))

So we have to carefully write every bracket for the right multiline pipes parsing that way.

readFile("example.txt")
  |> extract(language, {})
  |> parse(language)
  |> emit
  |> render
  |> print
refi64 commented 1 year ago

That makes sense, but I feel like the indentation is what makes this weirder? Like I'd certainly expect that behavior from, say:

f
  * a
  |> b

which is closer to the example you gave in terms of indentation. The weird part in the original example to me is that it's reaching across multiple levels of indentation.

pigpigyyy commented 1 year ago

In the current Yuescript compiler the orignal code:

f
  * a
    |> b

is just seen as:

[expression][newline character]
[advanced indentation][pipe expression]

And there is no rule to tell different [advanced indentation] levels should have different meanings.