Exemple #1
0
 /// <summary>
 /// Конструктор узла.
 /// </summary>
 /// <param name="ret_type">Тип возвращаемого значения функции.</param>
 public function_lambda_node(parameter_list parameters, type_node ret_type, statement_node body)
 {
     _parameters = parameters;
     _ret_type = ret_type;
     _body = body;
 }
Exemple #2
0
        /// <summary>
        /// Конструктор узла.
        /// </summary>
        /// <param name="mi">Оборачиваемый метод.</param>
		private compiled_function_node(System.Reflection.MethodInfo mi)
		{
			_mi=mi;
			type_node ret_val=null;
			if (_mi.ReturnType!=null)
			{
				ret_val=compiled_type_node.get_type_node(mi.ReturnType);
                if (ret_val == SystemLibrary.SystemLibrary.void_type)
                {
                    ret_val = null;
                }
			}
			System.Reflection.ParameterInfo[] pinf=mi.GetParameters();
            parameter_list pal = new parameter_list();
            //if (!(_mi.IsGenericMethod))
            {
                int i = 1;
                foreach (System.Reflection.ParameterInfo pi in pinf)
                {
                    Type t = null;
                    
                    type_node par_type = null;
                    SemanticTree.parameter_type pt = SemanticTree.parameter_type.value;
//                    if (pi.ParameterType.Name.EndsWith("&") == true)
                    //(ssyy) Лучше так:
                    if (pi.ParameterType.IsByRef)
                    {
                        //t = pi.ParameterType.Assembly.GetType(pi.ParameterType.FullName.Substring(0, pi.ParameterType.FullName.Length - 1));
                        //(ssyy) Лучше так:
                        t = pi.ParameterType.GetElementType();
                        par_type = compiled_type_node.get_type_node(t);
                        pt = SemanticTree.parameter_type.var;
                    }
                    else
                    {
                        if (pi.Position == 0)
                        {
                            par_type = compiled_type_node.get_type_node(pi.ParameterType);
                            if (NetHelper.NetHelper.IsExtensionMethod(mi))
                            {
                                connected_to_type = par_type as compiled_type_node;
                            }
                        }
                    }
                    string name = pi.Name;
                    compiled_parameter crpar = new compiled_parameter(pi);
                    crpar.SetParameterType(pt);
                    pal.AddElement(crpar);
                    if (pi.IsOptional && pi.DefaultValue != null)
                        _num_of_default_parameters++;
                    i++;
                }
            }
            //else
            if (_mi.IsGenericMethod)
            {
                _generic_params_count = mi.GetGenericArguments().Length;
            }
            _is_extension_method = NetHelper.NetHelper.IsExtensionMethod(mi);
			this.return_value_type=ret_val;
			this.parameters.AddRange(pal);
		}
Exemple #3
0
        //TODO: Возможно объеденить с compiled_function_node
		private compiled_constructor_node(System.Reflection.ConstructorInfo con_info)
		{
			_con_info=con_info;
            compiled_constructors[con_info] = this;
            //type_node ret_val=null;
			System.Reflection.ParameterInfo[] pinf=_con_info.GetParameters();
			parameter_list pal=new parameter_list();
			foreach(System.Reflection.ParameterInfo pi in pinf)
			{
				Type t=null;
				type_node par_type=null;
				SemanticTree.parameter_type pt=SemanticTree.parameter_type.value;
				if (pi.ParameterType.IsByRef) 
				{
					t=pi.ParameterType.GetElementType();
					par_type=compiled_type_node.get_type_node(t);
					pt=SemanticTree.parameter_type.var;
				}
				else
				{
					par_type=compiled_type_node.get_type_node(pi.ParameterType);
				}
				string name=pi.Name;
				compiled_parameter crpar=new compiled_parameter(pi);
				crpar.SetParameterType(pt);
				pal.AddElement(crpar);
                if (pi.IsOptional && pi.DefaultValue != null)
                    _num_of_default_parameters++;
			}
			this.return_value_type=compiled_type_node.get_type_node(_con_info.DeclaringType);
			this.parameters.AddRange(pal);
		}
        private common_type_node convert_function_type(SyntaxTree.formal_parameters syn_parametres, SyntaxTree.type_definition return_type,
            location loc, string type_name, common_type_node del_type)
        {
            //TODO: Добавить аттрибуты функции. Или не надо?
            //TODO: Сообщать о том что class keyword и of object игнорируется.
            parameter_list parameters = new parameter_list();
            bool params_met=false;
            if (syn_parametres != null)
            {
                parameter_list temp_params = new parameter_list();
                foreach (SyntaxTree.typed_parameters tpars in syn_parametres.params_list)
                {
                    temp_params.clear();
                    SemanticTree.parameter_type pt = SemanticTree.parameter_type.value;
                    concrete_parameter_type cpt = concrete_parameter_type.cpt_none;
                    switch (tpars.param_kind)
                    {
                        //TODO: Params parameter.
                        case SyntaxTree.parametr_kind.var_parametr:
                            {
                                pt = SemanticTree.parameter_type.var;
                                cpt = concrete_parameter_type.cpt_var;
                                break;
                            }
                        case PascalABCCompiler.SyntaxTree.parametr_kind.const_parametr:
                            {
                                pt = SemanticTree.parameter_type.value;
                                cpt = concrete_parameter_type.cpt_const;
                                break;
                            }
                        case PascalABCCompiler.SyntaxTree.parametr_kind.out_parametr:
                            {
                                pt = SemanticTree.parameter_type.var;
                                cpt = concrete_parameter_type.cpt_var;
                                break;
                            }
                    }
                    foreach (SyntaxTree.ident id in tpars.idents.idents)
                    {
                        common_parameter cp = new common_parameter(id.name, pt, null, cpt, get_location(id));
                        parameters.AddElement(cp);
                        if (tpars.param_kind == SyntaxTree.parametr_kind.params_parametr)
                        {
                        	cp.intrenal_is_params = true;
                        }
                        temp_params.AddElement(cp);
                    }
                    if (tpars.param_kind == SyntaxTree.parametr_kind.params_parametr)
            		{
                		if (tpars.idents.idents.Count > 1)
                		{
                            AddError(get_location(tpars.idents.idents[1]), "ONLY_ONE_PARAMS_PARAMETER_ALLOWED");
                		}
            		}

            		SyntaxTree.array_type arr = tpars.vars_type as SyntaxTree.array_type;
            		if (tpars.vars_type is SyntaxTree.class_definition || /*tpars.vars_type is SyntaxTree.enum_type_definition ||*/
                        (arr != null && arr.indexers != null && arr.indexers.indexers.Count > 0 && arr.indexers.indexers[0] != null))
            		{
                        AddError(get_location(tpars.vars_type), "STRUCT_TYPE_DEFINITION_IN_FORMAL_PARAM");
            		}
            		
                    type_node tp = convert_strong(tpars.vars_type);

                    /*if (depended_from_generic_parameter(tp)) // SSM 25/07/13 - закомментировал и пока всё работает
                    {
                        AddError(new DelegateCanNotUseComprehensiveGenericParameter(get_location(tpars.vars_type)));
                    }*/

                    if (tpars.param_kind == SyntaxTree.parametr_kind.params_parametr)
            		{
                		internal_interface ii = tp.get_internal_interface(internal_interface_kind.unsized_array_interface);
                		if (ii == null)
                		{
                            AddError(get_location(tpars.vars_type), "ONLY_UNSIZED_ARRAY_PARAMS_PARAMETER_ALLOWED");
                		}
            		}
                    foreach (common_parameter ccp in temp_params)
                    {
                        ccp.type = tp;
                    }
                   
                    
                    if (params_met)
                	{
                        AddError(get_location(tpars), "ONLY_LAST_PARAMETER_CAN_BE_PARAMS");
                	}
                	if (tpars.param_kind == PascalABCCompiler.SyntaxTree.parametr_kind.params_parametr)
                	{
                    	params_met = true;
//                    	if (default_value_met)
//                    	{
//                        	AddError(new FunctionWithParamsParameterCanNotHaveDefaultParameters(get_location(tp)));
//                    	}
                	}
                }
                
            }
            type_node ret_val_type = null;
            if (return_type != null)
            {
                ret_val_type = convert_strong(return_type);
                /*if (depended_from_generic_parameter(ret_val_type))  // SSM 25/07/13 - закомментировал и пока всё работает
                {
                    AddError(new DelegateCanNotUseComprehensiveGenericParameter(get_location(return_type)));
                }*/
            }
            common_type_node del;
            if (del_type == null)
            {
                del = convertion_data_and_alghoritms.type_constructor.create_delegate(type_name,
                        ret_val_type, parameters, context.converted_namespace, loc);
            }
            else
            {
                del = del_type;
                convertion_data_and_alghoritms.type_constructor.init_delegate(del, ret_val_type, parameters, loc);
            }
            context.converted_namespace.types.AddElement(del);
            return del;
        }
        //TODO: Если одного из акцессоров нет?
        public override void visit(SyntaxTree.simple_property _simple_property)
        {
            if (_simple_property.accessors == null)
                AddError(get_location(_simple_property), "PROPERTYACCESSOR_{0}_OR_{1}_EXPECTED", compiler_string_consts.PascalReadAccessorName, compiler_string_consts.PascalWriteAccessorName);
            if (_simple_property.property_type == null)
                AddError(get_location(_simple_property.property_name), "TYPE_NAME_EXPECTED");
            common_property_node pn = context.add_property(_simple_property.property_name.name,
                get_location(_simple_property.property_name));
            assign_doc_info(pn, _simple_property);
            //pn.polymorphic_state=SemanticTree.polymorphic_state.ps_common;
            //pn.loc=get_location(_simple_property.property_name);
            if (_simple_property.attr == SyntaxTree.definition_attribute.Static)
            	pn.polymorphic_state = SemanticTree.polymorphic_state.ps_static;
            parameter_list pal_big = new parameter_list();
            //TODO: Спросить у Саши как получить тип параметра - var,const и т.д.
            if (_simple_property.parameter_list != null)
            {
                foreach (SyntaxTree.property_parameter pp in _simple_property.parameter_list.parameters)
                {
                    parameter_list pal_small = new parameter_list();
                    foreach (SyntaxTree.ident id in pp.names.idents)
                    {
                        common_parameter cp = new common_parameter(id.name, SemanticTree.parameter_type.value, null,
                            concrete_parameter_type.cpt_none, get_location(id));
                        pal_small.AddElement(cp);
                    }
                    type_node tn = convert_strong(pp.type);
                    foreach (parameter pr in pal_small)
                    {
                        pr.type = tn;
                    }
                    pal_big.AddRange(pal_small);
                }
            }
            pn.parameters.AddRange(pal_big);
            pn.internal_property_type = convert_strong(_simple_property.property_type);

            if (_simple_property.accessors != null)
            {

                convertion_data_and_alghoritms.check_node_parser_error(_simple_property.accessors);

                SymbolInfo si = null;
                //definition_node dn = null;

                if (_simple_property.accessors.read_accessor != null)
                {
                    convertion_data_and_alghoritms.check_node_parser_error(_simple_property.accessors.read_accessor);
                    if (_simple_property.accessors.read_accessor.accessor_name == null)
                    {
                        if (!context.converted_type.IsInterface)
                        {
                            AddError(get_location(_simple_property.accessors.read_accessor), "ACCESSOR_NAME_EXPECTED");
                        }
                        pn.internal_get_function = GenerateGetSetMethodForInterfaceProperty(pn, get_location(_simple_property.accessors.read_accessor), true);
                    }
                    else
                    {
                        convertion_data_and_alghoritms.check_node_parser_error(_simple_property.accessors.read_accessor.accessor_name);
                        si = context.converted_type.find_in_type(_simple_property.accessors.read_accessor.accessor_name.name, context.CurrentScope);

                        location loc1 = get_location(_simple_property.accessors.read_accessor.accessor_name);

                        if (si == null)
                        {
                            AddError(new UndefinedNameReference(_simple_property.accessors.read_accessor.accessor_name.name, loc1));
                        }

                        //dn = check_name_node_type(_simple_property.accessors.read_accessor.accessor_name.name,
                        //    si, loc1, general_node_type.function_node, general_node_type.variable_node);

                        function_node read_accessor = si.sym_info as function_node;

                        if (read_accessor != null)
                        {
                            bool good_func = true;
                            bool one_func = si.Next == null;
                            while (si != null)
                            {
                                good_func = true;
                                if (read_accessor.parameters.Count != pn.parameters.Count)
                                {
                                    good_func = false;
                                    if (one_func)
                                    {
                                        AddError(new PropertyAndReadAccessorParamsCountConvergence(read_accessor, pn, loc1));
                                    }
                                }
                                //TODO: Сверять типы параметров - var, const и т.д.
                                else
                                {
                                    for (int i1 = 0; good_func && i1 < read_accessor.parameters.Count; i1++)
                                    {
                                        if (read_accessor.parameters[i1].parameter_type != pn.parameters[i1].parameter_type ||
                                            read_accessor.parameters[i1].type != pn.parameters[i1].type)
                                        {
                                            good_func = false;
                                            if (one_func)
                                            {
                                                AddError(loc1, "PROPERTY_{0}_AND_READ_ACCESSOR_{1}_PARAMS_TYPE_CONVERGENCE", pn.name, read_accessor.name);
                                            }
                                        }
                                    }
                                    if (read_accessor.return_value_type == null)
                                    {
                                        good_func = false;
                                        if (one_func)
                                        {
                                            AddError(loc1, "PROPERTY_READ_ACCESSOR_CAN_NOT_BE_PROCEDURE");
                                        }
                                    }
                                    if (read_accessor.return_value_type != pn.property_type)
                                    {
                                        good_func = false;
                                        if (one_func)
                                        {
                                            AddError(loc1, "PROPERTY_{0}_AND_READ_ACCESSOR_{1}_RETURN_VALUE_TYPE_CONVERGENCE", pn.name, read_accessor.name);
                                        }
                                    }
                                    if (read_accessor is common_method_node && (read_accessor as common_method_node).is_constructor)
                                    {
                                        AddError(loc1, "ACCESSOR_CAN_BE_FIELD_OR_METHOD_ONLY");
                                    }
                                }
                                if (good_func)
                                {
                                    break;
                                }
                                si = si.Next;
                                if (si != null)
                                {
                                    read_accessor = si.sym_info as function_node;
                                }
                            }
                            if (!good_func)
                            {
                                AddError(loc1, "NO_OVERLOAD_FUNCTION_{0}_USEFUL_FOR_ACCESSOR", read_accessor.name);
                            }
                            read_accessor = GenerateGetMethod(pn,read_accessor as common_method_node,pn.loc);
                           
                        }
                        else
                        {
                            class_field cfield = si.sym_info as class_field;
                            if (cfield == null)
                            {
                                AddError(loc1, "ACCESSOR_CAN_BE_FIELD_OR_METHOD_ONLY");
                            }
                            if (_simple_property.parameter_list != null)
                            {
                                AddError(loc1, "INDEX_PROPERTY_ACCESSOR_CAN_NOT_BE_VARIABLE");
                            }
                            if (cfield.type != pn.internal_property_type)
                            {
                                AddError(loc1, "PROPERTY_TYPE_MISMATCH_ACCESSOR_FIELD_TYPE");
                            }
                            if (pn.polymorphic_state == SemanticTree.polymorphic_state.ps_static && cfield.polymorphic_state != SemanticTree.polymorphic_state.ps_static)
                        		AddError(get_location(_simple_property.accessors.read_accessor.accessor_name), "ACCESSOR_{0}_MUST_BE_STATIC", cfield.name);
                    		if (pn.polymorphic_state != SemanticTree.polymorphic_state.ps_static && cfield.polymorphic_state == SemanticTree.polymorphic_state.ps_static)
                                AddError(get_location(_simple_property.accessors.read_accessor.accessor_name), "ACCESSOR_{0}_CANNOT_BE_STATIC", cfield.name);
                            read_accessor = GenerateGetMethodForField(pn, compiler_string_consts.GetGetAccessorName(pn.name), cfield, loc1);
                        }
                       
                        //Вот здесь уже можем добавить акцессор для чтения.
                        pn.internal_get_function = read_accessor;
                    }
                    if (pn.internal_get_function != null && pn.polymorphic_state == SemanticTree.polymorphic_state.ps_static && pn.internal_get_function.polymorphic_state != SemanticTree.polymorphic_state.ps_static)
                        AddError(get_location(_simple_property.accessors.read_accessor.accessor_name), "ACCESSOR_{0}_MUST_BE_STATIC", pn.internal_get_function.name);
                    if (pn.internal_get_function != null && pn.polymorphic_state != SemanticTree.polymorphic_state.ps_static && pn.internal_get_function.polymorphic_state == SemanticTree.polymorphic_state.ps_static)
                        AddError(get_location(_simple_property.accessors.read_accessor.accessor_name),  "ACCESSOR_{0}_CANNOT_BE_STATIC", pn.internal_get_function.name);
                }

                if (_simple_property.accessors.write_accessor != null)
                {
                    convertion_data_and_alghoritms.check_node_parser_error(_simple_property.accessors.write_accessor);
                    if (_simple_property.accessors.write_accessor.accessor_name == null)
                    {
                        if (!context.converted_type.IsInterface)
                        {
                            AddError(get_location(_simple_property.accessors.write_accessor), "ACCESSOR_NAME_EXPECTED");
                        }
                        pn.internal_set_function = GenerateGetSetMethodForInterfaceProperty(pn, get_location(_simple_property.accessors.write_accessor), false);
                    }
                    else
                    {
                        convertion_data_and_alghoritms.check_node_parser_error(_simple_property.accessors.write_accessor.accessor_name);
                        si = context.converted_type.find_in_type(_simple_property.accessors.write_accessor.accessor_name.name, context.CurrentScope);

                        location loc2 = get_location(_simple_property.accessors.write_accessor.accessor_name);

                        if (si == null)
                        {
                            AddError( new UndefinedNameReference(_simple_property.accessors.write_accessor.accessor_name.name, loc2));
                        }

                        //dn = check_name_node_type(_simple_property.accessors.write_accessor.accessor_name.name,
                        //    si, loc2, general_node_type.function_node, general_node_type.variable_node);

                        function_node write_accessor = si.sym_info as function_node;

                        if (write_accessor != null)
                        {
                            bool good_func = true;
                            bool one_func = si.Next == null;
                            while (si != null)
                            {
                                good_func = true;
                                if (write_accessor.parameters.Count != pn.parameters.Count + 1)
                                {
                                    good_func = false;
                                    if (one_func)
                                    {
                                        AddError( new PropertyAndWriteAccessorParamsCountConvergence(write_accessor, pn, loc2));
                                    }
                                }
                                else
                                {
                                    //TODO: Сверять типы параметров - var, const и т.д.
                                    for (int i2 = 0; good_func && i2 < pn.parameters.Count; i2++)
                                    {
                                        if (write_accessor.parameters[i2].parameter_type != pn.parameters[i2].parameter_type ||
                                            write_accessor.parameters[i2].type != pn.parameters[i2].type)
                                        {
                                            good_func = false;
                                            if (one_func)
                                            {
                                                AddError(loc2, "PROPERTY_{0}_AND_WRITE_ACCESSOR_{1}_PARAMS_TYPE_CONVERGENCE", pn.name ,write_accessor.name);
                                            }
                                        }
                                    }
                                    if (write_accessor.parameters[write_accessor.parameters.Count - 1].type != pn.property_type ||
                                        write_accessor.parameters[write_accessor.parameters.Count - 1].parameter_type != PascalABCCompiler.SemanticTree.parameter_type.value)
                                    {
                                        good_func = false;
                                        if (one_func)
                                        {
                                            AddError(loc2, "PROPERTY_{0}_AND_WRITE_ACCESSOR_LAST_PARAMETER_TYPE_CONVERGENCE", pn.name);
                                        }
                                    }
                                    if (write_accessor.return_value_type != null)
                                    {
                                        good_func = false;
                                        if (one_func)
                                        {
                                            AddError(loc2, "PROPERTY_WRITE_ACCESSOR_CAN_NOT_BE_FUNCTION");
                                        }
                                    }
                                }
                                if (good_func)
                                {
                                    break;
                                }
                                si = si.Next;
                                if (si != null)
                                {
                                    write_accessor = si.sym_info as function_node;
                                }
                            }
                            if (!good_func)
                            {
                                AddError(loc2, "NO_OVERLOAD_FUNCTION_{0}_USEFUL_FOR_ACCESSOR", write_accessor.name);
                            }
                            if (write_accessor is common_method_node && (write_accessor as common_method_node).is_constructor)
                            {
                                AddError(loc2, "ACCESSOR_CAN_BE_FIELD_OR_METHOD_ONLY");
                            }
                            write_accessor = GenerateSetMethod(pn, write_accessor as common_method_node, pn.loc);
                        }
                            else
                            {
                                class_field cfield = si.sym_info as class_field;
                                if (cfield == null)
                                {
                                    AddError(loc2, "ACCESSOR_CAN_BE_FIELD_OR_METHOD_ONLY");
                                }
                                if (_simple_property.parameter_list != null)
                                {
                                    AddError(loc2, "INDEX_PROPERTY_ACCESSOR_CAN_NOT_BE_VARIABLE");
                                }
                                if (cfield.type != pn.internal_property_type)
                                {
                                    AddError(loc2, "PROPERTY_TYPE_MISMATCH_ACCESSOR_FIELD_TYPE");
                                }
                                if (pn.polymorphic_state == SemanticTree.polymorphic_state.ps_static && cfield.polymorphic_state != SemanticTree.polymorphic_state.ps_static)
                        			AddError(get_location(_simple_property.accessors.write_accessor.accessor_name), "ACCESSOR_{0}_MUST_BE_STATIC", cfield.name);
                    			if (pn.polymorphic_state != SemanticTree.polymorphic_state.ps_static && cfield.polymorphic_state == SemanticTree.polymorphic_state.ps_static)
                        			AddError(get_location(_simple_property.accessors.write_accessor.accessor_name), "ACCESSOR_{0}_CANNOT_BE_STATIC", cfield.name);
                                write_accessor = GenerateSetMethodForField(pn, compiler_string_consts.GetSetAccessorName(pn.name), cfield, loc2);
                            }
                            //Вот здесь уже можем добавить акцессор для чтения.
                            pn.internal_set_function = write_accessor;
                        }
                    if (pn.internal_set_function != null && pn.polymorphic_state == SemanticTree.polymorphic_state.ps_static && pn.internal_set_function.polymorphic_state != SemanticTree.polymorphic_state.ps_static)
                        AddError(get_location(_simple_property.accessors.write_accessor.accessor_name), "ACCESSOR_{0}_MUST_BE_STATIC", pn.internal_set_function.name);
                    if (pn.internal_set_function != null && pn.polymorphic_state != SemanticTree.polymorphic_state.ps_static && pn.internal_set_function.polymorphic_state == SemanticTree.polymorphic_state.ps_static)
                        AddError(get_location(_simple_property.accessors.write_accessor.accessor_name), "ACCESSOR_{0}_CANNOT_BE_STATIC", pn.internal_set_function.name);
                }
            }
            make_attributes_for_declaration(_simple_property,pn);
            //TODO: Можно сделать множество свойств по умолчанию.
            if (_simple_property.array_default != null)
            {
                if (pn.parameters.Count == 0)
                {
                    AddError(pn.loc, "DEFAULT_PROPERTY_MUST_BE_INDEXED");
                }
                if (context.converted_type.default_property_node != null)
                {
                    AddError(pn.loc, "DUPLICATE_DEFAULT_PROPERTY_IN_CLASS");
                }
                context.converted_type.default_property = pn;
            }
        }
        /// <summary>
        /// Возвращает список преобразований типов для вызова метода.
        /// </summary>
        /// <param name="factparams">Список фактических параметров.</param>
        /// <param name="formalparams">Список формальных параметров.</param>
        /// <param name="is_alone_method_defined">Для единственного метода у которого типы параметров совпадают, но в качестве var параметра мы передаем константное значение мы можем сгенерировать более подробное сообщение об ошибке.</param>
        /// <returns>Список преобразований типов.</returns>
        internal possible_type_convertions_list get_conversions(expressions_list factparams,
			parameter_list formalparams,bool is_alone_method_defined, location locg)
		{
			//TODO:Явно указывать capacity при создании.
            possible_type_convertions_list tc = new possible_type_convertions_list();
			
			possible_type_convertions ptc;

            if (factparams.Count>formalparams.Count)
            {
                if ( (formalparams.Count==0) || (!(formalparams[formalparams.Count-1].is_params)) )
                {
                    return null;
                }
            }

            type_node for_par_type = null;
            array_internal_interface aii=null;
            if (formalparams.Count > 0)
            {
                parameter pr=formalparams[formalparams.Count - 1];
                if (pr.is_params && 
                    //это для возможности вызова сразу с массивом[], типа просто не обращаем внимаение на params
                    !(factparams.Count == formalparams.Count && factparams[factparams.Count - 1].type == formalparams[formalparams.Count - 1].type))
                {
                    //TODO: Добавить проверку на правильность.
                    aii = (array_internal_interface)
                        pr.type.get_internal_interface(internal_interface_kind.unsized_array_interface);
                    for_par_type = aii.element_type;

                    tc.snl = new statement_node_list();

                    location loc=null;
                    if (factparams.Count > 0) loc = factparams[factparams.Count-1].location;
                    //var_definition_node vdn=syntax_tree_visitor.context.add_var_definition_in_entry_scope(get_temp_arr_name(),loc);
                    var_definition_node vdn = null;
                    if (syntax_tree_visitor.context.converted_func_stack.size > 0)
                    {
                        common_function_node cfn = syntax_tree_visitor.context.converted_func_stack.first();
                        if (cfn.is_generic_function)
                        {
                            vdn = syntax_tree_visitor.context.add_var_definition(get_temp_arr_name(), loc);
                        }
                        else
                            vdn = syntax_tree_visitor.context.add_var_definition_in_entry_scope(get_temp_arr_name(), loc);
                        
                    }
                    else if (syntax_tree_visitor.context.converted_type != null)
                        vdn = syntax_tree_visitor.context.add_field(get_temp_arr_name(), loc, pr.type, polymorphic_state.ps_static);
                    else
                        vdn = syntax_tree_visitor.context.add_var_definition_in_entry_scope(get_temp_arr_name(), loc);
                    syntax_tree_visitor.context.close_var_definition_list(pr.type,null);
                    
                    expression_node fst=null;
                    /*switch (syntax_tree_visitor.context.converting_block())
                    {
                        case block_type.function_block:
                            {
                                fst=new local_variable_reference((local_variable)vdn,0,loc);
                                break;
                            }
                        case block_type.namespace_block:
                            {
                                fst=new namespace_variable_reference((namespace_variable)vdn,loc);
                                break;
                            }
                    }*/
                    switch (vdn.semantic_node_type)
                    {
                        case semantic_node_type.local_variable:
                            {
                                fst = new local_variable_reference((local_variable)vdn, 0, loc);
                                break;
                            }
                        case semantic_node_type.namespace_variable:
                            {
                                fst = new namespace_variable_reference((namespace_variable)vdn, loc);
                                break;
                            }
                        case semantic_node_type.local_block_variable:
                            {
                                fst = new local_block_variable_reference((local_block_variable)vdn, loc);
                                break;
                            }
                        case semantic_node_type.class_field:
                            {
                                class_field cf = vdn as class_field;
                                cf.polymorphic_state = polymorphic_state.ps_static;
                                fst = new static_class_field_reference(cf, loc);
                                break;
                            }
                        default:
                            throw new CompilerInternalError("Invalid node type");
                    }

                    tc.var_ref = fst;

                    int del=factparams.Count-formalparams.Count+1;
                    int_const_node icn=new int_const_node(del,loc);

                    expression_node bfc = create_simple_function_call(SystemLibrary.SystemLibrary.resize_func,
                        loc, fst, icn);
                    tc.snl.AddElement(bfc);
                    /*if (factparams.Count == 0)
                    {
                    	possible_type_convertions ptci=new possible_type_convertions();
						ptci.first=null;
						ptci.second=null;
						ptci.from=null;
                    	ptci.to = for_par_type;
						tc.AddElement(ptci);
                    }*/
                }
            }
			
			for(int i=0;i<factparams.Count;i++)
			{
                type_node formal_param_type = null;
                if ((for_par_type!=null)&&(i >= formalparams.Count-1))
                {
                    formal_param_type = for_par_type;
                }
                else
                {
                    formal_param_type = formalparams[i].type;
                }
                if (possible_equal_types(factparams[i].type, formal_param_type))
				{
					if ((i<formalparams.Count)&&(formalparams[i].parameter_type==SemanticTree.parameter_type.var))
					{
                        bool is_pascal_array_ref = false;
                        bool is_ok = false;
						if (factparams[i].is_addressed==false)
						{
                            if (factparams[i].semantic_node_type == semantic_node_type.common_method_call)
                            {
                                common_method_call cmc = (common_method_call)factparams[i];
                                internal_interface ii = cmc.obj.type.get_internal_interface(internal_interface_kind.bounded_array_interface);
                                if (ii != null)
                                {
                                    if (cmc.function_node.name == compiler_string_consts.get_val_pascal_array_name)
                                    {
                                        bounded_array_interface bai = (bounded_array_interface)ii;
                                        class_field cf = bai.int_array;
                                        expression_node left = new class_field_reference(cf, cmc.obj, cmc.location);
                                        expression_node right = cmc.parameters[0];
                                        //right = convert_type(right, SystemLibrary.SystemLibrary.integer_type);
                                        right = convert_type(right, (ii as bounded_array_interface).ordinal_type_interface.elems_type);
                                        right = create_simple_function_call(SystemLibrary.SystemLibrary.int_sub, cmc.location, right,
                                            new int_const_node(bai.ordinal_type_interface.ordinal_type_to_int(bai.ordinal_type_interface.lower_value),cmc.location));
                                        factparams[i] = new simple_array_indexing(left, right, cmc.type, cmc.location);
                                        is_pascal_array_ref = true;
                                    }
                                }
                            }
                            if (!is_pascal_array_ref)
                            {
                                //Если мы попали сюда, то мы пытаемся передать по ссылке значение,
                                //которое не мохет быть передано по ссылке. Например, передать
                                //по ссылки из одной функции в другую константный параметр.
                                if (is_alone_method_defined)
                                {
                                    if (syntax_tree_visitor.assign_is_converting)
                                    {
                                        AddError(factparams[i].location, "CAN_NOT_ASSIGN_TO_LEFT_PART");
                                    }
                                    else
                                    {
                                        if (formalparams[i] is common_parameter && (formalparams[i] as common_parameter).concrete_parameter_type == concrete_parameter_type.cpt_const /*&& factparams[i] is common_parameter_reference*/)
                                        {
                                            is_ok = true;
                                        }
                                        else if (formalparams[i] is common_parameter && (formalparams[i] as common_parameter).concrete_parameter_type == concrete_parameter_type.cpt_const)
                                            ;
                                        //throw new ThisExpressionCanNotBePassedAsConstParameter(factparams[i].location);
                                        else if (is_string_getter(factparams[i]))
                                        {
                                            if (factparams[i] is compiled_function_call)
                                                factparams[i] = make_unmanaged_string_getter(factparams[i] as compiled_function_call);
                                            else
                                                factparams[i] = make_unmanaged_shortstring_getter(factparams[i] as base_function_call);
                                            is_ok = true;
                                        }

                                        else
                                            AddError(new ThisExpressionCanNotBePassedAsVarParameter(factparams[i]));
                                    }
                                }
                                else if (is_string_getter(factparams[i]))
                                {
                                    if (factparams[i] is compiled_function_call)
                                        factparams[i] = make_unmanaged_string_getter(factparams[i] as compiled_function_call);
                                    else
                                        factparams[i] = make_unmanaged_shortstring_getter(factparams[i] as base_function_call);
                                    is_ok = true;
                                }

                                if (!is_ok)
                                    return null;
                            }
						}
					}
					//Разобраться: может лучше добавлять null к списку.
					possible_type_convertions ptci=new possible_type_convertions();
					ptci.first=null;
					ptci.second=null;
					ptci.from=factparams[i].type;
                    ptci.to = formal_param_type;
					tc.AddElement(ptci);

                    if ((for_par_type != null) && (i >= formalparams.Count - 1))
                    {
                        expression_node to = new simple_array_indexing(tc.var_ref,//factparams[formalparams.Count - 1],
                            new int_const_node(i - formalparams.Count + 1, factparams[i].location), aii.element_type, factparams[i].location);
                        expression_node from = factparams[i];
                        statement_node stat = syntax_tree_visitor.find_operator(compiler_string_consts.assign_name, to, from, factparams[i].location);
                        tc.snl.AddElement(stat);
                    }

					continue;
				}
				if ((i<formalparams.Count)&&(formalparams[i].parameter_type==SemanticTree.parameter_type.var))
				{
					return null;
				}
				else
				{
                    ptc = type_table.get_convertions(factparams[i].type, formal_param_type);
					if (ptc.first==null)
					{
                        if (type_table.is_derived(formal_param_type, factparams[i].type))
						{
							possible_type_convertions ptci=new possible_type_convertions();
							ptci.first=null;
							ptci.second=null;
							ptci.from=factparams[i].type;
                            ptci.to = formal_param_type;
							tc.AddElement(ptci);

                            if ((for_par_type != null) && (i >= formalparams.Count - 1))
                            {
                                expression_node to = new simple_array_indexing(tc.var_ref,//factparams[formalparams.Count - 1],
                                    new int_const_node(i - formalparams.Count + 1, factparams[i].location), aii.element_type, factparams[i].location);
                                expression_node from = factparams[i];
                                statement_node stat = syntax_tree_visitor.find_operator(compiler_string_consts.assign_name, to, from, factparams[i].location);
                                tc.snl.AddElement(stat);
                            }

						}
						else
						{
                            if (is_alone_method_defined)
                            {
                                AddError(new CanNotConvertTypes(factparams[i], factparams[i].type, formal_param_type, locg));
                            }
							return null;
                            
						}
					}
					else
					{
						tc.AddElement(ptc);
                        if ((for_par_type != null) && (i >= formalparams.Count - 1))
                        {
                            expression_node to = new simple_array_indexing(tc.var_ref,//factparams[formalparams.Count - 1],
                                new int_const_node(i - formalparams.Count + 1, factparams[i].location), aii.element_type, factparams[i].location);
                            expression_node from = create_simple_function_call(ptc.first.convertion_method,
                                factparams[i].location, factparams[i]);
                            statement_node stat = syntax_tree_visitor.find_operator(compiler_string_consts.assign_name, to, from, factparams[i].location);
                            tc.snl.AddElement(stat);
                        }
					}
				}
			}
            if (tc.snl != null)
            foreach (statement_node sn in tc.snl)
                sn.location = null;
			return tc;
		}
 private definition_node CreateInterfaceProperty(string name, int offset)
 {
     definition_node dn = null;
     if (members.TryGetValue(offset, out dn))
         return dn as common_property_node;
     common_property_node prop = null;
     int name_ref = br.ReadInt32();
     type_node type = GetTypeReference();
     common_method_node get_meth = null;
     if (br.ReadByte() == 1) get_meth = GetClassMethod(br.ReadInt32());
     common_method_node set_meth = null;
     if (br.ReadByte() == 1) set_meth = GetClassMethod(br.ReadInt32());
     int num = br.ReadInt32();
     parameter_list pl = new parameter_list();
     for (int i = 0; i < num; i++)
         pl.AddElement(GetParameter());
     common_type_node cont = (common_type_node)GetTypeReference(br.ReadInt32());
     SemanticTree.field_access_level fal = (SemanticTree.field_access_level)br.ReadByte();
     SemanticTree.polymorphic_state ps = (SemanticTree.polymorphic_state)br.ReadByte();
     attributes_list attrs = GetAttributes();
     location loc = ReadDebugInfo();
     if (name==null) 
         name = GetStringInClass(cont, name_ref);
     prop = new common_property_node(name, cont, type, get_meth, set_meth, loc, fal, ps);
     prop.attributes.AddRange(attrs);
     prop.parameters.AddRange(pl);
     cont.properties.AddElement(prop);
     //members[offset] = prop;
     AddMember(prop, offset);
     
     return prop;
 }
Exemple #8
0
 protected parameter_list make_parameters(parameter_list orig_pl, common_function_node fn)
 {
     parameter_list pl = new parameter_list();
     //TODO: разобраться с concrete_parameter_type
     foreach (parameter p in orig_pl)
     {
         common_parameter cp = new common_parameter(
             p.name, generic_convertions.determine_type(p.type, _instance_params, false),
             p.parameter_type,
             fn, concrete_parameter_type.cpt_none, p.inital_value, null);
         cp.intrenal_is_params = p.is_params;
         cp.is_special_name = p.is_special_name;
         cp.is_ret_value = p.is_ret_value;
         cp.default_value = p.default_value;
         pl.AddElement(cp);
     }
     return pl;
 }
		public void init_delegate(common_type_node ctn, type_node return_value_type, parameter_list parameters,
		                                        location loc)
		{
			common_method_node constructor=new common_method_node(compiler_string_consts.default_constructor_name,null,loc,ctn,SemanticTree.polymorphic_state.ps_common,
			                                                      SemanticTree.field_access_level.fal_public,
			                                                      convertion_data_and_alghoritms.symbol_table.CreateScope(ctn.scope));
			constructor.is_constructor = true;
			constructor.return_value_type = ctn;
			constructor.function_code=new runtime_statement(SemanticTree.runtime_statement_type.ctor_delegate,loc);

			common_method_node invoke=new common_method_node(compiler_string_consts.invoke_method_name,
			                                                 return_value_type,loc,ctn,SemanticTree.polymorphic_state.ps_virtual,
			                                                 SemanticTree.field_access_level.fal_public,
			                                                 convertion_data_and_alghoritms.symbol_table.CreateScope(ctn.scope));
			ctn.add_name(compiler_string_consts.invoke_method_name,new SymbolInfo(invoke));
			for (int i=0; i<parameters.Count; i++)
			{
				if (parameters[i] is compiled_parameter)
				{
					parameters[i] = new common_parameter(parameters[i].name,parameters[i].type,parameters[i].parameter_type,invoke,concrete_parameter_type.cpt_none,null,null);
				}
			}
				
			invoke.parameters.AddRange(parameters);
			invoke.function_code = new runtime_statement(SemanticTree.runtime_statement_type.invoke_delegate, loc);

			common_method_node begin_invoke = new common_method_node(compiler_string_consts.begin_invoke_method_name,
			                                                         begin_invoke_result_type, loc, ctn, SemanticTree.polymorphic_state.ps_virtual, SemanticTree.field_access_level.fal_public,
			                                                         convertion_data_and_alghoritms.symbol_table.CreateScope(ctn.scope));
			ctn.add_name(compiler_string_consts.begin_invoke_method_name,new SymbolInfo(begin_invoke));
			parameter_list begin_invoke_params=new parameter_list();
			begin_invoke_params.AddRange(parameters);
			common_parameter cp=new common_parameter(compiler_string_consts.callback_string,begin_invoke_parameter_type,
			                                         SemanticTree.parameter_type.value,begin_invoke,concrete_parameter_type.cpt_none,
			                                         null,loc);
			begin_invoke_params.AddElement(cp);
			cp = new common_parameter(compiler_string_consts.object_in_par_string, SystemLibrary.SystemLibrary.object_type,
			                          SemanticTree.parameter_type.value,begin_invoke, concrete_parameter_type.cpt_none,
			                          null, loc);
			begin_invoke_params.AddElement(cp);
			begin_invoke.parameters.AddRange(begin_invoke_params);
			begin_invoke.function_code = new runtime_statement(SemanticTree.runtime_statement_type.begin_invoke_delegate, loc);

			common_method_node end_invoke = new common_method_node(compiler_string_consts.end_invoke_method_name,
			                                                       return_value_type, loc, ctn, SemanticTree.polymorphic_state.ps_virtual, SemanticTree.field_access_level.fal_public,
			                                                       convertion_data_and_alghoritms.symbol_table.CreateScope(ctn.scope));
			ctn.add_name(compiler_string_consts.end_invoke_method_name,new SymbolInfo(end_invoke));
			cp = new common_parameter(compiler_string_consts.result_string, begin_invoke_result_type,
			                          SemanticTree.parameter_type.value, end_invoke, concrete_parameter_type.cpt_none,
			                          null, loc);
			end_invoke.parameters.AddElement(cp);
			end_invoke.function_code = new runtime_statement(SemanticTree.runtime_statement_type.end_invoke_delegate, loc);

			ctn.methods.AddElement(constructor);
			ctn.methods.AddElement(invoke);
			ctn.methods.AddElement(begin_invoke);
			ctn.methods.AddElement(end_invoke);

			SystemLibrary.SystemLibrary.init_reference_type(ctn);

			delegate_internal_interface dii = new delegate_internal_interface(return_value_type, invoke, constructor);
			dii.parameters.AddRange(parameters);

			ctn.add_internal_interface(dii);
			AddOperatorsToDelegate(ctn, loc);
		}
 public common_type_node create_delegate(string name, type_node return_value_type, parameter_list parameters,
                                         common_namespace_node cmn, location loc)
 {
     common_type_node ctn = create_delegate_without_init(name, cmn, loc);
     init_delegate(ctn, return_value_type, parameters, loc);
     return ctn;
 }