1#[macro_use]
2use crate::*;
3use nom::{
4 multi::separated_list0,
5 sequence::tuple as nom_tuple,
6};
7use crate::nodes::Matrix;
8
9pub fn max_err<'a>(x: Option<ParseError<'a>>, y: ParseError<'a>) -> ParseError<'a> {
12 match (x,&y) {
13 (None, y) => y.clone(),
14 _ => y.clone(),
15 }
16}
17
18pub fn structure(input: ParseString) -> ParseResult<Structure> {
20 match empty_set(input.clone()) {
21 Ok((input, set)) => {return Ok((input, Structure::Set(set)));},
22 _ => (),
23 }
24 match empty_map(input.clone()) {
25 Ok((input, map)) => {return Ok((input, Structure::Map(map)));},
26 _ => (),
27 }
28 match table(input.clone()) {
29 Ok((input, tbl)) => {return Ok((input, Structure::Table(tbl)));},
30 _ => (),
32 }
33 match matrix(input.clone()) {
34 Ok((input, mtrx)) => {return Ok((input, Structure::Matrix(mtrx)));},
35 _ => (),
37 }
38 match tuple(input.clone()) {
39 Ok((input, tpl)) => {return Ok((input, Structure::Tuple(tpl)));},
40 _ => (),
41 }
42 match tuple_struct(input.clone()) {
43 Ok((input, tpl)) => {return Ok((input, Structure::TupleStruct(tpl)));},
44 _ => (),
45 }
46 match record(input.clone()) {
47 Ok((input, table)) => {return Ok((input, Structure::Record(table)));},
48 _ => (),
49 }
50 match map(input.clone()) {
51 Ok((input, map)) => {return Ok((input, Structure::Map(map)));},
52 _ => (),
53 }
54 match set(input.clone()) {
55 Ok((input, set)) => {return Ok((input, Structure::Set(set)));},
56 Err(err) => {return Err(err);}
57 }
58}
59
60pub fn tuple(input: ParseString) -> ParseResult<Tuple> {
62 let (input, _) = left_parenthesis(input)?;
63 let (input, _) = whitespace0(input)?;
64 let (input, exprs) = separated_list0(list_separator, expression)(input)?;
65 let (input, _) = whitespace0(input)?;
66 let (input, _) = right_parenthesis(input)?;
67 Ok((input, Tuple{elements: exprs}))
68}
69
70pub fn atom(input: ParseString) -> ParseResult<Atom> {
72 let (input, _) = grave(input)?;
73 let (input, name) = identifier(input)?;
74 Ok((input, Atom{name}))
75}
76
77pub fn tuple_struct(input: ParseString) -> ParseResult<TupleStruct> {
79 let (input, _) = grave(input)?;
80 let (input, name) = identifier(input)?;
81 let (input, _) = left_parenthesis(input)?;
82 let (input, _) = whitespace0(input)?;
83 let (input, value) = expression(input)?;
84 let (input, _) = whitespace0(input)?;
85 let (input, _) = right_parenthesis(input)?;
86 Ok((input, TupleStruct{name, value: Box::new(value)}))
87}
88
89pub fn binding(input: ParseString) -> ParseResult<Binding> {
92 let msg1 = "Unexpected space before colon ':'";
93 let msg2 = "Expects a value";
94 let msg3 = "Expects whitespace or comma followed by whitespace";
95 let msg4 = "Expects whitespace";
96 let (input, _) = whitespace0(input)?;
97 let (input, name) = identifier(input)?;
98 let (input, kind) = opt(kind_annotation)(input)?;
99 let (input, _) = whitespace0(input)?;
100 let (input, _) = colon(input)?;
101 let (input, _) = whitespace0(input)?;
102 let (input, value) = label!(expression, msg2)(input)?;
103 let (input, _) = whitespace0(input)?;
104 let (input, _) = opt(comma)(input)?;
105 let (input, _) = whitespace0(input)?;
106 Ok((input, Binding{name, kind, value}))
107}
108
109pub fn table_column(input: ParseString) -> ParseResult<TableColumn> {
111 let (input, _) = many0(space_tab)(input)?;
112 let (input, element) = match expression(input) {
113 Ok(result) => result,
114 Err(err) => {
115 return Err(err);
116 }
117 };
118 let (input, _) = nom_tuple((many0(space_tab),opt(alt((comma,table_separator))), many0(space_tab)))(input)?;
119 Ok((input, TableColumn{element}))
120}
121
122pub fn matrix_column(input: ParseString) -> ParseResult<MatrixColumn> {
124 let (input, _) = many0(space_tab)(input)?;
125 let (input, element) = match expression(input) {
126 Ok(result) => result,
127 Err(err) => {
128 return Err(err);
129 }
130 };
131 let (input, _) = nom_tuple((many0(space_tab),opt(alt((comma,table_separator))), many0(space_tab)))(input)?;
132 Ok((input, MatrixColumn{element}))
133}
134
135
136pub fn table_row(input: ParseString) -> ParseResult<TableRow> {
138 let (input, _) = opt(table_separator)(input)?;
139 let (input, _) = many0(space_tab)(input)?;
140 let (input, columns) = match many1(table_column)(input) {
141 Ok(result) => result,
142 Err(error) => {
143 return Err(error);
144 }
145 };
146 let (input, _) = nom_tuple((opt(semicolon), opt(new_line)))(input)?;
147 let (input, _) = opt(nom_tuple((many1(box_drawing_char),new_line)))(input)?;
148 Ok((input, TableRow{columns}))
149}
150
151pub fn matrix_row(input: ParseString) -> ParseResult<MatrixRow> {
153 let (input, _) = opt(table_separator)(input)?;
154 let (input, _) = many0(space_tab)(input)?;
155 let (input, columns) = match many1(matrix_column)(input) {
156 Ok(result) => result,
157 Err(error) => {
158 return Err(error);
159 }
160 };
161 let (input, _) = nom_tuple((opt(semicolon), opt(new_line)))(input)?;
162 let (input, _) = opt(nom_tuple((many1(box_drawing_char),new_line)))(input)?;
163 Ok((input, MatrixRow{columns}))
164}
165
166pub fn table_header(input: ParseString) -> ParseResult<Vec<Field>> {
168 let (input, fields) = separated_list1(many1(space_tab),field)(input)?;
169 let (input, _) = many0(space_tab)(input)?;
170 let (input, _) = alt((bar,box_vert,box_vert_bold))(input)?;
171 let (input, _) = whitespace0(input)?;
172 Ok((input, fields))
173}
174
175pub fn field(input: ParseString) -> ParseResult<Field> {
177 let (input, name) = identifier(input)?;
178 let (input, kind) = opt(kind_annotation)(input)?;
179 Ok((input, Field{name, kind}))
180}
181
182pub fn box_drawing_char(input: ParseString) -> ParseResult<Token> {
184 alt((box_tl, box_bl, box_tr, box_tl_bold, box_bl_bold, box_tr_bold, box_tr_round, box_bl_round, box_vert, box_cross, box_horz, box_t_left, box_t_right, box_t_top, box_t_bottom))(input)
185}
186
187pub fn box_drawing_emoji(input: ParseString) -> ParseResult<Token> {
189 alt((box_tl, box_bl, box_tr, box_tl_bold, box_bl_bold, box_tr_bold, box_tl_round, box_br_round, box_tr_round, box_bl_round, box_vert, box_cross, box_horz, box_t_left, box_t_right, box_t_top, box_t_bottom))(input)
190}
191
192pub fn matrix_start(input: ParseString) -> ParseResult<Token> {
194 alt((box_tl_round, box_tl, box_tl_bold, left_bracket))(input)
195}
196
197pub fn matrix_end(input: ParseString) -> ParseResult<Token> {
199 let result = alt((box_br_round, box_br, box_br_bold, right_bracket))(input);
200 result
201}
202
203pub fn table_start(input: ParseString) -> ParseResult<Token> {
205 alt((box_tl_round, box_tl, box_tl_bold, left_brace))(input)
206}
207
208pub fn table_end(input: ParseString) -> ParseResult<Token> {
210 let result = alt((box_br_round, box_br, box_br_bold, right_brace))(input);
211 result
212}
213
214pub fn table_separator(input: ParseString) -> ParseResult<Token> {
216 let (input, token) = alt((box_vert,box_vert_bold))(input)?;
217 Ok((input, token))
218}
219
220pub fn matrix(input: ParseString) -> ParseResult<Matrix> {
222 let msg = "Expects right bracket ']' to finish the matrix";
223 let (input, (_, r)) = range(matrix_start)(input)?;
224 let (input, _) = many0(alt((box_drawing_char,whitespace)))(input)?;
225 let (input, rows) = many0(matrix_row)(input)?;
226 let (input, _) = many0(alt((box_drawing_char,whitespace)))(input)?;
227 let (input, _) = whitespace0(input)?;
228 let (input, _) = match label!(matrix_end, msg, r)(input) {
229 Ok(k) => k,
230 Err(err) => {
231 return Err(err);
232 }
233 };
234 Ok((input, Matrix{rows}))
235}
236
237pub fn table(input: ParseString) -> ParseResult<Table> {
239 let msg = "Expects right bracket '}' to finish the table";
240 let (input, (_, r)) = range(table_start)(input)?;
241 let (input, _) = many0(alt((box_drawing_char,whitespace)))(input)?;
242 let (input, header) = table_header(input)?;
243 let (input, _) = many0(alt((box_drawing_char,whitespace)))(input)?;
244 let (input, rows) = many1(table_row)(input)?;
245 let (input, _) = many0(box_drawing_char)(input)?;
246 let (input, _) = whitespace0(input)?;
247 let (input, _) = match label!(table_end, msg, r)(input) {
248 Ok(k) => k,
249 Err(err) => {
250 return Err(err);
251 }
252 };
253 Ok((input, Table{header,rows}))
254}
255
256pub fn empty_map(input: ParseString) -> ParseResult<Map> {
258 let (input, _) = table_start(input)?;
259 let (input, _) = whitespace0(input)?;
260 let (input, _) = table_end(input)?;
261 Ok((input, Map{elements: vec![]}))
262}
263
264pub fn empty_set(input: ParseString) -> ParseResult<Set> {
266 let (input, _) = table_start(input)?;
267 let (input, _) = whitespace0(input)?;
268 let (input, _) = empty(input)?;
269 let (input, _) = whitespace0(input)?;
270 let (input, _) = table_end(input)?;
271 Ok((input, Set{elements: vec![]}))
272}
273
274pub fn record(input: ParseString) -> ParseResult<Record> {
276 let msg = "Expects right bracket ']' to terminate inline table";
277 let (input, (_, r)) = range(table_start)(input)?;
278 let (input, _) = whitespace0(input)?;
279 let (input, bindings) = many1(binding)(input)?;
280 let (input, _) = whitespace0(input)?;
281 let (input, _) = label!(table_end, msg, r)(input)?;
282 Ok((input, Record{bindings}))
283}
284
285pub fn map(input: ParseString) -> ParseResult<Map> {
287 let msg = "Expects right bracket '}' to terminate inline table";
288 let (input, (_, r)) = range(left_brace)(input)?;
289 let (input, _) = whitespace0(input)?;
290 let (input, elements) = many0(mapping)(input)?;
291 let (input, _) = whitespace0(input)?;
292 let (input, _) = label!(right_brace, msg, r)(input)?;
293 Ok((input, Map{elements}))
294}
295
296pub fn mapping(input: ParseString) -> ParseResult<Mapping> {
298 let msg1 = "Unexpected space before colon ':'";
299 let msg2 = "Expects a value";
300 let msg3 = "Expects whitespace or comma followed by whitespace";
301 let msg4 = "Expects whitespace";
302 let (input, _) = whitespace0(input)?;
303 let (input, key) = expression(input)?;
304 let (input, _) = whitespace0(input)?;
305 let (input, _) = colon(input)?;
306 let (input, _) = whitespace0(input)?;
307 let (input, value) = label!(expression, msg2)(input)?;
308 let (input, _) = whitespace0(input)?;
309 let (input, _) = opt(comma)(input)?;
310 let (input, _) = whitespace0(input)?;
311 Ok((input, Mapping{key, value}))
312}
313
314pub fn set(input: ParseString) -> ParseResult<Set> {
316 let msg = "Expects right bracket '}' to terminate inline table";
317 let (input, (_, r)) = range(left_brace)(input)?;
318 let (input, _) = whitespace0(input)?;
319 let (input, elements) = separated_list0(alt((list_separator,whitespace1)), expression)(input)?;
320 let (input, _) = whitespace0(input)?;
321 let (input, _) = label!(right_brace, msg, r)(input)?;
322 Ok((input, Set{elements}))
323}