Skip to main content

typr_core/utils/
fluent_parser.rs

1#![allow(
2    dead_code,
3    unused_variables,
4    unused_imports,
5    unreachable_code,
6    unused_assignments
7)]
8use crate::components::context::Context;
9use crate::components::language::var::Var;
10use crate::components::language::Lang;
11use crate::components::r#type::type_system::TypeSystem;
12use crate::components::r#type::Type;
13use crate::processes::parsing::parse2;
14use crate::processes::transpiling::translatable::RTranslatable;
15use crate::processes::type_checking::typing;
16use crate::utils::builder;
17use rpds::Vector;
18
19#[derive(Debug, Clone)]
20pub struct FluentParser {
21    raw_code: Vector<String>,
22    code: Vector<Lang>,
23    new_code: Vector<Lang>,
24    r_code: Vector<String>,
25    logs: Vector<String>,
26    pub context: Context,
27    last_type: Type,
28    pub saved_r: Vector<String>,
29}
30
31impl FluentParser {
32    pub fn new() -> Self {
33        FluentParser {
34            raw_code: Vector::new(),
35            code: Vector::new(),
36            new_code: Vector::new(),
37            r_code: Vector::new(),
38            logs: Vector::new(),
39            context: Context::empty(),
40            last_type: builder::empty_type(),
41            saved_r: Vector::new(),
42        }
43    }
44
45    pub fn push(self, code: &str) -> Self {
46        Self {
47            raw_code: self.raw_code.push_back(code.to_string()),
48            ..self
49        }
50    }
51
52    pub fn push_log(self, log: &str) -> Self {
53        Self {
54            logs: self.logs.push_back(log.to_string()),
55            ..self
56        }
57    }
58
59    pub fn push_code(self, code: Lang) -> Self {
60        Self {
61            code: self.code.push_back(code),
62            ..self
63        }
64    }
65
66    fn drop_first_raw(self) -> Self {
67        Self {
68            raw_code: self.raw_code.iter().skip(1).cloned().collect(),
69            ..self
70        }
71    }
72
73    fn next_raw_code(self) -> Option<(String, Self)> {
74        match self.clone().raw_code.first() {
75            Some(val) => Some((val.clone(), self.drop_first_raw())),
76            _ => None,
77        }
78    }
79
80    /// Go from raw_code (String) to code (Lang)
81    pub fn parse_next(self) -> Self {
82        match self.clone().next_raw_code() {
83            Some((line, rest)) => match parse2((&line[..]).into()) {
84                Ok(code) => rest.push_code(code),
85                Err(msg) => rest.push_log(&msg),
86            },
87            _ => self.push_log("No more raw line left"),
88        }
89    }
90
91    pub fn clean_raw_code(self) -> Self {
92        Self {
93            raw_code: Vector::new(),
94            ..self
95        }
96    }
97
98    pub fn parse_all_lines(self) -> Self {
99        self.clone()
100            .raw_code
101            .iter()
102            .fold(self, |acc, x| match parse2(x[..].into()) {
103                Ok(code) => acc.push_code(code),
104                Err(msg) => acc.push_log(&msg),
105            })
106            .clean_raw_code()
107    }
108
109    fn drop_first_code(self) -> Self {
110        Self {
111            code: self.code.iter().skip(1).cloned().collect(),
112            ..self
113        }
114    }
115
116    pub fn next_code(self) -> Option<(Lang, Self)> {
117        match self.code.first() {
118            Some(lang) => Some((lang.clone(), self.drop_first_code())),
119            _ => None,
120        }
121    }
122
123    pub fn set_context(self, context: Context) -> Self {
124        Self { context, ..self }
125    }
126
127    fn set_last_type(self, typ: Type) -> Self {
128        Self {
129            last_type: typ,
130            ..self
131        }
132    }
133
134    pub fn push_new_code(self, code: Lang) -> Self {
135        Self {
136            new_code: self.new_code.push_back(code),
137            ..self
138        }
139    }
140
141    /// Typing from code (Lang) to new code (Lang)
142    pub fn type_next(self) -> Self {
143        match self.clone().next_code() {
144            Some((code, rest)) => {
145                let (typ, lang, new_context) = typing(&self.context, &code).to_tuple();
146                rest.set_context(new_context)
147                    .push_new_code(lang)
148                    .set_last_type(typ)
149            }
150            _ => self.push_log("No more Lang code left"),
151        }
152    }
153
154    pub fn type_all(self) -> Self {
155        let (new_context, new_type) = self.clone().code.iter().fold(
156            (self.clone().context, builder::empty_type()),
157            |(cont, typ), x| {
158                let (new_type, _, new_cont) = typing(&cont, x).to_tuple();
159                (new_cont, new_type)
160            },
161        );
162        self.set_context(new_context).set_last_type(new_type)
163    }
164
165    /// Parsing from raw code (String) to new code (Lang)
166    pub fn parse_type_next(self) -> Self {
167        self.parse_next().type_next()
168    }
169
170    pub fn parse_type_all(self) -> Self {
171        self.parse_all_lines().type_all()
172    }
173
174    pub fn type_of(&self, symbol: &str) -> Vec<Type> {
175        let var = Var::from_name(symbol);
176        vec![self.context.get_type_from_existing_variable(var)]
177    }
178
179    pub fn view_logs(&self) -> String {
180        self.logs.iter().cloned().collect::<Vec<_>>().join("\n")
181    }
182
183    pub fn get_code(self) -> Vector<Lang> {
184        self.code
185    }
186
187    pub fn get_new_code(self) -> Vector<Lang> {
188        self.new_code
189    }
190
191    pub fn get_r_code(self) -> Vector<String> {
192        self.r_code
193    }
194
195    pub fn get_log(&self, id: i32) -> String {
196        let id = id as usize;
197        if self.logs.len() > id {
198            self.logs[id].clone()
199        } else {
200            format!("There aren't any log at index {}", id)
201        }
202    }
203
204    pub fn get_last_log(&self) -> String {
205        if self.logs.len() > 0_usize {
206            self.logs.iter().rev().next().unwrap().clone()
207        } else {
208            "The logs are empty".to_string()
209        }
210    }
211
212    pub fn get_last_type(&self) -> Type {
213        self.last_type.clone()
214    }
215
216    fn drop_first_new_code(self) -> Self {
217        Self {
218            new_code: self.new_code.iter().skip(1).cloned().collect(),
219            ..self
220        }
221    }
222
223    pub fn next_new_code(self) -> Option<(Lang, Self)> {
224        match self.new_code.first() {
225            Some(lang) => Some((lang.clone(), self.drop_first_new_code())),
226            _ => None,
227        }
228    }
229
230    pub fn push_r_code(self, r_code: String) -> Self {
231        Self {
232            r_code: self.r_code.push_back(r_code),
233            ..self
234        }
235    }
236
237    fn save_r_code(self, r_code: &str) -> Self {
238        Self {
239            saved_r: self.saved_r.push_back(r_code.to_string()),
240            ..self
241        }
242    }
243
244    pub fn get_saved_r_code(&self) -> String {
245        self.saved_r
246            .iter()
247            .cloned()
248            .reduce(|acc, x| format!("{}\n{}", acc, &x))
249            .unwrap_or("".to_string())
250    }
251
252    fn get_let_definitions(v: Vector<Lang>, context: &Context) -> Vec<String> {
253        v.iter()
254            .filter(|x| x.save_in_memory())
255            .map(|x| x.to_r(context).0)
256            .collect()
257    }
258
259    pub fn transpile_next(self) -> Self {
260        match self.clone().next_new_code() {
261            Some((code, rest)) => {
262                let (r_code, new_context) = code.to_r(&self.context);
263                let res = rest.set_context(new_context).push_r_code(r_code);
264                Self::get_let_definitions(self.new_code, &self.context)
265                    .iter()
266                    .fold(res, |acc, x| acc.save_r_code(x))
267            }
268            _ => self.push_log("No more Lang code left"),
269        }
270    }
271
272    /// from raw code (String) to r code (String)
273    /// Do the same as .run() methode
274    pub fn parse_type_transpile_next(self) -> Self {
275        self.parse_next().type_next().transpile_next()
276    }
277
278    /// from raw code (String) to r code (String)
279    /// Call parse_type_transpile_next
280    pub fn run(self) -> Self {
281        self.parse_type_transpile_next()
282    }
283
284    fn drop_first_r_code(self) -> Self {
285        Self {
286            r_code: self.r_code.iter().skip(1).cloned().collect(),
287            ..self
288        }
289    }
290
291    pub fn next_r_code(self) -> Option<(String, Self)> {
292        match self.r_code.first() {
293            Some(lang) => Some((lang.clone(), self.drop_first_r_code())),
294            _ => None,
295        }
296    }
297
298    pub fn display_context(&self) -> String {
299        self.context.display_typing_context()
300    }
301
302    pub fn get_context(self) -> Context {
303        self.context
304    }
305
306    pub fn check_parsing(self, s: &str) -> Vector<Lang> {
307        self.push(s).parse_next().get_code()
308    }
309
310    pub fn check_typing(self, s: &str) -> Type {
311        self.push(s).parse_type_next().get_last_type()
312    }
313
314    pub fn check_transpiling(self, s: &str) -> Vector<String> {
315        self.push(s).parse_type_transpile_next().get_r_code()
316    }
317}
318
319use std::fmt;
320impl fmt::Display for FluentParser {
321    fn fmt(self: &Self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
322        let res = format!(
323            "raw_code: {}\ncode: {}\nnew_code: {}\nr_code: {}\nlast_type: {}",
324            self.raw_code
325                .iter()
326                .cloned()
327                .collect::<Vec<_>>()
328                .join(" | "),
329            self.code
330                .iter()
331                .map(|x| x.simple_print())
332                .collect::<Vec<_>>()
333                .join(" | "),
334            self.new_code
335                .iter()
336                .map(|x| x.simple_print())
337                .collect::<Vec<_>>()
338                .join(" | "),
339            self.r_code.iter().cloned().collect::<Vec<_>>().join(" | "),
340            self.last_type.pretty()
341        );
342        write!(f, "{}", res)
343    }
344}
345
346#[cfg(test)]
347mod tests {
348    use super::*;
349
350    #[test]
351    fn test_fluent_parser0() {
352        let typ = FluentParser::new()
353            .push("8")
354            .parse_type_next()
355            .get_last_type();
356        assert_eq!(typ, builder::integer_type(8))
357    }
358
359    #[test]
360    fn test_fluent_parser1() {
361        let typ = FluentParser::new()
362            .push("let df <- 8;")
363            .parse_type_next()
364            .push("9")
365            .parse_type_next()
366            .get_last_type();
367        assert_eq!(typ, builder::integer_type(8))
368    }
369
370    #[test]
371    fn test_fluent_transpiler1() {
372        let fp = FluentParser::new().push("8").run();
373        assert_eq!(fp.next_r_code().unwrap().0, "8L |> Integer()")
374    }
375}