1use crate::Analyzer;
6use crate::TypeContext;
7use swamp_semantic::intr::IntrinsicFunction;
8use swamp_semantic::{ArgumentExpression, Expression, ExpressionKind, Function};
9use swamp_types::prelude::*;
10
11impl Analyzer<'_> {
12 #[must_use]
13 pub fn lookup_associated_function(
14 &self,
15 ty: &TypeRef,
16 function_name: &str,
17 ) -> Option<Function> {
18 let x = self
19 .shared
20 .state
21 .associated_impls
22 .get_member_function(ty, function_name)
23 .cloned();
24
25 x.map(|found_func_ref| found_func_ref.as_ref().clone())
26 }
27
28 pub(crate) fn analyze_min_max_expr(
29 &mut self,
30 min_expr: &swamp_ast::Expression,
31 max_expr: &swamp_ast::Expression,
32 ) -> (Expression, Expression) {
33 let int_type = self.shared.state.types.int();
34 let context = TypeContext::new_argument(&int_type, false);
35
36 let resolved_min = self.analyze_expression(min_expr, &context);
37 let resolved_max = self.analyze_expression(max_expr, &context);
38
39 (resolved_min, resolved_max)
40 }
41
42 pub fn analyze_range(
47 &mut self,
48 min_expr: &swamp_ast::Expression,
49 max_expr: &swamp_ast::Expression,
50 mode: &swamp_ast::RangeMode,
51 ast_node: &swamp_ast::Node,
52 ) -> Expression {
53 let (min, max) = self.analyze_min_max_expr(min_expr, max_expr);
54
55 let range_type_ref = self
56 .shared
57 .core_symbol_table
58 .get_struct("Range")
59 .unwrap()
60 .clone();
61
62 let range_type = self.shared.state.types.range(range_type_ref);
63
64 let is_inclusive = matches!(mode, swamp_ast::RangeMode::Inclusive);
65
66 let bool_expr_kind = ExpressionKind::BoolLiteral(is_inclusive);
67 let bool_type = self.shared.state.types.bool();
68 let bool_expr = self.create_expr(bool_expr_kind, bool_type, ast_node);
69
70 let call_kind = ExpressionKind::IntrinsicCallEx(
71 IntrinsicFunction::RangeInit,
72 Vec::from(&[
73 ArgumentExpression::Expression(min),
74 ArgumentExpression::Expression(max),
75 ArgumentExpression::Expression(bool_expr),
76 ]), );
79
80 self.create_expr(call_kind, range_type, ast_node)
81 }
82}