1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
#[macro_export]
macro_rules! peek_token {
([ $($(|)? $( $pattern:pat_param )|+ $( if $guard: expr )? => $out:expr),+ $(,)? ], $state:expr, [ $($message:literal),+ $(,)? ]) => {{
match &$state.stream.current().kind {
$(
$( $pattern )|+ $( if $guard )? => $out,
)+
_ => {
return $crate::expected_token_err!([ $($message,)+ ], $state);
}
}
}};
([ $($(|)? $( $pattern:pat_param )|+ $( if $guard: expr )?),+ $(,)? ], $state:expr, [ $($message:literal),+ $(,)? ]) => {{
if !matches!($state.stream.current().kind, $( $pattern )|+ $( if $guard )?) {
return $crate::expected_token_err!([ $($message,)+ ], $state);
}
}};
([ $($(|)? $( $pattern:pat_param )|+ $( if $guard: expr )? => $out:expr),+ $(,)? ], $state:expr, $message:literal) => {
$crate::peek_token!([ $($( $pattern )|+ $( if $guard )? => $out,)+ ], $state, [$message])
};
([ $($(|)? $( $pattern:pat_param )|+ $( if $guard: expr )?),+ $(,)? ], $state:expr, $message:literal) => {
$crate::peek_token!([ $($( $pattern )|+ $( if $guard )?,)+ ], $state, [$message])
};
}
#[macro_export]
macro_rules! expect_token {
([ $($(|)? $( $pattern:pat_param )|+ $( if $guard: expr )? => $out:expr),+ $(,)? ], $state:expr, [ $($message:literal),+ $(,)? ]) => {{
let token = $state.stream.current();
$state.stream.next();
match token.kind {
$(
$( $pattern )|+ $( if $guard )? => {
$out
},
)+
_ => {
return Err($crate::parser::error::unexpected_token(
vec![$($message.into(),)+],
token,
))
}
}
}};
([ $($(|)? $( $pattern:pat_param )|+ $( if $guard: expr )? => $out:expr),+ $(,)? ], $state:expr, $message:literal) => {
$crate::expect_token!([ $($( $pattern )|+ $( if $guard )? => $out,)+ ], $state, [$message])
};
}
#[macro_export]
macro_rules! expect_literal {
($state:expr) => {{
let current = $state.stream.current();
match ¤t.kind {
TokenKind::LiteralInteger => {
$state.stream.next();
$crate::parser::ast::literals::Literal::Integer(
$crate::parser::ast::literals::LiteralInteger {
span: current.span,
value: current.value.clone(),
},
)
}
TokenKind::LiteralFloat => {
$state.stream.next();
$crate::parser::ast::literals::Literal::Float(
$crate::parser::ast::literals::LiteralFloat {
span: current.span,
value: current.value.clone(),
},
)
}
TokenKind::LiteralString => {
$state.stream.next();
$crate::parser::ast::literals::Literal::String(
$crate::parser::ast::literals::LiteralString {
span: current.span,
value: current.value.clone(),
},
)
}
_ => {
return $crate::expected_token_err!(["a literal"], $state);
}
}
}};
}
#[macro_export]
macro_rules! expected_token_err {
([ $($expected:literal),+ $(,)? ], $state:expr $(,)?) => {{
Err($crate::expected_token!([$($expected),+], $state))
}};
($expected:literal, $state:expr $(,)?) => {
$crate::expected_token_err!([$expected], $state)
};
}
#[macro_export]
macro_rules! expected_token {
([ $($expected:literal),+ $(,)? ], $state:expr $(,)?) => {{
$crate::parser::error::unexpected_token(
vec![$($expected.into()),+],
$state.stream.current(),
)
}};
($expected:literal, $state:expr $(,)?) => {
$crate::expected_token!([$expected], $state)
};
}
#[macro_export]
macro_rules! expected_scope {
([ $($(|)? $( $pattern:pat_param )|+ $( if $guard: expr )? => $out:expr),+ $(,)? ], $state:expr) => {{
match $state.scope().cloned()? {
$(
$( $pattern )|+ $( if $guard )? => $out,
)+
_ => {
return Err($crate::parser::error::reached_unpredictable_state($state.stream.current().span));
}
}
}};
}
#[macro_export]
macro_rules! scoped {
($state:expr, $scope:expr, $block:block) => {{
$state.enter($scope);
let result = $block;
$state.exit();
result
}};
}