intuicio_frontend_simpleton/
parser.rs1use 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}