mech_syntax/
literals.rs

1#[macro_use]
2use crate::*;
3use nom::{
4  multi::separated_list0,
5  sequence::tuple as nom_tuple,
6};
7use crate::nodes::Kind;
8
9// literal := (number | string | atom | boolean | empty), kind-annotation? ;
10pub fn literal(input: ParseString) -> ParseResult<Literal> {
11  let (input, result) = match number(input.clone()) {
12    Ok((input, num)) => (input, Literal::Number(num)),
13    _ => match string(input.clone()) {
14      Ok((input, s)) => (input, Literal::String(s)),
15      _ => match atom(input.clone()) {
16        Ok((input, atm)) => (input, Literal::Atom(atm)),
17        _ => match boolean(input.clone()) {
18          Ok((input, boolean)) => (input, Literal::Boolean(boolean)),
19          _ => match empty(input.clone()) {
20            Ok((input, empty)) => (input, Literal::Empty(empty)), 
21            Err(err) => {return Err(err);}
22          }
23        }
24      }
25    }
26  };
27  let (input, result) = match opt(kind_annotation)(input.clone()) {
28    Ok((input, Some(knd))) => ((input, Literal::TypedLiteral((Box::new(result),knd)))),
29    Ok((input, None)) => (input,result),
30    Err(err) => {return Err(err);}
31  };
32  Ok((input, result))
33}
34
35// string := quote, (!quote, text)*, quote ;
36pub fn string(input: ParseString) -> ParseResult<MechString> {
37  let msg = "Character not allowed in string";
38  let (input, _) = quote(input)?;
39  let (input, matched) = many0(nom_tuple((is_not(quote), alt((text,new_line)))))(input)?;
40  let (input, _) = quote(input)?;
41  let (_, mut text): ((), Vec<_>) = matched.into_iter().unzip();
42  let mut merged = Token::merge_tokens(&mut text).unwrap();
43  merged.kind = TokenKind::String;
44  Ok((input, MechString { text: merged }))
45}
46
47// boolean_literal := true_literal | false_literal ;
48pub fn boolean(input: ParseString) -> ParseResult<Token> {
49  let (input, boolean) = alt((true_literal, false_literal))(input)?;
50  Ok((input, boolean))
51}
52
53// true_literal := english_true_literal | check_mark ;
54pub fn true_literal(input: ParseString) -> ParseResult<Token> {
55  let (input, token) = alt((english_true_literal, check_mark))(input)?;
56  Ok((input, token))
57}
58
59// false_literal := english_false_literal | cross ;
60pub fn false_literal(input: ParseString) -> ParseResult<Token> {
61  let (input, token) = alt((english_false_literal, cross))(input)?;
62  Ok((input, token))
63}
64
65// number := real_number, "i"? | ("+", real_number, "i")? ;
66pub fn number(input: ParseString) -> ParseResult<Number> {
67  let (input, real_num) = real_number(input)?;
68  match tag("i")(input.clone()) {
69    Ok((input,_)) => {
70      return Ok((input, Number::Imaginary(
71        ComplexNumber{
72          real: None, 
73          imaginary: ImaginaryNumber{number: real_num}
74        })));
75      }
76    _ => match nom_tuple((plus,real_number,tag("i")))(input.clone()) {
77      Ok((input, (_,imaginary_num,_))) => {
78        return Ok((input, Number::Imaginary(
79          ComplexNumber{
80            real: Some(real_num), 
81            imaginary: ImaginaryNumber{number: imaginary_num},
82          })));
83        }
84      _ => ()
85    }
86  }
87  Ok((input, Number::Real(real_num)))
88}
89
90// real_number := dash?, (hexadecimal_literal | decimal_literal | octal_literal | binary_literal | scientific_literal | rational_literal | float_literal | integer_literal) ;
91pub fn real_number(input: ParseString) -> ParseResult<RealNumber> {
92  let (input, neg) = opt(dash)(input)?;
93  let (input, result) = alt((hexadecimal_literal, decimal_literal, octal_literal, binary_literal, scientific_literal, rational_literal, float_literal, integer_literal))(input)?;
94  let result = match neg {
95    Some(_) => RealNumber::Negated(Box::new(result)),
96    None => result,
97  };
98  Ok((input, result))
99}
100
101// rational_literal := integer_literal, "/", integer_literal ;
102pub fn rational_literal(input: ParseString) -> ParseResult<RealNumber> {
103  let (input, RealNumber::Integer(numerator)) = integer_literal(input)? else { unreachable!() };
104  let (input, _) = slash(input)?;
105  let (input, RealNumber::Integer(denominator)) = integer_literal(input)? else { unreachable!() };
106  Ok((input, RealNumber::Rational((numerator,denominator))))
107}
108
109// scientific_literal := (float_literal | integer_literal), ("e" | "E"), plus?, dash?, (float_literal | integer_literal) ;
110pub fn scientific_literal(input: ParseString) -> ParseResult<RealNumber> {
111  let (input, base) = match float_literal(input.clone()) {
112    Ok((input, RealNumber::Float(base))) => {
113      (input, base)
114    }
115    _ => match integer_literal(input.clone()) {
116      Ok((input, RealNumber::Integer(base))) => {
117        (input, (base, Token::default()))
118      }
119      Err(err) => {return Err(err);}
120      _ => unreachable!(),
121    }
122  };
123  let (input, _) = alt((tag("e"), tag("E")))(input)?;
124  let (input, _) = opt(plus)(input)?;
125  let (input, neg) = opt(dash)(input)?;
126  let (input, (ex_whole,ex_part)) = match float_literal(input.clone()) {
127    Ok((input, RealNumber::Float(exponent))) => {
128      (input, exponent)
129    }
130    _ => match integer_literal(input.clone()) {
131      Ok((input, RealNumber::Integer(exponent))) => {
132        (input, (exponent, Token::default()))
133      }
134      Err(err) => {return Err(err);}
135      _ => unreachable!(),
136    }
137  };
138  let ex_sign = match neg {
139    Some(_) => true,
140    None => false,
141  };
142  Ok((input, RealNumber::Scientific((base,(ex_sign,ex_whole,ex_part)))))
143}
144
145// float_decimal_start := ".", digit_sequence ;
146pub fn float_decimal_start(input: ParseString) -> ParseResult<RealNumber> {
147  let (input, _) = period(input)?;
148  let (input, part) = digit_sequence(input)?;
149  let mut tokens2 = part.clone();
150  let mut merged = Token::merge_tokens(&mut tokens2).unwrap();
151  merged.kind = TokenKind::Number;
152  Ok((input, RealNumber::Float((Token::default(),merged))))
153}
154
155// float_full := digit_sequence, ".", digit_sequnce ;
156pub fn float_full(input: ParseString) -> ParseResult<RealNumber> {
157  let (input, mut whole) = digit_sequence(input)?;
158  let (input, _) = period(input)?;
159  let (input, mut part) = digit_sequence(input)?;
160  let mut whole = Token::merge_tokens(&mut whole).unwrap();
161  let mut part = Token::merge_tokens(&mut part).unwrap();
162  whole.kind = TokenKind::Number;
163  part.kind = TokenKind::Number;
164  Ok((input, RealNumber::Float((whole,part))))
165}
166
167// float_literal := float_decimal_start | float_full;
168pub fn float_literal(input: ParseString) -> ParseResult<RealNumber> {
169  let (input, result) = alt((float_decimal_start,float_full))(input)?;
170  Ok((input, result))
171}
172
173// integer := digit1 ;
174pub fn integer_literal(input: ParseString) -> ParseResult<RealNumber> {
175  let (input, mut digits) = digit_sequence(input)?;
176  let mut merged = Token::merge_tokens(&mut digits).unwrap();
177  merged.kind = TokenKind::Number; 
178  Ok((input, RealNumber::Integer(merged)))
179}
180
181// decimal_literal := "0d", <digit1> ;
182pub fn decimal_literal(input: ParseString) -> ParseResult<RealNumber> {
183  let msg = "Expects decimal digits after \"0d\"";
184  let input = tag("0d")(input);
185  let (input, _) = input?;
186  let (input, mut tokens) = label!(digit_sequence, msg)(input)?;
187  let mut merged = Token::merge_tokens(&mut tokens).unwrap();
188  merged.kind = TokenKind::Number; 
189  Ok((input, RealNumber::Decimal(merged)))
190}
191
192// hexadecimal_literal := "0x", <hex_digit+> ;
193pub fn hexadecimal_literal(input: ParseString) -> ParseResult<RealNumber> {
194  let msg = "Expects hexadecimal digits after \"0x\"";
195  let input = tag("0x")(input);
196  let (input, _) = input?;
197  let (input, mut tokens) = label!(many1(alt((digit_token,underscore,alpha_token))), msg)(input)?;
198  let mut merged = Token::merge_tokens(&mut tokens).unwrap();
199  merged.kind = TokenKind::Number; 
200  Ok((input, RealNumber::Hexadecimal(merged)))
201}
202
203// octal_literal := "0o", <oct_digit+> ;
204pub fn octal_literal(input: ParseString) -> ParseResult<RealNumber> {
205  let msg = "Expects octal digits after \"0o\"";
206  let input = tag("0o")(input);
207  let (input, _) = input?;
208  let (input, mut tokens) = label!(many1(alt((digit_token,underscore,alpha_token))), msg)(input)?;
209  let mut merged = Token::merge_tokens(&mut tokens).unwrap();
210  merged.kind = TokenKind::Number; 
211  Ok((input, RealNumber::Octal(merged)))
212}
213
214// binary_literal := "0b", <bin_digit+> ;
215pub fn binary_literal(input: ParseString) -> ParseResult<RealNumber> {
216  let msg = "Expects binary digits after \"0b\"";
217  let input = tag("0b")(input);
218  let (input, _) = input?;
219  let (input, mut tokens) = label!(many1(alt((digit_token,underscore,alpha_token))), msg)(input)?;
220  let mut merged = Token::merge_tokens(&mut tokens).unwrap();
221  merged.kind = TokenKind::Number; 
222  Ok((input, RealNumber::Binary(merged)))
223}
224
225// empty := underscore+ ;
226pub fn empty(input: ParseString) -> ParseResult<Token> {
227  let (input, (g, src_range)) = range(many1(tag("_")))(input)?;
228  Ok((input, Token{kind: TokenKind::Empty, chars: g.join("").chars().collect(), src_range}))
229}
230
231// #### Kind Annotations
232
233// kind_annotation := left_angle, kind, right_angle ;
234pub fn kind_annotation(input: ParseString) -> ParseResult<KindAnnotation> {
235  let msg2 = "Expects at least one unit in kind annotation";
236  let msg3 = "Expects right angle";
237  let (input, (_, r)) = range(left_angle)(input)?;
238  let (input, kind) = kind(input)?;
239  let (input, _) = label!(right_angle, msg3, r)(input)?;
240  Ok((input, KindAnnotation{ kind }))
241}
242
243// kind := kind_fxn | kind_empty | kind_atom | kind_tuple | kind_scalar | kind_bracket | kind_map | kind_brace ;
244pub fn kind(input: ParseString) -> ParseResult<Kind> {
245  let (input, kind) = alt((kind_fxn,kind_empty,kind_atom,kind_tuple,kind_scalar,kind_bracket,kind_map,kind_brace))(input)?;
246  Ok((input, kind))
247}
248
249// kind_empty := underscore+ ;
250pub fn kind_empty(input: ParseString) -> ParseResult<Kind> {
251  let (input, _) = many1(underscore)(input)?;
252  Ok((input, Kind::Empty))
253}
254
255// kind_atom := "`", identifier ;
256pub fn kind_atom(input: ParseString) -> ParseResult<Kind> {
257  let (input, _) = grave(input)?;
258  let (input, atm) = identifier(input)?;
259  Ok((input, Kind::Atom(atm)))
260}
261
262// kind_map := "{", kind, ":", kind, "}" ;
263pub fn kind_map(input: ParseString) -> ParseResult<Kind> {
264  let (input, _) = left_brace(input)?;
265  let (input, key_kind) = kind(input)?;
266  let (input, _) = colon(input)?;
267  let (input, value_kind) = kind(input)?;
268  let (input, _) = right_brace(input)?;
269  Ok((input, Kind::Map(Box::new(key_kind),Box::new(value_kind))))
270}
271
272// kind_fxn := "(", list0(list_separator, kind), ")", "=", "(", list0(list_separator, kind), ")" ;
273pub fn kind_fxn(input: ParseString) -> ParseResult<Kind> {
274  let (input, _) = left_parenthesis(input)?;
275  let (input, input_kinds) = separated_list0(list_separator,kind)(input)?;
276  let (input, _) = right_parenthesis(input)?;
277  let (input, _) = equal(input)?;
278  let (input, _) = left_parenthesis(input)?;
279  let (input, output_kinds) = separated_list0(list_separator,kind)(input)?;
280  let (input, _) = right_parenthesis(input)?;
281  Ok((input, Kind::Function(input_kinds,output_kinds)))
282}
283
284// kind_brace := "{", list1(",", kind), "}", ":"?, list0("," , literal) ;
285pub fn kind_brace(input: ParseString) -> ParseResult<Kind> {
286  let (input, _) = left_brace(input)?;
287  let (input, kinds) = separated_list1(list_separator,kind)(input)?;
288  let (input, _) = right_brace(input)?;
289  let (input, _) = opt(colon)(input)?;
290  let (input, size) = separated_list0(list_separator,literal)(input)?;
291  Ok((input, Kind::Brace((kinds,size))))
292}
293
294// kind_bracket := "[", list1(",",kind), "]", ":"?, list0(",", literal) ;
295pub fn kind_bracket(input: ParseString) -> ParseResult<Kind> {
296  let (input, _) = left_bracket(input)?;
297  let (input, kinds) = separated_list1(list_separator,kind)(input)?;
298  let (input, _) = right_bracket(input)?;
299  let (input, _) = opt(colon)(input)?;
300  let (input, size) = separated_list0(list_separator,literal)(input)?;
301  Ok((input, Kind::Bracket((kinds,size))))
302}
303
304// kind_tuple := "(", list1(",", kind), ")" ;
305pub fn kind_tuple(input: ParseString) -> ParseResult<Kind> {
306  let (input, _) = left_parenthesis(input)?;
307  let (input, kinds) = separated_list1(list_separator, kind)(input)?;
308  let (input, _) = right_parenthesis(input)?;
309  Ok((input, Kind::Tuple(kinds)))
310}
311
312// kind_scalar := identifier, [":", range_expression] ;
313pub fn kind_scalar(input: ParseString) -> ParseResult<Kind> {
314  let (input, kind) = identifier(input)?;
315  let (input, range) = opt(tuple((colon,range_expression)))(input)?;
316  Ok((input, Kind::Scalar(kind)))
317}