1#[macro_use]
2use crate::*;
3use nom::sequence::tuple as nom_tuple;
4
5pub fn comment_sigil(input: ParseString) -> ParseResult<()> {
9 let (input, _) = alt((tag("--"),tag("//")))(input)?;
10 Ok((input, ()))
11}
12
13pub fn comment(input: ParseString) -> ParseResult<Comment> {
15 let (input, _) = many0(space_tab)(input)?;
16 let (input, _) = comment_sigil(input)?;
17 let (input, line_token) = skip_till_eol(input)?;
18 let comment_text = line_token.to_string();
19
20 if comment_text.is_empty() {
21 return Ok((input, Comment { paragraph: Paragraph { elements: vec![], error_range: None } }));
22 }
23
24 let line_graphemes = graphemes::init_source(&comment_text);
25 let line_input = ParseString::new(&line_graphemes);
26
27 match inline_paragraph(line_input) {
28 Ok((remaining, paragraph)) => {
29 if new_line(remaining.clone()).is_ok() {
31 Ok((input, Comment { paragraph }))
32 } else {
33 let mut recovered_input = input;
34 let start = line_token.src_range.start;
35 let end = line_token.src_range.end;
36 recovered_input.error_log.push((
37 SourceRange { start, end },
38 ParseErrorDetail {
39 message: "Invalid rich comment syntax, preserving raw comment text",
40 annotation_rngs: vec![],
41 },
42 ));
43 Ok((recovered_input, Comment { paragraph: Paragraph::from_tokens(vec![line_token]) }))
44 }
45 }
46 Err(_) => {
47 let mut recovered_input = input;
48 let start = line_token.src_range.start;
49 let end = line_token.src_range.end;
50 recovered_input.error_log.push((
51 SourceRange { start, end },
52 ParseErrorDetail {
53 message: "Invalid rich comment syntax, preserving raw comment text",
54 annotation_rngs: vec![],
55 },
56 ));
57 Ok((recovered_input, Comment { paragraph: Paragraph::from_tokens(vec![line_token]) }))
58 }
59 }
60}
61
62pub fn op_assign_operator(input: ParseString) -> ParseResult<OpAssignOp> {
64 alt((add_assign_operator, sub_assign_operator, mul_assign_operator, div_assign_operator, exp_assign_operator))(input)
65}
66
67pub fn add_assign_operator(input: ParseString) -> ParseResult<OpAssignOp> {
69 let (input, _) = whitespace0(input)?;
70 let (input, _) = tag("+=")(input)?;
71 let (input, _) = whitespace0(input)?;
72 Ok((input, OpAssignOp::Add))
73}
74
75pub fn sub_assign_operator(input: ParseString) -> ParseResult<OpAssignOp> {
77 let (input, _) = whitespace0(input)?;
78 let (input, _) = tag("-=")(input)?;
79 let (input, _) = whitespace0(input)?;
80 Ok((input, OpAssignOp::Sub))
81}
82
83pub fn mul_assign_operator(input: ParseString) -> ParseResult<OpAssignOp> {
85 let (input, _) = whitespace0(input)?;
86 let (input, _) = tag("*=")(input)?;
87 let (input, _) = whitespace0(input)?;
88 Ok((input, OpAssignOp::Mul))
89}
90pub fn div_assign_operator(input: ParseString) -> ParseResult<OpAssignOp> {
92 let (input, _) = whitespace0(input)?;
93 let (input, _) = tag("/=")(input)?;
94 let (input, _) = whitespace0(input)?;
95 Ok((input, OpAssignOp::Div))
96}
97
98pub fn exp_assign_operator(input: ParseString) -> ParseResult<OpAssignOp> {
100 let (input, _) = whitespace0(input)?;
101 let (input, _) = tag("^=")(input)?;
102 let (input, _) = whitespace0(input)?;
103 Ok((input, OpAssignOp::Exp))
104}
105
106pub fn variable_define(input: ParseString) -> ParseResult<VariableDefine> {
134 let msg1 = "Expects spaces around operator";
135 let msg2 = "Expects expression";
136 let (input, mutable) = opt(tilde)(input)?;
137 let (input, var) = var(input)?;
138 let (input, _) = labelr!(null(is_not(assign_operator)), skip_nil, msg1)(input)?;
139 let (input, _) = define_operator(input)?;
140 let (input, expression) = label!(expression, msg2)(input)?;
141 let mutable = match mutable {
142 Some(_) => true,
143 None => false,
144 };
145 Ok((input, VariableDefine{mutable, var, expression}))
146}
147
148pub fn variable_assign(input: ParseString) -> ParseResult<VariableAssign> {
150 let msg1 = "Expects spaces around operator";
151 let msg2 = "Expects expression";
152 let (input, target) = slice_ref(input)?;
153 let (input, _) = labelr!(null(is_not(define_operator)), skip_nil, msg1)(input)?;
154 let (input, _) = assign_operator(input)?;
155 let (input, expression) = label!(expression, msg2)(input)?;
156 Ok((input, VariableAssign{target,expression}))
157}
158
159pub fn op_assign(input: ParseString) -> ParseResult<OpAssign> {
161 let msg1 = "Expects spaces around operator";
162 let msg2 = "Expects expression";
163 let (input, target) = slice_ref(input)?;
164 let (input, _) = labelr!(null(is_not(define_operator)), skip_nil, msg1)(input)?;
165 let (input, op) = op_assign_operator(input)?;
166 let (input, expression) = label!(expression, msg2)(input)?;
167 Ok((input, OpAssign{target,op,expression}))
168}
169
170fn tuple_destructure(input: ParseString) -> ParseResult<TupleDestructure> {
188 let (input, _) = left_parenthesis(input)?;
189 let (input, vars) = separated_list1(list_separator, identifier)(input)?;
190 let (input, _) = right_parenthesis(input)?;
191 let (input, _) = define_operator(input)?;
192 let (input, expression) = expression(input)?;
193 Ok((input, TupleDestructure{vars, expression}))
194}
195
196pub fn statement(input: ParseString) -> ParseResult<Statement> {
198 let parsers: Vec<(&'static str,Box<dyn Fn(ParseString) -> ParseResult<Statement>>)> = vec![
199 ("fsm_declare", Box::new(|i| fsm_declare(i).map(|(i, v)| (i, Statement::FsmDeclare(v))))),
200 ("variable_define", Box::new(|i| variable_define(i).map(|(i, v)| (i, Statement::VariableDefine(v))))),
201 ("variable_assign", Box::new(|i| variable_assign(i).map(|(i, v)| (i, Statement::VariableAssign(v))))),
202 ("op_assign", Box::new(|i| op_assign(i).map(|(i, v)| (i, Statement::OpAssign(v))))),
203 ("enum_define", Box::new(|i| enum_define(i).map(|(i, v)| (i, Statement::EnumDefine(v))))),
204 ("tuple_destructure", Box::new(|i| tuple_destructure(i).map(|(i, v)| (i, Statement::TupleDestructure(v))))),
205 ("kind_define", Box::new(|i| kind_define(i).map(|(i, v)| (i, Statement::KindDefine(v))))),
206 ];
207 alt_best(input, &parsers)
208}
209
210pub fn enum_define(input: ParseString) -> ParseResult<EnumDefine> {
212 let (input, _) = left_angle(input)?;
213 let (input, name) = identifier(input)?;
214 let (input, _) = right_angle(input)?;
215 let (input, _) = define_operator(input)?;
216 let (input, variants) = separated_list1(enum_separator, enum_variant)(input)?;
217 Ok((input, EnumDefine{name, variants}))
218}
219
220pub fn enum_variant(input: ParseString) -> ParseResult<EnumVariant> {
222 let (input, _) = opt(grave)(input)?;
223 let (input, _) = opt(colon)(input)?;
224 let (input, name) = identifier(input)?;
225 let (input, value) = opt(alt((enum_variant_kind, enum_variant_inline_kind)))(input)?;
226 Ok((input, EnumVariant{name, value}))
227}
228
229pub fn enum_variant_kind(input: ParseString) -> ParseResult<KindAnnotation> {
231 let (input, _) = left_parenthesis(input)?;
232 let (input, annotation) = kind_annotation(input)?;
233 let (input, _) = right_parenthesis(input)?;
234 Ok((input, annotation))
235}
236
237pub fn enum_variant_inline_kind(input: ParseString) -> ParseResult<KindAnnotation> {
240 kind_annotation(input)
241}
242
243pub fn kind_define(input: ParseString) -> ParseResult<KindDefine> {
245 let (input, _) = left_angle(input)?;
246 let (input, name) = identifier(input)?;
247 let (input, _) = right_angle(input)?;
248 let (input, _) = define_operator(input)?;
249 let (input, knd) = kind_annotation(input)?;
250 Ok((input, KindDefine{name,kind:knd}))
251}