1#[macro_use]
2use crate::*;
3use nom::{
4 multi::separated_list0,
5 sequence::tuple as nom_tuple,
6};
7use crate::nodes::Kind;
8
9pub fn literal(input: ParseString) -> ParseResult<Literal> {
14 let (input, result) = match number(input.clone()) {
15 Ok((input, num)) => (input, Literal::Number(num)),
16 _ => match string(input.clone()) {
17 Ok((input, s)) => (input, Literal::String(s)),
18 _ => match atom(input.clone()) {
19 Ok((input, atm)) => (input, Literal::Atom(atm)),
20 _ => match boolean(input.clone()) {
21 Ok((input, boolean)) => (input, Literal::Boolean(boolean)),
22 _ => match empty(input.clone()) {
23 Ok((input, empty)) => (input, Literal::Empty(empty)),
24 Err(err) => match kind_annotation(input.clone()) {
25 Ok((input, knd)) => (input, Literal::Kind(knd.kind)),
26 Err(err) => return Err(err),
27 }
28 }
29 }
30 }
31 }
32 };
33 let (input, result) = match opt(kind_annotation)(input.clone()) {
34 Ok((input, Some(knd))) => ((input, Literal::TypedLiteral((Box::new(result),knd)))),
35 Ok((input, None)) => (input,result),
36 Err(err) => {return Err(err);}
37 };
38 Ok((input, result))
39}
40
41pub fn atom(input: ParseString) -> ParseResult<Atom> {
43 let (input, _) = grave(input)?;
44 let (input, name) = identifier(input)?;
45 Ok((input, Atom{name}))
46}
47
48
49pub fn string(input: ParseString) -> ParseResult<MechString> {
51 let msg = "Character not allowed in string";
52 let (input, _) = quote(input)?;
53 let (input, matched) = many0(nom_tuple((is_not(quote), alt((text,new_line)))))(input)?;
54 let (input, _) = quote(input)?;
55 let (_, mut text): ((), Vec<_>) = matched.into_iter().unzip();
56 let mut merged = Token::merge_tokens(&mut text).unwrap();
57 merged.kind = TokenKind::String;
58 Ok((input, MechString { text: merged }))
59}
60
61pub fn boolean(input: ParseString) -> ParseResult<Token> {
66 let (input, boolean) = alt((true_literal, false_literal))(input)?;
67 Ok((input, boolean))
68}
69
70pub fn true_literal(input: ParseString) -> ParseResult<Token> {
72 let (input, token) = alt((english_true_literal, check_mark))(input)?;
73 Ok((input, token))
74}
75
76pub fn false_literal(input: ParseString) -> ParseResult<Token> {
78 let (input, token) = alt((english_false_literal, cross))(input)?;
79 Ok((input, token))
80}
81
82pub fn number(input: ParseString) -> ParseResult<Number> {
87 match complex_number(input.clone()) {
88 Ok((input, complex_num)) => Ok((input, Number::Complex(complex_num))),
89 _ => match real_number(input.clone()) {
90 Ok((input, real_num)) => Ok((input, Number::Real(real_num))),
91 Err(err) => return Err(err),
92 },
93 }
94}
95
96pub fn complex_number(input: ParseString) -> ParseResult<C64Node> {
98 let (input, real_num) = real_number(input)?;
99 if let Ok((input, _)) = alt((tag("i"), tag("j")))(input.clone()) {
100 return Ok((
101 input,
102 C64Node {
103 real: None,
104 imaginary: ImaginaryNumber { number: real_num },
105 },
106 ));
107 }
108 if let Ok((input, (sign, imaginary_num, _))) =
109 nom_tuple((alt((plus, dash)), real_number, alt((tag("i"), tag("j")))))(input.clone())
110 {
111 let imaginary = match sign.kind {
112 TokenKind::Plus => imaginary_num,
113 TokenKind::Dash => RealNumber::Negated(Box::new(imaginary_num)),
114 _ => unreachable!(),
115 };
116 return Ok((
117 input,
118 C64Node {
119 real: Some(real_num),
120 imaginary: ImaginaryNumber { number: imaginary },
121 },
122 ));
123 } else {
124 return Err(nom::Err::Error(nom::error::make_error(
125 input,
126 nom::error::ErrorKind::Alt,
127 )));
128 }
129}
130
131pub fn real_number(input: ParseString) -> ParseResult<RealNumber> {
133 let (input, neg) = opt(dash)(input)?;
134 let (input, result) = alt((hexadecimal_literal, decimal_literal, octal_literal, binary_literal, scientific_literal, rational_literal, float_literal, integer_literal))(input)?;
135 let result = match neg {
136 Some(_) => RealNumber::Negated(Box::new(result)),
137 None => result,
138 };
139 Ok((input, result))
140}
141
142pub fn rational_literal(input: ParseString) -> ParseResult<RealNumber> {
144 let (input, RealNumber::Integer(numerator)) = integer_literal(input)? else { unreachable!() };
145 let (input, _) = slash(input)?;
146 let (input, RealNumber::Integer(denominator)) = integer_literal(input)? else { unreachable!() };
147 Ok((input, RealNumber::Rational((numerator,denominator))))
148}
149
150pub fn scientific_literal(input: ParseString) -> ParseResult<RealNumber> {
152 let (input, base) = match float_literal(input.clone()) {
153 Ok((input, RealNumber::Float(base))) => {
154 (input, base)
155 }
156 _ => match integer_literal(input.clone()) {
157 Ok((input, RealNumber::Integer(base))) => {
158 (input, (base, Token::default()))
159 }
160 Err(err) => {return Err(err);}
161 _ => unreachable!(),
162 }
163 };
164 let (input, _) = alt((tag("e"), tag("E")))(input)?;
165 let (input, _) = opt(plus)(input)?;
166 let (input, neg) = opt(dash)(input)?;
167 let (input, (ex_whole,ex_part)) = match float_literal(input.clone()) {
168 Ok((input, RealNumber::Float(exponent))) => {
169 (input, exponent)
170 }
171 _ => match integer_literal(input.clone()) {
172 Ok((input, RealNumber::Integer(exponent))) => {
173 (input, (exponent, Token::default()))
174 }
175 Err(err) => {return Err(err);}
176 _ => unreachable!(),
177 }
178 };
179 let ex_sign = match neg {
180 Some(_) => true,
181 None => false,
182 };
183 Ok((input, RealNumber::Scientific((base,(ex_sign,ex_whole,ex_part)))))
184}
185
186pub fn float_decimal_start(input: ParseString) -> ParseResult<RealNumber> {
188 let (input, _) = period(input)?;
189 let (input, part) = digit_sequence(input)?;
190 let mut tokens2 = part.clone();
191 let mut merged = Token::merge_tokens(&mut tokens2).unwrap();
192 merged.kind = TokenKind::Number;
193 Ok((input, RealNumber::Float((Token::default(),merged))))
194}
195
196pub fn float_full(input: ParseString) -> ParseResult<RealNumber> {
198 let (input, mut whole) = digit_sequence(input)?;
199 let (input, _) = period(input)?;
200 let (input, mut part) = digit_sequence(input)?;
201 let mut whole = Token::merge_tokens(&mut whole).unwrap();
202 let mut part = Token::merge_tokens(&mut part).unwrap();
203 whole.kind = TokenKind::Number;
204 part.kind = TokenKind::Number;
205 Ok((input, RealNumber::Float((whole,part))))
206}
207
208pub fn float_literal(input: ParseString) -> ParseResult<RealNumber> {
210 let (input, result) = alt((float_decimal_start,float_full))(input)?;
211 Ok((input, result))
212}
213
214pub fn integer_literal(input: ParseString) -> ParseResult<RealNumber> {
216 let (input, mut digits) = digit_sequence(input)?;
217 let mut merged = Token::merge_tokens(&mut digits).unwrap();
218 merged.kind = TokenKind::Number;
219 Ok((input, RealNumber::Integer(merged)))
220}
221
222pub fn decimal_literal(input: ParseString) -> ParseResult<RealNumber> {
224 let msg = "Expects decimal digits after \"0d\"";
225 let input = tag("0d")(input);
226 let (input, _) = input?;
227 let (input, mut tokens) = label!(digit_sequence, msg)(input)?;
228 let mut merged = Token::merge_tokens(&mut tokens).unwrap();
229 merged.kind = TokenKind::Number;
230 Ok((input, RealNumber::Decimal(merged)))
231}
232
233pub fn hexadecimal_literal(input: ParseString) -> ParseResult<RealNumber> {
235 let msg = "Expects hexadecimal digits after \"0x\"";
236 let input = tag("0x")(input);
237 let (input, _) = input?;
238 let (input, mut tokens) = label!(many1(alt((digit_token,underscore,alpha_token))), msg)(input)?;
239 let mut merged = Token::merge_tokens(&mut tokens).unwrap();
240 merged.kind = TokenKind::Number;
241 Ok((input, RealNumber::Hexadecimal(merged)))
242}
243
244pub fn octal_literal(input: ParseString) -> ParseResult<RealNumber> {
246 let msg = "Expects octal digits after \"0o\"";
247 let input = tag("0o")(input);
248 let (input, _) = input?;
249 let (input, mut tokens) = label!(many1(alt((digit_token,underscore,alpha_token))), msg)(input)?;
250 let mut merged = Token::merge_tokens(&mut tokens).unwrap();
251 merged.kind = TokenKind::Number;
252 Ok((input, RealNumber::Octal(merged)))
253}
254
255pub fn binary_literal(input: ParseString) -> ParseResult<RealNumber> {
257 let msg = "Expects binary digits after \"0b\"";
258 let input = tag("0b")(input);
259 let (input, _) = input?;
260 let (input, mut tokens) = label!(many1(alt((digit_token,underscore,alpha_token))), msg)(input)?;
261 let mut merged = Token::merge_tokens(&mut tokens).unwrap();
262 merged.kind = TokenKind::Number;
263 Ok((input, RealNumber::Binary(merged)))
264}
265
266pub fn empty(input: ParseString) -> ParseResult<Token> {
268 let (input, (g, src_range)) = range(many1(tag("_")))(input)?;
269 Ok((input, Token{kind: TokenKind::Empty, chars: g.join("").chars().collect(), src_range}))
270}
271
272pub fn kind_annotation(input: ParseString) -> ParseResult<KindAnnotation> {
277 let msg2 = "Expects at least one unit in kind annotation";
278 let msg3 = "Expects right angle";
279 let (input, (_, r)) = range(left_angle)(input)?;
280 let (input, kind) = kind(input)?;
281 let (input, optional) = opt(question)(input)?;
282 let (input, _) = label!(right_angle, msg3, r)(input)?;
283 let kind = match optional {
284 Some(_) => Kind::Option(Box::new(kind)),
285 None => kind,
286 };
287 Ok((input, KindAnnotation{ kind }))
288}
289
290pub fn kind(input: ParseString) -> ParseResult<Kind> {
292 let (input, kind) = alt((
293 kind_any,
294 kind_atom,
295 kind_empty,
296 kind_map,
297 kind_matrix,
298 kind_record,
299 kind_scalar,
300 kind_set,
301 kind_table,
302 kind_tuple,
303 ))(input)?;
304 Ok((input, kind))
305}
306
307pub fn kind_table(input: ParseString) -> ParseResult<Kind> {
309 let (input, _) = bar(input)?;
310 let (input, elements) = separated_list1(alt((null(list_separator),null(many1(space_tab)))), nom_tuple((identifier, kind_annotation)))(input)?;
311 let (input, _) = bar(input)?;
312 let (input, size) = opt(tuple((colon,literal)))(input)?;
313 let size = size.map(|(_, ltrl)| ltrl).unwrap_or_else(|| Literal::Empty(Token::default()));
314 let elements = elements.into_iter().map(|(id, knd)| (id, knd.kind)).collect();
315 Ok((input, Kind::Table((elements, Box::new(size)))))
316}
317
318pub fn kind_any(input: ParseString) -> ParseResult<Kind> {
320 let (input, _) = asterisk(input)?;
321 Ok((input, Kind::Any))
322}
323
324pub fn kind_empty(input: ParseString) -> ParseResult<Kind> {
326 let (input, _) = many1(underscore)(input)?;
327 Ok((input, Kind::Empty))
328}
329
330pub fn kind_atom(input: ParseString) -> ParseResult<Kind> {
332 let (input, _) = grave(input)?;
333 let (input, atm) = identifier(input)?;
334 Ok((input, Kind::Atom(atm)))
335}
336
337pub fn kind_set(input: ParseString) -> ParseResult<Kind> {
339 let (input, _) = left_brace(input)?;
340 let (input, kind) = kind(input)?;
341 let (input, _) = right_brace(input)?;
342 let (input, opt_lit) = opt(nom_tuple((colon, literal)))(input)?;
343 let ltrl = match opt_lit {
344 Some((_, ltrl)) => Some(Box::new(ltrl)),
345 None => None,
346 };
347 Ok((input, Kind::Set(Box::new(kind), ltrl)))
348}
349
350pub fn kind_map(input: ParseString) -> ParseResult<Kind> {
352 let (input, _) = left_brace(input)?;
353 let (input, key_kind) = kind(input)?;
354 let (input, _) = colon(input)?;
355 let (input, value_kind) = kind(input)?;
356 let (input, _) = right_brace(input)?;
357 Ok((input, Kind::Map(Box::new(key_kind),Box::new(value_kind))))
358}
359
360pub fn kind_record(input: ParseString) -> ParseResult<Kind> {
362 let (input, _) = left_brace(input)?;
363 let (input, elements) = separated_list1(list_separator, nom_tuple((identifier, kind_annotation)))(input)?;
364 let (input, _) = right_brace(input)?;
365 let elements = elements.into_iter().map(|(id, knd)| (id, knd.kind)).collect();
366 Ok((input, Kind::Record(elements)))
367}
368
369pub fn kind_matrix(input: ParseString) -> ParseResult<Kind> {
383 let (input, _) = left_bracket(input)?;
384 let (input, kind) = kind(input)?;
385 let (input, _) = right_bracket(input)?;
386 let (input, _) = opt(colon)(input)?;
387 let (input, size) = separated_list0(list_separator,literal)(input)?;
388 Ok((input, Kind::Matrix((Box::new(kind),size))))
389}
390
391pub fn kind_tuple(input: ParseString) -> ParseResult<Kind> {
393 let (input, _) = left_parenthesis(input)?;
394 let (input, kinds) = separated_list1(list_separator, kind)(input)?;
395 let (input, _) = right_parenthesis(input)?;
396 Ok((input, Kind::Tuple(kinds)))
397}
398
399pub fn kind_scalar(input: ParseString) -> ParseResult<Kind> {
401 let (input, kind) = identifier(input)?;
402 let (input, range) = opt(tuple((colon,range_expression)))(input)?;
403 Ok((input, Kind::Scalar(kind)))
404}