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 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 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 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 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}