interpreter/
parser.rs

1use std::collections::HashMap;
2
3use crate::error;
4
5#[derive(Debug)]
6pub struct ParsedTokenTree<'a> {
7  pub name: &'a str,
8  pub data: HashMap<&'a str, (&'a [&'a str], &'a [&'a [&'a str]])>,
9}
10
11pub fn parse_lead_module<'a>(lines: &'a [&'a [&'a str]]) -> Option<ParsedTokenTree<'a>> {
12  let mut name = "";
13  let mut data = HashMap::new();
14
15  let mut ctx = "";
16  let mut args: &'a [&'a str] = &[];
17
18  let mut start = usize::MAX;
19
20  for (index, tokens) in lines.iter().enumerate() {
21    let caller = tokens[0];
22
23    // Check for declarators if there's no `ctx`
24    if ctx == "" {
25      match caller {
26        "declare" => {
27          if name != "" {
28            error(
29              "Lead Language Module cannot have more than 1 module declaration",
30              ":fn",
31            );
32          }
33
34          name = tokens[1];
35        }
36        "fn" => {
37          ctx = tokens[1];
38          start = index + 1;
39
40          for t in &tokens[2..] {
41            if (!t.starts_with("->")) || (t.starts_with("->&")) {
42              error(
43                format!(
44                  "Arguments of module parameters can ONLY be of `move` type! {t} is not move!"
45                ),
46                ":fn",
47              );
48            }
49          }
50          args = &tokens[2..];
51        }
52        a => error(format!("Unknown `{a}`. No context was detected"), ":fn"),
53      }
54    } else {
55      if caller == "*end" {
56        if start == usize::MAX {
57          error("Something's not correct!!", ":fn");
58        }
59
60        // Upto the `*end` but not including `*end`
61        let code = &lines[start..index];
62
63        start = usize::MAX;
64
65        data.insert(ctx, (args, code));
66        ctx = "";
67      }
68    }
69  }
70
71  Some(ParsedTokenTree { name, data })
72}