1use std::cell::RefCell;
2use std::fmt::{Debug, Formatter};
3use std::rc::Rc;
4use log::{debug};
5use regex::Regex;
6use crate::context::Context;
7use crate::Errors::{FunctionNotFound, MemoryDefNotFound, TokenNotMatched};
8use crate::token::Token;
9
10pub mod context;
11pub mod token;
12#[cfg(test)]
13mod tests;
14
15#[macro_export]
23macro_rules! measure_time_debug {
24 ($expression:expr) => {{
25 use std::time::Instant;
26
27 let start = Instant::now();
28 let result = $expression; let duration = start.elapsed();
30
31 debug!("Run Time: {:?}", duration);
32
33 result }};
35}
36#[macro_export]
37macro_rules! measure_time {
38 ($expression:expr) => {{
39 use std::time::Instant;
40
41 let start = Instant::now();
42 let result = $expression; let duration = start.elapsed();
44
45 println!("Run Time: {:?}", duration);
46
47 result }};
49}
50
51
52lazy_static::lazy_static! {
53 static ref FUNC_REGEX: Regex = Regex::new(r"(.+)\((.+)\)").unwrap();
54}
55#[derive(Clone)]
65pub struct Program {
66 pub context: crate::context::Context,
67}
68impl Program {
69 pub fn new() -> Rc<RefCell<Self>> {
70 Rc::new(RefCell::new(Program { context: crate::context::Context::new() }))
71 }
72 pub fn new_from_context(context: crate::context::Context) -> Self {
73 Program { context }
74 }
75 pub fn exec(&mut self, token: &str) -> Result<Values, Errors> {
88
89 let token = token.trim();
90 let token = token.replace("\n", "");
91
92 debug!("[E] split token");
94 let split: Vec<String> = measure_time_debug!({token.to_owned().split_whitespace() .map(|s| s.to_string()) .collect()}); if self.context.keys.borrow().contains_key(&split[0]) {
99 debug!("[V] token is has key");
100 let content = token.replace(&split[0], "").trim().to_string();
101 debug!("[E] getting key function");
102 let func = measure_time_debug!({self.context.get_key(&split[0])});
103 return Ok(func(content, self));
104 }
105
106 debug!("[E] checking references");
108 if token.starts_with("$") {
109 debug!("[E] token is reference");
110 let name = token.replace("$", "").trim().to_string();
111 debug!("[E] getting memory value: {}", &name);
112 if !self.context.has_memory(&name) { return Err(MemoryDefNotFound(format!("\"{}\" not found", name))); }
113 return Ok(self.context.get_memory(&name));
114 }
115
116 debug!("[E] checking function");
118 debug!("[REGEX] Matching regex");
119 if measure_time_debug!({FUNC_REGEX.is_match(&token)}) {
120 debug!("[V] token is function");
121 debug!("[E] getting function infos");
122 let (name, args): (String, String) = if let Some(cap) = FUNC_REGEX.captures(&token) {
123 debug!("[V] getting name");
124 let name = measure_time_debug!({cap.get(1).map_or("", |m| m.as_str()).to_string()});
125 debug!("[E] getting args");
126 let args = measure_time_debug!({cap.get(2).map_or("", |m| m.as_str()).to_string()});
127 (name, args)
128 } else { ("".to_owned(), "".to_owned()) };
129 debug!("[INF] function data {} {}", name, args);
130 if !self.context.functions.borrow().contains_key(&name) { return Err(FunctionNotFound(format!("function call \"{}\" but function \"{}\" not found", token, &name))); }
131 let func = { self.context.get_function(&name) };
132
133 let mut pargs: Vec<Values> = Vec::new();
134
135 for arg in args.split(",") {
136 let res = self.exec(arg);
137 if res.is_err() {
138 return Err(res.err().unwrap())
139 } else {
140 pargs.push(res?);
141 }
142 }
143
144 return Ok((func)(pargs, self));
145 }
146
147 debug!("[E] other tokens definition");
149 debug!("[E] getting token definition index");
150 let index = measure_time_debug!({self.context.token_index(&token)});
151 debug!("[E] getting token");
152 if let None = index { return Err(Errors::TokenNotMatched(String::from(format!("token \"{}\" not matched with the registered token samples", token)))); }
153 let def_tok = measure_time_debug!({self.context.get_token(index.unwrap())});
154
155 debug!("[E] executing function");
156 let val = measure_time_debug!({def_tok.borrow().exec(&token, self).unwrap()});
157
158 Ok(val)
159 }
160 pub fn push_internal_token(&mut self, token: Box<dyn Token>) {
162 self.context.push_token(token);
163 }
164 pub fn push_internal_key(&mut self, key: &str, func: impl Fn(String, &mut Program) -> Values + 'static) {
166 self.context.push_key(key.to_owned(), func);
167 }
168 pub fn push_internal_memory(&mut self, key: &str, val: Values) {
170 self.context.push_memory(key, val);
171 }
172 pub fn push_internal_function(&mut self, name: &str, func: impl Fn(Vec<Values>, &mut Program) -> Values + 'static) {
174 self.context.push_function(name.to_owned(), func);
175 }
176 pub fn new_depth_context(&mut self) -> Rc<RefCell<Program>> {
177 let mut clone = self.clone();
178 clone.context.sub_context = Some(Box::new(Context::new()));
179
180 Rc::new(RefCell::new(clone))
181 }
182}
183#[derive(Clone)]
184pub enum Errors {
185 Non,
186 TokenNotMatched(String),
187 FunctionNotFound(String),
188 MemoryDefNotFound(String),
189}
190impl Errors {
191 pub fn to_str(&self) -> String {
192 let (name, message) = match self {
193 TokenNotMatched(msg) => ("ERRORS::TOKEN_NOT_FOUND", msg),
194 Errors::FunctionNotFound(msg) => ("ERRORS::FUNCTION_NOT_FOUND", msg),
195 MemoryDefNotFound(msg) => ("ERRORS::MEMORY_DEFINITION_NOT_FOUND", msg),
196 _ => { ("ERRORS::UNKNOWN", &"UNKNOWN ERROR".to_owned()) }
197 };
198 format!("ERROR PROCESSING: {} : {}", name, message)
199 }
200}
201impl Debug for Errors {
202 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
203 f.write_str(&*self.to_str())
204 }
205}
206#[derive(PartialEq, Clone)]
208pub enum Values {
209 String(String),
210 Number(f64),
211 Boolean(bool),
212 Array(Vec<Values>),
213 Null
214}
215impl Debug for Values {
216 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
217 match self {
218 Values::String(v) => write!(f, "{}", v),
219 Values::Number(v) => write!(f, "{}", v),
220 Values::Boolean(v) => write!(f, "{}", v),
221 Values::Array(v) => { write!(f, "[")?; v.fmt(f) },
222 _ => { write!(f, "null") }
223 }
224 }
225}