Ejemplo n.º 1
0
		public void write_closure_substituting_node(closure_substituting_node _closure_substituting_node)
		{
			write_ident(_closure_substituting_node);
			if (_closure_substituting_node.substitution == null)
			{
				bw.Write((byte)0);
			}
			else
			{
				bw.Write((byte)1);
				_closure_substituting_node.substitution.visit(this);
			}
		}
Ejemplo n.º 2
0
		public void visit(closure_substituting_node _closure_substituting_node)
		{
			bw.Write((Int16)198);
			write_closure_substituting_node(_closure_substituting_node);
		}
        /* Этот код мешает. Может, его убрать?
         
        public override void visit(SyntaxTree.function_lambda_definition _function_lambda_definition)
        {
        SyntaxTree.procedure_definition _func_def = new PascalABCCompiler.SyntaxTree.procedure_definition();
        SyntaxTree.method_name _method_name = new SyntaxTree.method_name(null, new SyntaxTree.ident("$a"), null);
        SyntaxTree.function_header _function_header = new SyntaxTree.function_header();

        object rt = new object();
        _function_header.name = _method_name;
        SyntaxTree.formal_parameters fps=new PascalABCCompiler.SyntaxTree.formal_parameters();
        for (int i = 0; i < _function_lambda_definition.formal_parameters.params_list.Count; i++)
        {
            SyntaxTree.ident_list _ident_list = new SyntaxTree.ident_list();
            SyntaxTree.ident id =_function_lambda_definition.formal_parameters.params_list[i].idents.idents[0];
            _ident_list.idents.Add(id);
            SyntaxTree.named_type_reference _named_type_reference1 = new SyntaxTree.named_type_reference();
            SyntaxTree.ident idtype1 = new SyntaxTree.ident("datatype");
            _named_type_reference1.names.Add(idtype1);
            SyntaxTree.typed_parameters _typed_parametres = new SyntaxTree.typed_parameters(_ident_list, (SyntaxTree.type_definition)_named_type_reference1, SyntaxTree.parametr_kind.none, null);
            fps.params_list.Add(_typed_parametres);
        }
        _function_header.parameters = fps;
        fps.visit(this);
        SyntaxTree.named_type_reference _named_type_reference = new SyntaxTree.named_type_reference();
        SyntaxTree.ident idtype = new SyntaxTree.ident("datatype");
        _named_type_reference.source_context = idtype.source_context;
        _named_type_reference.names.Add(idtype);

        rt = _named_type_reference;
        _function_header.return_type = (SyntaxTree.type_definition)_named_type_reference;

        _function_header.of_object = false;
        _function_header.class_keyword = false;
        SyntaxTree.block _block = new SyntaxTree.block(null, null);
        SyntaxTree.statement_list sl = new SyntaxTree.statement_list();
        sl.subnodes.Add(_function_lambda_definition.proc_body);
        _block.program_code = sl;
        _func_def.proc_header = _function_header;
        _func_def.proc_body = (SyntaxTree.proc_block)_block;
        _func_def.visit(this);
        expressions_list el = new expressions_list();
        foreach (SyntaxTree.expression en in _function_lambda_definition.parameters.expressions)
        {
            el.AddElement(convert_strong(en));
        }
        function_node fn = find_function("$a", get_location(_function_header), el);*/
        ///////////////////////////////////////////////////////////////////////////


            /*hard_node_test_and_visit(_function_lambda_definition.formal_parameters);
            hard_node_test_and_visit(_function_lambda_definition.proc_body);

            CheckToEmbeddedStatementCannotBeADeclaration(_function_lambda_definition.proc_body);
            statement_node body = convert_strong(_function_lambda_definition.proc_body);
            //context.leave_code_block();
            type_node tp = convert_strong(_function_lambda_definition.return_type);
            parameter_list pl = new parameter_list();
            for (int i = 0; i < _function_lambda_definition.formal_parameters.params_list.Count; i++)
            {
                common_parameter cp = new common_parameter(_function_lambda_definition.formal_parameters.params_list[i].idents.idents[0].name,
                            SemanticTree.parameter_type.value, null,
                            concrete_parameter_type.cpt_none, get_location(_function_lambda_definition.formal_parameters.params_list[i].idents.idents[0]));
                pl.AddElement(cp);
            }

            function_lambda_node fln = new function_lambda_node(pl, tp, body);
            fln.type = tp;
            //fln.function = fn;
            return_value(fln);*/


            //lroman// 
            /*LambdaHelper.captureCheck = true; //захват пока не делаем
            var block = LambdaHelper.CreateFictiveBlockForLambda(_function_lambda_definition);
            context.create_lambda();
            hard_node_test_and_visit(block.program_code);
            context.remove_lambda();
            LambdaHelper.captureCheck = false;*/

            //if (LambdaHelper.capturedVariables.Count == 0)


        // SSM - 15.1.2014
        //public void proba_after_visit_function_lambda_definition(SyntaxTree.function_lambda_definition _function_lambda_definition, SyntaxTree.procedure_definition pd)
        //{
        //    var fvisbody = new FindMainIdentsVisitor();
        //    fvisbody.ProcessNode(_function_lambda_definition.proc_body);

        //    var fvisparams = new FindMainIdentsVisitor();
        //    fvisparams.ProcessNode(_function_lambda_definition.formal_parameters);

        //    var fvislocaldefs = new FindLocalDefsVisitor();
        //    fvislocaldefs.ProcessNode(_function_lambda_definition.proc_body);
        //    fvislocaldefs.vars.Add("result");

        //    var candidates = fvisbody.vars.Except(fvisparams.vars, StringComparer.OrdinalIgnoreCase).Except(fvislocaldefs.vars, StringComparer.OrdinalIgnoreCase).ToArray();

        //    List<SyntaxTree.ident> li = new List<SyntaxTree.ident>();
        //    List<SyntaxTree.type_definition> lt = new List<SyntaxTree.type_definition>();
        //    SymbolInfo si;
        //    foreach (var x in candidates)
        //    {
        //        si = context.find(x);
        //        var tp = si.sym_info.GetType();
        //        if (tp == typeof(TreeRealization.local_block_variable) || tp == typeof(TreeRealization.local_variable))
        //        {
        //            var id = new SyntaxTree.ident(x);
        //            li.Add(id);
        //            var typ = ident_value_reciving(id).type;
        //            lt.Add(SyntaxTreeBuilder.BuildSemanticType(typ));
        //            // Попытаемся определить их типы
        //        }
        //        else if (tp == typeof(TreeRealization.class_field))
        //        {
        //            // Поля класса тоже захватываем! 
        //            var id = new SyntaxTree.ident(x);
        //            li.Add(id);
        //            var typ = ident_value_reciving(id).type;
        //            lt.Add(SyntaxTreeBuilder.BuildSemanticType(typ));
        //        }
        //        else if (tp == typeof(TreeRealization.common_parameter))
        //        {
        //            // И параметры метода/подпрограммы тоже захватываем! 
        //            var id = new SyntaxTree.ident(x);
        //            li.Add(id);
        //            var typ = ident_value_reciving(id).type;
        //            lt.Add(SyntaxTreeBuilder.BuildSemanticType(typ));
        //        }
        //    }

        //    var UNS = UniqueNumStr();
        //    var LambdaClassName = "#LambdaClassName" + UNS;
            
        //    //if (li.Count > 0)
        //    {
        //        contextChanger.SaveContextAndUpToGlobalLevel();
        //        var bt = SyntaxTreeBuilder.BuildClassWithOneMethod(LambdaClassName, li, lt, pd);
        //        visit(bt); // добавили класс __A в раздел описаний
        //        contextChanger.RestoreCurrentContext();
        //    }

        //    /* другая версия кода внизу
        //     * var ttp = new SyntaxTree.named_type_reference("__A", null);
        //    type_node semttp = convert_strong(ttp);

        //    common_function_node topfun = context.func_stack.top();
        //    local_variable lv = new local_variable("a1", semttp, topfun, null);

        //    topfun.var_definition_nodes_list.AddElement(lv);
        //    context.CurrentScope.AddSymbol("a1", new SymbolInfo(lv));*/

        //    // теперь сформируем семантический узел вида a1 := new __A()
        //    var ttp = new SyntaxTree.named_type_reference(LambdaClassName, null);
        //    type_node semttp = convert_strong(ttp);

        //    var LambdaVarName = "#LambdaVarName" + UNS;
        //    context.add_var_definition(LambdaVarName, null, semttp, SemanticTree.polymorphic_state.ps_common); // добавление описания локальной переменной. Все такие описания в .NET-коде делаются перед любыми операторами

        //    SyntaxTree.expression_list el = new SyntaxTree.expression_list();
        //    for (int i = 0; i < li.Count; i++)
        //        el.Add(li[i]);
        //    var nex = new SyntaxTree.new_expr(ttp, el, null);
        //    var ass = new SyntaxTree.assign(LambdaVarName, nex);
        //    var sass = convert_strong(ass);

        //    // теперь добавим этот узел в конец самого верхнего statement_list текущей функции
        //    var sf = convertion_data_and_alghoritms.statement_list_stack.first();
        //    sf.statements.AddElement(sass);

        //    var dn = new SyntaxTree.dot_node(new SyntaxTree.ident(LambdaVarName), pd.proc_header.name.meth_name);
        //    visit(dn);
        //}

        public override void visit(closure_substituting_node _closure_substituting_node)
        {
            visit(_closure_substituting_node.substitution);
        }
        private void SubstituteInNode(syntax_tree_node currentNode, syntax_tree_node nodeWhereSubstitute)
        {
            var identSubnodesIndexes = Enumerable
                .Range(0, nodeWhereSubstitute.subnodes_count)
                .Where(index => nodeWhereSubstitute[index] is ident)
                .ToList();

            if (nodeWhereSubstitute is for_node) //нужно исключить переменную цикла, так как она оброабатывается отдельно в SubstituteForLoopVariables
            {
                var fn = (for_node) nodeWhereSubstitute;
                var indexWithLoopIdent = identSubnodesIndexes.First(ind =>
                    {
                        var id = nodeWhereSubstitute[ind] as ident;
                        if (id == null)
                        {
                            return false;
                        }
                        return id == fn.loop_variable;
                    });

                identSubnodesIndexes.Remove(indexWithLoopIdent);
            }

            if (nodeWhereSubstitute is foreach_stmt) //нужно исключить переменную цикла, так как она оброабатывается отдельно в SubstituteForEachLoopVariables
            {
                var fn = (foreach_stmt)nodeWhereSubstitute;
                var indexWithLoopIdent = identSubnodesIndexes.First(ind =>
                {
                    var id = nodeWhereSubstitute[ind] as ident;
                    if (id == null)
                    {
                        return false;
                    }
                    return id == fn.identifier;
                });

                identSubnodesIndexes.Remove(indexWithLoopIdent);
            }

            if (identSubnodesIndexes.Count == 0)
            {
                return;
            }

            var keys = _substitutionsInfo
                .Keys
                .Where(k => k.IsPartialKeyEquals(currentNode))
                .Where(k => _identsReferences.ContainsKey(k));
            
            foreach (var key in keys)
            {
                var subst = _substitutionsInfo[key];
                foreach (var id in _identsReferences[key])
                {
                    for (var i = 0; i < identSubnodesIndexes.Count; i++)
                    {
                        if (nodeWhereSubstitute[identSubnodesIndexes[i]] == id)
                        {
                            nodeWhereSubstitute[identSubnodesIndexes[i]] = new closure_substituting_node(subst);
                        }
                    }
                }
            }
        }
		public void read_closure_substituting_node(closure_substituting_node _closure_substituting_node)
		{
			read_ident(_closure_substituting_node);
			_closure_substituting_node.substitution = _read_node() as dot_node;
		}
		public void visit(closure_substituting_node _closure_substituting_node)
		{
			read_closure_substituting_node(_closure_substituting_node);
		}