1#![allow(clippy::upper_case_acronyms)]
2
3#[macro_use]
4extern crate quick_error;
5extern crate pest;
6
7#[global_allocator]
8static GLOBAL: mimalloc::MiMalloc = mimalloc::MiMalloc;
9
10mod enums;
11mod error;
12mod expr;
13mod interpreter;
14mod namespace;
15mod table;
16
17pub use crate::enums::{Action, Block, Identifier, Identifiers, IfPart};
18pub use crate::error::Error;
19pub use crate::expr::{Expr, Op};
20pub use crate::interpreter::Interpreter;
21use crate::namespace::Namespace;
22use crate::table::Table;
23use pest_consume::{match_nodes, Error as PCError, Parser};
24use smartstring::alias::String;
25
26#[derive(Parser)]
27#[grammar = "psi.pest"]
28pub struct PsiParser;
29
30type Pesult<T> = std::result::Result<T, PCError<Rule>>;
31type Node<'i> = pest_consume::Node<'i, Rule, ()>;
32
33pub fn do_walk(node: Node) -> Result<Vec<Action>, Error> {
34 let instructions = PsiParser::stmts(node)?;
35 Ok(instructions)
36}
37
38pub fn do_parse(src: &str) -> Result<Node, Error> {
39 let parse = PsiParser::parse(Rule::stmts, src)?;
40 let input = parse.single()?;
41 Ok(input)
42}
43
44#[pest_consume::parser]
45impl PsiParser {
46 fn EOI(_input: Node) -> Pesult<()> {
47 Ok(())
48 }
49 fn positive(_input: Node) -> Pesult<()> {
50 Ok(())
51 }
52 fn negative(_input: Node) -> Pesult<()> {
53 Ok(())
54 }
55 fn equals(_input: Node) -> Pesult<()> {
56 Ok(())
57 }
58 fn not_equals(_input: Node) -> Pesult<()> {
59 Ok(())
60 }
61 fn greater(_input: Node) -> Pesult<()> {
62 Ok(())
63 }
64 fn less(_input: Node) -> Pesult<()> {
65 Ok(())
66 }
67 fn greater_eq(_input: Node) -> Pesult<()> {
68 Ok(())
69 }
70 fn less_eq(_input: Node) -> Pesult<()> {
71 Ok(())
72 }
73 fn and(_input: Node) -> Pesult<()> {
74 Ok(())
75 }
76 fn or(_input: Node) -> Pesult<()> {
77 Ok(())
78 }
79 fn continue_stmt(_input: Node) -> Pesult<()> {
80 Ok(())
81 }
82 fn break_stmt(_input: Node) -> Pesult<()> {
83 Ok(())
84 }
85
86 fn identifier_part(input: Node) -> Pesult<&str> {
87 Ok(input.as_str())
88 }
89
90 fn identifier(input: Node) -> Pesult<Expr> {
91 Ok(match_nodes!(input.into_children();
92 [identifier_part(part)..] => Expr::Identifier(part.map(|x| x.into()).collect()),
93 ))
94 }
95
96 fn boolean(input: Node) -> Pesult<Expr> {
97 let data = input.as_str().parse().map_err(|e| input.error(e));
98 Ok(Expr::Boolean(data?))
99 }
100
101 fn float(input: Node) -> Pesult<Expr> {
102 let data = input.as_str().parse().map_err(|e| input.error(e));
103 Ok(Expr::Float(data?))
104 }
105
106 fn integer(input: Node) -> Pesult<Expr> {
107 let data = input.as_str().parse().map_err(|e| input.error(e));
108 Ok(Expr::Integer(data?))
109 }
110
111 fn string_esc(input: Node) -> Pesult<&str> {
112 Ok(match_nodes!(input.into_children();
113 [string_brack] => "{",
114 [string_quote] => "\"",
115 ))
116 }
117
118 fn string_expr(input: Node) -> Pesult<Expr> {
119 Ok(match_nodes!(input.into_children();
120 [expr(e)] => e,
121 ))
122 }
123
124 fn string_char(input: Node) -> Pesult<&str> {
125 Ok(input.as_str())
126 }
127
128 fn string_part(input: Node) -> Pesult<Expr> {
129 Ok(match_nodes!(input.into_children();
130 [string_esc(e)] => Expr::StringRaw(e.into()),
131 [string_expr(e)] => e,
132 [string_char(c)] => Expr::StringRaw(c.into()),
133 ))
134 }
135
136 fn string(input: Node) -> Pesult<Expr> {
137 Ok(match_nodes!(input.into_children();
138 [string_part(parts)..] => Expr::StringFmt(parts.collect()),
139 ))
140 }
141
142 fn exclusive(input: Node) -> Pesult<Expr> {
143 Ok(match_nodes!(input.into_children();
144 [bound(start), bound(end)] => Expr::Exclusive(Box::new(start), Box::new(end)),
145 ))
146 }
147
148 fn inclusive(input: Node) -> Pesult<Expr> {
149 Ok(match_nodes!(input.into_children();
150 [bound(start), bound(end)] => Expr::Inclusive(Box::new(start), Box::new(end)),
151 ))
152 }
153
154 fn table_pair(input: Node) -> Pesult<(Expr, Expr)> {
155 Ok(match_nodes!(input.into_children();
156 [datatype(d), expr(e)] => (d, e),
157 ))
158 }
159
160 fn table(input: Node) -> Pesult<Expr> {
161 Ok(match_nodes!(input.into_children();
162 [table_pair(a)..] => Expr::Table(Table::new(a.collect())),
163 ))
164 }
165
166 fn array(input: Node) -> Pesult<Expr> {
167 Ok(match_nodes!(input.into_children();
168 [expr(a)..] => Expr::Array(a.collect()),
169 ))
170 }
171
172 fn bound(input: Node) -> Pesult<Expr> {
173 Ok(match_nodes!(input.into_children();
175 [expr(e)] => e,
176 [sign(s)] => s,
177 [integer(i)] => i,
178 [identifier(i)] => i,
179 ))
180 }
181
182 fn datatype(input: Node) -> Pesult<Expr> {
183 Ok(match_nodes!(input.into_children();
186 [boolean(e)] => e,
187 [array(d)] => d,
188 [table(s)] => s,
189 [inclusive(i)] => i,
190 [exclusive(e)] => e,
191 [float(f)] => f,
192 [integer(i)] => i,
193 [string(s)] => s,
194 ))
195 }
196
197 fn var_index(input: Node) -> Pesult<Expr> {
198 Ok(match_nodes!(input.into_children();
200 [atom(id)] => id,
201 [atom(id), expr(e)..] => Expr::VarIndex(Box::new(id), e.collect()),
202 ))
203 }
204
205 fn atom(input: Node) -> Pesult<Expr> {
206 Ok(match_nodes!(input.into_children();
208 [expr(e)] => e,
209 [datatype(d)] => d,
210 [sign(s)] => s,
211 [identifier(i)] => i,
212 ))
213 }
214
215 fn sign(input: Node) -> Pesult<Expr> {
216 Ok(match_nodes!(input.into_children();
218 [positive(_), float(f)] => f,
219 [positive(_), integer(i)] => i,
220 [positive(_), sign(s)] => s,
221 [negative(_), float(f)] =>
222 Expr::BinOp(Box::new(f), Op::Mul, Box::new(Expr::Integer(-1))),
223 [negative(_), integer(i)] =>
224 Expr::BinOp(Box::new(i), Op::Mul, Box::new(Expr::Integer(-1))),
225 [negative(_), sign(s)] =>
226 Expr::BinOp(Box::new(s), Op::Mul, Box::new(Expr::Integer(-1))),
227 ))
228 }
229
230 fn pow(input: Node) -> Pesult<Expr> {
231 Ok(match_nodes!(input.into_children();
233 [var_index(left)] => left,
234 [var_index(mut nums)..] => {
235 let mut result: Option<Expr> = None;
236 while let Some(p) = nums.next_back() {
237 if let Some(i) = result {
238 result = Some(Expr::BinOp(Box::new(p), Op::Pow, Box::new(i)));
239 } else {
240 result = Some(p);
241 }
242 }
243 result.unwrap()
244 }
245 ))
246 }
247
248 fn rem(input: Node) -> Pesult<Expr> {
249 Ok(match_nodes!(input.into_children();
251 [pow(left)] => left,
252 [pow(mut nums)..] => {
253 let mut result = None;
254 while let Some(p) = nums.next() {
255 if let Some(i) = result {
256 result = Some(Expr::BinOp(Box::new(i), Op::Rem, Box::new(p)));
257 } else {
258 result = Some(p);
259 }
260 }
261 result.unwrap()
262 }
263 ))
264 }
265
266 fn div(input: Node) -> Pesult<Expr> {
267 Ok(match_nodes!(input.into_children();
269 [rem(left)] => left,
270 [rem(mut nums)..] => {
271 let mut result = None;
272 while let Some(p) = nums.next() {
273 if let Some(i) = result {
274 result = Some(Expr::BinOp(Box::new(i), Op::Div, Box::new(p)));
275 } else {
276 result = Some(p);
277 }
278 }
279 result.unwrap()
280 }
281 ))
282 }
283
284 fn mul(input: Node) -> Pesult<Expr> {
285 Ok(match_nodes!(input.into_children();
287 [div(left)] => left,
288 [div(mut nums)..] => {
289 let mut result = None;
290 while let Some(p) = nums.next() {
291 if let Some(i) = result {
292 result = Some(Expr::BinOp(Box::new(i), Op::Mul, Box::new(p)));
293 } else {
294 result = Some(p);
295 }
296 }
297 result.unwrap()
298 }
299 ))
300 }
301
302 fn add(input: Node) -> Pesult<Expr> {
303 Ok(match_nodes!(input.into_children();
305 [mul(left)] => left,
306 [mul(mut nums)..] => {
307 let mut result = None;
308 while let Some(p) = nums.next() {
309 if let Some(i) = result {
310 result = Some(Expr::BinOp(Box::new(i), Op::Add, Box::new(p)));
311 } else {
312 result = Some(p);
313 }
314 }
315 result.unwrap()
316 }
317 ))
318 }
319
320 fn sub(input: Node) -> Pesult<Expr> {
321 Ok(match_nodes!(input.into_children();
323 [add(left)] => left,
324 [add(mut nums)..] => {
325 let mut result = None;
326 while let Some(p) = nums.next() {
327 if let Some(i) = result {
328 result = Some(Expr::BinOp(Box::new(i), Op::Sub, Box::new(p)));
329 } else {
330 result = Some(p);
331 }
332 }
333 result.unwrap()
334 }
335 ))
336 }
337
338 fn ss_add(input: Node) -> Pesult<Action> {
339 Ok(match_nodes!(input.into_children();
340 [identifier(i), expr(e)] => Action::SingleShot(i, Op::Add, e)
341 ))
342 }
343
344 fn ss_sub(input: Node) -> Pesult<Action> {
345 Ok(match_nodes!(input.into_children();
346 [identifier(i), expr(e)] => Action::SingleShot(i, Op::Sub, e)
347 ))
348 }
349
350 fn ss_mul(input: Node) -> Pesult<Action> {
351 Ok(match_nodes!(input.into_children();
352 [identifier(i), expr(e)] => Action::SingleShot(i, Op::Mul, e)
353 ))
354 }
355
356 fn ss_div(input: Node) -> Pesult<Action> {
357 Ok(match_nodes!(input.into_children();
358 [identifier(i), expr(e)] => Action::SingleShot(i, Op::Div, e)
359 ))
360 }
361
362 fn ss_rem(input: Node) -> Pesult<Action> {
363 Ok(match_nodes!(input.into_children();
364 [identifier(i), expr(e)] => Action::SingleShot(i, Op::Rem, e)
365 ))
366 }
367
368 fn ss_pow(input: Node) -> Pesult<Action> {
369 Ok(match_nodes!(input.into_children();
370 [identifier(i), expr(e)] => Action::SingleShot(i, Op::Pow, e)
371 ))
372 }
373
374 fn single_shot(input: Node) -> Pesult<Action> {
375 Ok(match_nodes!(input.into_children();
376 [ss_add(e)] => e,
377 [ss_sub(e)] => e,
378 [ss_mul(e)] => e,
379 [ss_div(e)] => e,
380 [ss_rem(e)] => e,
381 [ss_pow(e)] => e,
382 ))
383 }
384
385 fn comp(input: Node) -> Pesult<Expr> {
386 Ok(match_nodes!(input.into_children();
388 [sub(left)] => left,
389 [sub(left), greater_eq(_), sub(right)] =>
390 Expr::BinOp(Box::new(left), Op::GreaterEq, Box::new(right)),
391 [sub(left), less_eq(_), sub(right)] =>
392 Expr::BinOp(Box::new(left), Op::LessEq, Box::new(right)),
393 [sub(left), greater(_), sub(right)] =>
394 Expr::BinOp(Box::new(left), Op::Greater, Box::new(right)),
395 [sub(left), less(_), sub(right)] =>
396 Expr::BinOp(Box::new(left), Op::Less, Box::new(right)),
397 ))
398 }
399
400 fn eq(input: Node) -> Pesult<Expr> {
401 Ok(match_nodes!(input.into_children();
403 [comp(left)] => left,
404 [comp(left), equals(_), comp(right)] =>
405 Expr::BinOp(Box::new(left), Op::Equals, Box::new(right)),
406 [comp(left), not_equals(_), comp(right)] =>
407 Expr::BinOp(Box::new(left), Op::NotEquals, Box::new(right)),
408 ))
409 }
410
411 fn comb(input: Node) -> Pesult<Expr> {
412 Ok(match_nodes!(input.into_children();
414 [eq(left)] => left,
415 [eq(left), and(_), eq(right)] =>
416 Expr::BinOp(Box::new(left), Op::And, Box::new(right)),
417 [eq(left), or(_), eq(right)] =>
418 Expr::BinOp(Box::new(left), Op::Or, Box::new(right)),
419 ))
420 }
421
422 fn not(input: Node) -> Pesult<Expr> {
423 Ok(match_nodes!(input.into_children();
424 [expr(e)] => Expr::Not(Box::new(e)),
425 ))
426 }
427
428 fn iterable(input: Node) -> Pesult<Expr> {
429 Ok(match_nodes!(input.into_children();
431 [array(a)] => a,
432 [table(t)] => t,
433 [var_index(v)] => v,
434 [inclusive(i)] => i,
435 [exclusive(e)] => e,
436 [identifier(i)] => i,
437 ))
438 }
439
440 fn contains(input: Node) -> Pesult<Expr> {
441 Ok(match_nodes!(input.into_children();
442 [atom(a), iterable(i)] => Expr::BinOp(Box::new(a), Op::In, Box::new(i)),
443 ))
444 }
445
446 fn expr(input: Node) -> Pesult<Expr> {
447 Ok(match_nodes!(input.into_children();
448 [integer(int)] => int,
449 [comb(com)] => com,
450 [not(no)] => no,
451 [contains(con)] => con,
452 [fn_call(call)] => call.to_expr(),
453 ))
454 }
455
456 fn comment(input: Node) -> Pesult<Action> {
457 Ok(Action::Comment(input.as_str().into()))
458 }
459
460 fn fn_call(input: Node) -> Pesult<Action> {
461 Ok(match_nodes!(input.into_children();
462 [identifier(i), expr(e)..] => Action::FnCall(i, e.collect()),
463 ))
464 }
465
466 fn var_assign(input: Node) -> Pesult<Action> {
467 Ok(match_nodes!(input.into_children();
468 [identifier(id), expr(exp)] => Action::VarAssign(id, exp),
469 ))
470 }
471
472 fn block(input: Node) -> Pesult<Vec<Action>> {
473 Ok(match_nodes!(input.into_children();
474 [stmt(s)..] => s.collect(),
475 ))
476 }
477
478 fn if_stmt(input: Node) -> Pesult<IfPart> {
479 Ok(match_nodes!(input.into_children();
480 [expr(e), block(b)] => IfPart::If(e, b),
481 ))
482 }
483
484 fn else_if_stmt(input: Node) -> Pesult<IfPart> {
485 Ok(match_nodes!(input.into_children();
486 [expr(e), block(b)] => IfPart::IfElse(e, b),
487 ))
488 }
489
490 fn else_stmt(input: Node) -> Pesult<IfPart> {
491 Ok(match_nodes!(input.into_children();
492 [block(b)] => IfPart::Else(b),
493 ))
494 }
495
496 fn ifs(input: Node) -> Pesult<Action> {
497 Ok(match_nodes!(input.into_children();
498 [if_stmt(first)] => Action::If(vec![first]),
499 [if_stmt(first), else_if_stmt(second)..] => {
500 let mut result = vec![first];
501 result.extend(second);
502 Action::If(result)
503 },
504 [if_stmt(first), else_if_stmt(second).., else_stmt(third)] => {
505 let mut result = vec![first];
506 result.extend(second);
507 result.push(third);
508 Action::If(result)
509 },
510 [if_stmt(first), else_stmt(third)] => Action::If(vec![first, third]),
511 ))
512 }
513
514 fn args(input: Node) -> Pesult<Vec<String>> {
515 Ok(match_nodes!(input.into_children();
516 [identifier_part(i)..] => i.map(|x| x.into()).collect(),
517 ))
518 }
519
520 fn fn_def(input: Node) -> Pesult<Action> {
521 Ok(match_nodes!(input.into_children();
522 [identifier(i), args(a), block(b)] => Action::FnDef(i, a, b),
523 ))
524 }
525
526 fn return_stmt(input: Node) -> Pesult<Action> {
527 Ok(match_nodes!(input.into_children();
528 [return_expr(e)] => Action::Return(e),
529 ))
530 }
531
532 fn return_expr(input: Node) -> Pesult<Option<Expr>> {
533 Ok(match_nodes!(input.into_children();
534 [expr(e)] => Some(e),
535 [] => None,
536 ))
537 }
538
539 fn for_stmt(input: Node) -> Pesult<Action> {
540 Ok(match_nodes!(input.into_children();
541 [args(a), iterable(i), block(b)] => Action::For(a, i, b),
542 ))
543 }
544
545 fn loop_stmt(input: Node) -> Pesult<Action> {
546 Ok(match_nodes!(input.into_children();
547 [block(b)] => Action::Loop(b),
548 ))
549 }
550
551 fn while_stmt(input: Node) -> Pesult<Action> {
552 Ok(match_nodes!(input.into_children();
553 [expr(c), block(b)] => Action::While(c, b),
554 ))
555 }
556
557 fn loop_control(input: Node) -> Pesult<Action> {
558 Ok(match_nodes!(input.into_children();
559 [break_stmt(_)] => Action::Break,
560 [continue_stmt(_)] => Action::Continue,
561 ))
562 }
563
564 fn import_stmt(input: Node) -> Pesult<Action> {
565 Ok(match_nodes!(input.into_children();
566 [identifier(from), identifier(into)] =>
567 Action::Import(from, Some(into)),
568 [identifier(from)] => Action::Import(from, None),
569 ))
570 }
571
572 fn stmt(input: Node) -> Pesult<Action> {
573 Ok(match_nodes!(input.into_children();
574 [var_assign(var)] => var,
575 [comment(com)] => com,
576 [fn_call(call)] => call,
577 [fn_def(def)] => def,
578 [return_stmt(ret)] => ret,
579 [ifs(if_s)] => if_s,
580 [for_stmt(for_s)] => for_s,
581 [loop_stmt(loop_s)] => loop_s,
582 [while_stmt(loop_s)] => loop_s,
583 [single_shot(ss)] => ss,
584 [loop_control(lc)] => lc,
585 [import_stmt(imp)] => imp,
586 ))
587 }
588
589 pub fn stmts(input: Node) -> Pesult<Vec<Action>> {
590 Ok(match_nodes!(input.into_children();
591 [stmt(act).., _] => act.collect(),
592 ))
593 }
594}