rl_lang/checker/operators/
index_assign.rs1use crate::{
10 ast::{ExprId, statements::TypeAnnotation},
11 checker::structs::{CheckType, TypeChecker},
12 utils::span::Span,
13};
14
15impl TypeChecker {
16 pub fn check_index_assign(
17 &mut self,
18 target: ExprId,
19 index: ExprId,
20 value: ExprId,
21 span: Span,
22 ) -> CheckType {
23 let target_type = self.check_expression(target);
24 let index_type = self.check_expression(index);
25 let value_type = self.check_expression(value);
26 let index_id = self.ast_arena.exprs.get(index);
27
28 match &target_type {
30 CheckType::Known(TypeAnnotation::Array(inner))
31 | CheckType::Known(TypeAnnotation::CArray(inner)) => {
32 if !matches!(
35 index_type,
36 CheckType::Known(TypeAnnotation::Int | TypeAnnotation::CInt)
37 | CheckType::Unknown
38 ) {
39 self.error(
40 format!("index must be int, got {}", index_type.info()),
41 index_id.span,
42 );
43 }
44
45 let inner_ty = CheckType::Known((**inner).clone());
46
47 if !value_type.matches(&inner_ty) && !value_type.is_null() {
48 self.error(
49 format!(
50 "type mismatch: array is {}, cannot assign {}",
51 inner_ty.info(),
52 value_type.info()
53 ),
54 span,
55 );
56 }
57 value_type
58 }
59 CheckType::Known(TypeAnnotation::Set(_))
60 | CheckType::Known(TypeAnnotation::CSet(_)) => {
61 self.error("sets does not support index assigning", span);
62 CheckType::Unknown
63 }
64 CheckType::Known(TypeAnnotation::Map(key_ty, value_ty))
65 | CheckType::Known(TypeAnnotation::CMap(key_ty, value_ty)) => {
66 let expected_key = CheckType::Known((**key_ty).clone());
67 if !index_type.matches(&expected_key) {
68 self.error(
69 format!(
70 "map key type mismatch: expected {}, got {}",
71 expected_key.info(),
72 index_type.info()
73 ),
74 index_id.span,
75 );
76 }
77
78 let expected_value = CheckType::Known((**value_ty).clone());
79 if !value_type.matches(&expected_value) && !value_type.is_null() {
80 self.error(
81 format!(
82 "type mismatch: map value is {}, cannot assign {}",
83 expected_value.info(),
84 value_type.info()
85 ),
86 span,
87 );
88 }
89 value_type
90 }
91 CheckType::Unknown => CheckType::Unknown,
92 other => {
93 self.error(format!("cannot index-assign into {}", other.info()), span);
94 CheckType::Unknown
95 }
96 }
97 }
98}