rush_analyzer/
macros.rs

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