コード例 #1
0
        /// <summary>
        /// Временный узел, который используется при выведении типов параметров
        /// </summary>
        /// <param name="def"></param>
        /// <param name="visitor"></param>
        /// <returns></returns>
        public static typed_expression GetTempFunctionNodeForTypeInference(function_lambda_definition def, syntax_tree_visitor visitor)
        {
            var res = new common_namespace_function_node(def.lambda_name, visitor.get_location(def), null, null);

            if (def.return_type != null)
            {
                res.return_value_type = visitor.convert_strong(def.return_type);
            }
            else
            {
                res.return_value_type = null;
            }
            res.parameters.clear();
            if (def.formal_parameters != null && def.formal_parameters.params_list.Count != 0)
            {
                for (int i = 0; i < def.formal_parameters.params_list.Count; i++)
                {
                    for (int j = 0; j < def.formal_parameters.params_list[i].idents.idents.Count; j++)
                    {
                        var new_param = new common_parameter(null, parameter_type.value, res, concrete_parameter_type.cpt_none, visitor.get_location(def.formal_parameters.params_list[i].idents.idents[0]));
                        new_param.type = visitor.convert_strong(def.formal_parameters.params_list[i].vars_type);
                        res.parameters.AddElement(new_param);
                    }
                }
            }
            var hhh = new delegated_methods();

            hhh.proper_methods.AddElement(new common_namespace_function_call(res, visitor.get_location(def)));
            return(new typed_expression(hhh, visitor.get_location(def)));
        }
コード例 #2
0
        /// <summary>
        /// Вывод типа возвращаемого значения лямбды
        /// </summary>
        public static void InferResultType(function_header funcHeader, proc_block procBody, syntax_tree_visitor visitor)
        {
            var retType = funcHeader.return_type as lambda_inferred_type;

            if (retType != null && retType.real_type is lambda_any_type_node)
            {
                retType.real_type = new LambdaResultTypeInferrer(funcHeader, procBody, visitor).InferResultType();
            }
        }
コード例 #3
0
        /// <summary>
        /// Вывод типа параметров лямбд и типа возвращаемого значения при присваивании лямбды переменной
        /// </summary>
        public static void InferTypesFromVarStmt(type_node leftType, function_lambda_definition lambdaDef, syntax_tree_visitor visitor)
        {
            if (lambdaDef == null)
            {
                return;
            }
            if (leftType != null)
            {
                delegate_internal_interface dii_left =
                    (delegate_internal_interface)leftType.get_internal_interface(internal_interface_kind.delegate_interface);
                if (dii_left == null)
                {
                    if (leftType != SystemLibrary.system_delegate_type)
                    {
                        visitor.AddError(visitor.get_location(lambdaDef), "ILLEGAL_LAMBDA_VARIABLE_TYPE");
                    }
                    else
                    {
                        return;
                    }
                }

                int leftTypeParamsNumber = dii_left.parameters.Count;
                int lambdaDefParamsCount = 0;
                if (lambdaDef.formal_parameters != null && lambdaDef.formal_parameters.params_list.Count != 0)
                {
                    for (int i = 0; i < lambdaDef.formal_parameters.params_list.Count; i++)
                    {
                        lambdaDefParamsCount += lambdaDef.formal_parameters.params_list[i].idents.idents.Count;
                    }
                    if (lambdaDefParamsCount != leftTypeParamsNumber)
                    {
                        visitor.AddError(visitor.get_location(lambdaDef), "ILLEGAL_LAMBDA_PARAMETERS_NUMBER");
                    }
                    bool flag = true;
                    formal_parameters lambdaDefParamsTypes = new formal_parameters();
                    for (int i = 0; i < lambdaDef.formal_parameters.params_list.Count; i++)
                    {
                        for (int j = 0; j < lambdaDef.formal_parameters.params_list[i].idents.idents.Count; j++)
                        {
                            var param = new typed_parameters();
                            param.idents = new ident_list();
                            param.idents.Add(lambdaDef.formal_parameters.params_list[i].idents.idents[j]);
                            param.vars_type = lambdaDef.formal_parameters.params_list[i].vars_type;
                            lambdaDefParamsTypes.Add(param);
                        }
                    }
                    for (int i = 0; i < leftTypeParamsNumber && flag; i++)
                    {
                        if (lambdaDefParamsTypes.params_list[i].vars_type is lambda_inferred_type)
                        {
                            if ((lambdaDefParamsTypes.params_list[i].vars_type as lambda_inferred_type).real_type is lambda_any_type_node)
                            {
                                var curLeftParType = dii_left.parameters[i].type;
                                lambdaDefParamsTypes.params_list[i].vars_type = new lambda_inferred_type();
                                (lambdaDefParamsTypes.params_list[i].vars_type as lambda_inferred_type).real_type = curLeftParType;
                                continue;
                            }
                        }
                        var lambdaPar = visitor.convert_strong(lambdaDefParamsTypes.params_list[i].vars_type);
                        if (!convertion_data_and_alghoritms.eq_type_nodes(dii_left.parameters[i].type, lambdaPar))
                        {
                            visitor.AddError(visitor.get_location(lambdaDef), "ILLEGAL_LAMBDA_VARIABLE_TYPE");
                        }
                    }
                    lambdaDef.formal_parameters = lambdaDefParamsTypes;
                }
                if (lambdaDef.return_type != null && lambdaDef.return_type is lambda_inferred_type)
                {
                    if (dii_left.return_value_type != null)
                    {
                        (lambdaDef.return_type as lambda_inferred_type).real_type = dii_left.return_value_type;
                    }
                    else // SSM 23/07/16 - попытка бороться с var p: Shape->() := a->a.Print()
                    {
                        var b = TryConvertFuncLambdaBodyWithMethodCallToProcLambdaBody(lambdaDef);
                        if (!b)
                        {
                            throw new SimpleSemanticError(visitor.get_location(lambdaDef), "UNABLE_TO_CONVERT_FUNCTIONAL_TYPE_TO_PROCEDURAL_TYPE");
                        }
                    }
                }
            }
            else
            {
                if (lambdaDef.formal_parameters != null)
                {
                    for (int i = 0; i < lambdaDef.formal_parameters.params_list.Count; i++)
                    {
                        if (lambdaDef.formal_parameters.params_list[i].vars_type is lambda_inferred_type)
                        {
                            visitor.AddError(visitor.get_location(lambdaDef), "IMPOSSIBLE_TO_INFER_TYPES_IN_LAMBDA");
                        }
                    }
                }
            }
        }
コード例 #4
0
 public SubtreeCreator(syntax_tree_visitor visitor)
 {
     _syntaxTreeVisitor = visitor;
 }