Skip to content

Commit 94d6471

Browse files
Fix multiline stab clause with trailing identifier (#20)
1 parent 1b3ecf7 commit 94d6471

File tree

4 files changed

+185
-62
lines changed

4 files changed

+185
-62
lines changed

grammar.js

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -672,11 +672,22 @@ module.exports = grammar({
672672
),
673673

674674
_call_arguments_without_parentheses: ($) =>
675-
// Right precedence, because `fun1 fun2 x, y` is `fun1(fun2(x, y))`
676-
prec.right(
677-
choice(
678-
seq(sep1($._expression, ","), optional(seq(",", $.keywords))),
679-
$.keywords
675+
// In stab clauses a newline can either separate multiple body expressions
676+
// or multiple stab clauses, this falls under the $.body conflict. Given a
677+
// multiline stab clause with trailing identifier like `1 -> 1 \n x \n 2 -> x`,
678+
// there are two matching interpretations:
679+
// * `x` as identifier and `2` as stab argument
680+
// * `x 2` call as stab argument
681+
// Similarly for `Mod.fun` or `mod.fun` the newline should terminate the call.
682+
// Consequently, we reject the second interpretation using dynamic precedence
683+
prec.dynamic(
684+
-1,
685+
// Right precedence, because `fun1 fun2 x, y` is `fun1(fun2(x, y))`
686+
prec.right(
687+
choice(
688+
seq(sep1($._expression, ","), optional(seq(",", $.keywords))),
689+
$.keywords
690+
)
680691
)
681692
),
682693

src/grammar.json

Lines changed: 53 additions & 49 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/parser.c

Lines changed: 8 additions & 8 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

test/corpus/do_end.txt

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -575,6 +575,114 @@ fun do->end
575575
(do_block
576576
(stab_clause))))
577577

578+
579+
=====================================
580+
stab clause / edge cases / trailing call in multiline clause
581+
=====================================
582+
583+
fun do
584+
1 ->
585+
1
586+
x
587+
588+
1 ->
589+
1
590+
end
591+
592+
fun do
593+
1 ->
594+
1
595+
Mod.fun
596+
597+
1 ->
598+
1
599+
end
600+
601+
fun do
602+
1 ->
603+
1
604+
mod.fun
605+
606+
1 ->
607+
1
608+
end
609+
610+
fun do
611+
1 ->
612+
1
613+
614+
x 1 ->
615+
1
616+
end
617+
618+
---
619+
620+
(source
621+
(call
622+
(identifier)
623+
(do_block
624+
(stab_clause
625+
(arguments
626+
(integer))
627+
(body
628+
(integer)
629+
(identifier)))
630+
(stab_clause
631+
(arguments
632+
(integer))
633+
(body
634+
(integer)))))
635+
(call
636+
(identifier)
637+
(do_block
638+
(stab_clause
639+
(arguments
640+
(integer))
641+
(body
642+
(integer)
643+
(call
644+
(dot
645+
(alias)
646+
(identifier)))))
647+
(stab_clause
648+
(arguments
649+
(integer))
650+
(body
651+
(integer)))))
652+
(call
653+
(identifier)
654+
(do_block
655+
(stab_clause
656+
(arguments
657+
(integer))
658+
(body
659+
(integer)
660+
(call
661+
(dot
662+
(identifier)
663+
(identifier)))))
664+
(stab_clause
665+
(arguments
666+
(integer))
667+
(body
668+
(integer)))))
669+
(call
670+
(identifier)
671+
(do_block
672+
(stab_clause
673+
(arguments
674+
(integer))
675+
(body
676+
(integer)))
677+
(stab_clause
678+
(arguments
679+
(call
680+
(identifier)
681+
(arguments
682+
(integer))))
683+
(body
684+
(integer))))))
685+
578686
=====================================
579687
pattern matching
580688
=====================================

0 commit comments

Comments
 (0)