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