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)) => {
26 (input, Literal::Kind(knd.kind))
27 }
28 Err(err) => return Err(err),
29 }
30 }
31 }
32 }
33 }
34 };
35 let (input, result) = match opt(kind_annotation)(input.clone()) {
36 Ok((input, Some(knd))) => ((input, Literal::TypedLiteral((Box::new(result),knd)))),
37 Ok((input, None)) => (input,result),
38 Err(err) => {return Err(err);}
39 };
40 Ok((input, result))
41}
42
43pub fn atom(input: ParseString) -> ParseResult<Atom> {
45 let (input, _) = colon(input)?;
46 let (input, name) = identifier(input)?;
47 Ok((input, Atom{name}))
48}
49
50pub fn string(input: ParseString) -> ParseResult<MechString> {
52 match raw_string(input.clone()) {
53 Ok((input, s)) => Ok((input, s)),
54 _ => match utf8_string(input.clone()) {
55 Ok((input, s)) => Ok((input, s)),
56 Err(err) => return Err(err),
57 },
58 }
59}
60
61pub fn utf8_string(input: ParseString) -> ParseResult<MechString> {
63 let msg = "Character not allowed in string";
64 let (input, _) = quote(input)?;
65 let (input, matched) = many0(nom_tuple((is_not(quote), alt((text, new_line)))))(input)?;
66 let (input, _) = quote(input)?;
67 let (_, mut text): ((), Vec<_>) = matched.into_iter().unzip();
68 let mut merged = match Token::merge_tokens(&mut text) {
69 Some(t) => t,
70 None => Token::default(),
71 };
72 merged.kind = TokenKind::String;
73 Ok((input, MechString { text: merged }))
74}
75
76pub fn raw_string(input: ParseString) -> ParseResult<MechString> {
78 let msg = "Character not allowed in string";
79 let (input, _) = nom_tuple((quote, quote, quote))(input)?;
80 let (input, matched) = many0(nom_tuple((is_not(nom_tuple((quote, quote, quote))), alt((raw_text, new_line)))))(input)?;
81 let (input, _) = nom_tuple((quote, quote, quote))(input)?;
82 let (_, mut text): ((), Vec<_>) = matched.into_iter().unzip();
83 let mut merged = match Token::merge_tokens(&mut text) {
84 Some(t) => t,
85 None => Token::default(),
86 };
87 merged.kind = TokenKind::String;
88 Ok((input, MechString { text: merged }))
89}
90
91pub fn boolean(input: ParseString) -> ParseResult<Token> {
96 let (input, boolean) = alt((true_literal, false_literal))(input)?;
97 Ok((input, boolean))
98}
99
100pub fn true_literal(input: ParseString) -> ParseResult<Token> {
102 let (input, token) = alt((english_true_literal, check_mark))(input)?;
103 Ok((input, token))
104}
105
106pub fn false_literal(input: ParseString) -> ParseResult<Token> {
108 let (input, token) = alt((english_false_literal, cross))(input)?;
109 Ok((input, token))
110}
111
112pub fn number(input: ParseString) -> ParseResult<Number> {
117 match complex_number(input.clone()) {
118 Ok((input, complex_num)) => Ok((input, Number::Complex(complex_num))),
119 _ => match real_number(input.clone()) {
120 Ok((input, real_num)) => Ok((input, Number::Real(real_num))),
121 Err(err) => return Err(err),
122 },
123 }
124}
125
126pub fn complex_number(input: ParseString) -> ParseResult<C64Node> {
128 let (input, real_num) = untyped_real_number(input)?;
129 if let Ok((input, _)) = alt((tag("i"), tag("j")))(input.clone()) {
130 return Ok((
131 input,
132 C64Node {
133 real: None,
134 imaginary: ImaginaryNumber { number: real_num },
135 },
136 ));
137 }
138 if let Ok((input, (sign, imaginary_num, _))) =
139 nom_tuple((alt((plus, dash)), untyped_real_number, alt((tag("i"), tag("j")))))(input.clone())
140 {
141 let imaginary = match sign.kind {
142 TokenKind::Plus => imaginary_num,
143 TokenKind::Dash => RealNumber::Negated(Box::new(imaginary_num)),
144 _ => unreachable!(),
145 };
146 return Ok((
147 input,
148 C64Node {
149 real: Some(real_num),
150 imaginary: ImaginaryNumber { number: imaginary },
151 },
152 ));
153 } else {
154 return Err(nom::Err::Error(nom::error::make_error(
155 input,
156 nom::error::ErrorKind::Alt,
157 )));
158 }
159}
160
161pub fn real_number(input: ParseString) -> ParseResult<RealNumber> {
163 let (input, neg) = opt(dash)(input)?;
164 let (input, result) = alt((hexadecimal_literal, decimal_literal, octal_literal, binary_literal, scientific_literal, rational_literal, float_literal, integer_literal))(input)?;
165 let result = match neg {
166 Some(_) => RealNumber::Negated(Box::new(result)),
167 None => result,
168 };
169 Ok((input, result))
170}
171
172pub fn untyped_real_number(input: ParseString) -> ParseResult<RealNumber> {
174 let (input, neg) = opt(dash)(input)?;
175 let (input, result) = alt((hexadecimal_literal, decimal_literal, octal_literal, binary_literal, scientific_literal, rational_literal, float_literal, untyped_integer))(input)?;
176 let result = match neg {
177 Some(_) => RealNumber::Negated(Box::new(result)),
178 None => result,
179 };
180 Ok((input, result))
181}
182
183pub fn rational_literal(input: ParseString) -> ParseResult<RealNumber> {
185 let (input, numerator) = match integer_literal(input)? {
186 (input, RealNumber::Integer(num)) => (input, num),
187 (input, RealNumber::TypedInteger((num,_))) => (input, num),
188 _ => unreachable!(),
189 };
190 let (input, _) = slash(input)?;
191 let (input, denominator) = match integer_literal(input)? {
192 (input, RealNumber::Integer(den)) => (input, den),
193 (input, RealNumber::TypedInteger((den,_))) => (input, den),
194 _ => unreachable!(),
195 };
196 Ok((input, RealNumber::Rational((numerator, denominator))))
197}
198
199pub fn scientific_literal(input: ParseString) -> ParseResult<RealNumber> {
201 let (input, base) = match float_literal(input.clone()) {
202 Ok((input, RealNumber::Float(base))) => {
203 (input, base)
204 }
205 _ => match integer_literal(input.clone()) {
206 Ok((input, RealNumber::TypedInteger((base,_))) ) => {
207 (input, (base, Token::default()))
208 }
209 Ok((input, RealNumber::Integer(base))) => {
210 (input, (base, Token::default()))
211 }
212 Err(err) => {return Err(err);}
213 _ => unreachable!(),
214 }
215 };
216 let (input, _) = alt((tag("e"), tag("E")))(input)?;
217 let (input, _) = opt(plus)(input)?;
218 let (input, neg) = opt(dash)(input)?;
219 let (input, (ex_whole,ex_part)) = match float_literal(input.clone()) {
220 Ok((input, RealNumber::Float(exponent))) => {
221 (input, exponent)
222 }
223 _ => match integer_literal(input.clone()) {
224 Ok((input, RealNumber::Integer(exponent))) => {
225 (input, (exponent, Token::default()))
226 }
227 Err(err) => {return Err(err);}
228 _ => unreachable!(),
229 }
230 };
231 let ex_sign = match neg {
232 Some(_) => true,
233 None => false,
234 };
235 Ok((input, RealNumber::Scientific((base,(ex_sign,ex_whole,ex_part)))))
236}
237
238pub fn float_decimal_start(input: ParseString) -> ParseResult<RealNumber> {
240 let (input, _) = period(input)?;
241 let (input, part) = digit_sequence(input)?;
242 let mut tokens2 = part.clone();
243 let mut merged = Token::merge_tokens(&mut tokens2).unwrap();
244 merged.kind = TokenKind::Number;
245 Ok((input, RealNumber::Float((Token::default(),merged))))
246}
247
248pub fn float_full(input: ParseString) -> ParseResult<RealNumber> {
250 let (input, mut whole) = digit_sequence(input)?;
251 let (input, _) = period(input)?;
252 let (input, mut part) = digit_sequence(input)?;
253 let mut whole = Token::merge_tokens(&mut whole).unwrap();
254 let mut part = Token::merge_tokens(&mut part).unwrap();
255 whole.kind = TokenKind::Number;
256 part.kind = TokenKind::Number;
257 Ok((input, RealNumber::Float((whole,part))))
258}
259
260pub fn float_literal(input: ParseString) -> ParseResult<RealNumber> {
262 let (input, result) = alt((float_decimal_start,float_full))(input)?;
263 Ok((input, result))
264}
265
266pub fn integer_literal(input: ParseString) -> ParseResult<RealNumber> {
268 alt((typed_integer, untyped_integer))(input)
269}
270
271pub fn typed_integer(input: ParseString) -> ParseResult<RealNumber> {
273 let (input, mut digits) = digit_sequence(input)?;
274 let mut merged = Token::merge_tokens(&mut digits).unwrap();
275 let (input, suffix) = identifier(input)?; merged.kind = TokenKind::Number;
277 let kind_annotation = KindAnnotation {
278 kind: Kind::Scalar(suffix),
279 };
280 Ok((input, RealNumber::TypedInteger((merged, kind_annotation))))
281}
282
283pub fn untyped_integer(input: ParseString) -> ParseResult<RealNumber> {
285 let (input, mut digits) = digit_sequence(input)?;
286 let mut merged = Token::merge_tokens(&mut digits).unwrap();
287 merged.kind = TokenKind::Number;
288 Ok((input, RealNumber::Integer(merged)))
289}
290
291pub fn decimal_literal(input: ParseString) -> ParseResult<RealNumber> {
293 let msg = "Expects decimal digits after \"0d\"";
294 let input = tag("0d")(input);
295 let (input, _) = input?;
296 let (input, mut tokens) = label!(digit_sequence, msg)(input)?;
297 let mut merged = Token::merge_tokens(&mut tokens).unwrap();
298 merged.kind = TokenKind::Number;
299 Ok((input, RealNumber::Decimal(merged)))
300}
301
302pub fn hexadecimal_literal(input: ParseString) -> ParseResult<RealNumber> {
304 let msg = "Expects hexadecimal digits after \"0x\"";
305 let input = tag("0x")(input);
306 let (input, _) = input?;
307 let (input, mut tokens) = label!(many1(alt((digit_token,underscore,alpha_token))), msg)(input)?;
308 let mut merged = Token::merge_tokens(&mut tokens).unwrap();
309 merged.kind = TokenKind::Number;
310 Ok((input, RealNumber::Hexadecimal(merged)))
311}
312
313pub fn octal_literal(input: ParseString) -> ParseResult<RealNumber> {
315 let msg = "Expects octal digits after \"0o\"";
316 let input = tag("0o")(input);
317 let (input, _) = input?;
318 let (input, mut tokens) = label!(many1(alt((digit_token,underscore,alpha_token))), msg)(input)?;
319 let mut merged = Token::merge_tokens(&mut tokens).unwrap();
320 merged.kind = TokenKind::Number;
321 Ok((input, RealNumber::Octal(merged)))
322}
323
324pub fn binary_literal(input: ParseString) -> ParseResult<RealNumber> {
326 let msg = "Expects binary digits after \"0b\"";
327 let input = tag("0b")(input);
328 let (input, _) = input?;
329 let (input, mut tokens) = label!(many1(alt((digit_token,underscore,alpha_token))), msg)(input)?;
330 let mut merged = Token::merge_tokens(&mut tokens).unwrap();
331 merged.kind = TokenKind::Number;
332 Ok((input, RealNumber::Binary(merged)))
333}
334
335pub fn empty(input: ParseString) -> ParseResult<Token> {
337 let (input, (g, src_range)) = range(many1(tag("_")))(input)?;
338 Ok((input, Token{kind: TokenKind::Empty, chars: g.join("").chars().collect(), src_range}))
339}
340
341pub fn kind_annotation(input: ParseString) -> ParseResult<KindAnnotation> {
346 let msg2 = "Expects at least one unit in kind annotation";
347 let msg3 = "Expects right angle";
348 let (input, (_, r)) = range(left_angle)(input)?;
349 let (input, kind) = kind(input)?;
350 let (input, optional) = opt(question)(input)?;
351 let (input, _) = label!(right_angle, msg3, r)(input)?;
352 let kind = match optional {
353 Some(_) => Kind::Option(Box::new(kind)),
354 None => kind,
355 };
356 Ok((input, KindAnnotation{ kind }))
357}
358
359pub fn kind(input: ParseString) -> ParseResult<Kind> {
361 let (input, kind) = alt((
362 kind_any,
363 kind_atom,
364 kind_empty,
365 kind_map,
366 kind_matrix,
367 kind_record,
368 kind_scalar,
369 kind_set,
370 kind_table,
371 kind_tuple,
372 kind_kind,
373 ))(input)?;
374 Ok((input, kind))
375}
376
377pub fn kind_kind(input: ParseString) -> ParseResult<Kind> {
379 let msg2 = "Expects at least one unit in kind annotation";
380 let msg3 = "Expects right angle";
381 let (input, (_, r)) = range(left_angle)(input)?;
382
383 let (input, kind) = kind(input)?;
384 let (input, optional) = opt(question)(input)?;
385 let (input, _) = label!(right_angle, msg3, r)(input)?;
386 let kind = match optional {
387 Some(_) => Kind::Option(Box::new(kind)),
388 None => kind,
389 };
390 Ok((input, Kind::Kind(Box::new(kind))))
391}
392
393pub fn kind_table(input: ParseString) -> ParseResult<Kind> {
395 let (input, _) = bar(input)?;
396 let (input, elements) = separated_list1(alt((null(list_separator),null(many1(space_tab)))), nom_tuple((identifier, kind_annotation)))(input)?;
397 let (input, _) = bar(input)?;
398 let (input, size) = opt(tuple((colon,literal)))(input)?;
399 let size = size.map(|(_, ltrl)| ltrl).unwrap_or_else(|| Literal::Empty(Token::default()));
400 let elements = elements.into_iter().map(|(id, knd)| (id, knd.kind)).collect();
401 Ok((input, Kind::Table((elements, Box::new(size)))))
402}
403
404pub fn kind_any(input: ParseString) -> ParseResult<Kind> {
406 let (input, _) = asterisk(input)?;
407 Ok((input, Kind::Any))
408}
409
410pub fn kind_empty(input: ParseString) -> ParseResult<Kind> {
412 let (input, _) = many1(underscore)(input)?;
413 Ok((input, Kind::Empty))
414}
415
416pub fn kind_atom(input: ParseString) -> ParseResult<Kind> {
418 let (input, _) = colon(input)?;
419 let (input, atm) = identifier(input)?;
420 Ok((input, Kind::Atom(atm)))
421}
422
423pub fn kind_set(input: ParseString) -> ParseResult<Kind> {
425 let (input, _) = left_brace(input)?;
426 let (input, kind) = kind(input)?;
427 let (input, _) = right_brace(input)?;
428 let (input, opt_lit) = opt(nom_tuple((colon, literal)))(input)?;
429 let (input, notation) = opt(tag(":N"))(input)?;
430 let ltrl = match opt_lit {
431 Some((_, ltrl)) => Some(Box::new(ltrl)),
432 None => match notation {
433 Some(_) => Some(Box::new(Literal::Empty(Token::new(TokenKind::Empty, SourceRange::default(), vec!['N'])))),
434 None => None,
435 },
436 };
437 Ok((input, Kind::Set(Box::new(kind), ltrl)))
438}
439
440pub fn kind_map(input: ParseString) -> ParseResult<Kind> {
442 let (input, _) = left_brace(input)?;
443 let (input, key_kind) = kind(input)?;
444 let (input, _) = colon(input)?;
445 let (input, value_kind) = kind(input)?;
446 let (input, _) = right_brace(input)?;
447 Ok((input, Kind::Map(Box::new(key_kind),Box::new(value_kind))))
448}
449
450pub fn kind_record(input: ParseString) -> ParseResult<Kind> {
452 let (input, _) = left_brace(input)?;
453 let (input, _) = space_tab0(input)?;
454 let (input, elements) = separated_list1(alt((list_separator,space_tab1)), nom_tuple((identifier, kind_annotation)))(input)?;
455 let (input, _) = opt(tag(",..."))(input)?;
456 let (input, _) = space_tab0(input)?;
457 let (input, _) = right_brace(input)?;
458 let elements = elements.into_iter().map(|(id, knd)| (id, knd.kind)).collect();
459 Ok((input, Kind::Record(elements)))
460}
461
462pub fn kind_matrix(input: ParseString) -> ParseResult<Kind> {
476 let (input, _) = left_bracket(input)?;
477 let (input, kind) = kind(input)?;
478 let (input, _) = right_bracket(input)?;
479 let (input, _) = opt(colon)(input)?;
480 let (input, size) = separated_list0(list_separator,literal)(input)?;
481 Ok((input, Kind::Matrix((Box::new(kind),size))))
482}
483
484pub fn kind_tuple(input: ParseString) -> ParseResult<Kind> {
486 let (input, _) = left_parenthesis(input)?;
487 let (input, kinds) = separated_list1(list_separator, kind)(input)?;
488 let (input, _) = right_parenthesis(input)?;
489 Ok((input, Kind::Tuple(kinds)))
490}
491
492pub fn kind_scalar(input: ParseString) -> ParseResult<Kind> {
494 let (input, kind) = identifier(input)?;
495 let (input, range) = opt(tuple((colon,range_expression)))(input)?;
496 Ok((input, Kind::Scalar(kind)))
497}