Example #1
0
        /// <summary>
        /// Автовыведение типов в yield'ax.
        /// </summary>
        private void ProcessAssigntToAutoType(addressed_expression to, ref expression_node from)
        {
            var sequence = to.type as compiled_generic_instance_type_node;

            // SSM 26.06.16 - правка в связи с автовыведением типов в yieldах
            if (to.type is auto_type)
            {
                try_convert_typed_expression_to_function_call(ref from);
                if (to is class_field_reference)
                {
                    var cfr = to as class_field_reference;
                    cfr.field.type = from.type;
                    cfr.type       = from.type; // Это неверно работает когда yieldится процедура #1439
                    // SSM 1.11.18 попытка правки возвращения процедуры в yield
                    //if (from.type.semantic_node_type == semantic_node_type.delegated_method)

                    cfr.field.inital_value = context.GetInitalValueForVariable(cfr.field, cfr.field.inital_value);
                }
                else if (to is local_block_variable_reference)
                {
                    var lvr = to as local_block_variable_reference;
                    lvr.var.type         = from.type;
                    lvr.type             = from.type;
                    lvr.var.inital_value = context.GetInitalValueForVariable(lvr.var, lvr.var.inital_value);
                }
                else
                {
                    AddError(to.location, "Не могу вывести тип при наличии yield: " + to.type.full_name);
                }
                //to.type = from.type; // и без всякого real_type!
            }
            else if (sequence?.instance_params[0] is ienumerable_auto_type)
            {
                type_node elem_type = null;
                try_convert_typed_expression_to_function_call(ref from);
                bool bb; // здесь bb не нужно. Оно нужно в foreach
                var  b = FindIEnumerableElementType(from.type, ref elem_type, out bb);
                if (!b)
                {
                    AddError(from.location, "CAN_NOT_EXECUTE_FOREACH_BY_EXPR_OF_TYPE_{0}", from.type.full_name);
                }

                var IEnumType = new template_type_reference(new named_type_reference("System.Collections.Generic.IEnumerable"),
                                                            new template_param_list(new semantic_type_node(elem_type)));
                if (to is class_field_reference)
                {
                    var cfr = to as class_field_reference;

                    cfr.field.type = convert_strong(IEnumType);
                    cfr.type       = cfr.field.type;
                }
                else if (to is local_block_variable_reference)
                {
                    var lvr = to as local_block_variable_reference;

                    lvr.var.type = convert_strong(IEnumType); // замена типа у описания переменной
                    lvr.type     = lvr.var.type;              // замена типа у переменной
                }
            }
        }
Example #2
0
        /// <summary>
        /// Автовыведение типов в yield'ax.
        /// </summary>
        private void ProcessAssigntToAutoType(addressed_expression to, ref expression_node from)
        {
            var sequence = to.type as compiled_generic_instance_type_node;

            // SSM 26.06.16 - правка в связи с автовыведением типов в yieldах
            if (to.type is auto_type)
            {
                try_convert_typed_expression_to_function_call(ref from);
                if (to is class_field_reference)
                {
                    var cfr = to as class_field_reference;

                    if (from is typed_expression) // SSM 22.12.18 syntax_tree_visitor.cs 16066 - взял оттуда
                    {
                        base_function_call bfc = ((from as typed_expression).type as delegated_methods).proper_methods[0];

                        /*if (bfc.function.is_generic_function && _var_def_statement.vars_type == null)
                         * {
                         *  AddError(inital_value.location, "CAN_NOT_DEDUCE_TYPE_{0}", null);
                         * }
                         * foreach (parameter p in bfc.simple_function_node.parameters)
                         * {
                         *  if (p.type.is_generic_parameter)
                         *      AddError(inital_value.location, "USE_ANONYMOUS_FUNCTION_TYPE_WITH_GENERICS");
                         * } */
                        common_type_node del =
                            convertion_data_and_alghoritms.type_constructor.create_delegate(context.get_delegate_type_name(), bfc.simple_function_node.return_value_type, bfc.simple_function_node.parameters, context.converted_namespace, null);
                        context.converted_namespace.types.AddElement(del); //- сомневаюсь - контекст уже поменялся!
                        //tn = del;
                        from      = convertion_data_and_alghoritms.explicit_convert_type(from, del);
                        from.type = del;
                    }

                    cfr.field.type = from.type;
                    cfr.type       = from.type; // Это неверно работает когда yieldится процедура #1439
                                                // SSM 1.11.18 попытка правки возвращения процедуры в yield
                                                //if (from.type.semantic_node_type == semantic_node_type.delegated_method)
                                                //cfr.type.semantic_node_type = semantic_node_type.delegated_method;


                    cfr.field.inital_value = context.GetInitalValueForVariable(cfr.field, cfr.field.inital_value);
                }
                else if (to is local_block_variable_reference)
                {
                    var lvr = to as local_block_variable_reference;
                    lvr.var.type         = from.type;
                    lvr.type             = from.type;
                    lvr.var.inital_value = context.GetInitalValueForVariable(lvr.var, lvr.var.inital_value);
                }
                else
                {
                    AddError(to.location, "Не могу вывести тип при наличии yield: " + to.type.full_name);
                }
                //to.type = from.type; // и без всякого real_type!
            }
            else if (sequence?.instance_params[0] is ienumerable_auto_type)
            {
                type_node elem_type = null;
                try_convert_typed_expression_to_function_call(ref from);
                bool bb; // здесь bb не нужно. Оно нужно в foreach
                var  b = FindIEnumerableElementType(from.type, ref elem_type, out bb);
                if (!b)
                {
                    AddError(from.location, "CAN_NOT_EXECUTE_FOREACH_BY_EXPR_OF_TYPE_{0}", from.type.full_name);
                }

                var IEnumType = new template_type_reference(new named_type_reference("System.Collections.Generic.IEnumerable"),
                                                            new template_param_list(new semantic_type_node(elem_type)));
                if (to is class_field_reference)
                {
                    var cfr = to as class_field_reference;

                    cfr.field.type = convert_strong(IEnumType);
                    cfr.type       = cfr.field.type;
                }
                else if (to is local_block_variable_reference)
                {
                    var lvr = to as local_block_variable_reference;

                    lvr.var.type = convert_strong(IEnumType); // замена типа у описания переменной
                    lvr.type     = lvr.var.type;              // замена типа у переменной
                }
            }
        }
Example #3
0
 public override void visit(template_type_reference _template_type_reference)
 {
 }
Example #4
0
 public virtual void visit(template_type_reference _template_type_reference)
 {
     DefaultVisit(_template_type_reference);
 }
		public override void visit(template_type_reference _template_type_reference)
		{
			DefaultVisit(_template_type_reference);
			pre_do_visit(_template_type_reference);
			visit(template_type_reference.name);
			visit(template_type_reference.params_list);
			post_do_visit(_template_type_reference);
		}
		public virtual void post_do_visit(template_type_reference _template_type_reference)
		{
		}
Example #7
0
 public virtual void visit(template_type_reference _template_type_reference)
 {
 }
Example #8
0
 public override void visit(template_type_reference _template_type_reference)
 {
     throw new NotImplementedException();
 }
Example #9
0
        // frninja 21/05/16
        public override void visit(foreach_stmt frch)
        {
            // Полный код Loweringа c yield_unknown_foreach_type = integer
            //  var a: System.Collections.Generic.IEnumerable<integer>;
            //  a := l;
            //  var en := a.GetEnumerator();
            //  while en.MoveNext do
            //  begin
            //    var curr := en.Current; // var не нужно ставить если curr была описана раньше
            //    Print(curr);
            //  end;
            ///

            // var a: System.Collections.Generic.IEnumerable<yield_unknown_foreach_type> := l;
            var foreachCollIdent = this.NewForeachCollectionName();
            var foreachCollType  = new template_type_reference(new named_type_reference("System.Collections.Generic.IEnumerable"),
                                                               new template_param_list(new yield_unknown_foreach_type(frch)));
            var foreachCollVarDef = new var_statement(foreachCollIdent, foreachCollType);

            var ass = new assign(foreachCollIdent, frch.in_what);

            //  var en := a.GetEnumerator();
            var enumeratorIdent  = this.NewEnumeratorName();
            var enumeratorVarDef = new var_statement(enumeratorIdent, new method_call(new dot_node(foreachCollIdent, new ident("GetEnumerator")), new expression_list()));

            //var curr := en.Current;
            // Переменная цикла foreach. Есть три варианта:
            // 1. foreach x in l do           ->    curr := en.Current;
            // 2. foreach var x in l do       ->    var curr := en.Current;
            // 3. foreach var x: T in l do    ->    var curr: T := en.Current;
            var       currentIdent = frch.identifier;
            statement st           = null;

            var curExpr = new dot_node(enumeratorIdent, "Current");

            // С типом
            if (frch.type_name == null) // 1. foreach x in l do   ->   curr := en.Current;
            {
                st = new assign(currentIdent, curExpr);
            }
            else if (frch.type_name is no_type_foreach) // 2. foreach var x in l do    ->    var curr := en.Current;
            {
                // Получаем служебное имя с $ и заменяем его в теле цикла
                currentIdent = this.NewVarNames(frch.identifier).VarName;
                var replacerVis = new ReplaceVariableNameVisitor(frch.identifier, currentIdent);
                frch.visit(replacerVis);

                st = new var_statement(currentIdent, curExpr);
            }
            else // 3. foreach var x: T in l do    ->    var curr: T := en.Current;
            {
                // Получаем служебное имя с $ и заменяем его в теле цикла
                currentIdent = this.NewVarNames(frch.identifier).VarName;
                var replacerVis = new ReplaceVariableNameVisitor(frch.identifier, currentIdent);
                frch.visit(replacerVis);

                st = new var_statement(currentIdent, frch.type_name, curExpr);
            }

            // Добавляем тело цикла в stl
            var stl = new statement_list(st);

            ProcessNode(frch.stmt); // для обработки вложенных конструкций
            stl.Add(frch.stmt);

            var whileNode = new while_node(new method_call(new dot_node(enumeratorIdent, "MoveNext"), new expression_list()),
                                           stl,
                                           WhileCycleType.While);

            var sq = SeqStatements(foreachCollVarDef, ass, enumeratorVarDef, whileNode);

            ReplaceStatement(frch, sq);

            visit(whileNode); // Lowering оставшегося whileNode
        }
Example #10
0
        type_declarations GenClassesForYield(procedure_definition pd, IEnumerable <var_def_statement> fields)
        {
            var fh = (pd.proc_header as function_header);

            if (fh == null)
            {
                throw new SyntaxError("Only functions can contain yields", "", pd.proc_header.source_context, pd.proc_header);
            }
            var seqt = fh.return_type as sequence_type;

            if (seqt == null)
            {
                throw new SyntaxError("Functions with yields must return sequences", "", fh.return_type.source_context, fh.return_type);
            }

            // Теперь на месте функции генерируем класс

            // Захваченные переменные
            var cm = class_members.Public;

            foreach (var m in fields)
            {
                cm.Add(m);
            }

            // Параметры функции
            List <ident> lid  = new List <ident>();
            var          pars = fh.parameters;

            if (pars != null)
            {
                foreach (var ps in pars.params_list)
                {
                    if (ps.param_kind != parametr_kind.none)
                    {
                        throw new SyntaxError("Parameters of functions with yields must not have 'var', 'const' or 'params' modifier", "", pars.source_context, pars);
                    }
                    if (ps.inital_value != null)
                    {
                        throw new SyntaxError("Parameters of functions with yields must not have initial values", "", pars.source_context, pars);
                    }
                    var_def_statement vds = new var_def_statement(ps.idents, ps.vars_type);
                    cm.Add(vds); // все параметры функции делаем полями класса
                    lid.AddRange(vds.vars.idents);
                }
            }

            var stels = seqt.elements_type;

            // Системные поля и методы для реализации интерфейса IEnumerable
            cm.Add(new var_def_statement(Consts.State, "integer"),
                   new var_def_statement(Consts.Current, stels),
                   procedure_definition.EmptyDefaultConstructor,
                   new procedure_definition("Reset"),
                   new procedure_definition("MoveNext", "boolean", pd.proc_body),
                   new procedure_definition("get_Current", "object", new assign("Result", Consts.Current)),
                   new procedure_definition("GetEnumerator", "System.Collections.IEnumerator", new assign("Result", "Self"))
                   );

            var className       = newClassName();
            var classNameHelper = className + "Helper";

            var interfaces = new named_type_reference_list("System.Collections.IEnumerator", "System.Collections.IEnumerable");
            var td         = new type_declaration(classNameHelper, SyntaxTreeBuilder.BuildClassDefinition(interfaces, cm));

            // Изменение тела процедуры

            var stl = new statement_list(new var_statement("res", new new_expr(className)));

            stl.AddMany(lid.Select(id => new assign(new dot_node("res", id), id)));
            stl.Add(new assign("Result", "res"));
            pd.proc_body = new block(stl);

            // Второй класс

            var tpl = new template_param_list(stels);

            var IEnumeratorT = new template_type_reference("System.Collections.Generic.IEnumerator", tpl);

            var cm1 = class_members.Public.Add(
                procedure_definition.EmptyDefaultConstructor,
                new procedure_definition(new function_header("get_Current", stels), new assign("Result", Consts.Current)),
                new procedure_definition(new function_header("GetEnumerator", IEnumeratorT), new assign("Result", "Self")),
                new procedure_definition("Dispose")
                );

            var interfaces1  = new named_type_reference_list(classNameHelper);
            var IEnumerableT = new template_type_reference("System.Collections.Generic.IEnumerable", tpl);

            interfaces1.Add(IEnumerableT).Add(IEnumeratorT);

            var td1 = new type_declaration(className, SyntaxTreeBuilder.BuildClassDefinition(interfaces1, cm1));

            var cct = new type_declarations(td);

            cct.Add(td1);

            return(cct);
        }
Example #11
0
		public virtual void visit(template_type_reference _template_type_reference)
		{
		}
		public virtual void visit(template_type_reference _template_type_reference)
		{
			DefaultVisit(_template_type_reference);
		}
Example #13
0
 public override void visit(template_type_reference _template_type_reference)
 {
     prepare_node(_template_type_reference.name, "name");
     prepare_node(_template_type_reference.params_list, "params_list");
 }
Example #14
0
		public override void visit(template_type_reference _template_type_reference)
		{
			executer.visit(_template_type_reference);
			if (_template_type_reference.name != null)
				this.visit((dynamic)_template_type_reference.name);
			if (_template_type_reference.params_list != null)
				this.visit((dynamic)_template_type_reference.params_list);
			if (_template_type_reference.names != null)
			foreach (dynamic x in _template_type_reference.names)
				if(x != null)
					this.visit(x);
			if (_template_type_reference.attr_list != null)
				this.visit((dynamic)_template_type_reference.attr_list);
			if (_template_type_reference.attributes != null)
				this.visit((dynamic)_template_type_reference.attributes);
		}