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
46impl Default for FluentParser {
47    fn default() -> Self {
48        Self::new()
49    }
50}
51
52impl FluentParser {
53    pub fn push(self, code: &str) -> Self {
54        Self {
55            raw_code: self.raw_code.push_back(code.to_string()),
56            ..self
57        }
58    }
59
60    pub fn push_log(self, log: &str) -> Self {
61        Self {
62            logs: self.logs.push_back(log.to_string()),
63            ..self
64        }
65    }
66
67    pub fn push_code(self, code: Lang) -> Self {
68        Self {
69            code: self.code.push_back(code),
70            ..self
71        }
72    }
73
74    fn drop_first_raw(self) -> Self {
75        Self {
76            raw_code: self.raw_code.iter().skip(1).cloned().collect(),
77            ..self
78        }
79    }
80
81    fn next_raw_code(self) -> Option<(String, Self)> {
82        let val = self.clone().raw_code.first()?.clone();
83        Some((val, self.drop_first_raw()))
84    }
85
86    /// Go from raw_code (String) to code (Lang)
87    pub fn parse_next(self) -> Self {
88        match self.clone().next_raw_code() {
89            Some((line, rest)) => match parse2((&line[..]).into()) {
90                Ok(code) => rest.push_code(code),
91                Err(msg) => rest.push_log(&msg),
92            },
93            _ => self.push_log("No more raw line left"),
94        }
95    }
96
97    pub fn clean_raw_code(self) -> Self {
98        Self {
99            raw_code: Vector::new(),
100            ..self
101        }
102    }
103
104    pub fn parse_all_lines(self) -> Self {
105        self.clone()
106            .raw_code
107            .iter()
108            .fold(self, |acc, x| match parse2(x[..].into()) {
109                Ok(code) => acc.push_code(code),
110                Err(msg) => acc.push_log(&msg),
111            })
112            .clean_raw_code()
113    }
114
115    fn drop_first_code(self) -> Self {
116        Self {
117            code: self.code.iter().skip(1).cloned().collect(),
118            ..self
119        }
120    }
121
122    pub fn next_code(self) -> Option<(Lang, Self)> {
123        let lang = self.code.first()?.clone();
124        Some((lang, self.drop_first_code()))
125    }
126
127    pub fn set_context(self, context: Context) -> Self {
128        Self { context, ..self }
129    }
130
131    fn set_last_type(self, typ: Type) -> Self {
132        Self {
133            last_type: typ,
134            ..self
135        }
136    }
137
138    pub fn push_new_code(self, code: Lang) -> Self {
139        Self {
140            new_code: self.new_code.push_back(code),
141            ..self
142        }
143    }
144
145    /// Typing from code (Lang) to new code (Lang)
146    pub fn type_next(self) -> Self {
147        match self.clone().next_code() {
148            Some((code, rest)) => {
149                let (typ, lang, new_context) = typing(&self.context, &code).to_tuple();
150                rest.set_context(new_context)
151                    .push_new_code(lang)
152                    .set_last_type(typ)
153            }
154            _ => self.push_log("No more Lang code left"),
155        }
156    }
157
158    pub fn type_all(self) -> Self {
159        let (new_context, new_type) = self.clone().code.iter().fold(
160            (self.clone().context, builder::empty_type()),
161            |(cont, typ), x| {
162                let (new_type, _, new_cont) = typing(&cont, x).to_tuple();
163                (new_cont, new_type)
164            },
165        );
166        self.set_context(new_context).set_last_type(new_type)
167    }
168
169    /// Parsing from raw code (String) to new code (Lang)
170    pub fn parse_type_next(self) -> Self {
171        self.parse_next().type_next()
172    }
173
174    pub fn parse_type_all(self) -> Self {
175        self.parse_all_lines().type_all()
176    }
177
178    pub fn type_of(&self, symbol: &str) -> Vec<Type> {
179        let var = Var::from_name(symbol);
180        vec![self.context.get_type_from_existing_variable(var)]
181    }
182
183    pub fn view_logs(&self) -> String {
184        self.logs.iter().cloned().collect::<Vec<_>>().join("\n")
185    }
186
187    pub fn get_code(self) -> Vector<Lang> {
188        self.code
189    }
190
191    pub fn get_new_code(self) -> Vector<Lang> {
192        self.new_code
193    }
194
195    pub fn get_r_code(self) -> Vector<String> {
196        self.r_code
197    }
198
199    pub fn get_log(&self, id: i32) -> String {
200        let id = id as usize;
201        if self.logs.len() > id {
202            self.logs[id].clone()
203        } else {
204            format!("There aren't any log at index {}", id)
205        }
206    }
207
208    pub fn get_last_log(&self) -> String {
209        if !self.logs.is_empty() {
210            self.logs.iter().next_back().unwrap().clone()
211        } else {
212            "The logs are empty".to_string()
213        }
214    }
215
216    pub fn get_last_type(&self) -> Type {
217        self.last_type.clone()
218    }
219
220    fn drop_first_new_code(self) -> Self {
221        Self {
222            new_code: self.new_code.iter().skip(1).cloned().collect(),
223            ..self
224        }
225    }
226
227    pub fn next_new_code(self) -> Option<(Lang, Self)> {
228        let lang = self.new_code.first()?.clone();
229        Some((lang, self.drop_first_new_code()))
230    }
231
232    pub fn push_r_code(self, r_code: String) -> Self {
233        Self {
234            r_code: self.r_code.push_back(r_code),
235            ..self
236        }
237    }
238
239    fn save_r_code(self, r_code: &str) -> Self {
240        Self {
241            saved_r: self.saved_r.push_back(r_code.to_string()),
242            ..self
243        }
244    }
245
246    pub fn get_saved_r_code(&self) -> String {
247        self.saved_r
248            .iter()
249            .cloned()
250            .reduce(|acc, x| format!("{}\n{}", acc, &x))
251            .unwrap_or("".to_string())
252    }
253
254    fn get_let_definitions(v: Vector<Lang>, context: &Context) -> Vec<String> {
255        v.iter()
256            .filter(|x| x.save_in_memory())
257            .map(|x| x.to_r(context).0)
258            .collect()
259    }
260
261    pub fn transpile_next(self) -> Self {
262        match self.clone().next_new_code() {
263            Some((code, rest)) => {
264                let (r_code, new_context) = code.to_r(&self.context);
265                let res = rest.set_context(new_context).push_r_code(r_code);
266                Self::get_let_definitions(self.new_code, &self.context)
267                    .iter()
268                    .fold(res, |acc, x| acc.save_r_code(x))
269            }
270            _ => self.push_log("No more Lang code left"),
271        }
272    }
273
274    /// from raw code (String) to r code (String)
275    /// Do the same as .run() methode
276    pub fn parse_type_transpile_next(self) -> Self {
277        self.parse_next().type_next().transpile_next()
278    }
279
280    /// from raw code (String) to r code (String)
281    /// Call parse_type_transpile_next
282    pub fn run(self) -> Self {
283        self.parse_type_transpile_next()
284    }
285
286    fn drop_first_r_code(self) -> Self {
287        Self {
288            r_code: self.r_code.iter().skip(1).cloned().collect(),
289            ..self
290        }
291    }
292
293    pub fn next_r_code(self) -> Option<(String, Self)> {
294        let lang = self.r_code.first()?.clone();
295        Some((lang, self.drop_first_r_code()))
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, 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 |> as.Integer()")
374    }
375}