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