symboscript_parser/parser/
macro_utils.rs

1#[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            // node = $self.assign_statement(start, node, right, current_token.kind);
122        }
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}