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