1use crate::analyzer_error::InvalidSelectKind;
2use crate::conv::checker::separator::check_separator;
3use crate::conv::{Context, Conv};
4use crate::ir::{self, IrResult, VarPath, VarPathSelect, VarSelect, VarSelectOp};
5use crate::symbol_path::{GenericSymbol, GenericSymbolPath};
6use crate::{AnalyzerError, ir_error};
7use veryl_parser::token_range::TokenRange;
8use veryl_parser::veryl_grammar_trait::*;
9
10impl Conv<&Identifier> for VarPath {
11 fn conv(_context: &mut Context, value: &Identifier) -> IrResult<Self> {
12 Ok(VarPath(vec![value.text()]))
13 }
14}
15
16impl Conv<&ScopedIdentifier> for VarPath {
17 fn conv(_context: &mut Context, value: &ScopedIdentifier) -> IrResult<Self> {
18 let mut path = Vec::new();
19 match value.scoped_identifier_group.as_ref() {
20 ScopedIdentifierGroup::DollarIdentifier(x) => {
21 path.push(x.dollar_identifier.dollar_identifier_token.token.text);
22 }
23 ScopedIdentifierGroup::IdentifierScopedIdentifierOpt(x) => {
24 path.push(x.identifier.identifier_token.token.text);
25 }
26 }
27
28 for x in &value.scoped_identifier_list {
29 path.push(x.identifier.identifier_token.token.text);
30 }
31
32 Ok(VarPath(path))
33 }
34}
35
36impl Conv<&SelectOperator> for VarSelectOp {
37 fn conv(_context: &mut Context, value: &SelectOperator) -> IrResult<Self> {
38 let ret = match value {
39 SelectOperator::Colon(_) => VarSelectOp::Colon,
40 SelectOperator::PlusColon(_) => VarSelectOp::PlusColon,
41 SelectOperator::MinusColon(_) => VarSelectOp::MinusColon,
42 SelectOperator::Step(_) => VarSelectOp::Step,
43 };
44 Ok(ret)
45 }
46}
47
48fn check_select_type(context: &mut Context, expr: &mut ir::Expression, value: &Expression) {
49 let token: TokenRange = value.into();
50 let comptime = expr.eval_comptime(context, None);
51 if comptime.r#type.is_type() {
52 context.insert_error(AnalyzerError::invalid_factor(
53 None,
54 &comptime.r#type.to_string(),
55 &token,
56 &[],
57 ));
58 }
59}
60
61impl Conv<&ScopedIdentifier> for VarPathSelect {
62 fn conv(context: &mut Context, value: &ScopedIdentifier) -> IrResult<Self> {
63 let var_path: VarPath = Conv::conv(context, value)?;
64 let token: TokenRange = value.into();
65 Ok(VarPathSelect(var_path, VarSelect::default(), token))
66 }
67}
68
69impl Conv<&ExpressionIdentifier> for VarPathSelect {
70 fn conv(context: &mut Context, value: &ExpressionIdentifier) -> IrResult<Self> {
71 check_separator(context, value);
72
73 let mut path: VarPath = Conv::conv(context, value.scoped_identifier.as_ref())?;
74 let mut generic_path: GenericSymbolPath = value.scoped_identifier.as_ref().into();
75 let mut select = VarSelect::default();
76 let token: TokenRange = value.into();
77 let mut end: Option<(VarSelectOp, ir::Expression)> = None;
78
79 context.select_dims.push(0);
80
81 for x in &value.expression_identifier_list {
82 if end.is_some() {
83 context.insert_error(AnalyzerError::invalid_select(
84 &InvalidSelectKind::SelectAfterRange,
85 &token,
86 &[],
87 ));
88 return Err(ir_error!(token));
89 }
90 context
91 .select_paths
92 .push((path.clone(), generic_path.clone()));
93 let mut expr = Conv::conv(context, x.select.expression.as_ref())?;
94 check_select_type(context, &mut expr, &x.select.expression);
95 select.push(expr);
96 if let Some(x) = &x.select.select_opt {
97 let op = Conv::conv(context, x.select_operator.as_ref())?;
98 let mut expr = Conv::conv(context, x.expression.as_ref())?;
99 check_select_type(context, &mut expr, &x.expression);
100 end = Some((op, expr));
101 }
102 context.select_paths.pop();
103 context.inc_select_dim();
104 }
105
106 for x in &value.expression_identifier_list0 {
107 path.push(x.identifier.identifier_token.token.text);
108 generic_path.paths.push(GenericSymbol {
109 base: x.identifier.identifier_token.token,
110 arguments: vec![],
111 });
112 context
113 .select_paths
114 .push((path.clone(), generic_path.clone()));
115 for x in &x.expression_identifier_list0_list {
116 if end.is_some() {
117 context.insert_error(AnalyzerError::invalid_select(
118 &InvalidSelectKind::SelectAfterRange,
119 &token,
120 &[],
121 ));
122 return Err(ir_error!(token));
123 }
124 let mut expr = Conv::conv(context, x.select.expression.as_ref())?;
125 check_select_type(context, &mut expr, &x.select.expression);
126 select.push(expr);
127 if let Some(x) = &x.select.select_opt {
128 let op = Conv::conv(context, x.select_operator.as_ref())?;
129 let mut expr = Conv::conv(context, x.expression.as_ref())?;
130 check_select_type(context, &mut expr, &x.expression);
131 end = Some((op, expr));
132 }
133 context.inc_select_dim();
134 }
135 context.select_paths.pop();
136 }
137
138 context.select_dims.pop();
139
140 select.1 = end;
141
142 Ok(VarPathSelect(path, select, token))
143 }
144}
145
146impl Conv<&HierarchicalIdentifier> for VarPathSelect {
147 fn conv(context: &mut Context, value: &HierarchicalIdentifier) -> IrResult<Self> {
148 let mut path: VarPath = Conv::conv(context, value.identifier.as_ref())?;
149 let mut generic_path: GenericSymbolPath = value.identifier.as_ref().into();
150 let mut select = VarSelect::default();
151 let token: TokenRange = value.into();
152 let mut end: Option<(VarSelectOp, ir::Expression)> = None;
153
154 for x in &value.hierarchical_identifier_list {
155 if end.is_some() {
156 context.insert_error(AnalyzerError::invalid_select(
157 &InvalidSelectKind::SelectAfterRange,
158 &token,
159 &[],
160 ));
161 return Err(ir_error!(token));
162 }
163 context
164 .select_paths
165 .push((path.clone(), generic_path.clone()));
166 let mut expr = Conv::conv(context, x.select.expression.as_ref())?;
167 check_select_type(context, &mut expr, &x.select.expression);
168 select.push(expr);
169 if let Some(x) = &x.select.select_opt {
170 let op = Conv::conv(context, x.select_operator.as_ref())?;
171 let mut expr = Conv::conv(context, x.expression.as_ref())?;
172 check_select_type(context, &mut expr, &x.expression);
173 end = Some((op, expr));
174 }
175 context.select_paths.pop();
176 }
177
178 for x in &value.hierarchical_identifier_list0 {
179 path.push(x.identifier.identifier_token.token.text);
180 generic_path.paths.push(GenericSymbol {
181 base: x.identifier.identifier_token.token,
182 arguments: vec![],
183 });
184 context
185 .select_paths
186 .push((path.clone(), generic_path.clone()));
187 for x in &x.hierarchical_identifier_list0_list {
188 if end.is_some() {
189 context.insert_error(AnalyzerError::invalid_select(
190 &InvalidSelectKind::SelectAfterRange,
191 &token,
192 &[],
193 ));
194 return Err(ir_error!(token));
195 }
196 let mut expr = Conv::conv(context, x.select.expression.as_ref())?;
197 check_select_type(context, &mut expr, &x.select.expression);
198 select.push(expr);
199 if let Some(x) = &x.select.select_opt {
200 let op = Conv::conv(context, x.select_operator.as_ref())?;
201 let mut expr = Conv::conv(context, x.expression.as_ref())?;
202 check_select_type(context, &mut expr, &x.expression);
203 end = Some((op, expr));
204 }
205 }
206 context.select_paths.pop();
207 }
208
209 select.1 = end;
210
211 Ok(VarPathSelect(path, select, token))
212 }
213}
214
215impl Conv<&Expression> for Vec<VarPathSelect> {
216 fn conv(context: &mut Context, value: &Expression) -> IrResult<Self> {
217 let mut ret = vec![];
218
219 if let Some(x) = value.unwrap_factor() {
220 match x {
221 Factor::IdentifierFactor(x) => {
222 let x: VarPathSelect =
223 Conv::conv(context, x.identifier_factor.expression_identifier.as_ref())?;
224 ret.push(x);
225 }
226 Factor::LBraceConcatenationListRBrace(x) => {
227 let items: Vec<_> = x.concatenation_list.as_ref().into();
228 for item in items {
229 let mut x: Vec<VarPathSelect> =
230 Conv::conv(context, item.expression.as_ref())?;
231 ret.append(&mut x);
232 }
233 }
234 _ => (),
235 }
236 }
237
238 Ok(ret)
239 }
240}