1use std::collections::{HashSet, HashMap};
2
3use colored::Colorize;
4use rustc_hash::FxHashSet;
5
6use crate::annotations::Annotation;
7use crate::compilation::RynaError;
8use crate::context::RynaContext;
9use crate::formats::{check_class_name, check_fn_name, check_interface_name, check_template_name};
10use crate::{located_ryna_warning, ryna_error};
11use crate::parser::{RynaExpr, Location};
12use crate::operations::Operator;
13use crate::types::{Type, BOOL};
14use crate::patterns::Pattern;
15
16impl RynaContext {
23 pub fn check_forbidden_fn_names(name: &String) {
24 let forbidden_names = ["move", "fwd", "cfwd", "demut", "deref", "ref", "mut", "as", "is", "swap"];
25
26 for i in forbidden_names {
27 if i == name {
28 ryna_error!("Defining function overloads for {} is forbidden", i.green());
29 }
30 }
31 }
32
33 pub fn ensured_return_check(expr: &RynaExpr) -> Result<(), RynaError> {
34 match expr {
35 RynaExpr::PrefixOperationDefinition(l, _, _, _, _, _, _, body) |
36 RynaExpr::PostfixOperationDefinition(l, _, _, _, _, _, _, body) |
37 RynaExpr::BinaryOperationDefinition(l, _, _, _, _, _, _, body) |
38 RynaExpr::NaryOperationDefinition(l, _, _, _, _, _, _, body) => RynaContext::ensured_return_check_body(body, l, "Operation"),
39
40 RynaExpr::CompiledLambda(l, _, _, _, _, body) |
41 RynaExpr::FunctionDefinition(l, _, _, _, _, _, body) => RynaContext::ensured_return_check_body(body, l, "Function"),
42
43 RynaExpr::DoBlock(l, body, _) => RynaContext::ensured_return_check_body(body, l, "Do block"),
44
45 _ => Ok(())
46 }
47 }
48
49 pub fn ensured_return_check_body(lines: &Vec<RynaExpr>, l: &Location, instance: &str) -> Result<(), RynaError> {
50 for line in lines {
51 match line {
52 RynaExpr::Return(_, _) => return Ok(()),
53
54 RynaExpr::If(_, _, ib, ei, Some(eb_inner)) => {
55 let mut returns = RynaContext::ensured_return_check_body(ib, l, instance).is_ok() &&
56 RynaContext::ensured_return_check_body(eb_inner, l, instance).is_ok();
57
58 if returns { for (_, ei_b) in ei {
60 if RynaContext::ensured_return_check_body(ei_b, l, instance).is_err() {
61 returns = false;
62 break;
63 }
64 }
65 }
66
67 if returns {
68 return Ok(());
69 }
70 }
71
72 _ => {}
73 }
74 }
75
76 Err(RynaError::compiler_error(format!("{instance} may not always return a value"), l, vec!()))
77 }
78
79 pub fn return_check(&self, expr: &RynaExpr, ret_type: &Option<Type>) -> Result<(), RynaError> {
80 match (expr, ret_type) {
81 (RynaExpr::Break(..), _) |
82 (RynaExpr::Continue(..), _) |
83 (RynaExpr::Literal(..), _) |
84 (RynaExpr::Tuple(..), _) |
85 (RynaExpr::Variable(..), _) |
86 (RynaExpr::UnaryOperation(..), _) |
87 (RynaExpr::BinaryOperation(..), _) |
88 (RynaExpr::NaryOperation(..), _) |
89 (RynaExpr::FunctionCall(..), _) |
90 (RynaExpr::AttributeAccess(..), _) |
91 (RynaExpr::AttributeAssignment(..), _) |
92 (RynaExpr::PrefixOperatorDefinition(..), _) |
93 (RynaExpr::PostfixOperatorDefinition(..), _) |
94 (RynaExpr::BinaryOperatorDefinition(..), _) |
95 (RynaExpr::NaryOperatorDefinition(..), _) |
96 (RynaExpr::InterfaceDefinition(..), _) |
97 (RynaExpr::InterfaceImplementation(..), _) |
98 (RynaExpr::ClassDefinition(..), _) => Ok(()),
99
100 (RynaExpr::CompiledVariableDefinition(_, _, _, _, e, _), _) |
101 (RynaExpr::CompiledVariableAssignment(_, _, _, _, e, _), _) => self.return_check(e, &None),
102
103 (RynaExpr::Return(l, _), None) => {
104 Err(RynaError::compiler_error(
105 "Return statements are only allowed inside function and operation definition bodies".into(),
106 l, vec!()
107 ))
108 },
109
110 (RynaExpr::Return(l, e), Some(expected_t)) => {
111 self.return_check(e, ret_type)?;
112 let t = self.infer_type(e)?;
113
114 if t.bindable_to(expected_t, self) {
115 Ok(())
116
117 } else {
118 Err(RynaError::compiler_error(
119 format!("Value of type {} is not bindable to expected return value of type {}", t.get_name(self), expected_t.get_name(self)),
120 l, vec!()
121 ))
122 }
123 },
124
125 (RynaExpr::FunctionDefinition(_, _, _, t, _, ret, body), None) |
126 (RynaExpr::PrefixOperationDefinition(_, _, _, t, _, _, ret, body), None) |
127 (RynaExpr::PostfixOperationDefinition(_, _, _, t, _, _, ret, body), None) |
128 (RynaExpr::BinaryOperationDefinition(_, _, _, t, _, _, ret, body), None) |
129 (RynaExpr::NaryOperationDefinition(_, _, _, t, _, _, ret, body), None) => {
130 if t.is_empty() {
131 let expected_ret = Some(ret.clone());
132
133 for line in body {
134 self.return_check(line, &expected_ret)?;
135 }
136 }
137
138 RynaContext::ensured_return_check(expr)
139 }
140
141 (RynaExpr::CompiledLambda(_, _, _, _, ret, body), _) => {
142 let expected_ret = Some(ret.clone());
143
144 for line in body {
145 self.return_check(line, &expected_ret)?;
146 }
147
148 self.repeated_arguments_check(expr)?;
149 self.lambda_check(expr)?;
150 RynaContext::ensured_return_check(expr)
151 }
152
153 (RynaExpr::DoBlock(_, body, ret), _) => {
154 let expected_ret = Some(ret.clone());
155
156 for line in body {
157 self.return_check(line, &expected_ret)?;
158 }
159
160 RynaContext::ensured_return_check(expr)
161 }
162
163 (RynaExpr::While(_, cond, body), ret) |
164 (RynaExpr::CompiledFor(_, _, _, _, cond, body), ret) => {
165 self.return_check(cond, ret)?;
166
167 for line in body {
168 self.return_check(line, ret)?;
169 }
170
171 Ok(())
172 },
173
174 (RynaExpr::If(_, ih, ib, ei, eb), ret) => {
175 self.return_check(ih, ret)?;
176
177 for line in ib {
178 self.return_check(line, ret)?;
179 }
180
181 for (ei_h, ei_b) in ei {
182 self.return_check(ei_h, ret)?;
183
184 for line in ei_b {
185 self.return_check(line, ret)?;
186 }
187 }
188
189 if let Some(eb_inner) = eb {
190 for line in eb_inner {
191 self.return_check(line, ret)?;
192 }
193 }
194
195 Ok(())
196 },
197
198 (RynaExpr::Macro(..), _) => { Ok(()) },
199
200 _ => unimplemented!("{:?}", expr)
201 }
202 }
203
204 pub fn ambiguity_check(&self, expr: &RynaExpr) -> Result<(), RynaError> {
205 return match expr {
206 RynaExpr::Break(..) |
207 RynaExpr::Continue(..) |
208 RynaExpr::Literal(..) |
209 RynaExpr::Variable(..) |
210 RynaExpr::PrefixOperatorDefinition(..) |
211 RynaExpr::PostfixOperatorDefinition(..) |
212 RynaExpr::BinaryOperatorDefinition(..) |
213 RynaExpr::NaryOperatorDefinition(..) |
214 RynaExpr::InterfaceDefinition(..) |
215 RynaExpr::InterfaceImplementation(..) |
216 RynaExpr::ClassDefinition(..) => Ok(()),
217
218 RynaExpr::DoBlock(_, body, _) |
219 RynaExpr::CompiledLambda(_, _, _, _, _, body) |
220 RynaExpr::Tuple(_, body) => {
221 for line in body {
222 self.ambiguity_check(line)?;
223 }
224
225 Ok(())
226 }
227
228 RynaExpr::FunctionCall(l, id, _ , args) => {
229 let mut arg_types = Vec::with_capacity(args.len());
230
231 for arg in args.iter() {
232 self.ambiguity_check(arg)?;
233
234 let t = self.infer_type(arg)?;
235 arg_types.push(t);
236 }
237
238 if let Some(ov) = self.is_function_overload_ambiguous(*id, arg_types.clone()) {
239 let f_name = &self.functions[*id].name;
240 let possibilities = ov.iter().map(|(a, r)| format!("{}{} -> {}", f_name, a.get_name(self), r.get_name(self))).collect::<Vec<_>>();
241
242 Err(RynaError::compiler_error(
243 format!(
244 "Function call {}({}) is ambiguous",
245 f_name.green(),
246 arg_types.iter().map(|i| i.get_name(self)).collect::<Vec<_>>().join(", ")
247 ), l,
248 possibilities.into_iter().map(|i| format!("Possible overload: {}", i)).collect()
249 ))
250
251 } else {
252 Ok(())
253 }
254 },
255
256 RynaExpr::UnaryOperation(l, id, _, arg) => {
257 self.ambiguity_check(arg)?;
258 let t = self.infer_type(arg)?;
259
260 if let Some(ov) = self.is_unary_op_ambiguous(*id, t.clone()) {
261 if let Operator::Unary{representation, prefix, ..} = &self.unary_ops[*id] {
262 if *prefix {
263 let possibilities = ov.iter().map(|(a, r)| format!("{}({}) -> {}", representation, a.get_name(self), r.get_name(self))).collect::<Vec<_>>();
264
265 Err(RynaError::compiler_error(
266 format!(
267 "Unary operation {}({}) is ambiguous",
268 representation,
269 t.get_name(self)
270 ), l,
271 possibilities.into_iter().map(|i| format!("Possible overload: {}", i)).collect()
272 ))
273
274 } else {
275 let possibilities = ov.iter().map(|(a, r)| format!("({}){} -> {}", a.get_name(self), representation, r.get_name(self))).collect::<Vec<_>>();
276
277 Err(RynaError::compiler_error(
278 format!(
279 "Unary operation ({}){} is ambiguous",
280 t.get_name(self),
281 representation
282 ), l,
283 possibilities.into_iter().map(|i| format!("Possible overload: {}", i)).collect()
284 ))
285 }
286
287 } else {
288 unreachable!();
289 }
290
291 } else {
292 Ok(())
293 }
294 },
295
296 RynaExpr::BinaryOperation(l, id, _, arg1, arg2) => {
297 self.ambiguity_check(arg1)?;
298 self.ambiguity_check(arg2)?;
299
300 let t1 = self.infer_type(arg1)?;
301 let t2 = self.infer_type(arg2)?;
302
303 if let Some(ov) = self.is_binary_op_ambiguous(*id, t1.clone(), t2.clone()) {
304 if let Operator::Binary{representation, ..} = &self.binary_ops[*id] {
305 let possibilities = ov.iter()
306 .map(|(a1, a2, r)| format!("({}){}({}) -> {}", a1.get_name(self), representation, a2.get_name(self), r.get_name(self)))
307 .collect::<Vec<_>>();
308
309 Err(RynaError::compiler_error(
310 format!(
311 "Binary operation ({}){}({}) is ambiguous",
312 t1.get_name(self),
313 representation,
314 t2.get_name(self)
315 ), l,
316 possibilities.into_iter().map(|i| format!("Possible overload: {}", i)).collect()
317 ))
318
319 } else {
320 unreachable!();
321 }
322
323 } else {
324 Ok(())
325 }
326 },
327
328 RynaExpr::NaryOperation(l, id, _, first, args) => {
329 self.ambiguity_check(first)?;
330 let t = self.infer_type(first)?;
331
332 let mut arg_types = Vec::with_capacity(args.len());
333
334 for arg in args.iter() {
335 self.ambiguity_check(arg)?;
336 arg_types.push(self.infer_type(arg)?);
337 }
338
339 if let Some(ov) = self.is_nary_op_ambiguous(*id, t.clone(), arg_types.clone()) {
340 if let Operator::Nary{open_rep, close_rep, ..} = &self.nary_ops[*id] {
341 let possibilities = ov.iter()
342 .map(|(f, a, r)|
343 format!(
344 "{}{}{}{} -> {}",
345 f.get_name(self),
346 open_rep,
347 a.iter().map(|i| i.get_name(self)).collect::<Vec<_>>().join(", "),
348 close_rep,
349 r.get_name(self)
350 )
351 )
352 .collect::<Vec<_>>();
353
354 Err(RynaError::compiler_error(
355 format!(
356 "N-ary operation {}{}{}{} is ambiguous",
357 t.get_name(self),
358 open_rep,
359 arg_types.iter().map(|i| i.get_name(self)).collect::<Vec<_>>().join(", "),
360 close_rep
361 ), l,
362 possibilities.into_iter().map(|i| format!("Possible overload: {}", i)).collect()
363 ))
364
365 } else {
366 unreachable!()
367 }
368
369 } else {
370 Ok(())
371 }
372 },
373
374 RynaExpr::If(_, ih, ib, ei, eb) => {
375 self.ambiguity_check(ih)?;
376
377 for line in ib {
378 self.ambiguity_check(line)?;
379 }
380
381 for (ei_h, ei_b) in ei {
382 self.ambiguity_check(ei_h)?;
383
384 for line in ei_b {
385 self.ambiguity_check(line)?;
386 }
387 }
388
389 if let Some(eb_inner) = eb {
390 for line in eb_inner {
391 self.ambiguity_check(line)?;
392 }
393 }
394
395 Ok(())
396 },
397
398 RynaExpr::While(_, cond, body) => {
399 self.ambiguity_check(cond)?;
400
401 for line in body {
402 self.ambiguity_check(line)?;
403 }
404
405 Ok(())
406 },
407
408 RynaExpr::AttributeAssignment(_, a, b, _) => {
409 self.ambiguity_check(a)?;
410 self.ambiguity_check(b)
411 }
412
413 RynaExpr::CompiledVariableDefinition(_, _, _, _, e, _) |
414 RynaExpr::CompiledVariableAssignment(_, _, _, _, e, _) |
415 RynaExpr::AttributeAccess(_, e, _) |
416 RynaExpr::Return(_, e) => {
417 self.ambiguity_check(e)?;
418 self.infer_type(e)?;
419
420 Ok(())
421 }
422
423 RynaExpr::PrefixOperationDefinition(_, _, _, t, _, _, _, b) |
424 RynaExpr::PostfixOperationDefinition(_, _, _, t, _, _, _, b) |
425 RynaExpr::BinaryOperationDefinition(_, _, _, t, _, _, _, b) |
426 RynaExpr::NaryOperationDefinition(_, _, _, t, _, _, _, b) |
427 RynaExpr::FunctionDefinition(_, _, _, t, _, _, b) => {
428 if t.is_empty() {
429 for line in b {
430 self.ambiguity_check(line)?;
431 }
432 }
433
434 Ok(())
435 },
436
437 RynaExpr::CompiledFor(_, _, _, _, _, b) => {
438 for line in b {
439 self.ambiguity_check(line)?;
440 }
441
442 Ok(())
443 }
444
445 RynaExpr::Macro(..) => { Ok(()) },
446
447 _ => unimplemented!("{:?}", expr)
448 }
449 }
450
451 pub fn break_continue_check(expr: &RynaExpr, allowed: bool) -> Result<(), RynaError> {
452 return match expr {
453 RynaExpr::ClassDefinition(..) |
454 RynaExpr::InterfaceImplementation(..) |
455 RynaExpr::PrefixOperatorDefinition(..) |
456 RynaExpr::PostfixOperatorDefinition(..) |
457 RynaExpr::BinaryOperatorDefinition(..) |
458 RynaExpr::NaryOperatorDefinition(..) |
459 RynaExpr::InterfaceDefinition(..) |
460 RynaExpr::Macro(..) |
461 RynaExpr::Variable(..) |
462 RynaExpr::Literal(..) => Ok(()),
463
464 RynaExpr::Break(..) if allowed => Ok(()),
465 RynaExpr::Break(l) if !allowed => {
466 Err(RynaError::compiler_error("Break statement is not allowed in this context".into(), l, vec!()))
467 }
468
469 RynaExpr::Continue(..) if allowed => Ok(()),
470 RynaExpr::Continue(l) if !allowed => {
471 Err(RynaError::compiler_error("Continue statement is not allowed in this context".into(), l, vec!()))
472 }
473
474 RynaExpr::CompiledVariableAssignment(_, _, _, _, e, _) |
475 RynaExpr::CompiledVariableDefinition(_, _, _, _, e, _) => {
476 RynaContext::break_continue_check(e, allowed)
477 }
478
479 RynaExpr::Tuple(_, args) => args.iter().try_for_each(|i| RynaContext::break_continue_check(i, allowed)),
480
481 RynaExpr::If(_, i, ib, ei, eb) => {
482 RynaContext::break_continue_check(i, allowed)?;
483
484 for i in ib {
485 RynaContext::break_continue_check(i, allowed)?;
486 }
487
488 for (ei_h, ei_b) in ei {
489 RynaContext::break_continue_check(ei_h, allowed)?;
490
491 for i in ei_b {
492 RynaContext::break_continue_check(i, allowed)?;
493 }
494 }
495
496 if let Some(eb_inner) = eb {
497 for i in eb_inner {
498 RynaContext::break_continue_check(i, allowed)?;
499 }
500 }
501
502 Ok(())
503 },
504
505 RynaExpr::DoBlock(_, b, _) => {
506 for i in b {
507 RynaContext::break_continue_check(i, allowed)?;
508 }
509
510 Ok(())
511 }
512
513 RynaExpr::CompiledFor(_, _, _, _, c, b) |
514 RynaExpr::While(_, c, b) => {
515 RynaContext::break_continue_check(c, true)?;
516
517 for i in b {
518 RynaContext::break_continue_check(i, true)?;
519 }
520
521 Ok(())
522 },
523
524 RynaExpr::UnaryOperation(_, _, _, e) => {
525 RynaContext::break_continue_check(e, allowed)?;
526
527 Ok(())
528 }
529
530 RynaExpr::AttributeAssignment(_, a, b, _) |
531 RynaExpr::BinaryOperation(_, _, _, a, b) => {
532 RynaContext::break_continue_check(a, allowed)?;
533 RynaContext::break_continue_check(b, allowed)?;
534
535 Ok(())
536 },
537
538 RynaExpr::NaryOperation(_, _, _, a, args) => {
539 RynaContext::break_continue_check(a, allowed)?;
540
541 for i in args {
542 RynaContext::break_continue_check(i, allowed)?;
543 }
544
545 Ok(())
546 },
547
548 RynaExpr::FunctionCall(_, _, _, args) => {
549 for i in args {
550 RynaContext::break_continue_check(i, allowed)?;
551 }
552
553 Ok(())
554 },
555
556 RynaExpr::AttributeAccess(_, e, _) |
557 RynaExpr::Return(_, e) => RynaContext::break_continue_check(e, allowed),
558
559 RynaExpr::CompiledLambda(_, _, _, _, _, b) => {
560 for i in b {
561 RynaContext::break_continue_check(i, false)?;
562 }
563
564 Ok(())
565 },
566
567 RynaExpr::PrefixOperationDefinition(_, _, _, tm, _, _, _, b) => {
568 if tm.is_empty() {
569 for i in b {
570 RynaContext::break_continue_check(i, false)?;
571 }
572 }
573
574 Ok(())
575 },
576
577 RynaExpr::PostfixOperationDefinition(_, _, _, tm, _, _, _, b) => {
578 if tm.is_empty() {
579 for i in b {
580 RynaContext::break_continue_check(i, false)?;
581 }
582 }
583
584 Ok(())
585 },
586
587 RynaExpr::BinaryOperationDefinition(_, _, _, tm, (_, _), (_, _), _, b) => {
588 if tm.is_empty() {
589 for i in b {
590 RynaContext::break_continue_check(i, false)?;
591 }
592 }
593
594 Ok(())
595 },
596
597 RynaExpr::NaryOperationDefinition(_, _, _, tm, (_, _), _, _, b) => {
598 if tm.is_empty() {
599 for i in b {
600 RynaContext::break_continue_check(i, false)?;
601 }
602 }
603
604 Ok(())
605 },
606
607
608 RynaExpr::FunctionDefinition(_, _, _, tm, _, _, b) => {
609 if tm.is_empty() {
610 for i in b {
611 RynaContext::break_continue_check(i, false)?;
612 }
613 }
614
615 Ok(())
616 },
617
618 e => unreachable!("{:?}", e)
619 };
620 }
621
622 pub fn invalid_type_check(&self, expr: &RynaExpr) -> Result<(), RynaError> {
623 return match expr {
624 RynaExpr::PrefixOperatorDefinition(..) |
625 RynaExpr::PostfixOperatorDefinition(..) |
626 RynaExpr::BinaryOperatorDefinition(..) |
627 RynaExpr::NaryOperatorDefinition(..) |
628 RynaExpr::InterfaceDefinition(..) |
629 RynaExpr::Macro(..) |
630 RynaExpr::Break(..) |
631 RynaExpr::Continue(..) |
632 RynaExpr::Variable(..) |
633 RynaExpr::Literal(..) => Ok(()),
634
635 RynaExpr::CompiledVariableAssignment(l, _, _, t, e, _) |
636 RynaExpr::CompiledVariableDefinition(l, _, _, t, e, _) => {
637 if t.has_self() {
638 return Err(RynaError::compiler_error(
639 format!("{} type found outside an interface", Type::SelfType.get_name(self)),
640 l, vec!()
641 ));
642 }
643
644 self.invalid_type_check(e)
645 }
646
647 RynaExpr::AttributeAssignment(_, a, b, _) => {
648 self.invalid_type_check(a)?;
649 self.invalid_type_check(b)
650 }
651
652 RynaExpr::Tuple(_, args) => args.iter().try_for_each(|i| self.invalid_type_check(i)),
653
654 RynaExpr::If(_, i, ib, ei, eb) => {
655 self.invalid_type_check(i)?;
656
657 for i in ib {
658 self.invalid_type_check(i)?;
659 }
660
661 for (ei_h, ei_b) in ei {
662 self.invalid_type_check(ei_h)?;
663
664 for i in ei_b {
665 self.invalid_type_check(i)?;
666 }
667 }
668
669 if let Some(eb_inner) = eb {
670 for i in eb_inner {
671 self.invalid_type_check(i)?;
672 }
673 }
674
675 Ok(())
676 },
677
678 RynaExpr::DoBlock(l, b, t) => {
679 if t.has_self() {
680 return Err(RynaError::compiler_error(
681 format!("{} type found outside an interface", Type::SelfType.get_name(self)),
682 l, vec!()
683 ));
684 }
685
686 for i in b {
687 self.invalid_type_check(i)?;
688 }
689
690 Ok(())
691 }
692
693 RynaExpr::CompiledFor(_, _, _, _, c, b) |
694 RynaExpr::While(_, c, b) => {
695 self.invalid_type_check(c)?;
696
697 for i in b {
698 self.invalid_type_check(i)?;
699 }
700
701 Ok(())
702 },
703
704 RynaExpr::UnaryOperation(l, _, tm, e) => {
705 self.invalid_type_check(e)?;
706
707 for t in tm {
708 if t.has_self() {
709 return Err(RynaError::compiler_error(
710 format!("{} type found outside an interface", Type::SelfType.get_name(self)),
711 l, vec!()
712 ));
713 }
714 }
715
716 Ok(())
717 }
718
719 RynaExpr::BinaryOperation(l, _, tm, a, b) => {
720 self.invalid_type_check(a)?;
721 self.invalid_type_check(b)?;
722
723 for t in tm {
724 if t.has_self() {
725 return Err(RynaError::compiler_error(
726 format!("{} type found outside an interface", Type::SelfType.get_name(self)),
727 l, vec!()
728 ));
729 }
730 }
731
732 Ok(())
733 },
734
735 RynaExpr::NaryOperation(l, _, tm, a, args) => {
736 self.invalid_type_check(a)?;
737
738 for i in args {
739 self.invalid_type_check(i)?;
740 }
741
742 for t in tm {
743 if t.has_self() {
744 return Err(RynaError::compiler_error(
745 format!("{} type found outside an interface", Type::SelfType.get_name(self)),
746 l, vec!()
747 ));
748 }
749 }
750
751 Ok(())
752 },
753
754 RynaExpr::FunctionCall(l, _, tm, args) => {
755 for i in args {
756 self.invalid_type_check(i)?;
757 }
758
759 for t in tm {
760 if t.has_self() {
761 return Err(RynaError::compiler_error(
762 format!("{} type found outside an interface", Type::SelfType.get_name(self)),
763 l, vec!()
764 ));
765 }
766 }
767
768 Ok(())
769 },
770
771 RynaExpr::AttributeAccess(_, e, _) |
772 RynaExpr::Return(_, e) => self.invalid_type_check(e),
773
774 RynaExpr::CompiledLambda(l, _, c, args, ret, b) => {
775 for (_, i) in c {
776 self.invalid_type_check(i)?;
777 }
778
779 for i in b {
780 self.invalid_type_check(i)?;
781 }
782
783 for t in args.iter().map(|(_, t)| t).chain([ret]) {
784 if t.has_self() {
785 return Err(RynaError::compiler_error(
786 format!("{} type found outside an interface", Type::SelfType.get_name(self)),
787 l, vec!()
788 ));
789 }
790 }
791
792 Ok(())
793 },
794
795 RynaExpr::PrefixOperationDefinition(l, _, _, tm, _, a, ret, b) => {
796 if tm.is_empty() {
797 for i in b {
798 self.invalid_type_check(i)?;
799 }
800
801 for t in [a, ret] {
802 if t.has_self() {
803 return Err(RynaError::compiler_error(
804 format!("{} type found outside an interface", Type::SelfType.get_name(self)),
805 l, vec!()
806 ));
807 }
808 }
809 }
810
811 Ok(())
812 },
813
814 RynaExpr::PostfixOperationDefinition(l, _, _, tm, _, a, ret, b) => {
815 if tm.is_empty() {
816 for i in b {
817 self.invalid_type_check(i)?;
818 }
819
820 for t in [a, ret] {
821 if t.has_self() {
822 return Err(RynaError::compiler_error(
823 format!("{} type found outside an interface", Type::SelfType.get_name(self)),
824 l, vec!()
825 ));
826 }
827 }
828 }
829
830 Ok(())
831 },
832
833 RynaExpr::BinaryOperationDefinition(l, _, _, tm, (_, a_1), (_, a_2), ret, b) => {
834 if tm.is_empty() {
835 for i in b {
836 self.invalid_type_check(i)?;
837 }
838
839 for t in [a_1, a_2, ret] {
840 if t.has_self() {
841 return Err(RynaError::compiler_error(
842 format!("{} type found outside an interface", Type::SelfType.get_name(self)),
843 l, vec!()
844 ));
845 }
846 }
847 }
848
849 Ok(())
850 },
851
852 RynaExpr::NaryOperationDefinition(l, _, _, tm, (_, a), args, ret, b) => {
853 if tm.is_empty() {
854 for i in b {
855 self.invalid_type_check(i)?;
856 }
857
858 for t in args.iter().map(|(_, t)| t).chain([a, ret]) {
859 if t.has_self() {
860 return Err(RynaError::compiler_error(
861 format!("{} type found outside an interface", Type::SelfType.get_name(self)),
862 l, vec!()
863 ));
864 }
865 }
866 }
867
868 Ok(())
869 },
870
871
872 RynaExpr::FunctionDefinition(l, _, _, tm, args, ret, b) => {
873 if tm.is_empty() {
874 for i in b {
875 self.invalid_type_check(i)?;
876 }
877
878 for t in args.iter().map(|(_, t)| t).chain([ret]) {
879 if t.has_self() {
880 return Err(RynaError::compiler_error(
881 format!("{} type found outside an interface", Type::SelfType.get_name(self)),
882 l, vec!()
883 ));
884 }
885 }
886 }
887
888 Ok(())
889 },
890
891 RynaExpr::ClassDefinition(l, _, _, _, args, alias, _) => {
892 if let Some(t) = alias {
893 if t.has_self() {
894 return Err(RynaError::compiler_error(
895 format!("{} type found outside an interface", Type::SelfType.get_name(self)),
896 l, vec!()
897 ));
898 }
899
900 } else {
901 for t in args.iter().map(|(_, t)| t) {
902 if t.has_self() {
903 return Err(RynaError::compiler_error(
904 format!("{} type found outside an interface", Type::SelfType.get_name(self)),
905 l, vec!()
906 ));
907 }
908 }
909 }
910
911 Ok(())
912 },
913
914 RynaExpr::InterfaceImplementation(l, _, ret, _, args) => {
915 for t in args.iter().chain([ret]) {
916 if t.has_self() {
917 return Err(RynaError::compiler_error(
918 format!("{} type found outside an interface", Type::SelfType.get_name(self)),
919 l, vec!()
920 ));
921 }
922 }
923
924 Ok(())
925 },
926
927 e => unreachable!("{:?}", e)
928 };
929 }
930
931 pub fn check_type_well_formed(&self, t: &Type, l: &Location) -> Result<(), RynaError> {
932 return match t {
933 Type::Empty |
934 Type::SelfType |
935 Type::Basic(_) |
936 Type::Wildcard |
937 Type::InferenceMarker => Ok(()),
938
939 Type::Ref(i) |
940 Type::MutRef(i) => self.check_type_well_formed(i, l),
941
942 Type::Or(v) |
943 Type::And(v) => v.iter().try_for_each(|i| self.check_type_well_formed(i, l)),
944
945 Type::TemplateParamStr(n, _) => {
946 Err(RynaError::compiler_error(
947 format!(
948 "Template {} is not defined",
949 format!("'{}", n).green(),
950 ),
951 l,
952 vec!()
953 ))
954 }
955
956 Type::TemplateParam(_, cs) => {
957 for c in cs {
958 let interface = &self.interfaces[c.id];
959 let interface_args = interface.params.len();
960
961 if c.args.len() != interface_args {
962 return Err(
963 RynaError::compiler_error(
964 format!(
965 "Interface {}{} expected {} arguments (got {})",
966 interface.name.cyan(),
967 if interface_args == 0 {
968 "".into()
969 } else {
970 format!("<{}>", interface.params.iter().map(|i| i.green().to_string()).collect::<Vec<_>>().join(", "))
971 },
972 interface_args,
973 c.args.len()
974 ),
975 l,
976 vec!()
977 )
978 );
979 }
980
981 for arg in &c.args {
982 self.check_type_well_formed(arg, l)?;
983 }
984 }
985
986 Ok(())
987 },
988
989 Type::Template(id, args) => {
990 let t = &self.type_templates[*id];
991 let num_params = t.params.len();
992
993 if num_params != args.len() {
994 return Err(
995 RynaError::compiler_error(
996 format!(
997 "Type {}{} expected {} arguments (got {})",
998 t.name.cyan(),
999 if num_params == 0 { "".into() } else { format!("<{}>", t.params.iter().map(|i| i.green().to_string()).collect::<Vec<_>>().join(", ")) },
1000 num_params,
1001 args.len()
1002 ),
1003 l,
1004 vec!()
1005 )
1006 );
1007 }
1008
1009 args.iter().try_for_each(|i| self.check_type_well_formed(i, l))
1010 },
1011
1012 Type::Function(a, b) => {
1013 self.check_type_well_formed(a, l)?;
1014 self.check_type_well_formed(b, l)
1015 },
1016 }
1017 }
1018
1019 pub fn type_check(&self, expr: &RynaExpr) -> Result<(), RynaError> {
1020 match expr {
1021 RynaExpr::Break(..) |
1022 RynaExpr::Continue(..) |
1023 RynaExpr::Literal(..) |
1024 RynaExpr::Variable(..) |
1025 RynaExpr::PrefixOperatorDefinition(..) |
1026 RynaExpr::PostfixOperatorDefinition(..) |
1027 RynaExpr::BinaryOperatorDefinition(..) |
1028 RynaExpr::NaryOperatorDefinition(..) => Ok(()),
1029
1030 RynaExpr::DoBlock(_, args, _) |
1031 RynaExpr::Tuple(_, args) => {
1032 for arg in args {
1033 self.type_check(arg)?;
1034 }
1035
1036 Ok(())
1037 }
1038
1039 RynaExpr::CompiledVariableDefinition(l, _, n, t, e, _) |
1040 RynaExpr::CompiledVariableAssignment(l, _, n, t, e, _) => {
1041 self.check_type_well_formed(t, l)?;
1042 self.type_check(e)?;
1043
1044 let it = self.infer_type(e)?;
1045
1046 if it.bindable_to(t, self) {
1047 Ok(())
1048
1049 } else{
1050 Err(RynaError::compiler_error(format!(
1051 "Unable to bind value of type {} to variable {}, which is of type {}",
1052 it.get_name(self),
1053 n.cyan(),
1054 t.get_name(self)
1055 ), l, vec!()))
1056 }
1057 },
1058
1059 RynaExpr::AttributeAssignment(l, a, b, attr_idx) => {
1060 self.type_check(a)?;
1061 self.type_check(b)?;
1062
1063 let lhs_attr = self.infer_type(a)?;
1064
1065 let (attr_name, lhs) = if let Type::Basic(id) | Type::Template(id, _) = lhs_attr.deref_type() {
1066 self.type_templates[*id].attributes[*attr_idx].clone()
1067 } else {
1068 unreachable!()
1069 };
1070
1071 if let Type::Ref(_) = lhs_attr {
1072 return Err(RynaError::compiler_error(format!(
1073 "Unable assign value to attribute {} because it is accessed from a constant reference",
1074 attr_name.cyan()
1075 ), l, vec!()));
1076 }
1077
1078 if !matches!(lhs_attr, Type::MutRef(_)) {
1079 return Err(RynaError::compiler_error(format!(
1080 "Unable assign value to attribute {} because it is not accesed from a mutable reference",
1081 attr_name.cyan()
1082 ), l, vec!()));
1083 }
1084
1085 let rhs = self.infer_type(b)?;
1086
1087 if rhs.bindable_to(&lhs, self) {
1088 Ok(())
1089
1090 } else {
1091 return Err(RynaError::compiler_error(format!(
1092 "Unable to bind value of type {} to attribute {}, which is of type {}",
1093 rhs.get_name(self),
1094 attr_name.cyan(),
1095 lhs.get_name(self)
1096 ), l, vec!()));
1097 }
1098 },
1099
1100 RynaExpr::FunctionCall(l, id, templates, args) => {
1101 for t in templates {
1102 self.check_type_well_formed(t, l)?;
1103 }
1104
1105 let mut arg_types = Vec::with_capacity(args.len());
1106
1107 for arg in args.iter() {
1108 self.type_check(arg)?;
1109 arg_types.push(self.infer_type(arg)?);
1110 }
1111
1112 let (ov_id, _, _, _) = self.get_first_function_overload(*id, arg_types.clone(), Some(templates.clone()), false, l)?;
1113
1114 if self.functions[*id].overloads[ov_id].templates != templates.len() {
1116 Err(RynaError::compiler_error(format!(
1117 "Function overload for {}{}({}) expected {} type arguments (got {})",
1118 self.functions[*id].name.green(),
1119 if templates.is_empty() { "".into() } else { format!("<{}>", templates.iter().map(|i| i.get_name(self)).collect::<Vec<_>>().join(", ")) },
1120 arg_types.iter().map(|i| i.get_name(self)).collect::<Vec<_>>().join(", "),
1121 self.functions[*id].overloads[ov_id].templates, templates.len()
1122 ), l, vec!()))
1123
1124 } else {
1125 self.cache.usages.functions.add_new(*id, arg_types.clone(), templates.clone());
1127 self.cache.overloads.functions.insert((*id, arg_types.clone(), templates.clone()), ov_id);
1128
1129 if *id == self.get_function_id("destroy".into()).unwrap() {
1131 let dtor_arg = arg_types[0].deref_type();
1132
1133 if dtor_arg.has_invalid_destructor(self) {
1134 return Err(RynaError::compiler_error(
1135 format!("Type {} cannot implement Destroyable because it needs a compiler-generated destructor", dtor_arg.get_name(self)),
1136 l, vec!()
1137 ));
1138 }
1139 }
1140
1141 Ok(())
1142 }
1143 },
1144
1145 RynaExpr::UnaryOperation(l, id, templates, arg) => {
1146 for t in templates {
1147 self.check_type_well_formed(t, l)?;
1148 }
1149
1150 self.type_check(arg)?;
1151 let t = self.infer_type(arg)?;
1152
1153 let (ov_id, _, _, _) = self.get_first_unary_op(*id, t.clone(), Some(templates.clone()), false, l)?;
1154
1155 if let Operator::Unary{prefix, representation, operations, ..} = &self.unary_ops[*id] {
1156 if operations[ov_id].templates != templates.len() {
1157 if *prefix {
1158 Err(RynaError::compiler_error(format!(
1159 "Unary operator overload for {}({}) expected {} type arguments (got {})",
1160 representation,
1161 t.get_name(self),
1162 operations[ov_id].templates, templates.len()
1163 ), l, vec!()))
1164
1165 } else {
1166 Err(RynaError::compiler_error(format!(
1167 "Unary operator overload for ({}){} expected {} type arguments (got {})",
1168 t.get_name(self),
1169 representation,
1170 operations[ov_id].templates, templates.len()
1171 ), l, vec!()))
1172 }
1173
1174 } else {
1175 self.cache.usages.unary.add_new(*id, vec!(t.clone()), templates.clone());
1177 self.cache.overloads.unary.insert((*id, vec!(t.clone()), templates.clone()), ov_id);
1178
1179 Ok(())
1180 }
1181
1182 } else {
1183 unreachable!()
1184 }
1185 },
1186
1187 RynaExpr::BinaryOperation(l, id, templates, arg1, arg2) => {
1188 for t in templates {
1189 self.check_type_well_formed(t, l)?;
1190 }
1191
1192 self.type_check(arg1)?;
1193 self.type_check(arg2)?;
1194
1195 let t1 = self.infer_type(arg1)?;
1196 let t2 = self.infer_type(arg2)?;
1197
1198 let (ov_id, _, _, _) = self.get_first_binary_op(*id, t1.clone(), t2.clone(), Some(templates.clone()), false, l)?;
1199
1200 if let Operator::Binary{representation, operations, ..} = &self.binary_ops[*id] {
1201 if operations[ov_id].templates != templates.len() {
1202 Err(RynaError::compiler_error(format!(
1203 "Binary operator overload for ({}){}({}) expected {} type arguments (got {})",
1204 t1.get_name(self),
1205 representation,
1206 t2.get_name(self),
1207 operations[ov_id].templates, templates.len()
1208 ), l, vec!()))
1209
1210 } else {
1211 self.cache.usages.binary.add_new(*id, vec!(t1.clone(), t2.clone()), templates.clone());
1213 self.cache.overloads.binary.insert((*id, vec!(t1.clone(), t2.clone()), templates.clone()), ov_id);
1214
1215 Ok(())
1216 }
1217
1218 } else {
1219 unreachable!()
1220 }
1221 },
1222
1223 RynaExpr::NaryOperation(l, id, templates, first, args) => {
1224 for t in templates {
1225 self.check_type_well_formed(t, l)?;
1226 }
1227
1228 self.type_check(first)?;
1229 let t = self.infer_type(first)?;
1230
1231 let mut arg_types = Vec::with_capacity(args.len());
1232
1233 for arg in args.iter() {
1234 self.type_check(arg)?;
1235 arg_types.push(self.infer_type(arg)?);
1236 }
1237
1238 let (ov_id, _, _, _) = self.get_first_nary_op(*id, t.clone(), arg_types.clone(), Some(templates.clone()), false, l)?;
1239
1240 if let Operator::Nary{open_rep, close_rep, operations, ..} = &self.nary_ops[*id] {
1241 if operations[ov_id].templates != templates.len() {
1242 Err(RynaError::compiler_error(format!(
1243 "N-ary operator overload for {}{}{}{} expected {} type arguments (got {})",
1244 t.get_name(self),
1245 open_rep,
1246 arg_types.iter().map(|i| i.get_name(self)).collect::<Vec<_>>().join(", "),
1247 close_rep,
1248 operations[ov_id].templates, templates.len()
1249 ), l, vec!()))
1250
1251 } else {
1252 let mut all_args = vec!(t.clone());
1253 all_args.extend(arg_types);
1254
1255 self.cache.usages.nary.add_new(*id, all_args.clone(), templates.clone());
1257 self.cache.overloads.nary.insert((*id, all_args, templates.clone()), ov_id);
1258
1259 Ok(())
1260 }
1261
1262 } else {
1263 unreachable!()
1264 }
1265 },
1266
1267 RynaExpr::If(l, ih, ib, ei, eb) => {
1268 self.type_check(ih)?;
1269
1270 let t = self.infer_type(ih)?;
1271
1272 if *t.deref_type() != BOOL {
1273 return Err(RynaError::compiler_error(format!("If condition inferred to be of type {} (expected Bool, &Bool or @Bool)", t.get_name(self)), l, vec!()));
1274 }
1275
1276 for line in ib {
1277 self.type_check(line)?;
1278 }
1279
1280 for (ei_h, ei_b) in ei {
1281 self.type_check(ei_h)?;
1282 let t = self.infer_type(ei_h)?;
1283
1284 if *t.deref_type() != BOOL {
1285 return Err(RynaError::compiler_error(format!("If condition inferred to be of type {} (expected Bool, &Bool or @Bool)", t.get_name(self)), l, vec!()));
1286 }
1287
1288 for line in ei_b {
1289 self.type_check(line)?;
1290 }
1291 }
1292
1293 if let Some(eb_inner) = eb {
1294 for line in eb_inner {
1295 self.type_check(line)?;
1296 }
1297 }
1298
1299 Ok(())
1300 },
1301
1302 RynaExpr::CompiledFor(_, _, _, _, iter, body) => {
1303 self.type_check(iter)?;
1304
1305 for line in body {
1306 self.type_check(line)?;
1307 }
1308
1309 Ok(())
1310 }
1311
1312 RynaExpr::While(l, cond, body) => {
1313 self.type_check(cond)?;
1314 let t = self.infer_type(cond)?;
1315
1316 if *t.deref_type() != BOOL {
1317 return Err(RynaError::compiler_error(format!("While condition inferred to be of type {} (expected Bool, &Bool or @Bool)", t.get_name(self)), l, vec!()));
1318 }
1319
1320 for line in body {
1321 self.type_check(line)?;
1322 }
1323
1324 Ok(())
1325 },
1326
1327 RynaExpr::AttributeAccess(_, e, _) |
1328 RynaExpr::Return(_, e) => {
1329 self.type_check(e)?;
1330 self.infer_type(e)?;
1331
1332 Ok(())
1333 }
1334
1335 RynaExpr::CompiledLambda(l, _, c, args, _, b) => {
1336 for (_, i) in c {
1337 self.type_check(i)?;
1338 }
1339
1340 for (_, t) in args {
1341 self.check_type_well_formed(t, l)?;
1342 }
1343
1344 for line in b {
1345 self.type_check(line)?;
1346 }
1347
1348 Ok(())
1349 }
1350
1351 RynaExpr::PrefixOperationDefinition(l, _, _, t, _, arg, r, b) |
1352 RynaExpr::PostfixOperationDefinition(l, _, _, t, _, arg, r, b) => {
1353 self.check_type_well_formed(arg, l)?;
1354 self.check_type_well_formed(r, l)?;
1355
1356 if t.is_empty() {
1357 for line in b {
1358 self.type_check(line)?;
1359 }
1360
1361 } else {
1362 let mut templates = HashSet::new();
1363 arg.template_dependencies(&mut templates);
1364 r.template_dependencies(&mut templates);
1365
1366 for (i, n) in t.iter().enumerate() {
1367 if !templates.contains(&i) {
1368 return Err(RynaError::compiler_error(format!("Template parameter {} is not used anywhere", n.green()), l, vec!()));
1369 }
1370 }
1371 }
1372
1373 Ok(())
1374 }
1375
1376 RynaExpr::BinaryOperationDefinition(l, _, _, t, (_, ta), (_, tb), r, b) => {
1377 self.check_type_well_formed(ta, l)?;
1378 self.check_type_well_formed(tb, l)?;
1379 self.check_type_well_formed(r, l)?;
1380
1381 if t.is_empty() {
1382 for line in b {
1383 self.type_check(line)?;
1384 }
1385
1386 } else {
1387 let mut templates = HashSet::new();
1388 ta.template_dependencies(&mut templates);
1389 tb.template_dependencies(&mut templates);
1390 r.template_dependencies(&mut templates);
1391
1392 for (i, n) in t.iter().enumerate() {
1393 if !templates.contains(&i) {
1394 return Err(RynaError::compiler_error(format!("Template parameter {} is not used anywhere", n.green()), l, vec!()));
1395 }
1396 }
1397 }
1398
1399 Ok(())
1400 }
1401
1402 RynaExpr::NaryOperationDefinition(l, _, _, t, (_, ta), args, r, b) => {
1403 self.check_type_well_formed(ta, l)?;
1404 self.check_type_well_formed(r, l)?;
1405
1406 for (_, t) in args {
1407 self.check_type_well_formed(t, l)?;
1408 }
1409
1410 if t.is_empty() {
1411 for line in b {
1412 self.type_check(line)?;
1413 }
1414
1415 } else {
1416 let mut templates = HashSet::new();
1417 ta.template_dependencies(&mut templates);
1418 r.template_dependencies(&mut templates);
1419
1420 for (_, i) in args {
1421 i.template_dependencies(&mut templates);
1422 }
1423
1424 for (i, n) in t.iter().enumerate() {
1425 if !templates.contains(&i) {
1426 return Err(RynaError::compiler_error(format!("Template parameter {} is not used anywhere", n.green()), l, vec!()));
1427 }
1428 }
1429 }
1430
1431 Ok(())
1432 },
1433
1434 RynaExpr::FunctionDefinition(l, _, _, t, args, r, b) => {
1435 self.check_type_well_formed(r, l)?;
1436
1437 for (_, t) in args {
1438 self.check_type_well_formed(t, l)?;
1439 }
1440
1441 if t.is_empty() {
1442 for line in b {
1443 self.type_check(line)?;
1444 }
1445
1446 } else {
1447 let mut templates = HashSet::new();
1448 r.template_dependencies(&mut templates);
1449
1450 for (_, i) in args {
1451 i.template_dependencies(&mut templates);
1452 }
1453
1454 for (i, n) in t.iter().enumerate() {
1455 if !templates.contains(&i) {
1456 return Err(RynaError::compiler_error(format!("Template parameter {} is not used anywhere", n.green()), l, vec!()));
1457 }
1458 }
1459 }
1460
1461 Ok(())
1462 }
1463
1464 RynaExpr::InterfaceDefinition(l, _, _, t, fns, uns, bin, nary) => {
1465 let mut templates = HashSet::new();
1466
1467 for (_, _, f_t, args, r) in fns {
1468 let mut templates_f = HashSet::new();
1469
1470 self.check_type_well_formed(r, l)?;
1471 r.template_dependencies(&mut templates);
1472 r.template_dependencies(&mut templates_f);
1473
1474 for (_, i) in args {
1475 self.check_type_well_formed(i, l)?;
1476 i.template_dependencies(&mut templates);
1477 i.template_dependencies(&mut templates_f);
1478 }
1479
1480 if let Some(inner) = f_t {
1482 for (i, n) in inner.iter().enumerate() {
1483 let offset_id = i + t.len();
1484
1485 if !templates.contains(&offset_id) {
1486 return Err(RynaError::compiler_error(format!("Template parameter {} is not used anywhere", n.green()), l, vec!()));
1487 }
1488 }
1489 }
1490 }
1491
1492 for (_, _, f_t, _, at, r) in uns {
1493 self.check_type_well_formed(at, l)?;
1494 self.check_type_well_formed(r, l)?;
1495
1496 at.template_dependencies(&mut templates);
1497 r.template_dependencies(&mut templates);
1498
1499 for (i, n) in f_t.iter().enumerate() {
1500 let offset_id = i + t.len();
1501
1502 if !templates.contains(&offset_id) {
1503 return Err(RynaError::compiler_error(format!("Template parameter {} is not used anywhere", n.green()), l, vec!()));
1504 }
1505 }
1506 }
1507
1508 for (_, _, f_t, (_, a0t), (_, a1t), r) in bin {
1509 self.check_type_well_formed(a0t, l)?;
1510 self.check_type_well_formed(a1t, l)?;
1511 self.check_type_well_formed(r, l)?;
1512
1513 a0t.template_dependencies(&mut templates);
1514 a1t.template_dependencies(&mut templates);
1515 r.template_dependencies(&mut templates);
1516
1517 for (i, n) in f_t.iter().enumerate() {
1518 let offset_id = i + t.len();
1519
1520 if !templates.contains(&offset_id) {
1521 return Err(RynaError::compiler_error(format!("Template parameter {} is not used anywhere", n.green()), l, vec!()));
1522 }
1523 }
1524 }
1525
1526 for (_, _, f_t, (_, a0t), args, r) in nary {
1527 self.check_type_well_formed(a0t, l)?;
1528 self.check_type_well_formed(r, l)?;
1529
1530 a0t.template_dependencies(&mut templates);
1531 r.template_dependencies(&mut templates);
1532
1533 for (_, i) in args {
1534 self.check_type_well_formed(i, l)?;
1535 i.template_dependencies(&mut templates);
1536 }
1537
1538 for (i, n) in f_t.iter().enumerate() {
1539 let offset_id = i + t.len();
1540
1541 if !templates.contains(&offset_id) {
1542 return Err(RynaError::compiler_error(format!("Template parameter {} is not used anywhere", n.green()), l, vec!()));
1543 }
1544 }
1545 }
1546
1547 for (i, n) in t.iter().enumerate() {
1548 if !templates.contains(&i) {
1549 return Err(RynaError::compiler_error(format!("Template parameter {} is not used anywhere", n.green()), l, vec!()));
1550 }
1551 }
1552
1553 Ok(())
1554 }
1555
1556 RynaExpr::InterfaceImplementation(l, t, tp, _, args) => {
1557 let mut templates = HashSet::new();
1558 self.check_type_well_formed(tp, l)?;
1559 tp.template_dependencies(&mut templates);
1560
1561 for i in args {
1562 self.check_type_well_formed(i, l)?;
1563 i.template_dependencies(&mut templates);
1564 }
1565
1566 for (i, n) in t.iter().enumerate() {
1567 if !templates.contains(&i) {
1568 return Err(RynaError::compiler_error(format!("Template parameter {} is not used anywhere", n.green()), l, vec!()));
1569 }
1570 }
1571
1572 Ok(())
1573 }
1574
1575 RynaExpr::ClassDefinition(l, _, _, t, attrs, alias, _) => {
1576 let mut templates = HashSet::new();
1577
1578 if let Some(a) = alias {
1579 self.check_type_well_formed(a, l)?;
1580 a.template_dependencies(&mut templates);
1581
1582 } else {
1583 for (_, i) in attrs {
1584 self.check_type_well_formed(i, l)?;
1585 i.template_dependencies(&mut templates);
1586 }
1587 }
1588
1589 for (i, n) in t.iter().enumerate() {
1590 if !templates.contains(&i) {
1591 return Err(RynaError::compiler_error(format!("Template parameter {} is not used anywhere", n.green()), l, vec!()));
1592 }
1593 }
1594
1595 Ok(())
1596 }
1597
1598 RynaExpr::Macro(..) => { Ok(()) },
1599
1600 _ => unimplemented!("{:?}", expr)
1601 }
1602 }
1603
1604 #[allow(clippy::never_loop)] pub fn implicit_syntax_check(&self, name: &String, templates: &[String], attributes: &[(String, Type)], syntaxes: &Vec<Pattern>) -> Result<(), String> {
1606 if !syntaxes.is_empty() && !templates.is_empty() {
1607 return Err("Implicit syntaxes are not allowed when classes have type parameters".to_string())
1608 }
1609
1610 let atts = attributes.iter().map(|(n, _)| n.clone()).collect::<HashSet<_>>();
1611
1612 for s in syntaxes {
1613 let args = s.get_markers();
1614
1615 for diff in args.symmetric_difference(&atts) {
1616 if args.contains(diff) {
1617 return Err(format!("Syntax argument with name \"{}\" is not an attribute of {}", diff, name));
1618 }
1619
1620 return Err(format!("Attribute \"{}\" does not appear in syntax definition for {}", diff, name));
1621 }
1622 }
1623
1624 Ok(())
1625 }
1626
1627 pub fn class_check(&self, expr: &RynaExpr) -> Result<(), RynaError> {
1628 match expr {
1629 RynaExpr::ClassDefinition(l, _, n, _, attributes, _, _) => {
1630 for (att, _) in attributes {
1631 if attributes.iter().filter(|(i, _)| i == att).count() > 1 {
1632 return Err(RynaError::compiler_error(format!("Repeated attribute \"{}\" in class {}", att, n), l, vec!()));
1633 }
1634 }
1635
1636 Ok(())
1637 }
1638
1639 _ => Ok(())
1640 }
1641 }
1642
1643 pub fn macro_check(&self, expr: &RynaExpr) -> Result<(), RynaError> {
1644 match expr {
1645 RynaExpr::Macro(l, _, n, _, p, b) => {
1646 let pattern_args = p.get_markers();
1647 let macro_args = b.get_markers();
1648
1649 for p in &pattern_args {
1650 if !macro_args.contains(&(false, p.clone())) {
1651 return Err(RynaError::compiler_error(
1652 format!("Argument {} is not used inside {} syntax", p.green(), n.blue()),
1653 l, vec!()
1654 ));
1655 }
1656 }
1657
1658 for p in macro_args {
1659 if !p.0 && !pattern_args.contains(&p.1) {
1660 return Err(RynaError::compiler_error(
1661 format!("Argument {} is referenced inside {} syntax, but is not present in its RDL pattern", p.1.green(), n.blue()),
1662 l, vec!()
1663 ));
1664 }
1665 }
1666
1667 Ok(())
1668 }
1669
1670 _ => Ok(())
1671 }
1672 }
1673
1674 pub fn interface_impl_check(&self, expr: &RynaExpr) -> Result<(), RynaError> {
1675 return match expr {
1676 RynaExpr::InterfaceImplementation(l, tm, t, n, ts) => {
1677 match self.get_interface_id(n.clone()) {
1678 Ok(int_id) => {
1679 if tm.len() == 0 && int_id == self.get_interface_id("Destroyable".into()).unwrap() {
1681 if t.has_invalid_destructor(self) {
1682 return Err(RynaError::compiler_error(
1683 format!("Type {} cannot implement Destroyable because it needs a compiler-generated destructor", t.get_name(self)),
1684 l, vec!()
1685 ));
1686 }
1687 }
1688
1689 let fns = &self.interfaces[int_id].fns;
1690 let uns = &self.interfaces[int_id].uns;
1691 let bin = &self.interfaces[int_id].bin;
1692 let nary = &self.interfaces[int_id].nary;
1693
1694 let max_tms = fns.iter().map(|i| i.2.as_ref().map(|i| i.len()).unwrap_or(0)).max().unwrap_or(0) +
1695 uns.iter().map(|i| i.2.len()).max().unwrap_or(0) +
1696 bin.iter().map(|i| i.2.len()).max().unwrap_or(0) +
1697 nary.iter().map(|i| i.2.len()).max().unwrap_or(0) +
1698 self.interfaces[int_id].params.len();
1699
1700 let mut offset_t = t.clone();
1701 let mut offset_ts = ts.clone();
1702 offset_t.offset_templates(max_tms);
1703 offset_ts.iter_mut().for_each(|i| i.offset_templates(max_tms));
1704
1705 let t_subs = (0..offset_ts.len()).zip(offset_ts.clone()).collect::<HashMap<_, _>>();
1706
1707 for (_, f_n, _, args, ret) in fns {
1708 match self.get_function_id(f_n.clone()) {
1709 Ok(fn_id) => {
1710 let ret_sub = ret.sub_self(&offset_t).sub_templates(&t_subs);
1711 let args_sub = args.iter().map(|(_, tp)| tp.sub_self(&offset_t).sub_templates(&t_subs)).collect::<Vec<_>>();
1712
1713 match self.is_function_overload_ambiguous(fn_id, args_sub.clone()) {
1714 None => {
1715 if let Ok((_, r, _, _)) = self.get_first_function_overload(fn_id, args_sub.clone(), None, true, l) {
1716 if !r.bindable_to(&ret_sub, self) {
1717 return Err(RynaError::compiler_error(
1718 format!(
1719 "Function overload for {}({}) needed by interface {} returns {}, which is not bindable to the required {}",
1720 f_n, args_sub.iter().map(|i| i.get_name(self)).collect::<Vec<_>>().join(", "),
1721 n.green(), r.get_name(self), ret_sub.get_name(self)
1722 ),
1723 l, vec!()
1724 ));
1725 }
1726
1727 } else {
1728 return Err(RynaError::compiler_error(
1729 format!(
1730 "Unable to find the function overload for {}({}) needed by interface {}",
1731 f_n, args_sub.iter().map(|i| i.get_name(self)).collect::<Vec<_>>().join(", "),
1732 n.green()
1733 ),
1734 l, vec!()
1735 ));
1736 }
1737 },
1738
1739 Some(ov) => {
1740 if t.has_templates() || ts.iter().any(|i| i.has_templates()) {
1742 return Ok(());
1743 }
1744
1745 let possibilities = ov.iter().map(|(a, r)| format!("{}{} -> {}", self.functions[fn_id].name, a.get_name(self), r.get_name(self))).collect::<Vec<_>>();
1746
1747 return Err(RynaError::compiler_error(
1748 format!(
1749 "Function call {}({}) is ambiguous",
1750 f_n, args_sub.iter().map(|i| i.get_name(self)).collect::<Vec<_>>().join(", ")
1751 ),
1752 l, possibilities
1753 ));
1754 },
1755 }
1756 }
1757
1758 Err(err) => {
1759 return Err(RynaError::compiler_error(err, l, vec!()));
1760 }
1761 }
1762 }
1763
1764 for (_, op_id, _, _, at, ret) in uns {
1765 let ret_sub = ret.sub_self(&offset_t).sub_templates(&t_subs);
1766 let arg_sub = at.sub_self(&offset_t).sub_templates(&t_subs);
1767
1768 match self.is_unary_op_ambiguous(*op_id, arg_sub.clone()) {
1769 None => {
1770 if let Ok((_, r, _, _)) = self.get_first_unary_op(*op_id, arg_sub.clone(), None, true, l) {
1771 if !r.bindable_to(&ret_sub, self) {
1772 if let Operator::Unary{representation, prefix, ..} = &self.unary_ops[*op_id] {
1773 if *prefix {
1774 return Err(RynaError::compiler_error(
1775 format!(
1776 "Unary operation overload for {}({}) needed by interface {} returns {}, which is not bindable to the required {}",
1777 representation, arg_sub.get_name(self),
1778 n.green(), r.get_name(self), ret_sub.get_name(self)
1779 ),
1780 l, vec!()
1781 ));
1782
1783 } else {
1784 return Err(RynaError::compiler_error(
1785 format!(
1786 "Unary operation overload for ({}){} needed by interface {} returns {}, which is not bindable to the required {}",
1787 arg_sub.get_name(self), representation,
1788 n.green(), r.get_name(self), ret_sub.get_name(self)
1789 ),
1790 l, vec!()
1791 ));
1792 }
1793 }
1794 }
1795
1796 } else if let Operator::Unary{representation, prefix, ..} = &self.unary_ops[*op_id] {
1797 if *prefix {
1798 return Err(RynaError::compiler_error(
1799 format!(
1800 "Unable to find the unary operation overload overload for {}({}) needed by interface {}",
1801 representation, arg_sub.get_name(self),
1802 n.green()
1803 ),
1804 l, vec!()
1805 ));
1806
1807 } else {
1808 return Err(RynaError::compiler_error(
1809 format!(
1810 "Unable to find the unary operation overload overload for ({}){} needed by interface {}",
1811 arg_sub.get_name(self), representation,
1812 n.green()
1813 ),
1814 l, vec!()
1815 ));
1816 }
1817 }
1818 },
1819
1820 Some(ov) => {
1821 if t.has_templates() || ts.iter().any(|i| i.has_templates()) {
1823 return Ok(());
1824 }
1825
1826 if let Operator::Unary{representation, prefix, ..} = &self.unary_ops[*op_id] {
1827 if *prefix {
1828 let possibilities = ov.iter().map(|(a, r)| format!("{}({}) -> {}", representation, a.get_name(self), r.get_name(self))).collect::<Vec<_>>();
1829
1830 return Err(RynaError::compiler_error(
1831 format!(
1832 "Unary operation {}({}) is ambiguous",
1833 representation,
1834 t.get_name(self)
1835 ), l,
1836 possibilities.into_iter().map(|i| format!("Possible overload: {}", i)).collect()
1837 ));
1838
1839 } else {
1840 let possibilities = ov.iter().map(|(a, r)| format!("({}){} -> {}", a.get_name(self), representation, r.get_name(self))).collect::<Vec<_>>();
1841
1842 return Err(RynaError::compiler_error(
1843 format!(
1844 "Unary operation ({}){} is ambiguous",
1845 t.get_name(self),
1846 representation
1847 ), l,
1848 possibilities.into_iter().map(|i| format!("Possible overload: {}", i)).collect()
1849 ));
1850 }
1851
1852 } else {
1853 unreachable!();
1854 }
1855 },
1856 }
1857 }
1858
1859 for (_, op_id, _, (_, a0t), (_, a1t), ret) in bin {
1860 let ret_sub = ret.sub_self(&offset_t).sub_templates(&t_subs);
1861 let arg0_sub = a0t.sub_self(&offset_t).sub_templates(&t_subs);
1862 let arg1_sub = a1t.sub_self(&offset_t).sub_templates(&t_subs);
1863
1864 match self.is_binary_op_ambiguous(*op_id, arg0_sub.clone(), arg1_sub.clone()) {
1865 None => {
1866 if let Operator::Binary{representation, ..} = &self.binary_ops[*op_id] {
1867 if let Ok((_, r, _, _)) = self.get_first_binary_op(*op_id, arg0_sub.clone(), arg1_sub.clone(), None, true, l) {
1868 if !r.bindable_to(&ret_sub, self) {
1869 return Err(RynaError::compiler_error(
1870 format!(
1871 "Binary operation overload for ({}){}({}) needed by interface {} returns {}, which is not bindable to the required {}",
1872 arg0_sub.get_name(self), representation, arg1_sub.get_name(self),
1873 n.green(), r.get_name(self), ret_sub.get_name(self)
1874 ),
1875 l, vec!()
1876 ));
1877 }
1878
1879 } else {
1880 return Err(RynaError::compiler_error(
1881 format!(
1882 "Unable to find the binary operation overload for ({}){}({}) needed by interface {}",
1883 arg0_sub.get_name(self), representation, arg1_sub.get_name(self),
1884 n.green()
1885 ),
1886 l, vec!()
1887 ));
1888 }
1889 }
1890 },
1891
1892 Some(ov) => {
1893 if t.has_templates() || ts.iter().any(|i| i.has_templates()) {
1895 return Ok(());
1896 }
1897
1898 if let Operator::Binary{representation, ..} = &self.binary_ops[*op_id] {
1899 let possibilities = ov.iter()
1900 .map(|(a1, a2, r)| format!("({}){}({}) -> {}", a1.get_name(self), representation, a2.get_name(self), r.get_name(self)))
1901 .collect::<Vec<_>>();
1902
1903 return Err(RynaError::compiler_error(
1904 format!(
1905 "Binary operation ({}){}({}) is ambiguous",
1906 arg0_sub.get_name(self),
1907 representation,
1908 arg1_sub.get_name(self)
1909 ), l,
1910 possibilities.into_iter().map(|i| format!("Possible overload: {}", i)).collect()
1911 ));
1912 }
1913 }
1914 }
1915 }
1916
1917 for (_, op_id, _, (_, a0t), args, ret) in nary {
1918 let ret_sub = ret.sub_self(&offset_t).sub_templates(&t_subs);
1919 let arg0_sub = a0t.sub_self(&offset_t).sub_templates(&t_subs);
1920 let args_sub = args.iter().map(|(_, tp)| tp.sub_self(&offset_t).sub_templates(&t_subs)).collect::<Vec<_>>();
1921
1922 match self.is_nary_op_ambiguous(*op_id, arg0_sub.clone(), args_sub.clone()) {
1923 None => {
1924 if let Operator::Nary{open_rep, close_rep, ..} = &self.nary_ops[*op_id] {
1925 if let Ok((_, r, _, _)) = self.get_first_nary_op(*op_id, arg0_sub.clone(), args_sub.clone(), None, true, l) {
1926 if !r.bindable_to(&ret_sub, self) {
1927 return Err(RynaError::compiler_error(
1928 format!(
1929 "N-ary operation overload for {}{}{}{} needed by interface {} returns {}, which is not bindable to the required {}",
1930 arg0_sub.get_name(self),
1931 open_rep,
1932 args_sub.iter().map(|i| i.get_name(self)).collect::<Vec<_>>().join(", "),
1933 close_rep,
1934 n.green(), r.get_name(self), ret_sub.get_name(self)
1935 ),
1936 l, vec!()
1937 ));
1938 }
1939
1940 } else {
1941 return Err(RynaError::compiler_error(
1942 format!(
1943 "Unable to find the n-ary operation overload for {}{}{}{} needed by interface {}",
1944 arg0_sub.get_name(self),
1945 open_rep,
1946 args_sub.iter().map(|i| i.get_name(self)).collect::<Vec<_>>().join(", "),
1947 close_rep,
1948 n.green()
1949 ),
1950 l, vec!()
1951 ));
1952 }
1953 }
1954 },
1955
1956 Some(ov) => {
1957 if let Operator::Nary{open_rep, close_rep, ..} = &self.nary_ops[*op_id] {
1958 let possibilities = ov.iter()
1959 .map(|(f, a, r)|
1960 format!(
1961 "{}{}{}{} -> {}",
1962 f.get_name(self),
1963 open_rep,
1964 a.iter().map(|i| i.get_name(self)).collect::<Vec<_>>().join(", "),
1965 close_rep,
1966 r.get_name(self)
1967 )
1968 )
1969 .collect::<Vec<_>>();
1970
1971 return Err(RynaError::compiler_error(
1972 format!(
1973 "N-ary operation {}{}{}{} is ambiguous",
1974 arg0_sub.get_name(self),
1975 open_rep,
1976 args_sub.iter().map(|i| i.get_name(self)).collect::<Vec<_>>().join(", "),
1977 close_rep
1978 ), l,
1979 possibilities.into_iter().map(|i| format!("Possible overload: {}", i)).collect()
1980 ));
1981 }
1982 }
1983 }
1984 }
1985
1986 Ok(())
1987 }
1988
1989 Err(err) => Err(RynaError::compiler_error(err, l, vec!()))
1990 }
1991 }
1992
1993 _ => Ok(())
1994 };
1995 }
1996
1997 pub fn no_template_check_type(&self, t: &Type, l: &Location) -> Result<(), RynaError> {
1998 if t.has_templates() {
1999 Err(RynaError::compiler_error("Template types are not allowed in this context".into(), l, vec!()))
2000
2001 } else {
2002 Ok(())
2003 }
2004 }
2005
2006 pub fn no_template_check_types(&self, t: &[Type], l: &Location) -> Result<(), RynaError> {
2007 if t.iter().any(Type::has_templates) {
2008 Err(RynaError::compiler_error("Template types are not allowed in this context".into(), l, vec!()))
2009
2010 } else {
2011 Ok(())
2012 }
2013 }
2014
2015 pub fn no_template_check(&self, expr: &RynaExpr) -> Result<(), RynaError> {
2016 match expr {
2017 RynaExpr::Literal(..) |
2018 RynaExpr::CompiledLambda(..) => Ok(()),
2019
2020 RynaExpr::Variable(l, _, _, t, _) => self.no_template_check_type(t, l),
2021
2022 RynaExpr::AttributeAssignment(_, a, b, _) => {
2023 self.no_template_check(a)?;
2024 self.no_template_check(b)
2025 }
2026
2027 RynaExpr::AttributeAccess(_, e, _) => {
2028 self.no_template_check(e)
2029 }
2030
2031 RynaExpr::CompiledVariableAssignment(l, _, _, t, e, _) |
2032 RynaExpr::CompiledVariableDefinition(l, _, _, t, e, _) => {
2033 self.no_template_check_type(t, l)?;
2034 self.no_template_check(e)
2035 }
2036
2037 RynaExpr::DoBlock(_, e, _) |
2038 RynaExpr::Tuple(_, e) => {
2039 for i in e {
2040 self.no_template_check(i)?;
2041 }
2042
2043 Ok(())
2044 }
2045
2046 RynaExpr::UnaryOperation(l, _, tm, e) => {
2047 self.no_template_check_types(tm, l)?;
2048 self.no_template_check(e)
2049 }
2050
2051 RynaExpr::BinaryOperation(l, _, tm, a, b) => {
2052 self.no_template_check_types(tm, l)?;
2053 self.no_template_check(a)?;
2054 self.no_template_check(b)
2055 }
2056
2057 RynaExpr::NaryOperation(l, _, tm, a, b) => {
2058 self.no_template_check_types(tm, l)?;
2059 self.no_template_check(a)?;
2060
2061 for i in b {
2062 self.no_template_check(i)?;
2063 }
2064
2065 Ok(())
2066 }
2067
2068 RynaExpr::FunctionCall(l, _, tm, e) => {
2069 self.no_template_check_types(tm, l)?;
2070
2071 for i in e {
2072 self.no_template_check(i)?;
2073 }
2074
2075 Ok(())
2076 }
2077
2078 RynaExpr::CompiledFor(_, _, _, _, e, b) |
2079 RynaExpr::While(_, e, b) => {
2080 self.no_template_check(e)?;
2081
2082 for i in b {
2083 self.no_template_check(i)?;
2084 }
2085
2086 Ok(())
2087 }
2088
2089 RynaExpr::If(_, ih, ib, ei, eb) => {
2090 self.no_template_check(ih)?;
2091
2092 for i in ib {
2093 self.no_template_check(i)?;
2094 }
2095
2096 for (ei_h, ei_b) in ei {
2097 self.no_template_check(ei_h)?;
2098
2099 for i in ei_b {
2100 self.no_template_check(i)?;
2101 }
2102 }
2103
2104 if let Some(eb_inner) = eb {
2105 for i in eb_inner {
2106 self.no_template_check(i)?;
2107 }
2108 }
2109
2110 Ok(())
2111 }
2112
2113 RynaExpr::Return(_, e) => self.no_template_check(e),
2114
2115 _ => unimplemented!("{:?}", expr)
2116 }
2117 }
2118
2119 pub fn lambda_check(&self, expr: &RynaExpr) -> Result<(), RynaError> {
2120 if let RynaExpr::CompiledLambda(l, _, c, a, r, b) = expr {
2121 for (_, i) in c {
2122 self.no_template_check(i)?;
2123 }
2124
2125 if r.has_templates() {
2126 return Err(RynaError::compiler_error("Parametric types are not allowed in lambda return types".into(), l, vec!()));
2127 }
2128
2129 if a.iter().map(|(_, t)| t).any(Type::has_templates) {
2130 return Err(RynaError::compiler_error("Parametric types are not allowed in lambda parameters".into(), l, vec!()));
2131 }
2132
2133 for line in b {
2134 self.no_template_check(line)?;
2135 }
2136
2137 Ok(())
2138
2139 } else {
2140 unreachable!()
2141 }
2142 }
2143
2144 pub fn repeated_args(&self, args: &Vec<&String>, item: &str) -> Result<(), String> {
2145 let mut args_set = HashSet::new();
2146
2147 for i in args {
2148 if args_set.contains(i) {
2149 return Err(format!("{} \"{}\" is defined multiple times", item, i));
2150 }
2151
2152 args_set.insert(i);
2153 }
2154
2155 Ok(())
2156 }
2157
2158 pub fn repeated_arguments_check(&self, expr: &RynaExpr) -> Result<(), RynaError> {
2159 return match expr {
2160 RynaExpr::PostfixOperationDefinition(l, _, _, t, n, _, _, _) |
2161 RynaExpr::PrefixOperationDefinition(l, _, _, t, n, _, _, _) => {
2162 let err = self.repeated_args(&vec!(n), "Parameter");
2163
2164 if let Err(msg) = err {
2165 return Err(RynaError::compiler_error(msg, l, vec!()));
2166 }
2167
2168 let err = self.repeated_args(&t.iter().collect(), "Parameter");
2169
2170 if let Err(msg) = err {
2171 return Err(RynaError::compiler_error(msg, l, vec!()));
2172 }
2173
2174 Ok(())
2175 }
2176
2177 RynaExpr::BinaryOperationDefinition(l, _, _, t, (n1, _), (n2, _), _, _) => {
2178 let err = self.repeated_args(&vec!(n1, n2), "Parameter");
2179
2180 if let Err(msg) = err {
2181 return Err(RynaError::compiler_error(msg, l, vec!()));
2182 }
2183
2184 let err = self.repeated_args(&t.iter().collect(), "Parameter");
2185
2186 if let Err(msg) = err {
2187 return Err(RynaError::compiler_error(msg, l, vec!()));
2188 }
2189
2190 Ok(())
2191 }
2192
2193 RynaExpr::NaryOperationDefinition(l, _, _, t, (n1, _), n, _, _) => {
2194 let mut args = vec!(n1);
2195 args.extend(n.iter().map(|(i, _)| i));
2196
2197 let err = self.repeated_args(&args, "Parameter");
2198
2199 if let Err(msg) = err {
2200 return Err(RynaError::compiler_error(msg, l, vec!()));
2201 }
2202
2203 let err = self.repeated_args(&t.iter().collect(), "Parameter");
2204
2205 if let Err(msg) = err {
2206 return Err(RynaError::compiler_error(msg, l, vec!()));
2207 }
2208
2209 Ok(())
2210 }
2211
2212 RynaExpr::FunctionDefinition(l, _, _, t, a, _, _) => {
2213 let err = self.repeated_args(&a.iter().map(|(n, _)| n).collect(), "Parameter");
2214
2215 if let Err(msg) = err {
2216 return Err(RynaError::compiler_error(msg, l, vec!()));
2217 }
2218
2219 let err = self.repeated_args(&t.iter().collect(), "Parameter");
2220
2221 if let Err(msg) = err {
2222 return Err(RynaError::compiler_error(msg, l, vec!()));
2223 }
2224
2225 Ok(())
2226 }
2227
2228 RynaExpr::CompiledLambda(l, _, c, a, _, _) => {
2229 let err = self.repeated_args(&a.iter().map(|(n, _)| n).collect(), "Parameter");
2230
2231 if let Err(msg) = err {
2232 return Err(RynaError::compiler_error(msg, l, vec!()));
2233 }
2234
2235 let err = self.repeated_args(&c.iter().map(|(n, _)| n).collect(), "Capture");
2236
2237 if let Err(msg) = err {
2238 return Err(RynaError::compiler_error(msg, l, vec!()));
2239 }
2240
2241 let cap_names = &c.iter().map(|(n, _)| n).collect::<FxHashSet<_>>();
2242 let arg_names = &a.iter().map(|(n, _)| n).collect::<FxHashSet<_>>();
2243
2244 for n in cap_names {
2245 if arg_names.contains(n) {
2246 return Err(RynaError::compiler_error(format!("Capture \"{}\" is also defined as a parameter", n), l, vec!()));
2247 }
2248 }
2249
2250 Ok(())
2251 }
2252
2253 _ => Ok(())
2254 };
2255 }
2256
2257 pub fn check_test_annotation(&self, annot: &Annotation, t: &Vec<String>, args: &Vec<(String, Type)>, ret: &Type) -> Result<(), String> {
2258 annot.check_args(&[], &[])?;
2259
2260 if t.len() > 0 {
2261 return Err(format!("Functions annotated with {} cannot be generic", "test".cyan()));
2262 }
2263
2264 if args.len() > 0 {
2265 return Err(format!("Functions annotated with {} cannot take any parameters", "test".cyan()));
2266 }
2267
2268 if ret.deref_type() != &BOOL {
2269 return Err(format!(
2270 "Functions annotated with {} must return {}, {} or {}",
2271 "test".cyan(), BOOL.get_name(self), BOOL.to_ref().get_name(self), BOOL.to_mut().get_name(self)
2272 ));
2273 }
2274
2275 Ok(())
2276 }
2277
2278 pub fn check_fn_doc_annotation(&self, annot: &Annotation, args: &Vec<(String, Type)>) -> Result<(), String> {
2279 annot.check_args(
2280 &["0", "1"],
2281 args.iter()
2282 .map(|(n, _)| n.as_str())
2283 .collect::<Vec<_>>().as_slice()
2284 )?;
2285
2286 Ok(())
2287 }
2288
2289 pub fn check_noret_doc_annotation(&self, annot: &Annotation, args: &Vec<(String, Type)>) -> Result<(), String> {
2290 annot.check_args(
2291 &["0"],
2292 args.iter()
2293 .map(|(n, _)| n.as_str())
2294 .collect::<Vec<_>>().as_slice()
2295 )?;
2296
2297 Ok(())
2298 }
2299
2300 pub fn annotation_checks(&self, expr: &RynaExpr) -> Result<(), RynaError> {
2301 match expr {
2302 RynaExpr::Macro(l, an, _, _, _, _) => {
2303 for a in an {
2304 let res = match a.name.as_str() {
2305 "test" => Err(format!("Macros cannot have the {} annotation", "test".cyan())),
2306 "doc" => self.check_noret_doc_annotation(a, &vec!()),
2307
2308 n => Err(format!("Annotation with name {} does not exist", n.cyan()))
2309 };
2310
2311 res.map_err(|m| RynaError::compiler_error(m, l, vec!()))?;
2312 }
2313 }
2314
2315 RynaExpr::ClassDefinition(l, an, _, _, atts, _, _) => {
2316 for a in an {
2317 let res = match a.name.as_str() {
2318 "test" => Err(format!("Classes cannot have the {} annotation", "test".cyan())),
2319 "doc" => self.check_noret_doc_annotation(a, atts),
2320
2321 n => Err(format!("Annotation with name {} does not exist", n.cyan()))
2322 };
2323
2324 res.map_err(|m| RynaError::compiler_error(m, l, vec!()))?;
2325 }
2326 }
2327
2328 RynaExpr::InterfaceDefinition(l, an, _, _, fns, unops, binops, naryops) => {
2329 for a in an {
2330 let res = match a.name.as_str() {
2331 "test" => Err(format!("Interfaces cannot have the {} annotation", "test".cyan())),
2332 "doc" => self.check_noret_doc_annotation(a, &vec!()),
2333
2334 n => Err(format!("Annotation with name {} does not exist", n.cyan()))
2335 };
2336
2337 res.map_err(|m| RynaError::compiler_error(m, l, vec!()))?;
2338 }
2339
2340 for (inner_an, _, _, args, _) in fns {
2341 for a in inner_an {
2342 let res = match a.name.as_str() {
2343 "test" => Err(format!("Interface function headers cannot have the {} annotation", "test".cyan())),
2344 "doc" => self.check_fn_doc_annotation(a, args),
2345
2346 n => Err(format!("Annotation with name {} does not exist", n.cyan()))
2347 };
2348
2349 res.map_err(|m| RynaError::compiler_error(m, l, vec!()))?;
2350 }
2351 }
2352
2353 for (inner_an, _, _, n, t, _) in unops {
2354 for a in inner_an {
2355 let res = match a.name.as_str() {
2356 "test" => Err(format!("Interface operation headers cannot have the {} annotation", "test".cyan())),
2357 "doc" => self.check_fn_doc_annotation(a, &vec!((n.clone(), t.clone()))),
2358
2359 n => Err(format!("Annotation with name {} does not exist", n.cyan()))
2360 };
2361
2362 res.map_err(|m| RynaError::compiler_error(m, l, vec!()))?;
2363 }
2364 }
2365
2366 for (inner_an, _, _, arg_a, arg_b, _) in binops {
2367 for a in inner_an {
2368 let res = match a.name.as_str() {
2369 "test" => Err(format!("Interface operation headers cannot have the {} annotation", "test".cyan())),
2370 "doc" => self.check_fn_doc_annotation(a, &vec!(arg_a.clone(), arg_b.clone())),
2371
2372 n => Err(format!("Annotation with name {} does not exist", n.cyan()))
2373 };
2374
2375 res.map_err(|m| RynaError::compiler_error(m, l, vec!()))?;
2376 }
2377 }
2378
2379 for (inner_an, _, _, arg_a, arg_b, _) in naryops {
2380 let mut all_args = vec!(arg_a.clone());
2381 all_args.extend(arg_b.iter().cloned());
2382
2383 for a in inner_an {
2384 let res = match a.name.as_str() {
2385 "test" => Err(format!("Interface operation headers cannot have the {} annotation", "test".cyan())),
2386 "doc" => self.check_fn_doc_annotation(a, &all_args),
2387
2388 n => Err(format!("Annotation with name {} does not exist", n.cyan()))
2389 };
2390
2391 res.map_err(|m| RynaError::compiler_error(m, l, vec!()))?;
2392 }
2393 }
2394 }
2395
2396 RynaExpr::FunctionDefinition(l, an, _, t, args, r, _) => {
2397 for a in an {
2398 let res = match a.name.as_str() {
2399 "test" => self.check_test_annotation(a, t, args, r),
2400 "doc" => self.check_fn_doc_annotation(a, args),
2401
2402 n => Err(format!("Annotation with name {} does not exist", n.cyan()))
2403 };
2404
2405 res.map_err(|m| RynaError::compiler_error(m, l, vec!()))?;
2406 }
2407 }
2408
2409 RynaExpr::PrefixOperationDefinition(l, an, _, t, arg_n, arg_t, r, _) |
2410 RynaExpr::PostfixOperationDefinition(l, an, _, t, arg_n, arg_t, r, _) => {
2411 for a in an {
2412 let res = match a.name.as_str() {
2413 "test" => self.check_test_annotation(a, t, &vec!((arg_n.clone(), arg_t.clone())), r),
2414 "doc" => self.check_fn_doc_annotation(a, &vec!((arg_n.clone(), arg_t.clone()))),
2415
2416 n => Err(format!("Annotation with name {} does not exist", n.cyan()))
2417 };
2418
2419 res.map_err(|m| RynaError::compiler_error(m, l, vec!()))?;
2420 }
2421 }
2422
2423 RynaExpr::BinaryOperationDefinition(l, an, _, t, arg_a, arg_b, r, _) => {
2424 for a in an {
2425 let res = match a.name.as_str() {
2426 "test" => self.check_test_annotation(a, t, &vec!(arg_a.clone(), arg_b.clone()), r),
2427 "doc" => self.check_fn_doc_annotation(a, &vec!(arg_a.clone(), arg_b.clone())),
2428
2429 n => Err(format!("Annotation with name {} does not exist", n.cyan()))
2430 };
2431
2432 res.map_err(|m| RynaError::compiler_error(m, l, vec!()))?;
2433 }
2434 }
2435
2436 RynaExpr::NaryOperationDefinition(l, an, _, t, arg_a, arg_b, r, _) => {
2437 let mut all_args = vec!(arg_a.clone());
2438 all_args.extend(arg_b.iter().cloned());
2439
2440 for a in an {
2441 let res = match a.name.as_str() {
2442 "test" => self.check_test_annotation(a, t, &all_args, r),
2443 "doc" => self.check_fn_doc_annotation(a, &all_args),
2444
2445 n => Err(format!("Annotation with name {} does not exist", n.cyan()))
2446 };
2447
2448 res.map_err(|m| RynaError::compiler_error(m, l, vec!()))?;
2449 }
2450 }
2451
2452 _ => { }
2453 }
2454
2455 Ok(())
2456 }
2457
2458 pub fn check_formats(&self, expr: &RynaExpr) {
2459 match expr {
2460 RynaExpr::ClassDefinition(l, _, n, ts, _, _, _) => {
2461 if let Err(warn) = check_class_name(n) {
2462 located_ryna_warning!(l, "{}", warn);
2463 }
2464
2465 for t in ts {
2466 if let Err(warn) = check_template_name(t) {
2467 located_ryna_warning!(l, "{}", warn);
2468 }
2469 }
2470 }
2471
2472 RynaExpr::FunctionDefinition(l, _, id, ts, _, _, _) => {
2473 if let Err(warn) = check_fn_name(&self.functions[*id].name) {
2474 located_ryna_warning!(l, "{}", warn);
2475 }
2476
2477 for t in ts {
2478 if let Err(warn) = check_template_name(t) {
2479 located_ryna_warning!(l, "{}", warn);
2480 }
2481 }
2482 }
2483
2484 RynaExpr::InterfaceDefinition(l, _, n, ts, fns, _, _, _) => {
2485 if let Err(warn) = check_interface_name(n) {
2486 located_ryna_warning!(l, "{}", warn);
2487 }
2488
2489 for t in ts {
2490 if let Err(warn) = check_template_name(t) {
2491 located_ryna_warning!(l, "{}", warn);
2492 }
2493 }
2494
2495 for f in fns {
2496 if let Err(warn) = check_fn_name(&f.1) {
2497 located_ryna_warning!(l, "{}", warn);
2498 }
2499
2500 for t in f.2.as_ref().unwrap_or(&vec!()) {
2501 if let Err(warn) = check_template_name(t) {
2502 located_ryna_warning!(l, "{}", warn);
2503 }
2504 }
2505 }
2506 }
2507
2508 _ => {}
2509 }
2510 }
2511
2512 pub fn static_check_expected(&self, expr: &RynaExpr, expected: &Option<Type>) -> Result<(), RynaError> {
2513 self.repeated_arguments_check(expr)?;
2514 self.invalid_type_check(expr)?;
2515 self.type_check(expr)?;
2516 self.ambiguity_check(expr)?;
2517 self.return_check(expr, expected)?;
2518 RynaContext::break_continue_check(expr, false)?;
2519 self.class_check(expr)?;
2520 self.macro_check(expr)?;
2521 self.interface_impl_check(expr)?;
2522 self.annotation_checks(expr)?;
2523 self.check_formats(expr);
2524
2525 Ok(())
2526 }
2527
2528 pub fn static_check(&self, expr: &RynaExpr) -> Result<(), RynaError> {
2529 self.static_check_expected(expr, &None)
2530 }
2531}
2532
2533#[cfg(test)]
2540mod tests {
2541 use crate::context::*;
2542
2543 #[test]
2544 fn type_checks() {
2545 let mut ctx = standard_ctx();
2546
2547 let code_str = "
2548 let n: Int = 10;
2549
2550 let a: Int = 5 + n;
2551 let b: String = \"Test\";
2552 let c: Array<Int> = arr<Int>();
2553
2554 a = 3;
2555 b = \"Test 2\";
2556 c = arr<Int>();
2557 ".to_string();
2558
2559 ctx.parse_and_compile(&code_str).unwrap();
2560
2561 let mut ctx = standard_ctx();
2562
2563 let code_str = "
2564 let a: String = 5;
2565 ".to_string();
2566
2567 assert!(ctx.parse_and_compile(&code_str).is_err());
2568
2569 let mut ctx = standard_ctx();
2570
2571 let code_str = "
2572 let a: Int = 5;
2573
2574 a = \"Test\";
2575 ".to_string();
2576
2577 assert!(ctx.parse_and_compile(&code_str).is_err());
2578
2579 let mut ctx = standard_ctx();
2580
2581 let code_str = "
2582 let a: Array<Int> = 5;
2583 ".to_string();
2584
2585 assert!(ctx.parse_and_compile(&code_str).is_err());
2586
2587 let mut ctx = standard_ctx();
2588
2589 let code_str = "
2590 let a: Array<Int> = arr<Int>();
2591
2592 a = arr<String>();
2593 ".to_string();
2594
2595 assert!(ctx.parse_and_compile(&code_str).is_err());
2596 }
2597
2598 #[test]
2599 fn function_ambiguity_check() {
2600 let mut ctx = standard_ctx();
2601
2602 let code_str = "
2603 fn inc(a: String) -> @String {
2604 return a;
2605 }
2606
2607 let a: Int = 5;
2608
2609 a.inc();
2610 inc(\"Test\");
2611 ".to_string();
2612
2613 ctx.parse_and_compile(&code_str).unwrap();
2614 let mut ctx = standard_ctx();
2615
2616 let code_str = "
2617 fn test(a: Bool | String) -> String {
2618 return \"Test\";
2619 }
2620
2621 fn test(a: Bool | Int) -> String {
2622 return \"Test\";
2623 }
2624
2625 test(true);
2626 ".to_string();
2627
2628 assert!(ctx.parse_and_compile(&code_str).is_err());
2629 }
2630
2631 #[test]
2632 fn unary_ambiguity_check() {
2633 let mut ctx = standard_ctx();
2634
2635 let code_str = "
2636 op !(a: String) -> @String {
2637 return a;
2638 }
2639
2640 !\"Test\";
2641 ".to_string();
2642
2643 ctx.parse_and_compile(&code_str).unwrap();
2644 let mut ctx = standard_ctx();
2645
2646 let code_str = "
2647 op !(a: Int | String) -> String {
2648 return \"Test\";
2649 }
2650
2651 op !(a: Int | Array<*>) -> String {
2652 return \"Test\";
2653 }
2654
2655 !5;
2656 ".to_string();
2657
2658 assert!(ctx.parse_and_compile(&code_str).is_err());
2659 }
2660
2661 #[test]
2662 fn binary_ambiguity_check() {
2663 let mut ctx = standard_ctx();
2664
2665 let code_str = "
2666 op (a: String) + (b: Bool) -> @String {
2667 return a;
2668 }
2669
2670 \"Test\" + true;
2671 ".to_string();
2672
2673 ctx.parse_and_compile(&code_str).unwrap();
2674 let mut ctx = standard_ctx();
2675
2676 let code_str = "
2677 op (a: String) + (b: Int | Bool) -> String {
2678 return \"Test\";
2679 }
2680
2681 op (a: String) + (b: Int | Array<*>) -> String {
2682 return \"Test\";
2683 }
2684
2685 \"Test\" + 5;
2686 ".to_string();
2687
2688 assert!(ctx.parse_and_compile(&code_str).is_err());
2689 }
2690
2691 #[test]
2692 fn nary_ambiguity_check() {
2693 let mut ctx = standard_ctx();
2694
2695 let code_str = "
2696 op (a: String)[b: Bool] -> @String {
2697 return a;
2698 }
2699
2700 \"Test\"[true];
2701 ".to_string();
2702
2703 ctx.parse_and_compile(&code_str).unwrap();
2704 let mut ctx = standard_ctx();
2705
2706 let code_str = "
2707 op (a: String)[b: Bool | String] -> String {
2708 return \"Test\";
2709 }
2710
2711 op (a: String)[b: Bool | Array<*>] -> String {
2712 return \"Test\";
2713 }
2714
2715 \"Test\"[true];
2716 ".to_string();
2717
2718 assert!(ctx.parse_and_compile(&code_str).is_err());
2719 }
2720
2721 #[test]
2722 fn return_type_check() {
2723 let mut ctx = standard_ctx();
2724
2725 let code_str = "
2726 fn test(a: String) -> @String {
2727 return a;
2728 }
2729
2730 test(\"Test\");
2731 ".to_string();
2732
2733 ctx.parse_and_compile(&code_str).unwrap();
2734 let mut ctx = standard_ctx();
2735
2736 let code_str = "
2737 fn test(a: String) -> Int {
2738 return a;
2739 }
2740
2741 test(\"Test\");
2742 ".to_string();
2743
2744 assert!(ctx.parse_and_compile(&code_str).is_err());
2745 }
2746
2747 #[test]
2748 fn ensured_return_check() {
2749 let mut ctx = standard_ctx();
2750
2751 let code_str = "
2752 fn test(a: String) -> @String {
2753 return a;
2754 }
2755
2756 fn test(a: Int) -> Int {
2757 if true {
2758 return 0;
2759
2760 } else {
2761 return 1;
2762 }
2763 }
2764
2765 fn test(a: Bool) -> Int {
2766 if true {
2767 let a = 0;
2768
2769 } else {
2770 return 1;
2771 }
2772
2773 return 0;
2774 }
2775 ".to_string();
2776
2777 ctx.parse_and_compile(&code_str).unwrap();
2778 let mut ctx = standard_ctx();
2779
2780 let code_str = "
2781 fn test(a: Bool) -> Int {
2782 if true {
2783 let a = 0;
2784
2785 } else {
2786 return 1;
2787 }
2788 }
2789 ".to_string();
2790
2791 assert!(ctx.parse_and_compile(&code_str).is_err());
2792 }
2793
2794 #[test]
2795 fn class_check() {
2796 let mut ctx = standard_ctx();
2797
2798 let code_str = "
2799 class Test {
2800 att_1: Int;
2801 att_2: (String, Int);
2802 att_3: Int | Array<Int>;
2803 }
2804 ".to_string();
2805
2806 ctx.parse_and_compile(&code_str).unwrap();
2807
2808 let mut ctx = standard_ctx();
2809
2810 let code_str = "
2811 class Test {
2812 att_1: Int;
2813 att_1: (String, Int);
2814 att_3: Int | Array<Int>;
2815 }
2816 ".to_string();
2817
2818 assert!(ctx.parse_and_compile(&code_str).is_err());
2819
2820 let mut ctx = standard_ctx();
2821
2822 let code_str = "
2823 class Test {
2824 syntax from Arg(1{d}, att_1) Arg(\"true\" | \"false\", att_2);
2825
2826 att_1: Int;
2827 att_2: Bool;
2828 }
2829 ".to_string();
2830
2831 ctx.parse_and_compile(&code_str).unwrap();
2832
2833 let mut ctx = standard_ctx();
2834
2835 let code_str = "
2836 class Test {
2837 syntax from Arg(1{d}, att_1);
2838
2839 att_1: Int;
2840 att_2: Bool;
2841 }
2842 ".to_string();
2843
2844 assert!(ctx.parse_and_compile(&code_str).is_err());
2845 }
2846}