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