templo_engine/
parser.rs

1use std::vec;
2
3use regex::Regex;
4
5use crate::{
6    function_call::get_fn_obj,
7    syntax_tree::{SyntaxTree, TreeType, TreeValueType},
8    token::{Token, TokenType},
9    EngineArg, EngineArgType,
10};
11
12#[derive(Debug)]
13struct FnArg {
14    layer: usize,
15    args: usize,
16}
17
18pub fn parse(tokens: Vec<Token>, inputs: &Vec<EngineArg>) -> SyntaxTree {
19    if tokens[0].type_ == TokenType::Input {
20        parse_input_exp(&tokens[0], inputs)
21    } else {
22        parse_fn_exp(tokens, inputs)
23    }
24}
25
26pub fn parse_input_exp(token: &Token, inputs: &Vec<EngineArg>) -> SyntaxTree {
27    let input_value = inputs.iter().find(|input| input.key == token.value);
28    if input_value.is_none() && inputs.len() > 0 {
29        panic!("{}", format!("Input '{}' is not informed.", token.value));
30    }
31    SyntaxTree {
32        childs: vec![],
33        node: input_value.unwrap().value.clone(),
34        tree_type: TreeType::Input,
35        tree_val_type: TreeValueType::String,
36    }
37}
38
39pub fn parse_fn_exp(tokens: Vec<Token>, inputs: &Vec<EngineArg>) -> SyntaxTree {
40    let tokens = tokens[..tokens.len() - 1].to_vec();
41    let mut tokens_iter = tokens.iter();
42    let mut tree = SyntaxTree::new(
43        tokens_iter.next().unwrap().value.clone(),
44        TreeType::FunctionCall,
45        vec![],
46        TreeValueType::String,
47    );
48
49    let mut layer = 0;
50    let mut layer_args: Vec<FnArg> = vec![FnArg { layer: 0, args: 0 }];
51
52    for token in tokens_iter.rev() {
53        if token.type_ == TokenType::Function {
54            let args = layer_args[layer].args;
55            let range = (tree.childs.len() - args)..;
56            let mut args: Vec<SyntaxTree> = tree.get_childs(range);
57            args.reverse();
58
59            let fn_obj = get_fn_obj(&token.value);
60            let fun = SyntaxTree::new(
61                token.value.clone(),
62                TreeType::FunctionCall,
63                args,
64                fn_obj.return_type(),
65            );
66
67            tree.append_child(fun);
68            layer -= 1;
69            layer_args[layer].args += 1;
70        }
71
72        if token.type_ == TokenType::Input {
73            let input_value = inputs.into_iter().find(|input| input.key == token.value);
74
75            if input_value.is_none() && inputs.len() > 0 {
76                panic!("{}", format!("Input '{}' is not informed.", token.value));
77            }
78
79            let input_value = input_value.unwrap();
80
81            let input_type = match input_value.value_type {
82                EngineArgType::String => TreeValueType::String,
83                EngineArgType::Integer => TreeValueType::Integer,
84            };
85
86            let input = SyntaxTree::new(
87                input_value.value.clone(),
88                TreeType::Input,
89                vec![],
90                input_type,
91            );
92            tree.append_child(input);
93            layer_args[layer].args += 1;
94        }
95
96        if token.type_ == TokenType::Integer {
97            let input = SyntaxTree::new(
98                token.value.clone(),
99                TreeType::Input,
100                vec![],
101                TreeValueType::Integer,
102            );
103            tree.append_child(input);
104            layer_args[layer].args += 1;
105        }
106
107        if token.type_ == TokenType::String {
108            let value = &token.value[1..token.value.len() - 1];
109            let middle_quotes_reg = Regex::new(r"\\'").unwrap();
110            let real_string_value = middle_quotes_reg.replace_all(value, "'");
111
112            let input = SyntaxTree::new(
113                real_string_value.to_string(),
114                TreeType::Input,
115                vec![],
116                TreeValueType::String,
117            );
118
119            tree.append_child(input);
120            layer_args[layer].args += 1;
121        }
122
123        if token.type_ == TokenType::BracketRight {
124            layer += 1;
125
126            if layer_args.get(layer).is_none() {
127                layer_args.push(FnArg { args: 0, layer })
128            } else {
129                layer_args[layer] = FnArg { args: 0, layer }
130            }
131        }
132    }
133
134    tree.childs.reverse();
135    tree
136}