symboscript_parser/parser/
macro_utils.rs1#[macro_export]
2macro_rules! binary_left_associative {
3 ($self:ident, $Kinds: expr, $SubOp: ident) => {{
4 let start = $self.cur_token.start;
5 let mut node = $self.$SubOp();
6
7 while $Kinds.contains(&$self.cur_token.kind) {
8 let current_token = $self.cur_token.clone();
9
10 $self.eat(current_token.kind);
11
12 let right = $self.$SubOp();
13 node = $self.binary_expression(start, node, right, current_token.kind);
14 }
15
16 node
17 }};
18
19 ($self:ident, $SubOp: ident, [$($Kinds: expr),+], [$($EatOrNot: expr),+], [$($SubKind: expr),+]) => {{
20 let start = $self.cur_token.start;
21 let mut node = $self.$SubOp();
22
23 $(
24 while $Kinds.contains(&$self.cur_token.kind) {
25
26 if $EatOrNot {
27 $self.eat($self.cur_token.kind);
28 }
29
30 let operator = if $SubKind != TokenKind::Unexpected {
31 $SubKind
32 } else {
33 $self.cur_token.kind
34 };
35
36 let right = $self.$SubOp();
37 node = $self.binary_expression(start, node, right, operator);
38 }
39 )+
40
41 node
42 }};
43}
44
45#[macro_export]
46macro_rules! member_left_associative {
47 ($self:ident, $Kinds: expr, $SubOp: ident) => {{
48 let start = $self.cur_token.start;
49 let (mut node, _) = $self.$SubOp();
50
51 while $Kinds.contains(&$self.cur_token.kind) {
52 let current_token = $self.cur_token.clone();
53
54 $self.eat(current_token.kind);
55
56 let (right, is_expr) = $self.$SubOp();
57 node = $self.member_expression(start, node, right, is_expr);
58 }
59
60 node
61 }};
62}
63
64#[macro_export]
65macro_rules! word_right_associative_expr {
66 ($self:ident, $Kind: path, $SubOp: ident, $SelfOp: ident) => {{
67 let start = $self.cur_token.start;
68 match $self.cur_kind() {
69 $Kind => {
70 $self.advance();
71
72 let argument = $self.$SelfOp();
73 return word_expr_build!($self, $Kind, start, argument);
74 }
75
76 _ => {
77 return $self.$SubOp();
78 }
79 }
80 }};
81}
82
83#[macro_export]
84macro_rules! word_stmt {
85 ($self:ident, $Kind: path, $Stmt: ident) => {{
86 let start = $self.cur_token.start;
87 match $self.cur_kind() {
88 $Kind => {
89 $self.advance();
90
91 let argument = $self.expr();
92
93 $self.eat(TokenKind::Semicolon);
94
95 return word_stmt_build!($self, $Kind, start, argument, $Stmt);
96 }
97
98 got => {
99 $self.report_expected(start, $Kind, got);
100 unreachable!("Report ends proccess");
101 }
102 }
103 }};
104}
105
106#[macro_export]
107macro_rules! binary_right_associative {
108 ($self:ident, $SubOp: ident, $Kinds: expr) => {{
109 let start = $self.cur_token.start;
110 let mut left = $self.$SubOp();
111
112 while $Kinds.contains(&$self.cur_token.kind) {
113 let current_token = $self.cur_token.clone();
114
115 $self.eat(current_token.kind);
116
117 let right = $self.expr();
118 let operator = $self.kind_to_assign_op(current_token.kind);
119
120 left = uni_builder!($self, AssignStatement, start, [left, right, operator]);
121 }
123
124 left
125 }};
126}
127
128#[macro_export]
129macro_rules! word_expr_build {
130 ($self:ident, $operator: path, $start: ident, $argument: ident) => {
131 Expression::WordExpression(Box::new(WordExpression {
132 node: Node::new($start, $self.prev_token_end),
133 argument: $argument,
134 operator: $self.kind_to_word_op($operator),
135 }))
136 };
137}
138
139#[macro_export]
140macro_rules! word_stmt_build {
141 ($self:ident, $operator: path, $start: ident, $argument: ident, $Statement: ident) => {
142 Statement::$Statement($Statement {
143 node: Node::new($start, $self.prev_token_end),
144 argument: $argument,
145 })
146 };
147}
148
149#[macro_export]
150macro_rules! uni_builder {
151 ($self:ident, $Expr: ident, $start: ident,[$($properties: ident),+]) => {
152 $Expr {
153 node: Node::new($start, $self.prev_token_end),
154 $(
155 $properties,
156 )+
157 }
158 };
159}