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}