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 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 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 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 pub fn parse_type_transpile_next(self) -> Self {
277 self.parse_next().type_next().transpile_next()
278 }
279
280 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}