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 */
5
6use crate::Analyzer;
7use crate::err::Error;
8use std::rc::Rc;
9use swamp_script_semantic::{
10    ArrayType, ArrayTypeRef, MapType, MapTypeRef, Signature, TupleType, Type, TypeForParameter,
11};
12
13impl<'a> Analyzer<'a> {
14    /// # Errors
15    ///
16    pub fn analyze_map_type(
17        &mut self,
18        ast_key_type: &swamp_script_ast::Type,
19        ast_value_type: &swamp_script_ast::Type,
20    ) -> Result<MapTypeRef, Error> {
21        // TODO: Check for an existing map type with exact same type
22
23        let key_type = self.analyze_type(ast_key_type)?;
24        let value_type = self.analyze_type(ast_value_type)?;
25
26        let original_map_type = MapType {
27            key_type,
28            value_type,
29        };
30
31        let map_type_ref = Rc::new(original_map_type);
32
33        //self.state.map_types.push(rc_array.clone());
34
35        Ok(map_type_ref)
36    }
37
38    /// # Errors
39    ///
40    pub fn analyze_array_type(
41        &mut self,
42        ast_type: &swamp_script_ast::Type,
43    ) -> Result<ArrayTypeRef, Error> {
44        // TODO: Check for an existing array type with exact same type
45
46        let resolved_type = self.analyze_type(ast_type)?;
47
48        let original_array_type = ArrayType {
49            item_type: resolved_type,
50        };
51
52        let rc_array = Rc::new(original_array_type);
53
54        self.shared.state.array_types.push(rc_array.clone());
55
56        Ok(rc_array)
57    }
58
59    /// # Errors
60    ///
61    pub fn analyze_type(&mut self, ast_type: &swamp_script_ast::Type) -> Result<Type, Error> {
62        let resolved = match ast_type {
63            swamp_script_ast::Type::Int(_) => Type::Int,
64            swamp_script_ast::Type::Float(_) => Type::Float,
65            swamp_script_ast::Type::String(_) => Type::String,
66            swamp_script_ast::Type::Bool(_) => Type::Bool,
67            swamp_script_ast::Type::Unit(_) => Type::Unit,
68            swamp_script_ast::Type::Struct(ast_struct) => {
69                let struct_ref = self.get_struct_type(ast_struct)?;
70                Type::Struct(struct_ref)
71            }
72            swamp_script_ast::Type::Array(ast_type) => {
73                Type::Array(self.analyze_array_type(ast_type)?)
74            }
75            swamp_script_ast::Type::Map(key_type, value_type) => {
76                Type::Map(self.analyze_map_type(key_type, value_type)?)
77            }
78            swamp_script_ast::Type::Tuple(types) => {
79                Type::Tuple(TupleType(self.analyze_types(types)?).into())
80            }
81            swamp_script_ast::Type::Generic(base_type, generic_types) => {
82                let base_type = self.analyze_type(base_type)?;
83                Type::Generic(Box::new(base_type), self.analyze_types(generic_types)?)
84            }
85            swamp_script_ast::Type::Enum(_) => todo!(),
86            swamp_script_ast::Type::Named(ast_type_reference) => {
87                self.analyze_named_type(ast_type_reference)?
88            }
89            swamp_script_ast::Type::Optional(inner_type_ast, _node) => {
90                let inner_resolved_type = self.analyze_type(inner_type_ast)?;
91                Type::Optional(Box::from(inner_resolved_type))
92            }
93            swamp_script_ast::Type::Function(parameters, return_type) => {
94                let parameter_types = self.analyze_param_types(parameters)?;
95
96                let resolved_return_type = self.analyze_type(return_type)?;
97                Type::Function(Signature {
98                    parameters: parameter_types,
99                    return_type: Box::new(resolved_return_type),
100                })
101            }
102        };
103
104        Ok(resolved)
105    }
106
107    pub(crate) fn analyze_types(
108        &mut self,
109        types: &[swamp_script_ast::Type],
110    ) -> Result<Vec<Type>, Error> {
111        let mut resolved_types = Vec::new();
112        for some_type in types {
113            resolved_types.push(self.analyze_type(some_type)?);
114        }
115        Ok(resolved_types)
116    }
117
118    fn analyze_param_types(
119        &mut self,
120        type_for_parameters: &Vec<swamp_script_ast::TypeForParameter>,
121    ) -> Result<Vec<TypeForParameter>, Error> {
122        let mut vec = Vec::new();
123        for x in type_for_parameters {
124            vec.push(TypeForParameter {
125                name: String::new(),
126                resolved_type: self.analyze_type(&x.ast_type)?,
127                is_mutable: x.is_mutable,
128                node: None,
129            });
130        }
131
132        Ok(vec)
133    }
134}