swamp_script_analyzer/
types.rs

1/*
2 * Copyright (c) Peter Bjorklund. All rights reserved. https://github.com/swamp/script
3 * Licensed under the MIT License. See LICENSE in the project root for license information.
4 */
5use crate::Analyzer;
6use crate::err::Error;
7use swamp_script_types::{Signature, Type, TypeForParameter};
8
9impl Analyzer<'_> {
10    /// # Errors
11    ///
12    pub fn analyze_map_type(
13        &mut self,
14        ast_key_type: &swamp_script_ast::Type,
15        ast_value_type: &swamp_script_ast::Type,
16    ) -> Result<(Type, Type), Error> {
17        // TODO: Check for an existing map type with exact same type
18
19        let key_type = self.analyze_type(ast_key_type)?;
20        let value_type = self.analyze_type(ast_value_type)?;
21
22        Ok((key_type, value_type))
23    }
24
25    /// # Errors
26    ///
27    pub fn analyze_slice_type(&mut self, ast_type: &swamp_script_ast::Type) -> Result<Type, Error> {
28        self.analyze_type(ast_type)
29    }
30
31    /// # Errors
32    ///
33    pub fn analyze_type(&mut self, ast_type: &swamp_script_ast::Type) -> Result<Type, Error> {
34        let resolved = match ast_type {
35            swamp_script_ast::Type::AnonymousStruct(ast_struct) => {
36                let struct_ref = self.analyze_anonymous_struct_type(ast_struct)?;
37                Type::AnonymousStruct(struct_ref.into())
38            }
39            swamp_script_ast::Type::Slice(ast_type) => {
40                let analyzed_element_type = self.analyze_slice_type(ast_type)?;
41                let vec_blueprint = self
42                    .shared
43                    .core_symbol_table
44                    .get_blueprint("Vec")
45                    .unwrap()
46                    .clone();
47                let instantiated_vec = self
48                    .shared
49                    .state
50                    .instantiator
51                    .instantiate_blueprint_and_members(&vec_blueprint, &[analyzed_element_type])?;
52                instantiated_vec
53            }
54            swamp_script_ast::Type::SlicePair(key_type, value_type) => {
55                let analyzed_key_type = self.analyze_slice_type(key_type)?;
56                let analyzed_value_type = self.analyze_slice_type(value_type)?;
57                let map_blueprint = self
58                    .shared
59                    .core_symbol_table
60                    .get_blueprint("Map")
61                    .unwrap()
62                    .clone();
63
64                let instantiated_vec = self
65                    .shared
66                    .state
67                    .instantiator
68                    .instantiate_blueprint_and_members(
69                        &map_blueprint,
70                        &[analyzed_key_type, analyzed_value_type],
71                    )?;
72                instantiated_vec
73            }
74            swamp_script_ast::Type::Tuple(types) => Type::Tuple(self.analyze_types(types)?),
75            //            swamp_script_ast::Type::Generic(base_type, generic_types) => {
76            //              let base_type = self.analyze_type(base_type)?;
77            //Type::Generic(Box::new(base_type), self.analyze_types(generic_types)?)
78            //        }
79            swamp_script_ast::Type::Named(ast_type_reference) => {
80                self.analyze_named_type(ast_type_reference)?
81            }
82            swamp_script_ast::Type::Unit => Type::Unit,
83            swamp_script_ast::Type::Optional(inner_type_ast, _node) => {
84                let inner_resolved_type = self.analyze_type(inner_type_ast)?;
85                Type::Optional(Box::from(inner_resolved_type))
86            }
87            swamp_script_ast::Type::Function(parameters, return_type) => {
88                let parameter_types = self.analyze_param_types(parameters)?;
89
90                let resolved_return_type = self.analyze_type(return_type)?;
91                Type::Function(Signature {
92                    parameters: parameter_types,
93                    return_type: Box::new(resolved_return_type),
94                })
95            }
96        };
97
98        Ok(resolved)
99    }
100
101    pub(crate) fn analyze_types(
102        &mut self,
103        types: &[swamp_script_ast::Type],
104    ) -> Result<Vec<Type>, Error> {
105        let mut resolved_types = Vec::new();
106        for some_type in types {
107            resolved_types.push(self.analyze_type(some_type)?);
108        }
109        Ok(resolved_types)
110    }
111
112    fn analyze_param_types(
113        &mut self,
114        type_for_parameters: &Vec<swamp_script_ast::TypeForParameter>,
115    ) -> Result<Vec<TypeForParameter>, Error> {
116        let mut vec = Vec::new();
117        for x in type_for_parameters {
118            vec.push(TypeForParameter {
119                name: String::new(),
120                resolved_type: self.analyze_type(&x.ast_type)?,
121                is_mutable: x.is_mutable,
122                node: None,
123            });
124        }
125
126        Ok(vec)
127    }
128}