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