intuicio_frontend_simpleton/
parser.rs

1use crate::{
2    script::{
3        SimpletonExpressionNext, SimpletonExpressionStart, SimpletonFunction, SimpletonLiteral,
4        SimpletonModule, SimpletonStatement, SimpletonStruct,
5    },
6    Integer, Real, Text,
7};
8use pest::{iterators::Pair, Parser};
9use pest_derive::Parser;
10
11#[derive(Parser)]
12#[grammar = "grammar.pest"]
13pub struct SimpletonParser;
14
15pub fn parse(content: &str) -> Result<SimpletonModule, String> {
16    match SimpletonParser::parse(Rule::file, content) {
17        Ok(mut pairs) => {
18            let pair = pairs.next().unwrap();
19            match pair.as_rule() {
20                Rule::file => Ok(parse_module(pair.into_inner().next().unwrap())),
21                rule => unreachable!("{:?}", rule),
22            }
23        }
24        Err(error) => Err(format!("{}", error)),
25    }
26}
27
28fn parse_module(pair: Pair<Rule>) -> SimpletonModule {
29    let mut result = SimpletonModule {
30        name: Default::default(),
31        dependencies: vec![],
32        structs: vec![],
33        functions: vec![],
34    };
35    let mut pairs = pair.into_inner();
36    result.name = parse_identifier(pairs.next().unwrap());
37    for pair in pairs {
38        let pair = pair.into_inner().next().unwrap();
39        match pair.as_rule() {
40            Rule::import => {
41                result
42                    .dependencies
43                    .push(parse_text(pair.into_inner().next().unwrap()));
44            }
45            Rule::structure => {
46                result.structs.push(parse_structure(pair));
47            }
48            Rule::function => {
49                result.functions.push(parse_function(pair));
50            }
51            rule => unreachable!("{:?}", rule),
52        }
53    }
54    result
55}
56
57fn parse_structure(pair: Pair<Rule>) -> SimpletonStruct {
58    let mut pairs = pair.into_inner();
59    let mut result = SimpletonStruct {
60        name: Default::default(),
61        fields: vec![],
62    };
63    result.name = parse_identifier(pairs.next().unwrap());
64    for pair in pairs {
65        match pair.as_rule() {
66            Rule::structure_field => {
67                result.fields.push(parse_identifier(pair));
68            }
69            rule => unreachable!("{:?}", rule),
70        }
71    }
72    result
73}
74
75fn parse_function(pair: Pair<Rule>) -> SimpletonFunction {
76    let mut pairs = pair.into_inner();
77    let mut result = SimpletonFunction {
78        name: Default::default(),
79        arguments: vec![],
80        statements: vec![],
81    };
82    result.name = parse_identifier(pairs.next().unwrap());
83    for pair in pairs {
84        match pair.as_rule() {
85            Rule::function_argument => {
86                result.arguments.push(parse_identifier(pair));
87            }
88            Rule::statement => {
89                result.statements.push(parse_statement(pair));
90            }
91            rule => unreachable!("{:?}", rule),
92        }
93    }
94    result
95}
96
97fn parse_statement(pair: Pair<Rule>) -> SimpletonStatement {
98    let pair = pair.into_inner().next().unwrap();
99    match pair.as_rule() {
100        Rule::create_variable => parse_create_variable(pair),
101        Rule::assign_value => parse_assign_value(pair),
102        Rule::expression => SimpletonStatement::Expression(parse_expression_start(
103            pair.into_inner().next().unwrap(),
104        )),
105        Rule::return_value => {
106            SimpletonStatement::Return(parse_expression_start(pair.into_inner().next().unwrap()))
107        }
108        Rule::if_else => {
109            let mut pairs = pair.into_inner();
110            let condition = parse_expression_start(pairs.next().unwrap());
111            let mut success = vec![];
112            let mut failure = None;
113            for pair in pairs {
114                match pair.as_rule() {
115                    Rule::if_else_success => {
116                        success = pair.into_inner().map(parse_statement).collect();
117                    }
118                    Rule::if_else_failure => {
119                        failure = Some(pair.into_inner().map(parse_statement).collect());
120                    }
121                    rule => unreachable!("{:?}", rule),
122                }
123            }
124            SimpletonStatement::IfElse {
125                condition,
126                success,
127                failure,
128            }
129        }
130        Rule::while_loop => {
131            let mut pairs = pair.into_inner();
132            let condition = parse_expression_start(pairs.next().unwrap());
133            let statements = pairs.map(parse_statement).collect();
134            SimpletonStatement::While {
135                condition,
136                statements,
137            }
138        }
139        Rule::for_loop => {
140            let mut pairs = pair.into_inner();
141            let variable = parse_identifier(pairs.next().unwrap());
142            let iterator = parse_expression_start(pairs.next().unwrap());
143            let statements = pairs.map(parse_statement).collect();
144            SimpletonStatement::For {
145                variable,
146                iterator,
147                statements,
148            }
149        }
150        rule => unreachable!("{:?}", rule),
151    }
152}
153
154fn parse_create_variable(pair: Pair<Rule>) -> SimpletonStatement {
155    let mut pairs = pair.into_inner();
156    let name = parse_identifier(pairs.next().unwrap());
157    let value = parse_expression_start(pairs.next().unwrap());
158    SimpletonStatement::CreateVariable { name, value }
159}
160
161fn parse_assign_value(pair: Pair<Rule>) -> SimpletonStatement {
162    let mut pairs = pair.into_inner();
163    let object = parse_expression_start(pairs.next().unwrap());
164    let value = parse_expression_start(pairs.next().unwrap());
165    SimpletonStatement::AssignValue { object, value }
166}
167
168fn parse_expression_start(pair: Pair<Rule>) -> SimpletonExpressionStart {
169    let pair = pair.into_inner().next().unwrap();
170    match pair.as_rule() {
171        Rule::find_structure => {
172            let mut pairs = pair.into_inner();
173            let (name, module_name) = parse_path(pairs.next().unwrap());
174            let next = pairs.next().map(parse_expression_next);
175            SimpletonExpressionStart::FindStruct {
176                name,
177                module_name,
178                next,
179            }
180        }
181        Rule::find_function => {
182            let mut pairs = pair.into_inner();
183            let (name, module_name) = parse_path(pairs.next().unwrap());
184            let next = pairs.next().map(parse_expression_next);
185            SimpletonExpressionStart::FindFunction {
186                name,
187                module_name,
188                next,
189            }
190        }
191        Rule::closure => {
192            let pairs = pair.into_inner();
193            let mut captures = vec![];
194            let mut arguments = vec![];
195            let mut statements = vec![];
196            let mut next = None;
197            for pair in pairs {
198                match pair.as_rule() {
199                    Rule::closure_capture => {
200                        captures.push(parse_identifier(pair));
201                    }
202                    Rule::function_argument => {
203                        arguments.push(parse_identifier(pair));
204                    }
205                    Rule::statement => {
206                        statements.push(parse_statement(pair));
207                    }
208                    Rule::expression_next => {
209                        next = Some(parse_expression_next(pair));
210                    }
211                    rule => unreachable!("{:?}", rule),
212                }
213            }
214            SimpletonExpressionStart::Closure {
215                captures,
216                arguments,
217                statements,
218                next,
219            }
220        }
221        Rule::literal => {
222            let mut pairs = pair.into_inner();
223            let literal = parse_literal(pairs.next().unwrap());
224            let next = pairs.next().map(parse_expression_next);
225            SimpletonExpressionStart::Literal { literal, next }
226        }
227        Rule::get_variable => {
228            let mut pairs = pair.into_inner();
229            let name = parse_identifier(pairs.next().unwrap());
230            let next = pairs.next().map(parse_expression_next);
231            SimpletonExpressionStart::GetVariable { name, next }
232        }
233        Rule::call_function => {
234            let mut pairs = pair.into_inner();
235            let (name, module_name) = parse_path(pairs.next().unwrap());
236            let mut arguments = vec![];
237            let mut next = None;
238            for pair in pairs {
239                match pair.as_rule() {
240                    Rule::call_argument => {
241                        arguments.push(parse_expression_start(pair.into_inner().next().unwrap()));
242                    }
243                    Rule::expression_next => {
244                        next = Some(parse_expression_next(pair));
245                    }
246                    rule => unreachable!("{:?}", rule),
247                }
248            }
249            SimpletonExpressionStart::CallFunction {
250                name,
251                module_name,
252                arguments,
253                next,
254            }
255        }
256        rule => unreachable!("{:?}", rule),
257    }
258}
259
260fn parse_expression_next(pair: Pair<Rule>) -> SimpletonExpressionNext {
261    let pair = pair.into_inner().next().unwrap();
262    match pair.as_rule() {
263        Rule::get_field => {
264            let mut pairs = pair.into_inner();
265            let name = parse_identifier(pairs.next().unwrap());
266            let next = pairs
267                .next()
268                .map(|pair| Box::new(parse_expression_next(pair)));
269            SimpletonExpressionNext::GetField { name, next }
270        }
271        Rule::get_array_item => {
272            let mut pairs = pair.into_inner();
273            let index = Box::new(parse_expression_start(pairs.next().unwrap()));
274            let next = pairs
275                .next()
276                .map(|pair| Box::new(parse_expression_next(pair)));
277            SimpletonExpressionNext::GetArrayItem { index, next }
278        }
279        Rule::get_map_item => {
280            let mut pairs = pair.into_inner();
281            let index = Box::new(parse_expression_start(pairs.next().unwrap()));
282            let next = pairs
283                .next()
284                .map(|pair| Box::new(parse_expression_next(pair)));
285            SimpletonExpressionNext::GetMapItem { index, next }
286        }
287        rule => unreachable!("{:?}", rule),
288    }
289}
290
291fn parse_literal(pair: Pair<Rule>) -> SimpletonLiteral {
292    match pair.as_rule() {
293        Rule::null => SimpletonLiteral::Null,
294        Rule::bool_true => SimpletonLiteral::Boolean(true),
295        Rule::bool_false => SimpletonLiteral::Boolean(false),
296        Rule::integer => SimpletonLiteral::Integer(parse_integer(pair)),
297        Rule::hex_inner => SimpletonLiteral::Integer(parse_hex(pair)),
298        Rule::binary_inner => SimpletonLiteral::Integer(parse_binary(pair)),
299        Rule::real => SimpletonLiteral::Real(parse_real(pair)),
300        Rule::text => SimpletonLiteral::Text(parse_text(pair)),
301        Rule::array => SimpletonLiteral::Array {
302            items: parse_array(pair),
303        },
304        Rule::map => SimpletonLiteral::Map {
305            items: parse_map(pair),
306        },
307        Rule::object => {
308            let (name, module_name, fields) = parse_object(pair);
309            SimpletonLiteral::Object {
310                name,
311                module_name,
312                fields,
313            }
314        }
315        rule => unreachable!("{:?}", rule),
316    }
317}
318
319fn parse_integer(pair: Pair<Rule>) -> Integer {
320    pair.as_str().parse::<Integer>().unwrap()
321}
322
323fn parse_hex(pair: Pair<Rule>) -> Integer {
324    Integer::from_str_radix(pair.as_str(), 16).unwrap()
325}
326
327fn parse_binary(pair: Pair<Rule>) -> Integer {
328    Integer::from_str_radix(pair.as_str(), 2).unwrap()
329}
330
331fn parse_real(pair: Pair<Rule>) -> Real {
332    pair.as_str().parse::<Real>().unwrap()
333}
334
335fn parse_text(pair: Pair<Rule>) -> Text {
336    snailquote::unescape(pair.as_str()).unwrap()
337}
338
339fn parse_array(pair: Pair<Rule>) -> Vec<SimpletonExpressionStart> {
340    pair.into_inner().map(parse_expression_start).collect()
341}
342
343fn parse_map(pair: Pair<Rule>) -> Vec<(String, SimpletonExpressionStart)> {
344    pair.into_inner()
345        .map(|pair| {
346            let mut pairs = pair.into_inner();
347            let key = parse_identifier(pairs.next().unwrap());
348            let value = if let Some(pair) = pairs.next() {
349                parse_expression_start(pair)
350            } else {
351                SimpletonExpressionStart::GetVariable {
352                    name: key.to_owned(),
353                    next: None,
354                }
355            };
356            (key, value)
357        })
358        .collect()
359}
360
361fn parse_object(pair: Pair<Rule>) -> (String, String, Vec<(String, SimpletonExpressionStart)>) {
362    let mut pairs = pair.into_inner();
363    let (name, module_name) = parse_path(pairs.next().unwrap());
364    let fields = pairs
365        .map(|pair| {
366            let mut pairs = pair.into_inner();
367            let key = parse_identifier(pairs.next().unwrap());
368            let value = if let Some(pair) = pairs.next() {
369                parse_expression_start(pair)
370            } else {
371                SimpletonExpressionStart::GetVariable {
372                    name: key.to_owned(),
373                    next: None,
374                }
375            };
376            (key, value)
377        })
378        .collect();
379    (name, module_name, fields)
380}
381
382fn parse_path(pair: Pair<Rule>) -> (String, String) {
383    let mut pairs = pair.into_inner();
384    let module_name = parse_identifier(pairs.next().unwrap());
385    let name = parse_identifier(pairs.next().unwrap());
386    (name, module_name)
387}
388
389fn parse_identifier(pair: Pair<Rule>) -> String {
390    pair.as_str().to_owned()
391}