tr_lang/mem/
object.rs

1use crate::errwarn::{Error, ErrorGenerator};
2use crate::util::{get_lang, SupportedLanguage};
3use std::collections::HashMap;
4use std::fmt;
5
6#[derive(Clone)]
7pub struct List {
8    pub ls: Vec<Object>,
9}
10
11impl fmt::Debug for List {
12    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
13        Ok(write!(f, "{:?}", self.ls)?)
14    }
15}
16
17#[derive(Clone)]
18pub struct Map {
19    pub map: HashMap<String, Object>,
20}
21
22impl Map {
23    pub fn new() -> Self {
24        Self {
25            map: HashMap::new(),
26        }
27    }
28}
29
30impl fmt::Debug for Map {
31    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
32        Ok(write!(f, "{:?}", self.map)?)
33    }
34}
35
36#[derive(Clone)]
37pub enum Object {
38    Sayı(f64),
39    Yazı(String),
40    Bool(bool),
41    İşlev(usize),
42    Liste(List),
43    Harita(Map),
44    Hiç,
45}
46
47impl fmt::Debug for Object {
48    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
49        match self {
50            Self::Sayı(n) => {
51                if n.fract() == 0. {
52                    write!(f, "{:.0?}", n)?
53                } else {
54                    write!(f, "{:?}", n)?
55                }
56            }
57            Self::Bool(b) => match b {
58                true => write!(f, "doğru")?,
59                false => write!(f, "yanlış")?,
60            },
61            Self::Yazı(s) => write!(f, "{}", s)?,
62            Self::İşlev(loc) => write!(f, "<işlev: {:?}>", loc)?,
63            Self::Liste(ls) => write!(f, "{:?}", ls)?,
64            Self::Harita(map) => write!(f, "{:?}", map)?,
65            Self::Hiç => write!(f, "hiç")?,
66        }
67        Ok(())
68    }
69}
70
71type ObjectResult = Result<Object, Error>;
72
73impl Object {
74    // Karşılaştırma
75    pub fn eşittir(&self, a: Self) -> ObjectResult {
76        match self {
77            Self::Sayı(f) => match a {
78                Self::Sayı(a) => Ok(Self::Bool(f == &a)),
79                b => panic!("{:?} `=` {:?} operatörü desteklemiyor", f, b),
80            },
81            Self::Bool(b) => match a {
82                Self::Bool(a) => Ok(Self::Bool(b == &a)),
83                c => panic!("{:?} `=` {:?} operatörü desteklemiyor", b, c),
84            },
85            Self::Yazı(s) => match a {
86                Self::Yazı(a) => Ok(Self::Bool(s == &a)),
87                c => panic!("{:?} `=` {:?} operatörü desteklemiyor", s, c),
88            },
89            Self::İşlev(_) => unreachable!(),
90            Self::Liste(l) => match a {
91                Self::Liste(m) => Ok(Self::Bool(
92                    l.ls.len() == m.ls.len()
93                        && l.ls.iter().enumerate().all(|(k, v)| {
94                            match v.eşittir(m.ls.get(k).unwrap().clone()) {
95                                Ok(Self::Bool(b)) => b,
96                                _ => unreachable!(),
97                            }
98                        }),
99                )),
100                c => panic!("{:?} `=` {:?} operatörü desteklemiyor", l, c),
101            },
102            Self::Harita(m) => match a {
103                Self::Harita(n) => Ok(Self::Bool(
104                    m.map.len() == n.map.len()
105                        && m.map.keys().all(|k| {
106                            n.map.contains_key(k)
107                                && match m
108                                    .map
109                                    .get(k)
110                                    .unwrap()
111                                    .eşittir(n.map.get(k).unwrap().clone())
112                                {
113                                    Ok(Self::Bool(b)) => b,
114                                    _ => panic!(),
115                                }
116                        }),
117                )),
118                c => panic!("{:?} `=` {:?} operatörü desteklemiyor", m, c),
119            },
120            Self::Hiç => match a {
121                Self::Hiç => Ok(Self::Bool(true)),
122                _ => Ok(Self::Bool(false)),
123            },
124        }
125    }
126    pub fn eşit_değildir(&self, a: Self) -> ObjectResult {
127        match self {
128            Self::Sayı(f) => match a {
129                Self::Sayı(a) => Ok(Self::Bool(f != &a)),
130                b => panic!("{:?} `!=` {:?} operatörü desteklemiyor", f, b),
131            },
132            Self::Bool(b) => match a {
133                Self::Bool(a) => Ok(Self::Bool(b != &a)),
134                c => panic!("{:?} `!=` {:?} operatörü desteklemiyor", b, c),
135            },
136            Self::Yazı(s) => match a {
137                Self::Yazı(a) => Ok(Self::Bool(s != &a)),
138                c => panic!("{:?} `!=` {:?} operatörü desteklemiyor", s, c),
139            },
140            Self::İşlev(_) => unreachable!(),
141            Self::Liste(l) => match a {
142                Self::Liste(m) => Ok(Self::Bool(
143                    l.ls.len() != m.ls.len()
144                        || l.ls.iter().enumerate().any(|(k, v)| {
145                            match v.eşit_değildir(m.ls.get(k).unwrap().clone()) {
146                                Ok(Self::Bool(b)) => b,
147                                _ => unreachable!(),
148                            }
149                        }),
150                )),
151                c => panic!("{:?} `!=` {:?} operatörü desteklemiyor", l, c),
152            },
153            Self::Harita(m) => match a {
154                Self::Harita(n) => Ok(Self::Bool(
155                    m.map.len() != n.map.len()
156                        || m.map.keys().any(|k| {
157                            !n.map.contains_key(k)
158                                || match m
159                                    .map
160                                    .get(k)
161                                    .unwrap()
162                                    .eşit_değildir(n.map.get(k).unwrap().clone())
163                                {
164                                    Ok(Self::Bool(b)) => b,
165                                    _ => unreachable!(),
166                                }
167                        }),
168                )),
169                c => panic!("{:?} `!=` {:?} operatörü desteklemiyor", m, c),
170            },
171            Self::Hiç => match a {
172                Self::Hiç => Ok(Self::Bool(false)),
173                _ => Ok(Self::Bool(true)),
174            },
175        }
176    }
177    pub fn büyüktür(&self, a: Self) -> ObjectResult {
178        match self {
179            Self::Sayı(f) => match a {
180                Self::Sayı(a) => Ok(Self::Bool(f > &a)),
181                b => panic!("{:?} `>` {:?} operatörü desteklemiyor", f, b),
182            },
183            b => panic!("{:?} `>` operatörünü desteklemiyor", b),
184        }
185    }
186    pub fn büyük_eşittir(&self, a: Self) -> ObjectResult {
187        match self {
188            Self::Sayı(f) => match a {
189                Self::Sayı(a) => Ok(Self::Bool(f >= &a)),
190                b => panic!("{:?} `>=` {:?} operatörü desteklemiyor", f, b),
191            },
192            b => panic!("{:?} `>=` operatörünü desteklemiyor", b),
193        }
194    }
195    pub fn küçüktür(&self, a: Self) -> ObjectResult {
196        match self {
197            Self::Sayı(f) => match a {
198                Self::Sayı(a) => Ok(Self::Bool(f < &a)),
199                b => panic!("{:?} `<` {:?} operatörü desteklemiyor", f, b),
200            },
201            b => panic!("{:?} `<` operatörünü desteklemiyor", b),
202        }
203    }
204    pub fn küçük_eşittir(&self, a: Self) -> ObjectResult {
205        match self {
206            Self::Sayı(f) => match a {
207                Self::Sayı(a) => Ok(Self::Bool(f <= &a)),
208                b => panic!("{:?} `<=` {:?} operatörü desteklemiyor", f, b),
209            },
210            b => panic!("{:?} `<=` operatörünü desteklemiyor", b),
211        }
212    }
213    pub fn değildir(&self) -> ObjectResult {
214        match self {
215            Self::Bool(f) => Ok(Self::Bool(!f)),
216            b => panic!("{:?} `<` operatörünü desteklemiyor", b),
217        }
218    }
219    // Matematik
220    pub fn ekle(&self, a: Self) -> ObjectResult {
221        match self {
222            Self::Sayı(f) => match a {
223                Self::Sayı(a) => Ok(Self::Sayı(f + a)),
224                a => panic!("{:?} `+` {:?} desteklenmiyor", f, a),
225            },
226            Self::Yazı(s) => match a {
227                Self::Yazı(b) => {
228                    let mut buf = String::new();
229                    buf.push_str(s.as_str());
230                    buf.push_str(b.as_str());
231                    Ok(Self::Yazı(buf))
232                }
233                f => panic!("{:?} `+` {:?} desteklenmiyor", s, f),
234            },
235            Self::Liste(l) => match a {
236                Self::Liste(mut m) => {
237                    let mut l = l.clone();
238                    l.ls.append(&mut m.ls);
239                    Ok(Self::Liste(l))
240                }
241                f => panic!("{:?} `+` {:?} desteklenmiyor", l, f),
242            },
243            Self::Bool(b) => panic!("{:?} `+` operatörünü desteklemiyor", b),
244            Self::Harita(m) => panic!("{:?} `+` operatörünü desteklemiyor", m),
245            Self::İşlev(_) => unreachable!(),
246            Self::Hiç => panic!("hiç `+` operatörünü desteklemiyor"),
247        }
248    }
249    pub fn çıkar(&self, a: Self) -> ObjectResult {
250        match self {
251            Self::Sayı(f) => match a {
252                Self::Sayı(a) => Ok(Self::Sayı(f - a)),
253                b => panic!("{:?} `-` {:?} operatörü desteklemiyor", f, b),
254            },
255            b => panic!("{:?} `-` operatörünü desteklemiyor", b),
256        }
257    }
258    pub fn çarp(&self, a: Self) -> ObjectResult {
259        match self {
260            Self::Yazı(s) => {
261                match a {
262                    Self::Sayı(a) => {
263                        let mut buf = String::new();
264                        if a == (a as i128) as f64 {
265                            for _ in 0..(a as i128) {
266                                buf.push_str(s.as_str())
267                            }
268                        } else {
269                            panic!("`*` operatörü tam olmayan sayılar ve yazılar arasında desteklenmiyor");
270                        }
271                        Ok(Self::Yazı(buf))
272                    }
273                    a => panic!("{:?} `*` {:?} desteklenmiyor", s, a),
274                }
275            }
276            Self::Sayı(f) => {
277                match a {
278                    Self::Sayı(a) => Ok(Self::Sayı(f * a)),
279                    Self::Yazı(s) => {
280                        let mut buf = String::new();
281                        if f == &((*f as i128) as f64) {
282                            for _ in 0..(*f as i128) {
283                                buf.push_str(s.as_str())
284                            }
285                        } else {
286                            panic!("`*` operatörü tam olmayan sayılar ve yazılar arasında desteklenmiyor");
287                        }
288                        Ok(Self::Yazı(buf))
289                    }
290                    b => panic!("{:?} `*` {:?} operatörü desteklemiyor", f, b),
291                }
292            }
293            b => panic!("{:?} `*` operatörünü desteklemiyor", b),
294        }
295    }
296    pub fn böl(&self, a: Self) -> ObjectResult {
297        match self {
298            Self::Sayı(f) => match a {
299                Self::Sayı(a) => Ok(Self::Sayı(f / a)),
300                b => panic!("{:?} `/` {:?} operatörü desteklemiyor", f, b),
301            },
302            b => panic!("{:?} `/` operatörünü desteklemiyor", b),
303        }
304    }
305    pub fn modulo(&self, a: Self) -> ObjectResult {
306        match self {
307            Self::Sayı(f) => match a {
308                Self::Sayı(a) => Ok(Self::Sayı(f % a)),
309                b => panic!("{:?} `/` {:?} desteklenmiyor", f, b),
310            },
311            b => panic!("{:?} `/` operatörünü desteklemiyor", b),
312        }
313    }
314    // Mantık
315    pub fn ve(&self, a: Self, line: usize, col: usize, file: String) -> ObjectResult {
316        match self {
317            Self::Bool(f) => match a {
318                Self::Bool(a) => Ok(Self::Bool(*f && a)),
319                b => match get_lang() {
320                    SupportedLanguage::Turkish => Err(ErrorGenerator::error(
321                        "Desteklenmeyenİşlem",
322                        &format!("`{:?}` `ve` `{:?}` işlemi desteklemiyor", self, b),
323                        line,
324                        col,
325                        file,
326                        None,
327                    )),
328                    SupportedLanguage::English => Err(ErrorGenerator::error(
329                        "UnsupportedOperation",
330                        &format!("`{:?}` `ve` `{:?}` operation is not supported", self, b),
331                        line,
332                        col,
333                        file,
334                        None,
335                    )),
336                },
337            },
338            b => match get_lang() {
339                SupportedLanguage::Turkish => Err(ErrorGenerator::error(
340                    "Desteklenmeyenİşlem",
341                    &format!("{:?} `veya` anahtar kelimesini desteklemiyor", b),
342                    line,
343                    col,
344                    file,
345                    None,
346                )),
347                SupportedLanguage::English => Err(ErrorGenerator::error(
348                    "UnsupportedOperation",
349                    &format!("{:?} does not support the keyword `veya`", b),
350                    line,
351                    col,
352                    file,
353                    None,
354                )),
355            },
356        }
357    }
358    pub fn veya(&self, a: Self, line: usize, col: usize, file: String) -> ObjectResult {
359        match self {
360            Self::Bool(f) => match a {
361                Self::Bool(a) => Ok(Self::Bool(*f || a)),
362                b => match get_lang() {
363                    SupportedLanguage::Turkish => Err(ErrorGenerator::error(
364                        "Desteklenmeyenİşlem",
365                        &format!("`{:?}` `veya` `{:?}` işlemi desteklemiyor", self, b),
366                        line,
367                        col,
368                        file,
369                        None,
370                    )),
371                    SupportedLanguage::English => Err(ErrorGenerator::error(
372                        "UnsupportedOperation",
373                        &format!("`{:?}` `veya` `{:?}` operation is not supported", self, b),
374                        line,
375                        col,
376                        file,
377                        None,
378                    )),
379                },
380            },
381            b => match get_lang() {
382                SupportedLanguage::Turkish => Err(ErrorGenerator::error(
383                    "Desteklenmeyenİşlem",
384                    &format!("{:?} `veya` anahtar kelimesini desteklemiyor", b),
385                    line,
386                    col,
387                    file,
388                    None,
389                )),
390                SupportedLanguage::English => Err(ErrorGenerator::error(
391                    "UnsupportedOperation",
392                    &format!("{:?} does not support the keyword `veya`", b),
393                    line,
394                    col,
395                    file,
396                    None,
397                )),
398            },
399        }
400    }
401    // Dönüşüm
402    pub fn dönüştür(&self, a: String, line: usize, col: usize, file: String) -> ObjectResult {
403        match a.to_lowercase().as_str() {
404            "yazı" => match self {
405                Self::Bool(b) => match b {
406                    true => Ok(Self::Yazı("doğru".to_string())),
407                    false => Ok(Self::Yazı("yanlış".to_string())),
408                },
409                Self::Sayı(n) => Ok(Self::Yazı(format!("{:?}", n))),
410                Self::Yazı(_) => Ok(self.clone()),
411                Self::İşlev(_) => unreachable!(),
412                Self::Liste(l) => Ok(Self::Yazı(format!("{:?}", l))),
413                Self::Harita(m) => Ok(Self::Yazı(format!("{:?}", m))),
414                Self::Hiç => Ok(Self::Yazı("hiç".to_string())),
415            },
416            "bool" | "boolean" => match self {
417                Self::Bool(_) => Ok(self.clone()),
418                Self::Hiç => Ok(Self::Bool(false)),
419                Self::Sayı(n) => Ok(if n == &0. {
420                    Self::Bool(false)
421                } else {
422                    Self::Bool(true)
423                }),
424                Self::Yazı(s) => match s.as_str() {
425                    "doğru" => Ok(Self::Bool(true)),
426                    "yanlış" => Ok(Self::Bool(false)),
427                    _ => Err(match get_lang() {
428                        SupportedLanguage::Turkish => ErrorGenerator::error(
429                            "DeğerHatası",
430                            &format!("`{:?}` beklenen değerlerin arasında bulunmuyor", s),
431                            line,
432                            col,
433                            file,
434                            None,
435                        ),
436                        SupportedLanguage::English => ErrorGenerator::error(
437                            "ValueError",
438                            &format!("`{:?}` is not one of the expected values", s),
439                            line,
440                            col,
441                            file,
442                            None,
443                        ),
444                    }),
445                },
446                Self::İşlev(_) => unreachable!(),
447                Self::Liste(_) | Self::Harita(_) => panic!("unsupported conversion"),
448            },
449            "sayı" => match self {
450                Self::Bool(b) => Ok(match b {
451                    true => Self::Sayı(1.),
452                    false => Self::Sayı(0.),
453                }),
454                Self::Hiç => Ok(Self::Sayı(0.)),
455                Self::Sayı(_) => Ok(self.clone()),
456                Self::Yazı(s) => match s.parse::<f64>() {
457                    Ok(m) => Ok(Self::Sayı(m)),
458                    Err(_) => Err(match get_lang() {
459                        SupportedLanguage::Turkish => ErrorGenerator::error(
460                            "DeğerHatası",
461                            &format!("`{:?}` beklenen değerlerin arasında bulunmuyor", s),
462                            line,
463                            col,
464                            file,
465                            None,
466                        ),
467                        SupportedLanguage::English => ErrorGenerator::error(
468                            "ValueError",
469                            &format!("`{:?}` is not one of the expected values", s),
470                            line,
471                            col,
472                            file,
473                            None,
474                        ),
475                    }),
476                },
477                Self::İşlev(_) => unreachable!(),
478                Self::Liste(_) | Self::Harita(_) => panic!("unsupported conversion"),
479            },
480            a => Err(match get_lang() {
481                SupportedLanguage::Turkish => ErrorGenerator::error(
482                    "DeğerHatası",
483                    &format!("`{:?}` beklenen değerlerin arasında bulunmuyor", a),
484                    line,
485                    col,
486                    file,
487                    None,
488                ),
489                SupportedLanguage::English => ErrorGenerator::error(
490                    "ValueError",
491                    &format!("`{:?}` is not one of the expected values", a),
492                    line,
493                    col,
494                    file,
495                    None,
496                ),
497            }),
498        }
499    }
500}