Skip to content

Commit 4b42d73

Browse files
committed
fix: in_op precedence
The Elixir parser rewrites `(!left) in right` into `!(left in right)`, regardless of operator precedence. This rule does not exist in Spitfire, causing a discrepancy in the generated ast. Spitfire: ```elixir {:in, _, [{:!, _, [left]}, right]} ``` Elixir: ```elixir {:!, _, [{:in, _, [left, right]}]} ``` The fix is to add a clause for this rearrangement like the one in the Elixir parser [here](https://github.com/elixir-lang/elixir/blob/c40c140e3f524fa8384efd33137ec1c3fab341d3/lib/elixir/src/elixir_parser.yrl#L749-L756)
1 parent dd45cb1 commit 4b42d73

2 files changed

Lines changed: 13 additions & 0 deletions

File tree

‎lib/spitfire.ex‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1012,6 +1012,16 @@ defmodule Spitfire do
10121012
:"not in" ->
10131013
{:not, meta, [{:in, meta, [lhs, rhs]}]}
10141014

1015+
:in ->
1016+
case lhs do
1017+
{op, _meta, [inner]} when op in [:!, :not] ->
1018+
in_ast = {:in, meta, [inner, rhs]}
1019+
{op, meta, [in_ast]}
1020+
1021+
_ ->
1022+
{token, newlines ++ meta, [lhs, rhs]}
1023+
end
1024+
10151025
:when ->
10161026
lhs =
10171027
case lhs do

‎test/spitfire_test.exs‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -814,6 +814,9 @@ defmodule SpitfireTest do
814814
~s'''
815815
1 in foo()
816816
''',
817+
"!A.a() in B.b()",
818+
"!fn -> a end in a",
819+
"not fn x -> x end in a",
817820
~s'''
818821
foo not in bar
819822
''',

0 commit comments

Comments
 (0)