diff --git a/Cargo.lock b/Cargo.lock index 353f276..0f5eac7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "atty" @@ -408,7 +408,7 @@ checksum = "a3f87b73ce11b1619a3c6332f45341e0047173771e8b8b73f87bfeefb7b56244" [[package]] name = "rnix" -version = "0.11.0" +version = "0.11.1" dependencies = [ "criterion", "expect-test", diff --git a/Cargo.toml b/Cargo.toml index 9ee294f..8dbf660 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,7 +6,7 @@ license = "MIT" name = "rnix" readme = "README.md" repository = "https://github.com/nix-community/rnix-parser" -version = "0.11.0" +version = "0.11.1" [[bench]] harness = false diff --git a/src/ast/operators.rs b/src/ast/operators.rs index 80afe3f..b908aa6 100644 --- a/src/ast/operators.rs +++ b/src/ast/operators.rs @@ -19,6 +19,8 @@ pub enum BinOpKind { MoreOrEq, NotEqual, Or, + PipeRight, + PipeLeft, } impl BinOpKind { @@ -43,6 +45,9 @@ impl BinOpKind { TOKEN_NOT_EQUAL => Some(BinOpKind::NotEqual), TOKEN_OR_OR => Some(BinOpKind::Or), + TOKEN_PIPE_RIGHT => Some(BinOpKind::PipeRight), + TOKEN_PIPE_LEFT => Some(BinOpKind::PipeLeft), + _ => None, } } diff --git a/src/kinds.rs b/src/kinds.rs index 5e212ba..9ccd26c 100644 --- a/src/kinds.rs +++ b/src/kinds.rs @@ -54,6 +54,8 @@ pub enum SyntaxKind { TOKEN_MORE_OR_EQ, TOKEN_NOT_EQUAL, TOKEN_OR_OR, + TOKEN_PIPE_RIGHT, + TOKEN_PIPE_LEFT, // Identifiers and values TOKEN_FLOAT, diff --git a/src/macros.rs b/src/macros.rs index 58806d0..575d692 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -45,5 +45,7 @@ macro_rules! T { (>=) => ($crate::SyntaxKind::TOKEN_MORE_OR_EQ); (!=) => ($crate::SyntaxKind::TOKEN_NOT_EQUAL); (||) => ($crate::SyntaxKind::TOKEN_OR_OR); + ("|>") => ($crate::SyntaxKind::TOKEN_PIPE_RIGHT); + ("<|") => ($crate::SyntaxKind::TOKEN_PIPE_LEFT); ($kind:ident) => ($crate::SyntaxKind::$kind); } diff --git a/src/parser.rs b/src/parser.rs index 9f2055f..895af92 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -693,6 +693,12 @@ where // Always point this to the lowest-level math function there is self.parse_implication() } + fn parse_pipe_right(&mut self) -> Checkpoint { + self.parse_left_assoc(Self::parse_math, T!["|>"] | ()) + } + fn parse_pipe_left(&mut self) -> Checkpoint { + self.parse_right_assoc(Self::parse_pipe_right, T!["<|"] | ()) + } /// Parse Nix code into an AST pub fn parse_expr(&mut self) -> Checkpoint { // Limit chosen somewhat arbitrarily @@ -758,7 +764,7 @@ where self.finish_node(); checkpoint } - _ => self.parse_math(), + _ => self.parse_pipe_left(), }; self.depth -= 1; out diff --git a/src/tokenizer.rs b/src/tokenizer.rs index 4cc734c..6cddb7f 100644 --- a/src/tokenizer.rs +++ b/src/tokenizer.rs @@ -364,6 +364,10 @@ impl Tokenizer<'_> { '-' => TOKEN_SUB, '*' => TOKEN_MUL, '/' => TOKEN_DIV, + '<' if self.peek() == Some('|') => { + self.next().unwrap(); + TOKEN_PIPE_LEFT + } '<' if kind == Some(IdentType::Store) => { self.consume(is_valid_path_char); if self.next() != Some('>') { @@ -376,6 +380,10 @@ impl Tokenizer<'_> { self.next().unwrap(); TOKEN_AND_AND } + '|' if self.peek() == Some('>') => { + self.next().unwrap(); + TOKEN_PIPE_RIGHT + } '|' if self.peek() == Some('|') => { self.next().unwrap(); TOKEN_OR_OR diff --git a/test_data/parser/success/pipe_left.expect b/test_data/parser/success/pipe_left.expect new file mode 100644 index 0000000..236be39 --- /dev/null +++ b/test_data/parser/success/pipe_left.expect @@ -0,0 +1,15 @@ +NODE_ROOT@0..22 + NODE_BIN_OP@0..22 + NODE_SELECT@0..17 + NODE_IDENT@0..8 + TOKEN_IDENT@0..8 "builtins" + TOKEN_DOT@8..9 "." + NODE_ATTRPATH@9..17 + NODE_IDENT@9..17 + TOKEN_IDENT@9..17 "toString" + TOKEN_WHITESPACE@17..18 " " + TOKEN_PIPE_LEFT@18..20 "<|" + TOKEN_WHITESPACE@20..21 " " + NODE_LITERAL@21..22 + TOKEN_INTEGER@21..22 "1" + diff --git a/test_data/parser/success/pipe_left.nix b/test_data/parser/success/pipe_left.nix new file mode 100644 index 0000000..ce3b8e1 --- /dev/null +++ b/test_data/parser/success/pipe_left.nix @@ -0,0 +1 @@ +builtins.toString <| 1 diff --git a/test_data/parser/success/pipe_left_assoc.expect b/test_data/parser/success/pipe_left_assoc.expect new file mode 100644 index 0000000..f58e2e4 --- /dev/null +++ b/test_data/parser/success/pipe_left_assoc.expect @@ -0,0 +1,21 @@ +NODE_ROOT@0..29 + NODE_BIN_OP@0..29 + NODE_IDENT@0..3 + TOKEN_IDENT@0..3 "foo" + TOKEN_WHITESPACE@3..4 " " + TOKEN_PIPE_LEFT@4..6 "<|" + TOKEN_WHITESPACE@6..7 " " + NODE_BIN_OP@7..29 + NODE_SELECT@7..24 + NODE_IDENT@7..15 + TOKEN_IDENT@7..15 "builtins" + TOKEN_DOT@15..16 "." + NODE_ATTRPATH@16..24 + NODE_IDENT@16..24 + TOKEN_IDENT@16..24 "toString" + TOKEN_WHITESPACE@24..25 " " + TOKEN_PIPE_LEFT@25..27 "<|" + TOKEN_WHITESPACE@27..28 " " + NODE_LITERAL@28..29 + TOKEN_INTEGER@28..29 "1" + diff --git a/test_data/parser/success/pipe_left_assoc.nix b/test_data/parser/success/pipe_left_assoc.nix new file mode 100644 index 0000000..c0d111c --- /dev/null +++ b/test_data/parser/success/pipe_left_assoc.nix @@ -0,0 +1 @@ +foo <| builtins.toString <| 1 diff --git a/test_data/parser/success/pipe_left_math.expect b/test_data/parser/success/pipe_left_math.expect new file mode 100644 index 0000000..3dbf0bb --- /dev/null +++ b/test_data/parser/success/pipe_left_math.expect @@ -0,0 +1,21 @@ +NODE_ROOT@0..26 + NODE_BIN_OP@0..26 + NODE_SELECT@0..17 + NODE_IDENT@0..8 + TOKEN_IDENT@0..8 "builtins" + TOKEN_DOT@8..9 "." + NODE_ATTRPATH@9..17 + NODE_IDENT@9..17 + TOKEN_IDENT@9..17 "toString" + TOKEN_WHITESPACE@17..18 " " + TOKEN_PIPE_LEFT@18..20 "<|" + TOKEN_WHITESPACE@20..21 " " + NODE_BIN_OP@21..26 + NODE_LITERAL@21..22 + TOKEN_INTEGER@21..22 "1" + TOKEN_WHITESPACE@22..23 " " + TOKEN_ADD@23..24 "+" + TOKEN_WHITESPACE@24..25 " " + NODE_LITERAL@25..26 + TOKEN_INTEGER@25..26 "1" + diff --git a/test_data/parser/success/pipe_left_math.nix b/test_data/parser/success/pipe_left_math.nix new file mode 100644 index 0000000..62872ee --- /dev/null +++ b/test_data/parser/success/pipe_left_math.nix @@ -0,0 +1 @@ +builtins.toString <| 1 + 1 diff --git a/test_data/parser/success/pipe_mixed.expect b/test_data/parser/success/pipe_mixed.expect new file mode 100644 index 0000000..7462509 --- /dev/null +++ b/test_data/parser/success/pipe_mixed.expect @@ -0,0 +1,21 @@ +NODE_ROOT@0..29 + NODE_BIN_OP@0..29 + NODE_SELECT@0..17 + NODE_IDENT@0..8 + TOKEN_IDENT@0..8 "builtins" + TOKEN_DOT@8..9 "." + NODE_ATTRPATH@9..17 + NODE_IDENT@9..17 + TOKEN_IDENT@9..17 "toString" + TOKEN_WHITESPACE@17..18 " " + TOKEN_PIPE_LEFT@18..20 "<|" + TOKEN_WHITESPACE@20..21 " " + NODE_BIN_OP@21..29 + NODE_LITERAL@21..22 + TOKEN_INTEGER@21..22 "1" + TOKEN_WHITESPACE@22..23 " " + TOKEN_PIPE_RIGHT@23..25 "|>" + TOKEN_WHITESPACE@25..26 " " + NODE_IDENT@26..29 + TOKEN_IDENT@26..29 "foo" + diff --git a/test_data/parser/success/pipe_mixed.nix b/test_data/parser/success/pipe_mixed.nix new file mode 100644 index 0000000..260f2f8 --- /dev/null +++ b/test_data/parser/success/pipe_mixed.nix @@ -0,0 +1 @@ +builtins.toString <| 1 |> foo diff --git a/test_data/parser/success/pipe_mixed_math.expect b/test_data/parser/success/pipe_mixed_math.expect new file mode 100644 index 0000000..69bd187 --- /dev/null +++ b/test_data/parser/success/pipe_mixed_math.expect @@ -0,0 +1,27 @@ +NODE_ROOT@0..33 + NODE_BIN_OP@0..33 + NODE_SELECT@0..17 + NODE_IDENT@0..8 + TOKEN_IDENT@0..8 "builtins" + TOKEN_DOT@8..9 "." + NODE_ATTRPATH@9..17 + NODE_IDENT@9..17 + TOKEN_IDENT@9..17 "toString" + TOKEN_WHITESPACE@17..18 " " + TOKEN_PIPE_LEFT@18..20 "<|" + TOKEN_WHITESPACE@20..21 " " + NODE_BIN_OP@21..33 + NODE_BIN_OP@21..26 + NODE_LITERAL@21..22 + TOKEN_INTEGER@21..22 "1" + TOKEN_WHITESPACE@22..23 " " + TOKEN_ADD@23..24 "+" + TOKEN_WHITESPACE@24..25 " " + NODE_LITERAL@25..26 + TOKEN_INTEGER@25..26 "1" + TOKEN_WHITESPACE@26..27 " " + TOKEN_PIPE_RIGHT@27..29 "|>" + TOKEN_WHITESPACE@29..30 " " + NODE_IDENT@30..33 + TOKEN_IDENT@30..33 "foo" + diff --git a/test_data/parser/success/pipe_mixed_math.nix b/test_data/parser/success/pipe_mixed_math.nix new file mode 100644 index 0000000..880807d --- /dev/null +++ b/test_data/parser/success/pipe_mixed_math.nix @@ -0,0 +1 @@ +builtins.toString <| 1 + 1 |> foo diff --git a/test_data/parser/success/pipe_right.expect b/test_data/parser/success/pipe_right.expect new file mode 100644 index 0000000..7d35f6e --- /dev/null +++ b/test_data/parser/success/pipe_right.expect @@ -0,0 +1,15 @@ +NODE_ROOT@0..22 + NODE_BIN_OP@0..22 + NODE_LITERAL@0..1 + TOKEN_INTEGER@0..1 "1" + TOKEN_WHITESPACE@1..2 " " + TOKEN_PIPE_RIGHT@2..4 "|>" + TOKEN_WHITESPACE@4..5 " " + NODE_SELECT@5..22 + NODE_IDENT@5..13 + TOKEN_IDENT@5..13 "builtins" + TOKEN_DOT@13..14 "." + NODE_ATTRPATH@14..22 + NODE_IDENT@14..22 + TOKEN_IDENT@14..22 "toString" + diff --git a/test_data/parser/success/pipe_right.nix b/test_data/parser/success/pipe_right.nix new file mode 100644 index 0000000..5666662 --- /dev/null +++ b/test_data/parser/success/pipe_right.nix @@ -0,0 +1 @@ +1 |> builtins.toString diff --git a/test_data/parser/success/pipe_right_assoc.expect b/test_data/parser/success/pipe_right_assoc.expect new file mode 100644 index 0000000..c279197 --- /dev/null +++ b/test_data/parser/success/pipe_right_assoc.expect @@ -0,0 +1,21 @@ +NODE_ROOT@0..29 + NODE_BIN_OP@0..29 + NODE_BIN_OP@0..22 + NODE_LITERAL@0..1 + TOKEN_INTEGER@0..1 "1" + TOKEN_WHITESPACE@1..2 " " + TOKEN_PIPE_RIGHT@2..4 "|>" + TOKEN_WHITESPACE@4..5 " " + NODE_SELECT@5..22 + NODE_IDENT@5..13 + TOKEN_IDENT@5..13 "builtins" + TOKEN_DOT@13..14 "." + NODE_ATTRPATH@14..22 + NODE_IDENT@14..22 + TOKEN_IDENT@14..22 "toString" + TOKEN_WHITESPACE@22..23 " " + TOKEN_PIPE_RIGHT@23..25 "|>" + TOKEN_WHITESPACE@25..26 " " + NODE_IDENT@26..29 + TOKEN_IDENT@26..29 "foo" + diff --git a/test_data/parser/success/pipe_right_assoc.nix b/test_data/parser/success/pipe_right_assoc.nix new file mode 100644 index 0000000..bbb2e8f --- /dev/null +++ b/test_data/parser/success/pipe_right_assoc.nix @@ -0,0 +1 @@ +1 |> builtins.toString |> foo diff --git a/test_data/parser/success/pipe_right_math.expect b/test_data/parser/success/pipe_right_math.expect new file mode 100644 index 0000000..a41e870 --- /dev/null +++ b/test_data/parser/success/pipe_right_math.expect @@ -0,0 +1,21 @@ +NODE_ROOT@0..26 + NODE_BIN_OP@0..26 + NODE_BIN_OP@0..5 + NODE_LITERAL@0..1 + TOKEN_INTEGER@0..1 "1" + TOKEN_WHITESPACE@1..2 " " + TOKEN_ADD@2..3 "+" + TOKEN_WHITESPACE@3..4 " " + NODE_LITERAL@4..5 + TOKEN_INTEGER@4..5 "1" + TOKEN_WHITESPACE@5..6 " " + TOKEN_PIPE_RIGHT@6..8 "|>" + TOKEN_WHITESPACE@8..9 " " + NODE_SELECT@9..26 + NODE_IDENT@9..17 + TOKEN_IDENT@9..17 "builtins" + TOKEN_DOT@17..18 "." + NODE_ATTRPATH@18..26 + NODE_IDENT@18..26 + TOKEN_IDENT@18..26 "toString" + diff --git a/test_data/parser/success/pipe_right_math.nix b/test_data/parser/success/pipe_right_math.nix new file mode 100644 index 0000000..9245e7d --- /dev/null +++ b/test_data/parser/success/pipe_right_math.nix @@ -0,0 +1 @@ +1 + 1 |> builtins.toString