swamp_script_analyzer/
access.rs1use crate::Analyzer;
6use crate::TypeContext;
7use crate::err::{Error, ErrorKind};
8use swamp_script_semantic::{
9 ArrayTypeRef, Expression, ExpressionKind, Function, FunctionRef, Range, RangeMode, Type,
10};
11use tracing::info;
12
13impl Analyzer<'_> {
14 pub fn convert_to_function_access_kind(function_ref: &FunctionRef) -> ExpressionKind {
15 match &**function_ref {
16 Function::Internal(internal_function) => {
17 ExpressionKind::InternalFunctionAccess(internal_function.clone())
18 }
19 Function::External(external_function) => {
20 ExpressionKind::ExternalFunctionAccess(external_function.clone())
21 }
22 }
23 }
24
25 #[must_use]
26 pub fn lookup_associated_function(
27 &self,
28 ty: &Type,
29 function_name: &str,
30 ) -> Option<FunctionRef> {
31 self.shared
32 .state
33 .associated_impls
34 .get_member_function(ty, function_name)
35 .cloned()
36 }
37
38 #[must_use]
39 pub fn convert_to_function_access_expr(
40 &self,
41 associated_function_info: &FunctionRef,
42 ast_node: &swamp_script_ast::Node,
43 ) -> Expression {
44 let kind = Self::convert_to_function_access_kind(associated_function_info);
45 self.create_expr(
46 kind,
47 Type::Function(associated_function_info.signature().clone()),
48 ast_node,
49 )
50 }
51
52 pub(crate) fn analyze_static_member_access(
53 &mut self,
54 named_type: &swamp_script_ast::QualifiedTypeIdentifier,
55 member_name_node: &swamp_script_ast::Node,
56 ) -> Result<Expression, Error> {
57 let some_type = self.analyze_named_type(named_type)?;
58 let member_name = self.get_text(member_name_node);
59 self.lookup_associated_function(&some_type, member_name)
60 .map_or_else(
61 || Err(self.create_err(ErrorKind::UnknownMemberFunction, member_name_node)),
62 |member_function| {
63 let expr =
64 self.convert_to_function_access_expr(&member_function, member_name_node);
65 Ok(expr)
66 },
67 )
68 }
69
70 pub(crate) fn analyze_min_max_expr(
71 &mut self,
72 min_expr: &swamp_script_ast::Expression,
73 max_expr: &swamp_script_ast::Expression,
74 ) -> Result<(Expression, Expression), Error> {
75 let context = TypeContext::new_argument(&Type::Int);
76
77 let resolved_min = self.analyze_expression(min_expr, &context)?;
78 let resolved_max = self.analyze_expression(max_expr, &context)?;
79
80 Ok((resolved_min, resolved_max))
81 }
82
83 pub fn analyze_range(
84 &mut self,
85 min_expr: &swamp_script_ast::Expression,
86 max_expr: &swamp_script_ast::Expression,
87 mode: &swamp_script_ast::RangeMode,
88 ) -> Result<Range, Error> {
89 let (min, max) = self.analyze_min_max_expr(min_expr, max_expr)?;
90
91 let resolved_range_mode = match mode {
92 swamp_script_ast::RangeMode::Inclusive => RangeMode::Inclusive,
93 swamp_script_ast::RangeMode::Exclusive => RangeMode::Exclusive,
94 };
95 Ok(Range {
96 min,
97 max,
98 mode: resolved_range_mode,
99 })
100 }
101
102 pub fn analyze_array_range_access(
105 &mut self,
106 base_expression: Expression,
107 array_type_ref: &ArrayTypeRef,
108 range: Range,
109 ) -> Result<Expression, Error> {
110 let node = &base_expression.node.clone();
111
112 Ok(self.create_expr_resolved(
113 ExpressionKind::ArrayRangeAccess(Box::from(base_expression), Box::from(range)),
114 Type::Array(array_type_ref.clone()),
115 &node,
116 ))
117 }
118
119 pub fn analyze_string_range_access(
122 &mut self,
123 base_expr: Expression,
124 range: Range,
125 ) -> Result<Expression, Error> {
126 let ty = base_expr.ty.clone();
127 let node = base_expr.node.clone();
128 Ok(self.create_expr_resolved(
129 ExpressionKind::StringRangeAccess(Box::from(base_expr), Box::from(range)),
130 ty,
131 &node,
132 ))
133 }
134}