Skip to content

Commit 57a9131

Browse files
author
Gilad Chase
committed
feat: Add &T to parser, semantic not implemented yet
Note: change in `attribute_errors` are since `&` can now also be Unary, and the test wanted to test a missing binary operator, so `/` is now the binary operator used to keep the spirit of the test without changing the diff.
1 parent a01206a commit 57a9131

File tree

10 files changed

+173
-11
lines changed

10 files changed

+173
-11
lines changed

crates/cairo-lang-formatter/src/node_properties.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ impl<'a> SyntaxNodeFormat for SyntaxNode<'a> {
150150
{
151151
true
152152
}
153-
SyntaxKind::TokenMinus | SyntaxKind::TokenMul => {
153+
SyntaxKind::TokenMinus | SyntaxKind::TokenMul | SyntaxKind::TokenAnd => {
154154
matches!(self.grandparent_kind(db), Some(SyntaxKind::ExprUnary))
155155
}
156156
SyntaxKind::TokenPlus

crates/cairo-lang-parser/src/operators.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use cairo_lang_syntax::node::kind::SyntaxKind;
33
pub fn get_unary_operator_precedence(kind: SyntaxKind) -> Option<usize> {
44
match kind {
55
SyntaxKind::TerminalAt
6+
| SyntaxKind::TerminalAnd
67
| SyntaxKind::TerminalNot
78
| SyntaxKind::TerminalBitNot
89
| SyntaxKind::TerminalMul

crates/cairo-lang-parser/src/parser.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1503,6 +1503,7 @@ impl<'a, 'mt> Parser<'a, 'mt> {
15031503
fn expect_unary_operator(&mut self) -> UnaryOperatorGreen<'a> {
15041504
match self.peek().kind {
15051505
SyntaxKind::TerminalAt => self.take::<TerminalAt<'_>>().into(),
1506+
SyntaxKind::TerminalAnd => self.take::<TerminalAnd<'_>>().into(),
15061507
SyntaxKind::TerminalNot => self.take::<TerminalNot<'_>>().into(),
15071508
SyntaxKind::TerminalBitNot => self.take::<TerminalBitNot<'_>>().into(),
15081509
SyntaxKind::TerminalMinus => self.take::<TerminalMinus<'_>>().into(),
@@ -1706,6 +1707,11 @@ impl<'a, 'mt> Parser<'a, 'mt> {
17061707
let expr = self.parse_type_expr();
17071708
Ok(ExprUnary::new_green(self.db, op, expr).into())
17081709
}
1710+
SyntaxKind::TerminalAnd => {
1711+
let op = self.take::<TerminalAnd<'_>>().into();
1712+
let expr = self.parse_type_expr();
1713+
Ok(ExprUnary::new_green(self.db, op, expr).into())
1714+
}
17091715
SyntaxKind::TerminalIdentifier | SyntaxKind::TerminalDollar => {
17101716
Ok(self.parse_type_path().into())
17111717
}

crates/cairo-lang-parser/src/parser_test.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,7 @@ cairo_lang_test_utils::test_file_test!(
199199
while_: "while",
200200
for_: "for",
201201
range: "range",
202+
reference: "reference",
202203
use_: "use",
203204
type_alias: "type_alias",
204205
macro_declaration: "macro_declaration",

crates/cairo-lang-parser/src/parser_test_data/partial_trees/logical_operator

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
//! > Test binary expression.
1+
//! > Test logical AND and OR
22

33
//! > test_runner_name
44
test_partial_parser_tree(expect_diagnostics: false)
@@ -42,3 +42,38 @@ ExprBinary
4242
└── segments (kind: ExprPathInner)
4343
└── item #0 (kind: PathSegmentSimple)
4444
└── ident (kind: TokenIdentifier): 'd'
45+
46+
//! > ==========================================================================
47+
48+
//! > Test reference type param with bitwise AND expression
49+
50+
//! > test_runner_name
51+
test_partial_parser_tree(expect_diagnostics: false)
52+
53+
//! > cairo_code
54+
fn foo(a: &u32, b: u32) {
55+
a & &b
56+
}
57+
58+
//! > top_level_kind
59+
ExprBinary
60+
61+
//! > ignored_kinds
62+
63+
//! > expected_diagnostics
64+
65+
//! > expected_tree
66+
└── Top level kind: ExprBinary
67+
├── lhs (kind: ExprPath)
68+
│ ├── dollar (kind: OptionTerminalDollarEmpty) []
69+
│ └── segments (kind: ExprPathInner)
70+
│ └── item #0 (kind: PathSegmentSimple)
71+
│ └── ident (kind: TokenIdentifier): 'a'
72+
├── op (kind: TokenAnd): '&'
73+
└── rhs (kind: ExprUnary)
74+
├── op (kind: TokenAnd): '&'
75+
└── expr (kind: ExprPath)
76+
├── dollar (kind: OptionTerminalDollarEmpty) []
77+
└── segments (kind: ExprPathInner)
78+
└── item #0 (kind: PathSegmentSimple)
79+
└── ident (kind: TokenIdentifier): 'b'
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
//! > Test basic reference type
2+
3+
//! > test_runner_name
4+
test_partial_parser_tree(expect_diagnostics: false)
5+
6+
//! > cairo_code
7+
fn f(x: &u32) {}
8+
9+
//! > top_level_kind
10+
ExprUnary
11+
12+
//! > ignored_kinds
13+
14+
//! > expected_diagnostics
15+
16+
//! > expected_tree
17+
└── Top level kind: ExprUnary
18+
├── op (kind: TokenAnd): '&'
19+
└── expr (kind: ExprPath)
20+
├── dollar (kind: OptionTerminalDollarEmpty) []
21+
└── segments (kind: ExprPathInner)
22+
└── item #0 (kind: PathSegmentSimple)
23+
└── ident (kind: TokenIdentifier): 'u32'
24+
25+
//! > ==========================================================================
26+
27+
//! > Test reference of snapshot vs snapshot of reference
28+
29+
//! > test_runner_name
30+
test_partial_parser_tree(expect_diagnostics: false)
31+
32+
//! > cairo_code
33+
fn f(x: &@u32, y: @ &u32) {}
34+
35+
//! > top_level_kind
36+
ParamList
37+
38+
//! > ignored_kinds
39+
40+
//! > expected_diagnostics
41+
42+
//! > expected_tree
43+
└── Top level kind: ParamList
44+
├── item #0 (kind: Param)
45+
│ ├── modifiers (kind: ModifierList) []
46+
│ ├── name (kind: TokenIdentifier): 'x'
47+
│ └── type_clause (kind: TypeClause)
48+
│ ├── colon (kind: TokenColon): ':'
49+
│ └── ty (kind: ExprUnary)
50+
│ ├── op (kind: TokenAnd): '&'
51+
│ └── expr (kind: ExprUnary)
52+
│ ├── op (kind: TokenAt): '@'
53+
│ └── expr (kind: ExprPath)
54+
│ ├── dollar (kind: OptionTerminalDollarEmpty) []
55+
│ └── segments (kind: ExprPathInner)
56+
│ └── item #0 (kind: PathSegmentSimple)
57+
│ └── ident (kind: TokenIdentifier): 'u32'
58+
├── separator #0 (kind: TokenComma): ','
59+
└── item #1 (kind: Param)
60+
├── modifiers (kind: ModifierList) []
61+
├── name (kind: TokenIdentifier): 'y'
62+
└── type_clause (kind: TypeClause)
63+
├── colon (kind: TokenColon): ':'
64+
└── ty (kind: ExprUnary)
65+
├── op (kind: TokenAt): '@'
66+
└── expr (kind: ExprUnary)
67+
├── op (kind: TokenAnd): '&'
68+
└── expr (kind: ExprPath)
69+
├── dollar (kind: OptionTerminalDollarEmpty) []
70+
└── segments (kind: ExprPathInner)
71+
└── item #0 (kind: PathSegmentSimple)
72+
└── ident (kind: TokenIdentifier): 'u32'
73+
74+
//! > ==========================================================================
75+
76+
//! > Test reference inside generics
77+
78+
//! > test_runner_name
79+
test_partial_parser_tree(expect_diagnostics: false)
80+
81+
//! > cairo_code
82+
fn f() -> Option< &u64> {}
83+
84+
//! > top_level_kind
85+
ExprUnary
86+
87+
//! > ignored_kinds
88+
89+
//! > expected_diagnostics
90+
91+
//! > expected_tree
92+
└── Top level kind: ExprUnary
93+
├── op (kind: TokenAnd): '&'
94+
└── expr (kind: ExprPath)
95+
├── dollar (kind: OptionTerminalDollarEmpty) []
96+
└── segments (kind: ExprPathInner)
97+
└── item #0 (kind: PathSegmentSimple)
98+
└── ident (kind: TokenIdentifier): 'u64'

crates/cairo-lang-parser/src/parser_test_data/partial_trees_with_trivia/attribute_errors

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -978,7 +978,7 @@ test_partial_parser_tree_with_trivia(expect_diagnostics: true)
978978
//! > cairo_code
979979
fn foo() {
980980
#[aaa]
981-
&
981+
/
982982
}
983983

984984
//! > top_level_kind
@@ -1002,7 +1002,7 @@ error: Missing tokens. Expected a statement after attributes.
10021002

10031003
error: Skipped tokens. Expected: statement.
10041004
--> dummy_file.cairo:3:5
1005-
&
1005+
/
10061006
^
10071007

10081008
//! > expected_tree
@@ -1028,7 +1028,7 @@ error: Skipped tokens. Expected: statement.
10281028
│ │ ├── arguments (kind: OptionArgListParenthesizedEmpty) []
10291029
│ │ └── rbrack (kind: TerminalRBrack) <ignored>
10301030
│ ├── child #1 (kind: TokenWhitespace).
1031-
│ ├── child #2 (kind: TokenSkipped): '&'
1031+
│ ├── child #2 (kind: TokenSkipped): '/'
10321032
│ └── child #3 (kind: TokenNewline).
10331033
├── token (kind: TokenRBrace): '}'
10341034
└── trailing_trivia (kind: Trivia) []
@@ -1042,7 +1042,7 @@ test_partial_parser_tree_with_trivia(expect_diagnostics: true)
10421042

10431043
//! > cairo_code
10441044
fn foo() {
1045-
&
1045+
/
10461046
#[aaa]
10471047
}
10481048

@@ -1061,7 +1061,7 @@ TerminalSemicolon
10611061
//! > expected_diagnostics
10621062
error: Skipped tokens. Expected: statement.
10631063
--> dummy_file.cairo:2:5
1064-
&
1064+
/
10651065
^
10661066

10671067
error: Missing tokens. Expected a statement after attributes.
@@ -1082,7 +1082,7 @@ error: Missing tokens. Expected a statement after attributes.
10821082
│ ├── hash (kind: TerminalHash)
10831083
│ │ ├── leading_trivia (kind: Trivia)
10841084
│ │ │ ├── child #0 (kind: TokenWhitespace).
1085-
│ │ │ ├── child #1 (kind: TokenSkipped): '&'
1085+
│ │ │ ├── child #1 (kind: TokenSkipped): '/'
10861086
│ │ │ ├── child #2 (kind: TokenNewline).
10871087
│ │ │ └── child #3 (kind: TokenWhitespace).
10881088
│ │ ├── token (kind: TokenHash): '#'
@@ -1111,7 +1111,7 @@ test_partial_parser_tree_with_trivia(expect_diagnostics: true)
11111111
//! > cairo_code
11121112
fn foo() {
11131113
#[aaa]
1114-
&
1114+
/
11151115
#[bbb]
11161116
}
11171117

@@ -1135,7 +1135,7 @@ error: Missing tokens. Expected a statement after attributes.
11351135

11361136
error: Skipped tokens. Expected: statement.
11371137
--> dummy_file.cairo:3:5
1138-
&
1138+
/
11391139
^
11401140

11411141
error: Missing tokens. Expected a statement after attributes.
@@ -1176,7 +1176,7 @@ error: Missing tokens. Expected a statement after attributes.
11761176
│ │ │ │ ├── arguments (kind: OptionArgListParenthesizedEmpty) []
11771177
│ │ │ │ └── rbrack (kind: TerminalRBrack) <ignored>
11781178
│ │ │ ├── child #1 (kind: TokenWhitespace).
1179-
│ │ │ ├── child #2 (kind: TokenSkipped): '&'
1179+
│ │ │ ├── child #2 (kind: TokenSkipped): '/'
11801180
│ │ │ ├── child #3 (kind: TokenNewline).
11811181
│ │ │ └── child #4 (kind: TokenWhitespace).
11821182
│ │ ├── token (kind: TokenHash): '#'

crates/cairo-lang-semantic/src/corelib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -552,6 +552,7 @@ pub fn core_unary_operator<'db>(
552552
UnaryOperator::BitNot(_) => (info.bitnot_trt, info.bitnot_fn),
553553
UnaryOperator::At(_) => unreachable!("@ is not an unary operator."),
554554
UnaryOperator::Desnap(_) => unreachable!("* is not an unary operator."),
555+
UnaryOperator::Reference(_) => unreachable!("& is handled before reaching here."),
555556
};
556557
Ok(Ok(get_core_trait_function_infer(db, inference, trait_id, trait_fn, stable_ptr)))
557558
}

crates/cairo-lang-syntax-codegen/src/cairo_spec.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ pub fn get_spec() -> Vec<Node> {
102102
.node_with_explicit_kind("Minus", "TerminalMinus")
103103
.node_with_explicit_kind("At", "TerminalAt")
104104
.node_with_explicit_kind("Desnap", "TerminalMul")
105+
.node_with_explicit_kind("Reference", "TerminalAnd")
105106
)
106107
.add_struct(StructBuilder::new("ExprBinary")
107108
.node("lhs", "Expr")

crates/cairo-lang-syntax/src/node/ast.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2706,6 +2706,7 @@ pub enum UnaryOperator<'db> {
27062706
Minus(TerminalMinus<'db>),
27072707
At(TerminalAt<'db>),
27082708
Desnap(TerminalMul<'db>),
2709+
Reference(TerminalAnd<'db>),
27092710
}
27102711
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, salsa::Update)]
27112712
pub struct UnaryOperatorPtr<'db>(pub SyntaxStablePtrId<'db>);
@@ -2748,6 +2749,11 @@ impl<'db> From<TerminalMulPtr<'db>> for UnaryOperatorPtr<'db> {
27482749
Self(value.0)
27492750
}
27502751
}
2752+
impl<'db> From<TerminalAndPtr<'db>> for UnaryOperatorPtr<'db> {
2753+
fn from(value: TerminalAndPtr<'db>) -> Self {
2754+
Self(value.0)
2755+
}
2756+
}
27512757
impl<'db> From<TerminalNotGreen<'db>> for UnaryOperatorGreen<'db> {
27522758
fn from(value: TerminalNotGreen<'db>) -> Self {
27532759
Self(value.0)
@@ -2773,6 +2779,11 @@ impl<'db> From<TerminalMulGreen<'db>> for UnaryOperatorGreen<'db> {
27732779
Self(value.0)
27742780
}
27752781
}
2782+
impl<'db> From<TerminalAndGreen<'db>> for UnaryOperatorGreen<'db> {
2783+
fn from(value: TerminalAndGreen<'db>) -> Self {
2784+
Self(value.0)
2785+
}
2786+
}
27762787
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, salsa::Update)]
27772788
pub struct UnaryOperatorGreen<'db>(pub GreenId<'db>);
27782789
impl<'db> TypedSyntaxNode<'db> for UnaryOperator<'db> {
@@ -2796,6 +2807,9 @@ impl<'db> TypedSyntaxNode<'db> for UnaryOperator<'db> {
27962807
SyntaxKind::TerminalMul => {
27972808
UnaryOperator::Desnap(TerminalMul::from_syntax_node(db, node))
27982809
}
2810+
SyntaxKind::TerminalAnd => {
2811+
UnaryOperator::Reference(TerminalAnd::from_syntax_node(db, node))
2812+
}
27992813
_ => panic!("Unexpected syntax kind {:?} when constructing {}.", kind, "UnaryOperator"),
28002814
}
28012815
}
@@ -2817,6 +2831,9 @@ impl<'db> TypedSyntaxNode<'db> for UnaryOperator<'db> {
28172831
SyntaxKind::TerminalMul => {
28182832
Some(UnaryOperator::Desnap(TerminalMul::from_syntax_node(db, node)))
28192833
}
2834+
SyntaxKind::TerminalAnd => {
2835+
Some(UnaryOperator::Reference(TerminalAnd::from_syntax_node(db, node)))
2836+
}
28202837
_ => None,
28212838
}
28222839
}
@@ -2827,6 +2844,7 @@ impl<'db> TypedSyntaxNode<'db> for UnaryOperator<'db> {
28272844
UnaryOperator::Minus(x) => x.as_syntax_node(),
28282845
UnaryOperator::At(x) => x.as_syntax_node(),
28292846
UnaryOperator::Desnap(x) => x.as_syntax_node(),
2847+
UnaryOperator::Reference(x) => x.as_syntax_node(),
28302848
}
28312849
}
28322850
fn stable_ptr(&self, db: &'db dyn Database) -> Self::StablePtr {
@@ -2843,6 +2861,7 @@ impl<'db> UnaryOperator<'db> {
28432861
| SyntaxKind::TerminalMinus
28442862
| SyntaxKind::TerminalAt
28452863
| SyntaxKind::TerminalMul
2864+
| SyntaxKind::TerminalAnd
28462865
)
28472866
}
28482867
}

0 commit comments

Comments
 (0)