Skip to main content

whiledb/
lib.rs

1mod lexer;
2pub mod ast;
3mod grammar;
4mod src_error;
5pub mod interpreter;
6
7use ast::Cmd;
8pub use src_error::SrcError;
9use src_error::{lexer_error_msg, parse_error_msg};
10
11pub fn parse(input: &str) -> Result<Cmd, SrcError<Cmd>> {
12    let lexer_rules = lexer::lexer_rules();
13    let lexemes = match santiago::lexer::lex(&lexer_rules, input) {
14        Ok(lexemes) => lexemes,
15        Err(err) => {
16            let msg = lexer_error_msg(input, &err);
17            return Err(SrcError::LexerError(err, msg));
18        },
19    };
20
21    let grammar = grammar::grammar();
22    let parse_trees = match santiago::parser::parse(&grammar, &lexemes) {
23        Ok(parse_trees) => parse_trees,
24        Err(err) => {
25            let msg = parse_error_msg(input, &err);
26            return Err(SrcError::ParseError(err, msg));
27        },
28    };
29    let mut asts = parse_trees.into_iter().map(|e| e.as_abstract_syntax_tree()).collect::<Vec<_>>();
30    match asts.len() {
31        0 => Err(SrcError::SelfError("No any possible Parse Tree. Incorrect parse rules.".to_string())),
32        1 => Ok(asts.pop().unwrap()),
33        _ => {
34            use colored::Colorize;
35            let n = asts.len();
36            eprintln!("{}", format!("{:?}", asts).bright_yellow());
37            Err(SrcError::SelfWarning(asts.pop().unwrap(), format!("Exists {n} possible Parse Tree. Ambiguous parse rules.")))
38        }
39    }
40}
41
42
43#[cfg(test)]
44mod tests {
45    use std::rc::Rc;
46
47    use crate::{parse, interpreter::{self, init_state}};
48    #[test]
49    fn sample_src() {
50        match parse(include_str!("../tests/sample_src.wd")) {
51            Ok(res) => println!("{:?}", res),
52            Err(err) => panic!("{}", err)
53        }
54    }
55    #[test]
56    fn test() {
57        match parse(include_str!("../tests/test.wd")) {
58            Ok(res) => println!("{:?}", res),
59            Err(err) => panic!("{}", err)
60        }
61    }
62    #[test]
63    fn test2() {
64        match parse(include_str!("../tests/test2.wd")) {
65            Ok(res) => {
66                let state = init_state().unwrap();
67                interpreter::exec(Rc::new(res), interpreter::utils::local_state(state.clone())).unwrap();
68            },
69            Err(err) => panic!("{}", err)
70        }
71    }
72}