swamp-script-analyzer 0.1.10

analyzer for swamp script
Documentation
/*
 * Copyright (c) Peter Bjorklund. All rights reserved. https://github.com/swamp/script
 * Licensed under the MIT License. See LICENSE in the project root for license information.
 */
use crate::Analyzer;
use crate::err::Error;
use swamp_script_types::{Signature, Type, TypeForParameter};

impl Analyzer<'_> {
    /// # Errors
    ///
    pub fn analyze_map_type(
        &mut self,
        ast_key_type: &swamp_script_ast::Type,
        ast_value_type: &swamp_script_ast::Type,
    ) -> Result<(Type, Type), Error> {
        // TODO: Check for an existing map type with exact same type

        let key_type = self.analyze_type(ast_key_type)?;
        let value_type = self.analyze_type(ast_value_type)?;

        Ok((key_type, value_type))
    }

    /// # Errors
    ///
    pub fn analyze_slice_type(&mut self, ast_type: &swamp_script_ast::Type) -> Result<Type, Error> {
        self.analyze_type(ast_type)
    }

    /// # Errors
    ///
    pub fn analyze_type(&mut self, ast_type: &swamp_script_ast::Type) -> Result<Type, Error> {
        let resolved = match ast_type {
            swamp_script_ast::Type::AnonymousStruct(ast_struct) => {
                let struct_ref = self.analyze_anonymous_struct_type(ast_struct)?;
                Type::AnonymousStruct(struct_ref.into())
            }
            swamp_script_ast::Type::Slice(ast_type) => {
                let analyzed_element_type = self.analyze_slice_type(ast_type)?;
                let vec_blueprint = self
                    .shared
                    .core_symbol_table
                    .get_blueprint("Vec")
                    .unwrap()
                    .clone();
                let instantiated_vec = self
                    .shared
                    .state
                    .instantiator
                    .instantiate_blueprint_and_members(&vec_blueprint, &[analyzed_element_type])?;
                instantiated_vec
            }
            swamp_script_ast::Type::SlicePair(key_type, value_type) => {
                let analyzed_key_type = self.analyze_slice_type(key_type)?;
                let analyzed_value_type = self.analyze_slice_type(value_type)?;
                let map_blueprint = self
                    .shared
                    .core_symbol_table
                    .get_blueprint("Map")
                    .unwrap()
                    .clone();

                let instantiated_vec = self
                    .shared
                    .state
                    .instantiator
                    .instantiate_blueprint_and_members(
                        &map_blueprint,
                        &[analyzed_key_type, analyzed_value_type],
                    )?;
                instantiated_vec
            }
            swamp_script_ast::Type::Tuple(types) => Type::Tuple(self.analyze_types(types)?),
            //            swamp_script_ast::Type::Generic(base_type, generic_types) => {
            //              let base_type = self.analyze_type(base_type)?;
            //Type::Generic(Box::new(base_type), self.analyze_types(generic_types)?)
            //        }
            swamp_script_ast::Type::Named(ast_type_reference) => {
                self.analyze_named_type(ast_type_reference)?
            }
            swamp_script_ast::Type::Unit => Type::Unit,
            swamp_script_ast::Type::Optional(inner_type_ast, _node) => {
                let inner_resolved_type = self.analyze_type(inner_type_ast)?;
                Type::Optional(Box::from(inner_resolved_type))
            }
            swamp_script_ast::Type::Function(parameters, return_type) => {
                let parameter_types = self.analyze_param_types(parameters)?;

                let resolved_return_type = self.analyze_type(return_type)?;
                Type::Function(Signature {
                    parameters: parameter_types,
                    return_type: Box::new(resolved_return_type),
                })
            }
        };

        Ok(resolved)
    }

    pub(crate) fn analyze_types(
        &mut self,
        types: &[swamp_script_ast::Type],
    ) -> Result<Vec<Type>, Error> {
        let mut resolved_types = Vec::new();
        for some_type in types {
            resolved_types.push(self.analyze_type(some_type)?);
        }
        Ok(resolved_types)
    }

    fn analyze_param_types(
        &mut self,
        type_for_parameters: &Vec<swamp_script_ast::TypeForParameter>,
    ) -> Result<Vec<TypeForParameter>, Error> {
        let mut vec = Vec::new();
        for x in type_for_parameters {
            vec.push(TypeForParameter {
                name: String::new(),
                resolved_type: self.analyze_type(&x.ast_type)?,
                is_mutable: x.is_mutable,
                node: None,
            });
        }

        Ok(vec)
    }
}