rush_parser/
macros.rs

1#[macro_export]
2macro_rules! tree {
3    ((None)) => { None };
4    ((Some($($node:tt)*))) => { Some(tree!(($($node)*))) };
5
6    ((
7        Program @ $start:literal .. $end:literal,
8        functions: [$($func:tt),* $(,)?],
9        globals: [$($global:tt),* $(,)?] $(,)?
10    )) => {
11        Program {
12            span: span!($start..$end),
13            functions: vec![$(tree!($func)),*],
14            globals: vec![$(tree!($global)),*],
15        }
16    };
17    ((
18        FunctionDefinition @ $start:literal .. $end:literal,
19        name: $ident:tt,
20        params @ $params_start:literal .. $params_end:literal: [$($param:tt),* $(,)?],
21        return_type: $return_type:tt,
22        block: $block:tt $(,)?
23    )) => {
24        FunctionDefinition {
25            span: span!($start..$end),
26            name: tree!($ident),
27            params: tree!((vec![$(tree!($param)),*], @ $params_start..$params_end)),
28            return_type: tree!($return_type),
29            block: tree!($block),
30        }
31    };
32    ((
33        Parameter,
34        mutable: $mutable:expr,
35        name: $ident:tt,
36        type: $type:tt $(,)?
37    )) => {
38        Parameter {
39            mutable: $mutable,
40            name: tree!($ident),
41            type_: tree!($type),
42        }
43    };
44
45    ((
46        Let @ $start:literal .. $end:literal,
47        mutable: $mut:literal,
48        name: $ident:tt,
49        type: $type:tt,
50        expr: $expr:tt $(,)?
51    )) => {
52        LetStmt {
53            span: span!($start..$end),
54            mutable: $mut,
55            name: tree!($ident),
56            type_: tree!($type),
57            expr: tree!($expr),
58        }
59    };
60    ((LetStmt $($rest:tt)*)) => {
61        Statement::Let(tree!((Let $($rest)*)))
62    };
63    ((ReturnStmt @ $start:literal .. $end:literal, $expr:tt $(,)?)) => {
64        Statement::Return(ReturnStmt {
65            span: span!($start..$end),
66            expr: tree!($expr),
67        })
68    };
69    ((ExprStmt @ $start:literal .. $end:literal, $expr:tt $(,)?)) => {
70        Statement::Expr(ExprStmt {
71            span: span!($start..$end),
72            expr: tree!($expr),
73        })
74    };
75
76    ((
77        Block @ $start:literal .. $end:literal,
78        stmts: [$($stmt:tt),* $(,)?],
79        expr: $expr:tt $(,)?
80    )) => {
81        Block {
82            span: span!($start..$end),
83            stmts: vec![$(tree!($stmt)),*],
84            expr: tree!($expr),
85        }
86    };
87    ((BlockExpr $($rest:tt)*)) => {
88        Expression::Block(tree!((Block $($rest)*)).into())
89    };
90    ((
91        IfExpr @ $start:literal .. $end:literal,
92        cond: $cond:tt,
93        then_block: $then_block:tt,
94        else_block: $else_block:tt $(,)?
95    )) => {
96        Expression::If(IfExpr {
97            span: span!($start..$end),
98            cond: tree!($cond),
99            then_block: tree!($then_block),
100            else_block: tree!($else_block),
101        }.into())
102    };
103    ((Int $($rest:tt)*)) => { Expression::Int(tree!(($($rest)*))) };
104    ((Float $($rest:tt)*)) => { Expression::Float(tree!(($($rest)*))) };
105    ((Bool $($rest:tt)*)) => { Expression::Bool(tree!(($($rest)*))) };
106    ((Char $($rest:tt)*)) => { Expression::Char(tree!(($($rest)*))) };
107    ((Ident $($rest:tt)*)) => { Expression::Ident(tree!(($($rest)*))) };
108    ((Grouped @ $start:literal .. $end:literal, $expr:tt)) => {
109        Expression::Grouped(Spanned {
110            span: span!($start..$end),
111            inner: tree!($expr).into(),
112        })
113    };
114    ((
115        PrefixExpr @ $start:literal .. $end:literal,
116        op: $op:expr,
117        expr: $expr:tt $(,)?
118    )) => {
119        Expression::Prefix(PrefixExpr {
120            span: span!($start..$end),
121            op: $op,
122            expr: tree!($expr),
123        }.into())
124    };
125    ((
126        InfixExpr @ $start:literal .. $end:literal,
127        lhs: $lhs:tt,
128        op: $op:expr,
129        rhs: $rhs:tt $(,)?
130    )) => {
131        Expression::Infix(InfixExpr {
132            span: span!($start..$end),
133            lhs: tree!($lhs),
134            op: $op,
135            rhs: tree!($rhs),
136        }.into())
137    };
138    ((
139        AssignExpr @ $start:literal .. $end:literal,
140        assignee: $assignee:tt,
141        assignee_ptr_count: $assignee_ptr_count:expr,
142        op: $op:expr,
143        expr: $expr:tt $(,)?
144    )) => {
145        Expression::Assign(AssignExpr {
146            span: span!($start..$end),
147            assignee: tree!($assignee),
148            assignee_ptr_count: $assignee_ptr_count,
149            op: $op,
150            expr: tree!($expr),
151        }.into())
152    };
153    ((
154        CallExpr @ $start:literal .. $end:literal,
155        func: $func:tt,
156        args: [$($arg:tt),* $(,)?] $(,)?
157    )) => {
158        Expression::Call(CallExpr {
159            span: span!($start..$end),
160            func: tree!($func),
161            args: vec![$(tree!($arg)),*],
162        }.into())
163    };
164    ((
165        CastExpr @ $start:literal .. $end:literal,
166        expr: $expr:tt,
167        type: $type:expr $(,)?
168    )) => {
169        Expression::Cast(CastExpr {
170            span: span!($start..$end),
171            expr: tree!($expr),
172            type_: $type,
173        }.into())
174    };
175
176    (($value:expr, @ $start:literal .. $end:literal)) => {
177        Spanned {
178            span: span!($start..$end),
179            inner: $value,
180        }
181    };
182}
183
184#[macro_export]
185macro_rules! tokens {
186    ($($kind:ident $(($($tt:tt)*))? @ $start:literal .. $end:literal),* $(,)?) => {
187        [$(TokenKind::$kind $(($($tt)*))? .spanned(span!($start..$end))),*]
188    };
189}