コード例 #1
0
ファイル: LambdaHelper.cs プロジェクト: ikvm/pascalabcnet
        /// <summary>
        /// Заменяет x -> begin result := x.Print end;  на  x -> begin x.Print end  в случае если это один оператор и вызов метода
        ///
        /// </summary>
        public static bool TryConvertFuncLambdaBodyWithMethodCallToProcLambdaBody(function_lambda_definition lambdaDef)
        {
            // SSM 12/12/16 - сделал чтобы всегда эта функция возвращала true.
            // Посмотрю далее на её поведение. Мне кажется, что если мы попали сюда, то мы хотим присвоить процедурному типу,
            // и в любом случае это надо интерпретировать как процедуру
            var stl = lambdaDef.proc_body as SyntaxTree.statement_list;

            if (stl.expr_lambda_body)
            {
                // Очищаем от Result := , который мы создали на предыдущем этапе

                var ass = stl.list[0] as assign;
                if (ass != null && ass.to is ident && (ass.to as ident).name.ToLower() == "result")
                {
                    var f = ass.from;
                    if (f is method_call)
                    {
                        var ff = f as method_call;
                        stl.list[0]           = new procedure_call(ff, ff.source_context); // заменить result := Print(x) на Print(x)
                        lambdaDef.return_type = null;
                        return(true);
                    }
                    else
                    {
                        return(false);
                    }
                }
            }

            lambdaDef.return_type = null;
            return(true);
//            return false;
        }
コード例 #2
0
 public void for_assignment(object lr0, object lr2)
 {
     if (lr0 is ident && lr2 is ident && ((ident)lr2).name.Contains("__lambda__"))
     {
         string            type_name = "";
         var_def_statement vds       = find_var_statements(((ident)lr0).name);
         if (vds != null)
         {
             type_name = ((named_type_reference)vds.vars_type).names[0].name;
         }
         if (type_name != "")
         {
             int ii = 0;
             while (ii < pascalABC_type_declarations.Count &&
                    ((type_declaration)pascalABC_type_declarations[ii]).type_name.name != type_name)
             {
                 ii++;
             }
             if (ii < pascalABC_type_declarations.Count)
             {
                 type_definition            td  = ((type_declaration)pascalABC_type_declarations[ii]).type_def;
                 function_lambda_definition fld = find_pascalABC_lambda_name(((ident)lr2).name);
                 fld.return_type = ((function_header)td).return_type;
                 for (int k = 0; k < fld.formal_parameters.params_list.Count && k < ((function_header)td).parameters.params_list.Count; k++)
                 {
                     fld.formal_parameters.params_list[k].vars_type = ((function_header)td).parameters.params_list[k].vars_type;
                 }
             }
             pascalABC_var_statements.Remove(vds);
         }
     }
 }
コード例 #3
0
        public static procedure_definition ConvertLambdaNodeToProcDefNode(function_lambda_definition functionLambdaDef)
        {
            procedure_definition procDef = null;

            if (functionLambdaDef.return_type == null)
            {
                procDef = SyntaxTreeNodesConstructor.CreateProcedureDefinitionNode(new method_name(null, null, new ident(functionLambdaDef.lambda_name, functionLambdaDef.source_context), null),
                                                                                   functionLambdaDef.formal_parameters,
                                                                                   false,
                                                                                   false,
                                                                                   functionLambdaDef.proc_body,
                                                                                   functionLambdaDef.source_context);
            }
            else
            {
                procDef = SyntaxTreeNodesConstructor.CreateFunctionDefinitionNode(new method_name(null, null, new ident(functionLambdaDef.lambda_name), null),
                                                                                  functionLambdaDef.formal_parameters,
                                                                                  false,
                                                                                  false,
                                                                                  functionLambdaDef.proc_body,
                                                                                  functionLambdaDef.return_type,
                                                                                  functionLambdaDef.source_context);
            }
            procDef.proc_header.name.meth_name.source_context = procDef.proc_header.source_context;
            functionLambdaDef.proc_definition = procDef;
            return(procDef);
        }
コード例 #4
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)));
        }
コード例 #5
0
 public CapturedVariablesTreeNodeLambdaScope(CapturedVariablesTreeNode parentNode, function_lambda_definition lambdaDef, int scopeNum, syntax_tree_node correspondingSyntaxTreeNode)
     : base(parentNode, scopeNum, correspondingSyntaxTreeNode)
 {
     LambdaDefinition       = lambdaDef;
     CapturedVarsSymbolInfo = new List <SymbolInfo>();
     ScopeIndexOfClassWhereLambdaWillBeAddedAsMethod = null;
 }
コード例 #6
0
        public override void visit(function_lambda_definition fld)
        {
            ProcessNode(fld.proc_body);
            if (fld.unpacked_params == null)
            {
                return;
            }

            fld.formal_parameters = new formal_parameters();
            fld.formal_parameters.source_context = fld.source_context;

            // Пусть параметр имеет вид \(x,y)
            // Тогда в начало тела лямбды надо добавить var (x,y) = #fpl1;
            //var idl = new ident_list(fld.unpacked_params.Select(p => p.id).ToList(),fld.source_context); //

            //var ass = new assign_var_tuple(idl, main_param_id, fld.source_context);

            List <statement> res = new List <statement>();

            foreach (var param in fld.unpacked_params)
            {
                if (param is unpacked_list_of_ident_or_list unpacked_param)
                {
                    var lam_inft   = new lambda_inferred_type(new lambda_any_type_node());
                    var param_id   = CreateIdent(fld.source_context);
                    var idlist     = new ident_list(param_id, unpacked_param.source_context);
                    var typed_pars = new typed_parameters(idlist, lam_inft, parametr_kind.none, null, unpacked_param.source_context);
                    fld.formal_parameters.Add(typed_pars, unpacked_param.source_context);
                    fld.ident_list.Add(param_id);
                    fld.parameters.Add(param_id);

                    CreateUnpackedListOfAssignments(unpacked_param, res, param_id, unpacked_param.source_context);
                }
                else if (param is ident id)
                {
                    var lam_inft   = new lambda_inferred_type(new lambda_any_type_node());
                    var idlist     = new ident_list(id, id.source_context);
                    var typed_pars = new typed_parameters(idlist, lam_inft);
                    fld.formal_parameters.Add(typed_pars, fld.source_context);
                    fld.ident_list.Add(id);
                    fld.parameters.Add(id);
                }
            }


            var stl = fld.proc_body as statement_list;

            res.Reverse();
            foreach (var st in res)
            {
                var ass = st as assign_var_tuple;
                ass.idents.source_context = new SourceContext(ass.idents[0].source_context, ass.idents[ass.idents.Count - 1].source_context);
                ass.expr.source_context   = ass.idents.source_context;
                stl.Insert(0, st); // возможно, в обратном порядке
            }

            //stl.Insert(0, ass);
            fld.unpacked_params = null; // на рассахаренном уровне это поле нулевое!
        }
コード例 #7
0
        public procedure_definition lambda(function_lambda_definition _function_lambda_definition)
        {
            procedure_definition _func_def     = new procedure_definition();
            method_name          _method_name1 = new method_name(null, null, new ident(_function_lambda_definition.lambda_name), null);
            //parsertools.create_source_context(_method_name1, _method_name1.meth_name, _method_name1.meth_name);
            function_header _function_header1 = new function_header();

            object rt1 = new object();

            _function_header1.name = _method_name1;
            if (_function_header1.name.meth_name is template_type_name)
            {
                _function_header1.template_args = (_function_header1.name.meth_name as template_type_name).template_args;
                ident id = new ident(_function_header1.name.meth_name.name);
                //parsertools.create_source_context(id, _function_header1.name.meth_name, _function_header1.name.meth_name);
                _function_header1.name.meth_name = id;
            }

            formal_parameters fps = new PascalABCCompiler.SyntaxTree.formal_parameters();

            _function_header1.parameters = _function_lambda_definition.formal_parameters;//fps;

            /*SyntaxTree.named_type_reference _named_type_reference = new SyntaxTree.named_type_reference();
             * SyntaxTree.ident idtype = new SyntaxTree.ident("object");
             * _named_type_reference.source_context = idtype.source_context;
             * _named_type_reference.names.Add(idtype);
             * rt1 = _named_type_reference;
             * _function_header1.return_type = (SyntaxTree.type_definition)_named_type_reference;*/
            _function_header1.return_type = _function_lambda_definition.return_type;

            _function_header1.of_object     = false;
            _function_header1.class_keyword = false;
            token_info _token_info = new token_info("function");
            //_token_info.source_context = parsertools.GetTokenSourceContext();
            //parsertools.create_source_context(_function_header1, _token_info, _token_info);

            block          _block1 = new block(null, null);
            statement_list sl1     = new statement_list();

            sl1.subnodes.Add(_function_lambda_definition.proc_body);
            _block1.program_code  = sl1;
            _func_def.proc_header = _function_header1;
            _func_def.proc_body   = (proc_block)_block1;
            if (_function_lambda_definition.defs != null)
            {
                if (((block)_func_def.proc_body).defs == null)
                {
                    ((block)_func_def.proc_body).defs = new declarations();
                }
                for (int l = 0; l < _function_lambda_definition.defs.Count; l++)
                {
                    ((block)_func_def.proc_body).defs.defs.Add(_function_lambda_definition.defs[l] as procedure_definition);
                }
            }
            _function_lambda_definition.proc_definition = _func_def;
            //parsertools.create_source_context(_func_def, _function_header1, _function_header1);
            return(_func_def);
        }
コード例 #8
0
        public override void visit(function_lambda_definition ld)
        {
            if (ld.DescendantNodes().OfType <yield_node>().Count() > 0)
            {
                throw new SyntaxVisitorError("LAMBDA_EXPRESSIONS_CANNOT_CONTAIN_YIELD", ld.source_context);
            }

            //base.visit(ld); // SSM 15/07/16 - незачем обходить внутренности лямбды - мы и так ищем внутри них yield - этого в этом визиторе достаточно
        }
コード例 #9
0
        public override void visit(function_lambda_definition lambdaDefinition)
        {
            if (lambdaDefinition.formal_parameters != null && lambdaDefinition.formal_parameters.params_list != null && lambdaDefinition.formal_parameters.params_list.Count != 0)
            {
                var varDefsList = new List <statement>();
                for (var i = 0; i < lambdaDefinition.formal_parameters.params_list.Count; i++)
                {
                    var varType = lambdaDefinition.formal_parameters.params_list[i].vars_type is lambda_inferred_type?
                                  LambdaHelper.ConvertSemanticTypeToSyntaxType((type_node)((lambda_inferred_type)lambdaDefinition.formal_parameters.params_list[i].vars_type).real_type) :
                                      //new semantic_type_node(((lambda_inferred_type)lambdaDefinition.formal_parameters.params_list[i].vars_type).real_type): // SSM 29/12/18 поменял - пробую - не получилось
                                      lambdaDefinition.formal_parameters.params_list[i].vars_type;

                    for (var j = 0; j < lambdaDefinition.formal_parameters.params_list[i].idents.idents.Count; j++)
                    {
                        var           varName = "<>" + lambdaDefinition.formal_parameters.params_list[i].idents.idents[j].name;
                        SourceContext sc      = lambdaDefinition.formal_parameters.params_list[i].idents.idents[j].source_context;
                        var           vds     = new var_def_statement(new ident(lambdaDefinition.formal_parameters.params_list[i].idents.idents[j].name, sc), varType, sc);
                        vds.inital_value = new ident(varName, sc);
                        lambdaDefinition.formal_parameters.params_list[i].idents.idents[j].name = varName;
                        varDefsList.Add(new var_statement(vds, sc));
                    }
                }

                ((statement_list)lambdaDefinition.proc_body).subnodes.InsertRange(0, varDefsList);
            }

            var procDecl = LambdaHelper.ConvertLambdaNodeToProcDefNode(lambdaDefinition);

            _visitor.body_exists = true;
            _visitor.hard_node_test_and_visit(procDecl.proc_header);

            var newTreeNode = new CapturedVariablesTreeNodeLambdaScope(_currentTreeNode,
                                                                       lambdaDefinition,
                                                                       _visitor.context.func_stack.top().scope.ScopeNum, lambdaDefinition);

            _currentTreeNode.LambdasDefinedInScope.Add(newTreeNode);
            _currentLambdaScopeNodeStack.Push(newTreeNode);

            if (_currentTreeNode != null)
            {
                _currentTreeNode.ChildNodes.Add(newTreeNode);
            }
            _currentTreeNode = newTreeNode;
            _scopesCapturedVarsNodesDictionary.Add(_currentTreeNode.ScopeIndex, _currentTreeNode);

            VisitProcParameters(procDecl.proc_header.parameters);
            ProcessNode(procDecl.proc_body);

            _visitor.context.leave_block();
            _visitor.context.remove_lambda_function(procDecl.proc_header.name.meth_name.name, false);

            _currentTreeNode = _currentTreeNode.ParentNode;
            _currentLambdaScopeNodeStack.Pop();

            LambdaHelper.RemoveLambdaInfoFromCompilationContext(_visitor.context, lambdaDefinition);
        }
 public override void visit(function_lambda_definition fld)
 {
     countNestedLambdas += 1;
     if (countNestedLambdas > 10)
     {
         throw new SyntaxVisitors.SyntaxVisitorError("NESTED_LAMBDAS_MAXIMUM_10", fld.source_context);
     }
     ProcessNode(fld.proc_body);
     countNestedLambdas -= 1;
 }
コード例 #11
0
        public override void visit(function_lambda_definition fld)
        {
            BlockNamesStack.Add(new Dictionary <string, string>());
            var last = BlockNamesStack.Count - 1;

            for (var i = 0; i < fld.parameters.expressions.Count; i++)
            {
                var qname = (fld.parameters.expressions[i] as ident).name.ToLower();
                BlockNamesStack[last][qname] = "-fl"; // -fl - формальный параметр лямбды - это стоп в поиске в GetNewVariableName
            }
            base.visit(fld);
        }
コード例 #12
0
        public override void visit(function_lambda_definition fd)
        {
            PushNamespace(fd);
            if (fd.formal_parameters != null)
            {
                var allnames = fd.formal_parameters.params_list.SelectMany(tp => tp.idents.idents);
                foreach (var name in allnames)
                {
                    AddNameNewName(name, null); // null означает, что переименовывать не надо
                }
            }

            base.visit(fd);
            PopNamespace();
        }
        public override void visit(function_lambda_definition fld)
        {
            InLambda = true;
            // Исключить все параметры из idents
            foreach (var fid in fld.ident_list.idents)
            {
                var ind = idents.FindIndex(x => string.Compare(x.name, fid.name, true) == 0);
                if (ind != -1)
                {
                    idents.RemoveAt(ind);
                }
            }

            ProcessNode(fld.proc_body);
        }
コード例 #14
0
        /// <summary>
        /// Фиктивный блок, представляющий лямбда-выражение. Используется для обхода с целью получения списка захватываемых переменных
        /// </summary>
        /// <param name="lambdaDef"></param>
        /// <returns></returns>
        public static block CreateFictiveBlockForLambda(function_lambda_definition lambdaDef)
        {
            statement_list stmtList = new statement_list();

            if (lambdaDef.formal_parameters != null)
            {
                for (int i = 0; i < lambdaDef.formal_parameters.params_list.Count; i++)
                {
                    stmtList.subnodes.Add(SyntaxTreeNodesConstructor.CreateVarStatementNode(lambdaDef.formal_parameters.params_list[i].idents,
                                                                                            lambdaDef.formal_parameters.params_list[i].vars_type,
                                                                                            null));
                }
            }
            if (lambdaDef.return_type != null)
            {
                stmtList.subnodes.Add(SyntaxTreeNodesConstructor.CreateVarStatementNode("result", lambdaDef.return_type, null)); // переделать, не сработает, если тип возвращаемого значения не указан
            }
            stmtList.subnodes.AddRange((lambdaDef.proc_body as statement_list).subnodes);
            block resBlock = new block();

            resBlock.program_code = stmtList;
            return(resBlock);
        }
コード例 #15
0
        /// <summary>
        /// Заменяет x -> begin result := x.Print end;  на  x -> begin x.Print end  в случае если это один оператор и вызов метода
        ///
        /// </summary>
        public static bool TryConvertFuncLambdaBodyWithMethodCallToProcLambdaBody(function_lambda_definition lambdaDef)
        {
            var stl = lambdaDef.proc_body as SyntaxTree.statement_list;

            if (stl.expr_lambda_body)
            {
                // Очищаем от Result :=

                var ass = stl.list[0] as assign;
                if (ass != null && ass.to is ident && (ass.to as ident).name.ToLower() == "result")
                {
                    var f = ass.from;
                    if (f is method_call)
                    {
                        var ff = f as method_call;
                        stl.list[0]           = new procedure_call(ff, ff.source_context); // заменить result := Print(x) на Print(x)
                        lambdaDef.return_type = null;
                        return(true);
                    }
                }
            }

            return(false);
        }
コード例 #16
0
 public override void visit(function_lambda_definition fd)
 {
 }
コード例 #17
0
 public override void visit(function_lambda_definition fld)
 {
     LambdasCount++;
     base.visit(fld);
 }
コード例 #18
0
 public override void visit(function_lambda_definition fd)
 {
     // не заходить во внутренние лямбды
 }
コード例 #19
0
 public static void RemoveLambdaInfoFromCompilationContext(compilation_context context, function_lambda_definition lambdaDefinition)
 {
     if (context.converted_namespace != null &&
         context.converted_namespace.functions != null &&
         context.converted_namespace.functions.Any())
     // Если добавилось в глобальные функции, то удаляем оттуда
     {
         var lastIndex = context.converted_namespace.functions.Count - 1;
         if (context.converted_namespace.functions[lastIndex].name ==
             lambdaDefinition.lambda_name)
         {
             context.converted_namespace.functions.remove_at(lastIndex);
         }
     }
     //else SSM 27/04/16 - грубое исправление ошибки #147
     {
         // Если добавилась лямбда как метод класса, то удаляем оттуда
         if (context.converted_type != null &&
             context.converted_type.methods != null &&
             context.converted_type.methods.Any())
         {
             var lastIndex = context.converted_type.methods.Count - 1;
             if (context.converted_type.methods[lastIndex].name ==
                 lambdaDefinition.lambda_name)
             {
                 context.converted_type.methods.remove_at(lastIndex);
             }
         }
     }
 }
コード例 #20
0
        /// <summary>
        /// Вывод типа параметров лямбд и типа возвращаемого значения при присваивании лямбды переменной
        /// </summary>
        public static void InferTypesFromVarStmt(type_node leftType, function_lambda_definition lambdaDef, syntax_tree_visitor visitor, Operators op = Operators.Undefined)
        {
            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.SystemLibrary.system_delegate_type)
                    {
                        if (op != Operators.Undefined)
                        {
                            var sil = leftType.find_in_type(name_reflector.get_name(op));
                            if (sil != null && sil.Count > 0)
                            {
                                foreach (SymbolInfo si in sil)
                                {
                                    if (si.sym_info is function_node)
                                    {
                                        function_node fn = si.sym_info as function_node;
                                        if (fn.parameters.Count == 2)
                                        {
                                            dii_left = (delegate_internal_interface)fn.parameters[1].type.get_internal_interface(internal_interface_kind.delegate_interface);
                                            if (dii_left != null)
                                            {
                                                break;
                                            }
                                            if (fn.parameters[1].type.is_generic_parameter)
                                            {
                                                compiled_type_node ctn  = leftType as compiled_type_node;
                                                common_type_node   ctn2 = leftType as common_type_node;
                                                if (ctn != null && ctn.is_generic_type_instance && fn.parameters[0].type.is_generic_type_instance && ctn.original_generic == fn.parameters[0].type.original_generic)
                                                {
                                                    dii_left = (delegate_internal_interface)ctn.generic_params[0].get_internal_interface(internal_interface_kind.delegate_interface);
                                                    if (dii_left != null)
                                                    {
                                                        break;
                                                    }
                                                }
                                                if (ctn2 != null && ctn2.is_generic_type_instance && ctn2.instance_params.Count > 0 && fn.parameters[0].type.is_generic_type_instance && ctn2.original_generic == fn.parameters[0].type.original_generic)
                                                {
                                                    dii_left = (delegate_internal_interface)ctn2.instance_params[0].get_internal_interface(internal_interface_kind.delegate_interface);
                                                    if (dii_left != null)
                                                    {
                                                        break;
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                        if (dii_left == null)
                        {
                            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;
                    SyntaxTree.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 SyntaxTree.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;
                            param.source_context = lambdaDef.formal_parameters.source_context;
                            lambdaDefParamsTypes.Add(param);
                        }
                    }
                    for (int i = 0; i < leftTypeParamsNumber && flag; i++)
                    {
                        if (lambdaDefParamsTypes.params_list[i].vars_type is SyntaxTree.lambda_inferred_type)
                        {
                            if ((lambdaDefParamsTypes.params_list[i].vars_type as SyntaxTree.lambda_inferred_type).real_type is lambda_any_type_node)
                            {
                                var curLeftParType = dii_left.parameters[i].type;
                                lambdaDefParamsTypes.params_list[i].vars_type = new SyntaxTree.lambda_inferred_type();
                                (lambdaDefParamsTypes.params_list[i].vars_type as SyntaxTree.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()
                    {
                        // lambdaDef.usedkeyword == 1 // function
                        var b = lambdaDef.usedkeyword == 0 && TryConvertFuncLambdaBodyWithMethodCallToProcLambdaBody(lambdaDef); // пытаться конвертировать только если мы явно не указали, что это функция
                        if (!b)
                        {
                            visitor.AddError(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");
                        }
                    }
                }
            }
        }
コード例 #21
0
 public override void visit(function_lambda_definition fld)
 {
     // Нельзя Lowerить содержимое лямбды !!! Баг #1641!
 }
コード例 #22
0
ファイル: LambdaHelper.cs プロジェクト: ikvm/pascalabcnet
        /// <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.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;
                    SyntaxTree.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 SyntaxTree.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;
                            param.source_context = lambdaDef.formal_parameters.source_context;
                            lambdaDefParamsTypes.Add(param);
                        }
                    }
                    for (int i = 0; i < leftTypeParamsNumber && flag; i++)
                    {
                        if (lambdaDefParamsTypes.params_list[i].vars_type is SyntaxTree.lambda_inferred_type)
                        {
                            if ((lambdaDefParamsTypes.params_list[i].vars_type as SyntaxTree.lambda_inferred_type).real_type is lambda_any_type_node)
                            {
                                var curLeftParType = dii_left.parameters[i].type;
                                lambdaDefParamsTypes.params_list[i].vars_type = new SyntaxTree.lambda_inferred_type();
                                (lambdaDefParamsTypes.params_list[i].vars_type as SyntaxTree.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");
                        }
                    }
                }
            }
        }
コード例 #23
0
 public override void visit(function_lambda_definition node)
 {
     prepare_node(node.formal_parameters, "formal_parameters");
     prepare_node(node.return_type, "return_type");
 }
コード例 #24
0
 public virtual void visit(function_lambda_definition _function_lambda_definition)
 {
     DefaultVisit(_function_lambda_definition);
 }
コード例 #25
0
		public virtual void visit(function_lambda_definition _function_lambda_definition)
		{
			DefaultVisit(_function_lambda_definition);
		}
コード例 #26
0
		public override void visit(function_lambda_definition _function_lambda_definition)
		{
			DefaultVisit(_function_lambda_definition);
			pre_do_visit(_function_lambda_definition);
			visit(function_lambda_definition.ident_list);
			visit(function_lambda_definition.return_type);
			visit(function_lambda_definition.formal_parameters);
			visit(function_lambda_definition.proc_body);
			visit(function_lambda_definition.proc_definition);
			visit(function_lambda_definition.parameters);
			for (int i = 0; i < defs.Count; i++)
				visit(function_lambda_definition.defs[i]);
			visit(function_lambda_definition.substituting_node);
			post_do_visit(_function_lambda_definition);
		}
コード例 #27
0
		public virtual void post_do_visit(function_lambda_definition _function_lambda_definition)
		{
		}
コード例 #28
0
		public override void visit(function_lambda_definition _function_lambda_definition)
		{
			executer.visit(_function_lambda_definition);
			if (_function_lambda_definition.ident_list != null)
				this.visit((dynamic)_function_lambda_definition.ident_list);
			if (_function_lambda_definition.return_type != null)
				this.visit((dynamic)_function_lambda_definition.return_type);
			if (_function_lambda_definition.formal_parameters != null)
				this.visit((dynamic)_function_lambda_definition.formal_parameters);
			if (_function_lambda_definition.proc_body != null)
				this.visit((dynamic)_function_lambda_definition.proc_body);
			if (_function_lambda_definition.proc_definition != null)
				this.visit((dynamic)_function_lambda_definition.proc_definition);
			if (_function_lambda_definition.parameters != null)
				this.visit((dynamic)_function_lambda_definition.parameters);
			if (_function_lambda_definition.defs != null)
			foreach (dynamic x in _function_lambda_definition.defs)
				if(x != null)
					this.visit(x);
			if (_function_lambda_definition.attributes != null)
				this.visit((dynamic)_function_lambda_definition.attributes);
		}
 public HasCapturedLambdaParameterInInternalLambdaBody(function_lambda_definition fld)
 {
     idents = fld.ident_list.idents;
 }
 public static HasCapturedLambdaParameterInInternalLambdaBody New(function_lambda_definition fld)
 {
     return(new HasCapturedLambdaParameterInInternalLambdaBody(fld));
 }
コード例 #31
0
        public ident func_decl_lambda(object lr0, object lr2)
        {
            statement_list    _statement_list    = (statement_list)lr2;
            expression_list   _expression_list   = new expression_list();
            ident_list        _i_l               = new ident_list();
            formal_parameters _formal_parameters = new formal_parameters();

            if (lr0 != null)
            {
                List <object> ar = (List <object>)lr0;
                for (int i = 0; i < ar.Count; i++)
                {
                    if (ar[i] is ident)
                    {
                        _i_l.idents.Add((ident)ar[i]);
                    }
                    else
                    {
                        _i_l.idents.Add(((var_def_statement)ar[i]).vars.idents[0]);
                    }
                }

                for (int i = 0; i < _i_l.idents.Count; i++)
                {
                    _expression_list.expressions.Add(_i_l.idents[i]);
                }

                for (int i = 0; i < ar.Count; i++)
                {
                    ident_list _ident_list = new ident_list();
                    ident      id          = _i_l.idents[i];
                    _ident_list.idents.Add(id);
                    string           name_param        = id.name;
                    typed_parameters _typed_parameters = null;
                    int k = 0;
                    {
                        named_type_reference _named_type_reference = new named_type_reference();
                        type_definition      t_d = new type_definition();
                        if (ar[i] is ident)
                        {
                            ident idtype = new ident("object");
                            _named_type_reference.names.Add(idtype);
                            t_d = (type_definition)_named_type_reference;
                        }
                        else
                        {
                            t_d = ((var_def_statement)ar[i]).vars_type;
                        }
                        _typed_parameters = new typed_parameters(_ident_list, t_d, parametr_kind.none, null);
                        //parsertools.create_source_context(_typed_parameters, _ident_list, t_d);
                    }
                    _formal_parameters.params_list.Add(_typed_parameters);
                }
            }
            //////////////////////////
            named_type_reference _named_type_reference1 = new named_type_reference();
            ident idtype1 = new ident("object");

            _named_type_reference1.source_context = idtype1.source_context;
            _named_type_reference1.names.Add(idtype1);
            /////////////////////////////
            lambda_num++;
            function_lambda_definition _procedure_definition = new function_lambda_definition();

            _procedure_definition.formal_parameters = _formal_parameters;
            _procedure_definition.return_type       = (type_definition)_named_type_reference1;
            _procedure_definition.ident_list        = _i_l;
            _procedure_definition.proc_body         = null;
            _procedure_definition.parameters        = _expression_list;
            _procedure_definition.lambda_name       = "__lambda__" + lambda_num;
            //new function_lambda_definition(_formal_parameters, (type_definition)_named_type_reference1, _i_l, null, _expression_list, "lambda" + lambda_num);
            object rt = _i_l;

            _procedure_definition.proc_body = _statement_list;

            //////////////////////////////vnutrennie lambda
            if (_procedure_definition.defs == null)
            {
                _procedure_definition.defs = new List <declaration>();
            }
            while (pascalABC_lambda_definitions.Count > 0 && pascalABC_lambda_definitions[pascalABC_lambda_definitions.Count - 1] != null)
            {
                _procedure_definition.defs.Add(lambda((function_lambda_definition)pascalABC_lambda_definitions[pascalABC_lambda_definitions.Count - 1]));
                pascalABC_lambda_definitions.RemoveAt(pascalABC_lambda_definitions.Count - 1);
            }
            if (pascalABC_lambda_definitions.Count > 0 && pascalABC_lambda_definitions[pascalABC_lambda_definitions.Count - 1] == null)
            {
                pascalABC_lambda_definitions.RemoveAt(pascalABC_lambda_definitions.Count - 1);
            }
            pascalABC_lambda_definitions.Add(_procedure_definition);
            ///////////////////////////////////////////////
            //parsertools.create_source_context(_procedure_definition, _expression_list, rt);
            ident _name = new ident(_procedure_definition.lambda_name);

            if (lr0 != null)
            {
                _name.source_context = _i_l.idents[0].source_context;
            }
            return(_name);
        }
コード例 #32
0
 public override void visit(function_lambda_definition _function_lambda_definition)
 {
     throw new NotImplementedException();
 }
コード例 #33
0
 public override void visit(function_lambda_definition lambdaDef)
 {
     FoundLambda = lambdaDef;
     throw new LambdaIsFound();
 }
コード例 #34
0
 public virtual void visit(function_lambda_definition _function_lambda_definition)
 {
 }