From 08dbe8978c3c62a874745f46e84a6ebac72acd5c Mon Sep 17 00:00:00 2001 From: Michael Davis Date: Sun, 13 Feb 2022 13:19:53 -0600 Subject: [PATCH] parse nullary range operator (#25) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Jonatan KÅ‚osko --- grammar.js | 16 ++++++++++++++-- test/corpus/expression/operator.txt | 25 +++++++++++++++++++++++++ test/highlight/operators.ex | 5 +++++ 3 files changed, 44 insertions(+), 2 deletions(-) diff --git a/grammar.js b/grammar.js index 6bd3f61..f91bdbf 100644 --- a/grammar.js +++ b/grammar.js @@ -16,6 +16,7 @@ const PREC = { XOR_OP: 140, TERNARY_OP: 150, CONCAT_OPS: 160, + RANGE_OP: 160, ADD_OPS: 170, MULT_OPS: 180, POWER_OP: 190, @@ -33,13 +34,13 @@ const COMP_OPS = ["==", "!=", "=~", "===", "!=="]; const REL_OPS = ["<", ">", "<=", ">="]; const ARROW_OPS = ["|>", "<<<", ">>>", "<<~", "~>>", "<~", "~>", "<~>", "<|>"]; const IN_OPS = ["in", "not in"]; -const CONCAT_OPS = ["++", "--", "+++", "---", "..", "<>"]; +const CONCAT_OPS = ["++", "--", "+++", "---", "<>"]; const ADD_OPS = ["+", "-"]; const MULT_OPS = ["*", "/"]; const UNARY_OPS = ["+", "-", "!", "^", "~~~", "not"]; const ALL_OPS = [ - ["->", "when", "::", "|", "=>", "&", "=", "^^^", "//", "**", ".", "@"], + ["->", "when", "::", "|", "=>", "&", "=", "^^^", "//", "..", "**", ".", "@"], IN_MATCH_OPS, OR_OPS, AND_OPS, @@ -213,6 +214,7 @@ module.exports = grammar({ $.tuple, $.bitstring, $.map, + $._nullary_operator, $.unary_operator, $.binary_operator, $.dot, @@ -426,6 +428,11 @@ module.exports = grammar({ ) ), + _nullary_operator: ($) => + // Nullary operators don't have any child nodes, so we reuse the + // operator_identifier node + alias(prec(PREC.RANGE_OP, ".."), $.operator_identifier), + unary_operator: ($) => choice( unaryOp($, prec, PREC.CAPTURE_OP, "&", $._capture_expression), @@ -480,6 +487,7 @@ module.exports = grammar({ binaryOp($, prec.left, PREC.XOR_OP, "^^^"), binaryOp($, prec.right, PREC.TERNARY_OP, "//"), binaryOp($, prec.right, PREC.CONCAT_OPS, choice(...CONCAT_OPS)), + binaryOp($, prec.right, PREC.RANGE_OP, ".."), binaryOp($, prec.left, PREC.ADD_OPS, choice(...ADD_OPS)), binaryOp($, prec.left, PREC.MULT_OPS, choice(...MULT_OPS)), binaryOp($, prec.left, PREC.POWER_OP, "**"), @@ -524,6 +532,10 @@ module.exports = grammar({ alias($._not_in, "not in"), "^^", ...CONCAT_OPS, + // The range operator has both a binary and a nullary version. + // The nullary version is already parsed as operator_identifier, + // so it covers this case + // ".." ...MULT_OPS, "**", "->", diff --git a/test/corpus/expression/operator.txt b/test/corpus/expression/operator.txt index a441b87..2cf312c 100644 --- a/test/corpus/expression/operator.txt +++ b/test/corpus/expression/operator.txt @@ -656,6 +656,31 @@ x +y +z (unary_operator (identifier)))))))) +===================================== +nullary range +===================================== + +.. +Enum.to_list(..) +not .. +range = .. + +--- + +(source + (operator_identifier) + (call + (dot + (alias) + (identifier)) + (arguments + (operator_identifier))) + (unary_operator + (operator_identifier)) + (binary_operator + (identifier) + (operator_identifier))) + ===================================== stepped range ===================================== diff --git a/test/highlight/operators.ex b/test/highlight/operators.ex index 0d3b5bf..b210782 100644 --- a/test/highlight/operators.ex +++ b/test/highlight/operators.ex @@ -82,3 +82,8 @@ y = true and false # ^ module # ^ operator # ^ function + +range = .. +# <- variable +# ^ operator +# ^ operator