private void VisitSimpleArrayIndexing(simple_array_indexing expr)
		{
            VisitExpression(expr.simple_arr_expr);
            VisitExpression(expr.ind_expr);
            if (CanWriteObject(expr.expr_indices))
            {
            	bw.Write(expr.expr_indices.Length);
            	for (int i=0; i<expr.expr_indices.Length; i++)
            		VisitExpression(expr.expr_indices[i]);
            }
            WriteTypeReference(expr.type);
		}
Ejemplo n.º 2
0
 private void VisitSimpleArrayIndexing(simple_array_indexing en)
 {
     VisitExpression(en.simple_arr_expr);
     VisitExpression(en.ind_expr);
 }
        private expression_node make_dec_call(SymbolInfo si, SyntaxTree.expression_list parameters, location loc)
        {
        	if (parameters == null) throw new NoFunctionWithSameParametresNum(loc,false,si.sym_info as function_node);
        	if (parameters.expressions.Count == 1 || parameters.expressions.Count == 2)
        	{
        		expression_node param0 = convert_strong(parameters.expressions[0]);
        		if (!param0.is_addressed)
        		{
        			bool is_pascal_array_ref = false;
                    if (param0.semantic_node_type == semantic_node_type.common_method_call)
                    {
                        common_method_call cmc = (common_method_call)param0;
                        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 = convertion_data_and_alghoritms.convert_type(right, (ii as bounded_array_interface).ordinal_type_interface.elems_type);
                                right = convertion_data_and_alghoritms.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));
                                param0 = new simple_array_indexing(left, right, cmc.type, cmc.location);
                                is_pascal_array_ref = true;

                            }
                        }
                        if (!is_pascal_array_ref)
                        {
							throw new ThisExpressionCanNotBePassedAsVarParameter(param0);
                    	}
        				
        			}
                    else if (param0 is compiled_function_call)
                    {
                    	compiled_function_call cfc = param0 as compiled_function_call;
                    	if ((cfc.function_node.return_value_type == SystemLibrary.SystemLibrary.char_type && cfc.function_node.cont_type == SystemLibrary.SystemLibrary.string_type
                    	      && cfc.function_node == cfc.function_node.cont_type.default_property_node.get_function))
                    	{
                    		expressions_list exl = new expressions_list();
                            exl.AddElement(cfc.obj);
                            exl.AddElement(cfc.parameters[0]);
                            basic_function_call bfc2 = new basic_function_call(SystemLibrary.SystemLibrary.int_sub as basic_function_node,loc);
                            bfc2.parameters.AddElement(param0);
                            expression_node _param1 = null;
                            if (parameters.expressions.Count == 2) 
        					{
        						_param1 = convert_strong(parameters.expressions[1]);
        					}
                            if (_param1 != null)
                            	bfc2.parameters.AddElement(convertion_data_and_alghoritms.convert_type(_param1,SystemLibrary.SystemLibrary.integer_type));
                            else
                            	bfc2.parameters.AddElement(new int_const_node(1,null));
                            expressions_list el = new expressions_list();
                            el.AddElement(convertion_data_and_alghoritms.convert_type(bfc2,SystemLibrary.SystemLibrary.ushort_type));
                            function_node chr_func = convertion_data_and_alghoritms.select_function(el, SystemLibrary.SystemLibInitializer.ChrUnicodeFunction.SymbolInfo, loc);
                            exl.AddElement(convertion_data_and_alghoritms.create_simple_function_call(chr_func, loc, el.ToArray()));
                            function_node fn = convertion_data_and_alghoritms.select_function(exl, SystemLibrary.SystemLibInitializer.StringDefaultPropertySetProcedure.SymbolInfo, loc);
                            expression_node ret = convertion_data_and_alghoritms.create_simple_function_call(fn, loc, exl.ToArray());
                            return ret;
                    	}
                    	else
                    	{
                    		throw new ThisExpressionCanNotBePassedAsVarParameter(param0);
                    	}
                    }
                    else throw new ThisExpressionCanNotBePassedAsVarParameter(param0);
        		}
        		else
        			check_on_loop_variable(param0);
        		expression_node param1 = null;
        		int type_flag = 0;
        		bool is_uint=false;
        		bool is_enum=false;
        		if (parameters.expressions.Count == 2) 
        		{
        			param1 = convert_strong(parameters.expressions[1]);
        			param1 = convertion_data_and_alghoritms.convert_type(param1,SystemLibrary.SystemLibrary.integer_type);
        		}
        		basic_function_call ass = null;
        		basic_function_call bfc = null;
        		if (param0.type == SystemLibrary.SystemLibrary.integer_type)
        		{
        			ass = new basic_function_call(SystemLibrary.SystemLibrary.int_assign as basic_function_node,loc);
        			bfc = new basic_function_call(SystemLibrary.SystemLibrary.int_sub as basic_function_node,loc);
        		}
        		else if (param0.type == SystemLibrary.SystemLibrary.char_type)
        		{
        			ass = new basic_function_call(SystemLibrary.SystemLibrary.char_assign as basic_function_node,loc);
        			bfc = new basic_function_call(SystemLibrary.SystemLibrary.int_sub as basic_function_node,loc);
        		}
        		else if (param0.type == SystemLibrary.SystemLibrary.byte_type)
        		{
        			ass = new basic_function_call(SystemLibrary.SystemLibrary.byte_assign as basic_function_node,loc);
        			bfc = new basic_function_call(SystemLibrary.SystemLibrary.int_sub as basic_function_node,loc);
        		}
        		else if (param0.type == SystemLibrary.SystemLibrary.sbyte_type)
        		{
        			ass = new basic_function_call(SystemLibrary.SystemLibrary.sbyte_assign as basic_function_node,loc);
        			bfc = new basic_function_call(SystemLibrary.SystemLibrary.int_sub as basic_function_node,loc);
        		}
        		else if (param0.type == SystemLibrary.SystemLibrary.short_type)
        		{
        			ass = new basic_function_call(SystemLibrary.SystemLibrary.short_assign as basic_function_node,loc);
        			bfc = new basic_function_call(SystemLibrary.SystemLibrary.int_sub as basic_function_node,loc);
        		}
        		else if (param0.type == SystemLibrary.SystemLibrary.ushort_type)
        		{
        			ass = new basic_function_call(SystemLibrary.SystemLibrary.ushort_assign as basic_function_node,loc);
        			bfc = new basic_function_call(SystemLibrary.SystemLibrary.int_sub as basic_function_node,loc);
        		}
        		else if (param0.type == SystemLibrary.SystemLibrary.uint_type)
        		{
        			ass = new basic_function_call(SystemLibrary.SystemLibrary.uint_assign as basic_function_node,loc);
        			bfc = new basic_function_call(SystemLibrary.SystemLibrary.uint_sub as basic_function_node,loc);
        			type_flag = 2;
        			is_uint = true;
        		}
        		else if (param0.type == SystemLibrary.SystemLibrary.int64_type)
        		{
        			ass = new basic_function_call(SystemLibrary.SystemLibrary.long_assign as basic_function_node,loc);
        			bfc = new basic_function_call(SystemLibrary.SystemLibrary.long_sub as basic_function_node,loc);
        			type_flag = 1;
        		}
        		else if (param0.type == SystemLibrary.SystemLibrary.uint64_type)
        		{
        			ass = new basic_function_call(SystemLibrary.SystemLibrary.ulong_assign as basic_function_node,loc);
        			bfc = new basic_function_call(SystemLibrary.SystemLibrary.ulong_sub as basic_function_node,loc);
        			type_flag = 2;
        		}
        		else if (param0.type == SystemLibrary.SystemLibrary.bool_type)
        		{
        			if (param1 == null)
        			{
        				ass = new basic_function_call(SystemLibrary.SystemLibrary.bool_assign as basic_function_node,loc);
        				bfc = new basic_function_call(SystemLibrary.SystemLibrary.bool_not as basic_function_node,loc);
        				type_flag = 4;
        			}
        			else
        			{
        				basic_function_call mod_expr = new basic_function_call(SystemLibrary.SystemLibrary.int_mod as basic_function_node,loc);
        				mod_expr.parameters.AddElement(convertion_data_and_alghoritms.convert_type(param1,SystemLibrary.SystemLibrary.integer_type));
        				mod_expr.parameters.AddElement(new int_const_node(2,loc));
        				basic_function_call condition = new basic_function_call(SystemLibrary.SystemLibrary.int_eq as basic_function_node,loc);
        				condition.parameters.AddElement(mod_expr);
        				condition.parameters.AddElement(new int_const_node(0,loc));
        				basic_function_call not_expr = new basic_function_call(SystemLibrary.SystemLibrary.bool_not as basic_function_node,loc);
        				not_expr.parameters.AddElement(param0);
        				question_colon_expression qce = new question_colon_expression(condition, param0, not_expr, loc);
        				ass = new basic_function_call(SystemLibrary.SystemLibrary.bool_assign as basic_function_node,loc);
        				ass.parameters.AddElement(param0);
        				ass.parameters.AddElement(qce);
        				type_flag = 5;
        			}
        		}
        		else if (param0.type.type_special_kind == PascalABCCompiler.SemanticTree.type_special_kind.diap_type || param0.type.IsEnum)
        		{
        			ass = new basic_function_call(SystemLibrary.SystemLibrary.int_assign as basic_function_node,loc);
        			bfc = new basic_function_call(SystemLibrary.SystemLibrary.int_sub as basic_function_node,loc);
        			if (param0.type.type_special_kind == PascalABCCompiler.SemanticTree.type_special_kind.diap_type)
        			{
        				type_node bt = param0.type.base_type;
        				if (bt == SystemLibrary.SystemLibrary.int64_type) type_flag = 1;
        				else if (bt == SystemLibrary.SystemLibrary.uint64_type) type_flag = 2;
        				else if (bt == SystemLibrary.SystemLibrary.uint_type) 
        				{
        					type_flag =2;
        					is_uint = true;
        				}
        				else if (bt.IsEnum) is_enum = true;
        			}
        			else if (param0.type.IsEnum) is_enum = true;
        		}
        		else throw new NoFunctionWithSameArguments(loc,false);
                if (type_flag != 5)
                {
                    if (param1 != null)
                        switch (type_flag)
                        {
                            case 0: param1 = convertion_data_and_alghoritms.convert_type(param1, SystemLibrary.SystemLibrary.integer_type); break;
                            case 3:
                            case 1: param1 = convertion_data_and_alghoritms.convert_type(param1, SystemLibrary.SystemLibrary.int64_type); break;
                            case 2: param1 = convertion_data_and_alghoritms.convert_type(param1, SystemLibrary.SystemLibrary.uint64_type); break;
                        }
                    //bfc.parameters.AddElement(param0);
                    if (param0.type != SystemLibrary.SystemLibrary.char_type && !is_enum && param0.type != SystemLibrary.SystemLibrary.bool_type)
                        switch (type_flag)
                        {
                            case 0: bfc.parameters.AddElement(convertion_data_and_alghoritms.convert_type(param0, SystemLibrary.SystemLibrary.integer_type)); break;
                            case 3:
                            case 1: bfc.parameters.AddElement(convertion_data_and_alghoritms.convert_type(param0, SystemLibrary.SystemLibrary.int64_type)); break;
                            case 2: bfc.parameters.AddElement(convertion_data_and_alghoritms.convert_type(param0, SystemLibrary.SystemLibrary.uint64_type)); break;
                        }
                    else bfc.parameters.AddElement(param0);
                    if (param1 == null)
                    {
                        if (type_flag == 0 || type_flag == 3)
                            bfc.parameters.AddElement(new int_const_node(1, null));
                        else if (type_flag == 1)
                            bfc.parameters.AddElement(new long_const_node(1, null));
                        else if (type_flag == 2)
                            bfc.parameters.AddElement(new ulong_const_node(1, null));
                    }
                    else bfc.parameters.AddElement(param1);
                    ass.parameters.AddElement(param0);
                    if (is_uint)
                        ass.parameters.AddElement(convertion_data_and_alghoritms.convert_type(bfc, SystemLibrary.SystemLibrary.uint_type));
                    else
                        ass.parameters.AddElement(bfc);
                }
        		return ass;
        	}
        	
        	throw new NoFunctionWithSameParametresNum(loc,false,si.sym_info as function_node);
        }
        private expression_node make_read_call(SymbolInfo si, SyntaxTree.expression_list parameters, location loc)
        {

            // вызов read(a,b,c) разбивается на несколько вызовов, последний возвращается узлом, а остальные добавляются здесь в теле            expressions_list exl = new expressions_list();
            expression_node last_call = null;
            expressions_list exl = new expressions_list();
            expression_node file = null;
            bool read_from_file = false;
            bool read_from_text_file = false;
            bool read_from_typed_file = false;
            bool read_from_binary_file = false;
            bool readln_string_file = false;
            if (parameters != null) // если список параметров не пуст
            {
                if (parameters.expressions.Count >= 1)
                {
                    expression_node param0 = convert_strong(parameters.expressions[0]);
                    if (param0.type != null)
                    {
                        if (SystemLibrary.SystemLibInitializer.TextFileType.Found && param0.type == SystemLibrary.SystemLibInitializer.TextFileType.sym_info)
                        {
                            file = param0;
                            read_from_text_file = true;
                        }
                        if (param0.type.type_special_kind == SemanticTree.type_special_kind.typed_file
                            && parameters.expressions.Count > 1                        //это можно внести во внутрь
                            )//и побросать приличные исключения
                        {
                            if (!SystemLibrary.SystemLibInitializer.read_procedure.FromDll)
                            {
                                if (si == SystemLibrary.SystemLibInitializer.read_procedure.SymbolInfo)
                                {
                                    file = param0;
                                    read_from_typed_file = true;
                                }
                            }
                            else if (SystemLibrary.SystemLibInitializer.read_procedure.Equal(si))
                            {
                                file = param0;
                                read_from_typed_file = true;
                            }
                        }
                        if (param0.type.type_special_kind == SemanticTree.type_special_kind.binary_file
                            && parameters.expressions.Count > 1                        //это можно внести во внутрь
                            )//и побросать приличные исключения
                        {
                            if (!SystemLibrary.SystemLibInitializer.read_procedure.FromDll)
                            {
                                if (si == SystemLibrary.SystemLibInitializer.read_procedure.SymbolInfo)
                                {
                                    file = param0;
                                    read_from_binary_file = true;
                                }
                            }
                            else if (SystemLibrary.SystemLibInitializer.read_procedure.Equal(si))
                            {
                                file = param0;
                                read_from_binary_file = true;
                            }
                        }
                    }
                    read_from_file = read_from_text_file || read_from_typed_file || read_from_binary_file;
                }
                bool first_iteration = true;
                
                foreach (SyntaxTree.expression ex in parameters.expressions)
                {
                    if (first_iteration && read_from_file)
                    {
                        first_iteration = false;
                        continue;
                    }
                    if (last_call != null && convertion_data_and_alghoritms.statement_list_stack.size > 0)
                        convertion_data_and_alghoritms.statement_list_stack.top().statements.AddElement(last_call);
                    expression_node en = convert_strong(ex);
                    check_on_loop_variable(en);
                    //if (en.type == null)
                    //throw new CanNotRead(en.location);
                    exl.clear();
                    if (read_from_file)
                        exl.AddElement(file);
                    if (read_from_typed_file)
                    {
                        if (SystemLibrary.SystemLibInitializer.TypedFileReadProcedure == null)
                            AddError(new NotSupportedError(loc));
                        if (en.type != file.type.element_type)
                            AddError(new ExpectedExprHaveTypeTypedFile(file.type.element_type, en.type, true, get_location(ex)));
                        bool is_char_getter = false;
                        if (!en.is_addressed)
                        {
                            if (en is compiled_function_call)
                            {
                                compiled_function_call cfc = en as compiled_function_call;
                                
                                if ((cfc.function_node.return_value_type == SystemLibrary.SystemLibrary.char_type && cfc.function_node.cont_type == SystemLibrary.SystemLibrary.string_type
                                      && cfc.function_node == cfc.function_node.cont_type.default_property_node.get_function))
                                {
                                    en = new simple_array_indexing((en as compiled_function_call).obj, (en as compiled_function_call).parameters[0], SystemLibrary.SystemLibrary.char_type, en.location);
                                    is_char_getter = true;
                                }
                                
                            }
                        }
                        function_node fn = convertion_data_and_alghoritms.select_function(exl, SystemLibrary.SystemLibInitializer.TypedFileReadProcedure.SymbolInfo, loc);
                        expression_node expr = convertion_data_and_alghoritms.create_simple_function_call(fn, get_location(ex), file);
                        //expression_node expr = convertion_data_and_alghoritms.create_full_function_call(exl, SystemLibrary.SystemLibInitializer.TypedFileReadProcedure.SymbolInfo, loc, context.converted_type, context.top_function, true);
                        expr = convertion_data_and_alghoritms.explicit_convert_type(expr, file.type.element_type);
                        if (is_char_getter)
                            expr = convertion_data_and_alghoritms.create_simple_function_call(SystemLibrary.SystemLibInitializer.StringDefaultPropertySetProcedure.sym_info as function_node, loc, (en as simple_array_indexing).simple_arr_expr, (en as simple_array_indexing).ind_expr, expr);
                        else
                            expr = find_operator(compiler_string_consts.assign_name, en, expr, loc);
                        last_call = expr;
                    }
                    else if (read_from_binary_file)
                    {
                        if (SystemLibrary.SystemLibInitializer.BinaryFileReadProcedure == null)
                            AddError(new NotSupportedError(loc));
                        if (!CanUseThisTypeForBinaryFiles(en.type))
                        {
                            AddError(en.location, "CAN_NOT_READ_REFERENCE_DATA_FROM_BINARY_FILE");
                        }
                        exl.AddElement(new typeof_operator(en.type, loc));
                        function_node fn = convertion_data_and_alghoritms.select_function(exl, SystemLibrary.SystemLibInitializer.BinaryFileReadProcedure.SymbolInfo, loc);
                        expression_node expr = convertion_data_and_alghoritms.create_simple_function_call(fn, get_location(ex), exl.ToArray());
                        expr = convertion_data_and_alghoritms.explicit_convert_type(expr, en.type);
                        expr = find_operator(compiler_string_consts.assign_name, en, expr, loc);
                        last_call = expr;
                    }
                    else
                    {
                        exl.AddElement(en);
                        try
                        {
                        	function_node fn = null;
                        	if (en.type.type_special_kind == SemanticTree.type_special_kind.short_string)
                        	{
                        		exl.AddElement(new int_const_node((en.type as short_string_type_node).Length,null));
                        		if (!read_from_file)
                        		last_call = convertion_data_and_alghoritms.create_simple_function_call(SystemLibrary.SystemLibInitializer.read_short_string_procedure.sym_info as function_node,get_location(ex),exl.ToArray());
                        		else
                        		last_call = convertion_data_and_alghoritms.create_simple_function_call(SystemLibrary.SystemLibInitializer.read_short_string_from_file_procedure.sym_info as function_node,get_location(ex),exl.ToArray());
                        	}
                        	else if (en.type.type_special_kind == SemanticTree.type_special_kind.diap_type)
                        	{
                        		exl.remove(en);
                        		en.type = en.type.base_type;
                        		exl.AddElement(en);
                        		fn = convertion_data_and_alghoritms.select_function(exl, SystemLibrary.SystemLibInitializer.read_procedure.SymbolInfo, loc);
                            	last_call = convertion_data_and_alghoritms.create_simple_function_call(fn, get_location(ex), exl.ToArray());
                        	}
                        	else
                        	{
                                if (SystemLibrary.SystemLibInitializer.readln_procedure.Equal(si) && parameters.expressions.Count == 2 && en.type == SystemLibrary.SystemLibrary.string_type)
                                {
                                    fn = convertion_data_and_alghoritms.select_function(exl, SystemLibrary.SystemLibInitializer.readln_procedure.SymbolInfo, loc);
                                    readln_string_file = true;
                                }
                                else
                                    fn = convertion_data_and_alghoritms.select_function(exl, SystemLibrary.SystemLibInitializer.read_procedure.SymbolInfo, loc);
                            	last_call = convertion_data_and_alghoritms.create_simple_function_call(fn, get_location(ex), exl.ToArray());
                        	}
                            //last_call = convertion_data_and_alghoritms.create_full_function_call(exl, SystemLibrary.SystemLibInitializer.read_procedure.SymbolInfo, loc, context.converted_type, context.top_function, true);
                        }
                        catch (NoFunctionWithSameArguments)
                        {
                            AddError(en.location, "CAN_NOT_READ");
                        }
                    }
                    first_iteration = false;
                }
            }
            if ((parameters == null) || (parameters.expressions.Count == 0)) // read(), readln()
            {
                if (SystemLibrary.SystemLibInitializer.read_procedure.Equal(si))
                {
                    if (read_from_file)
                        exl.AddElement(file);
                    function_node fn = convertion_data_and_alghoritms.select_function(exl,
                        SystemLibrary.SystemLibInitializer.read_procedure.SymbolInfo, loc);
                    if (read_from_file)
                        last_call = convertion_data_and_alghoritms.create_simple_function_call(fn, loc, file);
                    else
                        last_call = convertion_data_and_alghoritms.create_simple_function_call(fn, loc);
                }
            }
            if (SystemLibrary.SystemLibInitializer.readln_procedure.Equal(si)) // readln(...)
            {
                if (!readln_string_file)
                {
                    if (last_call != null && convertion_data_and_alghoritms.statement_list_stack.size > 0)
                        convertion_data_and_alghoritms.statement_list_stack.top().statements.AddElement(last_call);
                    exl.clear();

                    if (read_from_file)
                        exl.AddElement(file);

                    function_node fn = convertion_data_and_alghoritms.select_function(exl,
                            SystemLibrary.SystemLibInitializer.readln_procedure.SymbolInfo, loc);
                    if (read_from_file)
                        last_call = convertion_data_and_alghoritms.create_simple_function_call(fn, loc, file);
                    else
                        last_call = convertion_data_and_alghoritms.create_simple_function_call(fn, loc);
                }
            }
            return last_call;
        }
        private expression_node make_dispose_call(SymbolInfo si, SyntaxTree.expression_list parameters, location loc)
        {
            if (parameters == null)
            {
                AddError(new NoFunctionWithSameParametresNum(loc, false, si.sym_info as function_node));
                return null;
            }
            if (parameters.expressions.Count == 1)
            {
                expression_node param0 = convert_strong(parameters.expressions[0]);
                if (!param0.type.IsPointer || param0.type == SystemLibrary.SystemLibrary.pointer_type)
                    AddError(new NoFunctionWithSameArguments(loc, true));
                if (!param0.is_addressed)
                {
                    bool is_pascal_array_ref = false;
                    if (param0.semantic_node_type == semantic_node_type.common_method_call)
                    {
                        common_method_call cmc = (common_method_call)param0;
                        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 = convertion_data_and_alghoritms.convert_type(right, (ii as bounded_array_interface).ordinal_type_interface.elems_type);
                                right = convertion_data_and_alghoritms.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));
                                param0 = new simple_array_indexing(left, right, cmc.type, cmc.location);
                                is_pascal_array_ref = true;
                            }
                        }
                        if (!is_pascal_array_ref)
                        {
                            AddError(new ThisExpressionCanNotBePassedAsVarParameter(param0));
                            return null;
                        }

                    }
                    else
                    {
                        AddError(new ThisExpressionCanNotBePassedAsVarParameter(param0));
                        return null;
                    }
                }
                function_node fn = si.sym_info as function_node;
                common_namespace_function_call cnfc = new common_namespace_function_call(fn as common_namespace_function_node, loc);
                cnfc.parameters.AddElement(param0);
                return cnfc;

            }
            else
            {
                AddError(new NoFunctionWithSameParametresNum(loc, false, si.sym_info as function_node));
                return null;
            }
        }
        private void indexer_as_expression_index(expression_node expr, SyntaxTree.expression_list parameters,
            motivation mot, location loc)
        {
            try_convert_typed_expression_to_function_call(ref expr);

            // SSM 10.01.16 Tuple t[i]
            var ent = expr.type as compiled_type_node;

            if (ent== null)
            {
                var eeee = expr.type as compiled_generic_instance_type_node;
                if (eeee!= null)
                    ent = eeee.original_generic as compiled_type_node;
            }

            if (ent != null)
            {
                var t = ent.compiled_type;
                if (t.FullName.StartsWith("System.Tuple"))
                {
                    expression eee = parameters.expressions[0];

                    if (parameters.expressions.Count > 1)
                        AddError(get_location(eee), "TUPLE_CAN_HAVE_ONLY_ONE_INDEX");

                    var cn = convert_strong_to_constant_node(eee);

                    var v = cn as int_const_node;

                    if (v != null)
                    {
                        if (v.constant_value<0 || v.constant_value >= t.GetGenericArguments().Count())
                            AddError(cn.location, "TUPLE_INDEX_OUT_OF_RANGE_{0}", t.GetGenericArguments().Count()-1);
                        var dn = new dot_node(new semantic_addr_value(expr), new ident("Item" + (v.constant_value + 1).ToString(), eee.source_context),new SourceContext(loc.begin_line_num,loc.begin_column_num,loc.end_line_num,loc.end_column_num));
                        visit(dn);
                        return;
                    }
                    else AddError(cn.location, "TUPLE_INDEX_MUST_BE_INTEGER_CONSTANT");
                }
            }
            // end SSM 09.01.16 Tuple t[i]

            if (expr.type.type_special_kind == SemanticTree.type_special_kind.array_kind)
            {
                internal_interface ii = expr.type.get_internal_interface(internal_interface_kind.unsized_array_interface);
                array_internal_interface aii = (array_internal_interface)ii;
                int rank = aii.rank;
                //TODO: Многомерные массивы.
                expression_node ind_expr = convert_strong(parameters.expressions[0]);
                ind_expr = additional_indexer_convertion(ind_expr, expr.type);
                simple_array_indexing sai = new simple_array_indexing(expr, ind_expr, aii.element_type, loc);
                if (rank == 1)
                for (int i = 1; i < parameters.expressions.Count; i++)
                {
                    ii = sai.type.get_internal_interface(internal_interface_kind.unsized_array_interface);
                    location lloc = get_location(parameters.expressions[i]);
                    if (ii == null)
                    {
                        AddError(lloc, "{0}_DIMENSIONAL_ARRAY_CAN_NOT_HAVE_{1}_AND_MORE_INDEXING", i, i+1);
                    }
                    aii = (array_internal_interface)ii;
                    ind_expr = convert_strong(parameters.expressions[i]);
                    ind_expr = additional_indexer_convertion(ind_expr, sai.type);
                    sai = new simple_array_indexing(sai, ind_expr, aii.element_type, lloc);
                }
                else
                {
                    if (rank != parameters.expressions.Count)
                        AddError(get_location(parameters), "{0}_DIMENSIONAL_ARRAY_CAN_NOT_HAVE_{1}_AND_MORE_INDEXING", rank, rank + 1);
                	List<expression_node> lst = new List<expression_node>();
                	for (int i = 0; i < parameters.expressions.Count; i++)
                	{
                    	location lloc = get_location(parameters.expressions[i]);
                    	ind_expr = convert_strong(parameters.expressions[i]);
                    	ind_expr = additional_indexer_convertion(ind_expr, sai.type);
                    	lst.Add(ind_expr);
                	}
                	sai = new simple_array_indexing(expr, lst[0], aii.element_type, get_location(parameters));
                	sai.expr_indices = lst.ToArray();
                }
                switch (mot)
                {
                    case motivation.address_reciving:
                        {
                            return_addressed_value(sai);
                            break;
                        }
                    case motivation.expression_evaluation:
                        {
                            return_value(sai);
                            break;
                        }
                    case motivation.semantic_node_reciving:
                        {
                            return_semantic_value(sai);
                            break;
                        }
                }
                return;
            }
            else if (expr.type.type_special_kind == SemanticTree.type_special_kind.short_string)
            {
            	if (parameters.expressions.Count != 1)
                    AddError(loc, "INVALID_PARAMETER_COUNT_IN_INDEXER");
            	expression_node ind_expr = convert_strong(parameters.expressions[0]);
            	ind_expr = additional_indexer_convertion(ind_expr, expr.type);
            	//expression_node en = convertion_data_and_alghoritms.create_simple_function_call(SystemLibrary.SystemLibInitializer.GetCharInShortStringProcedure.sym_info as function_node,loc,ind_expr,new int_const_node((expr.type as short_string_type_node).Length,null));
            	switch (mot)
                {
                    case motivation.address_reciving:
                        {
                            simple_array_indexing sai = new simple_array_indexing(expr, ind_expr, SystemLibrary.SystemLibrary.char_type, loc);
                            return_addressed_value(sai);
                            //return_addressed_value(convertion_data_and_alghoritms.create_simple_function_call(SystemLibrary.SystemLibInitializer.SetCharInShortStringProcedure.sym_info as function_node,loc,expr,ind_expr) as common_namespace_function_call);
                            break;
                        }
                    case motivation.expression_evaluation:
                        {
            				return_value(convertion_data_and_alghoritms.create_simple_function_call(SystemLibrary.SystemLibInitializer.GetCharInShortStringProcedure.sym_info as function_node,loc,expr,ind_expr,new int_const_node((expr.type as short_string_type_node).Length,null)));
                            break;
                        }
                    case motivation.semantic_node_reciving:
                        {
            				return_semantic_value(convertion_data_and_alghoritms.create_simple_function_call(SystemLibrary.SystemLibInitializer.GetCharInShortStringProcedure.sym_info as function_node,loc,expr,ind_expr,new int_const_node((expr.type as short_string_type_node).Length,null)));
                            break;
                        }
                }
                return;
            	
            }
            /*else if (expr.type.type_special_kind == SemanticTree.type_special_kind.array_wrapper)
            {
            	internal_interface ii = expr.type.get_internal_interface(internal_interface_kind.bounded_array_interface);
                array_internal_interface aii = (array_internal_interface)ii;
                //TODO: Многомерные массивы.
                expression_node ind_expr = convert_strong(parameters.expressions[0]);
                ind_expr = additional_indexer_convertion(ind_expr, expr.type);
                simple_array_indexing sai = new simple_array_indexing(expr, ind_expr, aii.element_type, loc);
                for (int i = 1; i < parameters.expressions.Count; i++)
                {
                    ii = sai.type.get_internal_interface(internal_interface_kind.bounded_array_interface);
                    location lloc = get_location(parameters.expressions[i]);
                    if (ii == null)
                    {
                        throw new NDimensionalArrayCanNotHaveNPlusOneIndexer(lloc, expr, i);
                    }
                    aii = (array_internal_interface)ii;
                    ind_expr = convert_strong(parameters.expressions[i]);
                    ind_expr = create_simple_function_call(SystemLibrary.SystemLibrary.int_sub, cmc.location, ind_expr,
                                            new int_const_node(ii.ordinal_type_interface.ordinal_type_to_int(bai.ordinal_type_interface.lower_value),cmc.location));
                    ind_expr = additional_indexer_convertion(ind_expr, sai.type);
                    sai = new simple_array_indexing(sai, ind_expr, aii.element_type, lloc);
                }
                switch (mot)
                {
                    case motivation.address_reciving:
                        {
                            return_addressed_value(sai);
                            break;
                        }
                    case motivation.expression_evaluation:
                        {
                            return_value(sai);
                            break;
                        }
                    case motivation.semantic_node_reciving:
                        {
                            return_semantic_value(sai);
                            break;
                        }
                }
                return;
                
                 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 (expr.type.default_property_node == null)
            {
                if (expr.type.semantic_node_type != semantic_node_type.delegated_method)
                {
                    AddError(loc, "NO_DEFAULT_PROPERTY_TO_TYPE_{0}", expr.type.PrintableName);
                }
                else
                {
                    AddError(loc, "NO_DEFAULT_PROPERTY_TO_FUNCTION_TYPE");
                }
            }

            if (expr.type.default_property_node.polymorphic_state == SemanticTree.polymorphic_state.ps_static)
            {
                AddError(new CanNotReferenceToStaticPropertyWithExpression(expr.type.default_property_node, loc, expr.type));
            }
            non_static_property_reference nspr = new non_static_property_reference(expr.type.default_property_node, expr, loc);
            indexer_as_property_indexes(nspr, parameters, mot, loc);
            //eto vrode rabotaet normalno. no imet v vidu
            if (expr.type.type_special_kind == SemanticTree.type_special_kind.array_wrapper)
            {
            	expression_node en = ret.get_expression();
                if (en is non_static_property_reference)
                {
                    non_static_property_reference cmc = (non_static_property_reference)en;
                    internal_interface ii = cmc.expression.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.expression, cmc.location);
                            expression_node right = cmc.fact_parametres[0];
                            //right = convert_type(right, SystemLibrary.SystemLibrary.integer_type);
                            right = convertion_data_and_alghoritms.convert_type(right, (ii as bounded_array_interface).ordinal_type_interface.elems_type);
                            right = convertion_data_and_alghoritms.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));
                            en = new simple_array_indexing(left, right, cmc.type, cmc.location);
                            //is_pascal_array_ref = true;
                        }
                    }
                }
                else
                {
                    common_method_call cmc = (common_method_call)en;
                    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 = convertion_data_and_alghoritms.convert_type(right, (ii as bounded_array_interface).ordinal_type_interface.elems_type);
                            right = convertion_data_and_alghoritms.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));
                            en = new simple_array_indexing(left, right, cmc.type, cmc.location);
                            //is_pascal_array_ref = true;
                        }
                    }
                }
                return_value(en);
            }
            
            return;
        }
        /// <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 simple_array_indexing CreateSimpleArrayIndexing()
 {
     expression_node arr = CreateExpression();
     expression_node ind_expr = CreateExpression();
     List<expression_node> lst = null;
     if (CanReadObject())
     {
     	int len = br.ReadInt32();
     	lst = new List<expression_node>();
     	for (int i=0; i<len; i++)
     		lst.Add(CreateExpression());
     }
     type_node type = GetTypeReference(); 
     simple_array_indexing expr = new simple_array_indexing(arr, ind_expr, type, null);
     if (lst != null)
     	expr.expr_indices = lst.ToArray();
     return expr;
 }
Ejemplo n.º 9
0
		private type_node create_array_type(ordinal_type_interface oti_indexer, type_node element_type,common_namespace_node _cmn, location loc)
		{
			int arr_length = oti_indexer.ordinal_type_to_int(oti_indexer.upper_value) -
				oti_indexer.ordinal_type_to_int(oti_indexer.lower_value) + 1;

			if (arr_length <= 0)
			{
				throw new SimpleSemanticError(loc, "NEGATIVE_ARRAY_LENGTH_({0})_NOT_ALLOWED", arr_length);
			}

			simple_array sa = new simple_array(element_type, arr_length);
			//sa.length = arr_length;
			//sa.element_type = element_type;

			SymbolTable.Scope top_scope = null;
			if (_cmn != null)
			{
				top_scope = _cmn.scope;
			}
			string name = get_pascal_array_name();
			//if (_cmn.namespace_name != null)
			//    name = _cmn.namespace_name + name;
			common_type_node ctn = new common_type_node(null, name, SemanticTree.type_access_level.tal_public,
			                                            _cmn, convertion_data_and_alghoritms.symbol_table.CreateClassScope(top_scope, null), loc);

			ctn.SetBaseType(SystemLibrary.SystemLibrary.object_type);
			//DarkStar Add
			//loc не нужно мне это!  и некому не нужно!
			//loc = null;
			
			//ctn.internal_is_value = true;

			class_constant_definition cdn1 = new class_constant_definition(compiler_string_consts.lower_array_const_name,
			                                                               oti_indexer.lower_value, loc, ctn, SemanticTree.field_access_level.fal_public);
			ctn.scope.AddSymbol(cdn1.name, new SymbolInfo(cdn1));

			class_constant_definition cdn2 = new class_constant_definition(compiler_string_consts.upper_array_const_name,
			                                                               oti_indexer.upper_value, loc, ctn, SemanticTree.field_access_level.fal_public);
			ctn.scope.AddSymbol(cdn2.name, new SymbolInfo(cdn2));

			class_field int_arr = new class_field(compiler_string_consts.internal_array_name, sa, ctn,
			                                      SemanticTree.polymorphic_state.ps_common, SemanticTree.field_access_level.fal_public,loc);
			ctn.scope.AddSymbol(int_arr.name, new SymbolInfo(int_arr));
			ctn.fields.AddElement(int_arr);

			SystemLibrary.SystemLibrary.init_reference_type(ctn);

			ctn.const_defs.AddElement(cdn1);
			ctn.const_defs.AddElement(cdn2);

			common_method_node get_func = new common_method_node(compiler_string_consts.get_val_pascal_array_name,
			                                                     element_type, /*loc*/new location(0xFFFFFF, 0, 0xFFFFFF, 0, loc.doc), ctn, SemanticTree.polymorphic_state.ps_common, SemanticTree.field_access_level.fal_private,
			                                                     convertion_data_and_alghoritms.symbol_table.CreateScope(ctn.scope));
			common_parameter get_param = new common_parameter(compiler_string_consts.unary_param_name,
			                                                  oti_indexer.lower_value.type, SemanticTree.parameter_type.value, get_func, concrete_parameter_type.cpt_none,
			                                                  null, loc);
			get_func.parameters.AddElement(get_param);

			common_parameter_reference cpr = new common_parameter_reference(get_param, 0, loc);
			expression_node en1 = convertion_data_and_alghoritms.create_simple_function_call(oti_indexer.value_to_int,
			                                                                                 loc, cpr);
			expression_node en2 = new int_const_node(oti_indexer.ordinal_type_to_int(oti_indexer.lower_value), loc);
			expression_node sub_expr = convertion_data_and_alghoritms.create_simple_function_call(
				SystemLibrary.SystemLibrary.int_sub, loc, en1, en2);

			this_node thisnode = new this_node(ctn, loc);

			class_field_reference cfr1 = new class_field_reference(int_arr, thisnode, loc);

			expression_node index_expr = new simple_array_indexing(cfr1, sub_expr, element_type, loc);

			statement_node sn = new return_node(index_expr, /*loc*/new location(0xFFFFFF, 0, 0xFFFFFF, 0, loc.doc));

			get_func.function_code = sn;

			common_method_node set_func = new common_method_node(compiler_string_consts.set_val_pascal_array_name,
			                                                     null, /*loc*/new location(0xFFFFFF, 0, 0xFFFFFF, 0, loc.doc), ctn, SemanticTree.polymorphic_state.ps_common, SemanticTree.field_access_level.fal_private,
			                                                     convertion_data_and_alghoritms.symbol_table.CreateScope(ctn.scope));
			common_parameter set_ind = new common_parameter(compiler_string_consts.left_param_name,
			                                                oti_indexer.lower_value.type, SemanticTree.parameter_type.value, set_func, concrete_parameter_type.cpt_none,
			                                                null, loc);
			set_func.parameters.AddElement(set_ind);
			common_parameter set_val = new common_parameter(compiler_string_consts.right_param_name,
			                                                element_type, SemanticTree.parameter_type.value, set_func, concrete_parameter_type.cpt_none, null, loc);
			set_func.parameters.AddElement(set_val);

			common_parameter_reference cpr2 = new common_parameter_reference(set_ind, 0, loc);
			expression_node en3 = convertion_data_and_alghoritms.create_simple_function_call(oti_indexer.value_to_int,
			                                                                                 loc, cpr2);
			expression_node en4 = new int_const_node(oti_indexer.ordinal_type_to_int(oti_indexer.lower_value), loc);
			expression_node sub_expr2 = convertion_data_and_alghoritms.create_simple_function_call(
				SystemLibrary.SystemLibrary.int_sub, loc, en3, en4);

			class_field_reference cfr2 = new class_field_reference(int_arr, thisnode, loc);

			expression_node index_expr2 = new simple_array_indexing(cfr2, sub_expr2, element_type,loc);

			SymbolInfo si = element_type.find_in_type(compiler_string_consts.assign_name);
			if (si == null)
			{
				throw new NotSupportedError(loc);
				throw new CompilerInternalError("Varable of this type can not be assigned");
			}
			if (si.sym_info.general_node_type != general_node_type.function_node)
			{
				throw new CompilerInternalError("Invalid assign operator");
			}

			expression_node val_ref = new common_parameter_reference(set_val, 0, loc);

			function_node assign = (function_node)si.sym_info;
			statement_node assign_call = convertion_data_and_alghoritms.create_simple_function_call(assign,
			                                                                                        /*loc*/new location(0xFFFFFF, 0, 0xFFFFFF, 0, loc.doc), index_expr2, val_ref);

			set_func.function_code = assign_call;

			ctn.methods.AddElement(get_func);
			ctn.methods.AddElement(set_func);

			common_property_node cpn = new common_property_node(compiler_string_consts.index_property_pascal_array_name,
			                                                    ctn, element_type, get_func, set_func, loc, SemanticTree.field_access_level.fal_public, SemanticTree.polymorphic_state.ps_common);

			common_parameter prop_cp = new common_parameter(compiler_string_consts.unary_param_name, oti_indexer.lower_value.type,
			                                                SemanticTree.parameter_type.value, null, concrete_parameter_type.cpt_none, null, loc);
			cpn.parameters.AddElement(prop_cp);

			ctn.properties.AddElement(cpn);

			ctn.default_property = cpn;

			if (_cmn != null)
			{
				_cmn.types.AddElement(ctn);
			}

			bounded_array_interface bai = new bounded_array_interface(oti_indexer, element_type, cpn, oti_indexer.lower_value.type, int_arr);
			ctn.add_internal_interface(bai);
			ctn.type_special_kind = SemanticTree.type_special_kind.array_wrapper;

            if (element_type.type_special_kind != SemanticTree.type_special_kind.array_wrapper)
            {
                ctn.ImplementingInterfaces.Add(compiled_type_node.get_type_node(NetHelper.NetHelper.FindType(compiler_string_consts.IEnumerableInterfaceName)));
                common_method_node en_cmn = new common_method_node(compiler_string_consts.GetEnumeratorMethodName, compiled_type_node.get_type_node(NetHelper.NetHelper.FindType(compiler_string_consts.IEnumeratorInterfaceName)), null, ctn, SemanticTree.polymorphic_state.ps_virtual, SemanticTree.field_access_level.fal_public, null);

                compiled_function_node en_fnc = NetHelper.NetHelper.FindName(NetHelper.NetHelper.FindType(compiler_string_consts.IEnumerableInterfaceName), compiler_string_consts.GetEnumeratorMethodName).sym_info as compiled_function_node;
                statements_list sl = new statements_list(null);
                sl.statements.AddElement(new return_node(
                    new compiled_function_call(en_fnc, new class_field_reference(int_arr, new this_node(ctn, null), null), null), null));
                en_cmn.function_code = sl;
                en_cmn.newslot_awaited = true;
                ctn.methods.AddElement(en_cmn);

                if (!element_type.IsPointer)
                {
                    List<type_node> generic_args = new List<type_node>();
                    generic_args.Add(element_type);
                    type_node en_tn = compiled_type_node.get_type_node(NetHelper.NetHelper.FindType(compiler_string_consts.IGenericEnumerableInterfaceName)).get_instance(generic_args);
                    ctn.ImplementingInterfaces.Add(en_tn);

                    en_cmn = new common_method_node(compiler_string_consts.GetEnumeratorMethodName, compiled_type_node.get_type_node(NetHelper.NetHelper.FindType(compiler_string_consts.IGenericEnumeratorInterfaceName)).get_instance(generic_args), null, ctn, SemanticTree.polymorphic_state.ps_virtual, SemanticTree.field_access_level.fal_public, null);
                    //en_fnc = en_tn.find_in_type("GetEnumerator").sym_info as function_node;//NetHelper.NetHelper.FindName(NetHelper.NetHelper.FindType(compiler_string_consts.IGenericEnumerableInterfaceName), compiler_string_consts.GetEnumeratorMethodName).sym_info as compiled_function_node;
                    SymbolInfo en_si = en_tn.find_in_type("GetEnumerator");
                    if (en_si.Next != null && (en_si.Next.sym_info as function_node).return_value_type.is_generic_type_instance)
                        en_si = en_si.Next;
                    function_node en_fnc_inst = en_si.sym_info as function_node; ;//.get_instance(generic_args, true, loc);
                    sl = new statements_list(null);
                    if (en_fnc_inst is compiled_function_node)
                        sl.statements.AddElement(new return_node(
                            new compiled_function_call(en_fnc_inst as compiled_function_node, new class_field_reference(int_arr, new this_node(ctn, null), null), null), null));
                    else
                        sl.statements.AddElement(new return_node(
                            new common_method_call(en_fnc_inst as common_method_node, new class_field_reference(int_arr, new this_node(ctn, null), null), null), null));
                    en_cmn.function_code = sl;
                    en_cmn.newslot_awaited = true;
                    ctn.methods.AddElement(en_cmn);
                }
            }
			
			//= operation
			SymbolTable.ClassMethodScope scope = convertion_data_and_alghoritms.symbol_table.CreateClassMethodScope(_cmn.scope,ctn.scope);
        	common_method_node cmn_eq = new common_method_node(compiler_string_consts.GetNETOperName(compiler_string_consts.eq_name),SystemLibrary.SystemLibrary.bool_type,null,ctn,
        	                                                SemanticTree.polymorphic_state.ps_static,SemanticTree.field_access_level.fal_public,scope);
        	cmn_eq.IsOperator = true;
        	common_parameter prm1 = new common_parameter("a",ctn,SemanticTree.parameter_type.value,cmn_eq,concrete_parameter_type.cpt_none,null,null);
        	common_parameter prm2 = new common_parameter("b",ctn,SemanticTree.parameter_type.value,cmn_eq,concrete_parameter_type.cpt_none,null,null);
        	cmn_eq.parameters.AddElement(prm1);
        	cmn_eq.parameters.AddElement(prm2);
        	statements_list body = new statements_list(null);
        	local_variable vdn = new local_variable("$i",SystemLibrary.SystemLibrary.integer_type,cmn_eq,null);//this.convertion_data_and_alghoritms.syntax_tree_visitor.context.create_for_temp_variable(SystemLibrary.SystemLibrary.integer_type, null);
        	cmn_eq.var_definition_nodes_list.AddElement(vdn);
        	expression_node var_ref = new local_variable_reference(vdn,0,null);//this.convertion_data_and_alghoritms.syntax_tree_visitor.create_variable_reference(vdn,null);
        	basic_function_call cond = new basic_function_call(SystemLibrary.SystemLibrary.int_sm as basic_function_node,null);
        	cond.parameters.AddElement(var_ref);
        	cond.parameters.AddElement(new int_const_node(arr_length,null));
        	while_node while_stmt = new while_node(cond,null);
        	statements_list while_body = new statements_list(null);
        	while_stmt.body = while_body;
        	simple_array_indexing left_sar = new simple_array_indexing(new class_field_reference(int_arr, new common_parameter_reference(prm1,0,null), null),var_ref,element_type,null);
        	simple_array_indexing right_sar = new simple_array_indexing(new class_field_reference(int_arr, new common_parameter_reference(prm2,0,null), null),var_ref,element_type,null);
        	expression_node cond2 = SystemLibrary.SystemLibrary.syn_visitor.find_operator(compiler_string_consts.noteq_name,
        		                                                                            left_sar,right_sar,null);
        	if_node if_stmt = new if_node(cond2,new return_node(new bool_const_node(false,null),null),null,null);
        	while_body.statements.AddElement(if_stmt);
        	while_body.statements.AddElement(new basic_function_call(SystemLibrary.SystemLibrary.int_assign as basic_function_node,null
        	                                                   ,var_ref,new basic_function_call(SystemLibrary.SystemLibrary.int_add as basic_function_node,null,var_ref,new int_const_node(1,null))));
        	
        	body.statements.AddElement(while_stmt);
        	body.statements.AddElement(new return_node(new bool_const_node(true,null),null));
        	cmn_eq.function_code = body;
        	cmn_eq.is_overload = true;
        	ctn.methods.AddElement(cmn_eq);
        	ctn.Scope.AddSymbol(compiler_string_consts.eq_name,new SymbolInfo(cmn_eq));
        	
        	//<> operation
			scope = convertion_data_and_alghoritms.symbol_table.CreateClassMethodScope(_cmn.scope,ctn.scope);
        	common_method_node cmn_noteq = new common_method_node(compiler_string_consts.GetNETOperName(compiler_string_consts.noteq_name),SystemLibrary.SystemLibrary.bool_type,null,ctn,
        	                                                SemanticTree.polymorphic_state.ps_static,SemanticTree.field_access_level.fal_public,scope);
        	cmn_noteq.IsOperator = true;
        	prm1 = new common_parameter("a",ctn,SemanticTree.parameter_type.value,cmn_noteq,concrete_parameter_type.cpt_none,null,null);
        	prm2 = new common_parameter("b",ctn,SemanticTree.parameter_type.value,cmn_noteq,concrete_parameter_type.cpt_none,null,null);
        	cmn_noteq.parameters.AddElement(prm1);
        	cmn_noteq.parameters.AddElement(prm2);
        	body = new statements_list(null);
        	vdn = new local_variable("$i",SystemLibrary.SystemLibrary.integer_type,cmn_noteq,null);//this.convertion_data_and_alghoritms.syntax_tree_visitor.context.create_for_temp_variable(SystemLibrary.SystemLibrary.integer_type, null);
        	cmn_noteq.var_definition_nodes_list.AddElement(vdn);
        	var_ref = new local_variable_reference(vdn,0,null);//this.convertion_data_and_alghoritms.syntax_tree_visitor.create_variable_reference(vdn,null);
        	cond = new basic_function_call(SystemLibrary.SystemLibrary.int_sm as basic_function_node,null);
        	cond.parameters.AddElement(var_ref);
        	cond.parameters.AddElement(new int_const_node(arr_length,null));
        	while_stmt = new while_node(cond,null);
        	while_body = new statements_list(null);
        	while_stmt.body = while_body;
        	left_sar = new simple_array_indexing(new class_field_reference(int_arr, new common_parameter_reference(prm1,0,null), null),var_ref,element_type,null);
        	right_sar = new simple_array_indexing(new class_field_reference(int_arr, new common_parameter_reference(prm2,0,null), null),var_ref,element_type,null);
        	cond2 = SystemLibrary.SystemLibrary.syn_visitor.find_operator(compiler_string_consts.noteq_name,
        		                                                                            left_sar,right_sar,null);
        	if_stmt = new if_node(cond2,new return_node(new bool_const_node(true,null),null),null,null);
        	while_body.statements.AddElement(if_stmt);
        	while_body.statements.AddElement(new basic_function_call(SystemLibrary.SystemLibrary.int_assign as basic_function_node,null
        	                                                   ,var_ref,new basic_function_call(SystemLibrary.SystemLibrary.int_add as basic_function_node,null,var_ref,new int_const_node(1,null))));
        	
        	body.statements.AddElement(while_stmt);
        	body.statements.AddElement(new return_node(new bool_const_node(false,null),null));
        	cmn_noteq.function_code = body;
        	cmn_noteq.is_overload = true;
        	ctn.methods.AddElement(cmn_noteq);
        	ctn.Scope.AddSymbol(compiler_string_consts.noteq_name,new SymbolInfo(cmn_noteq));
        	
        	//Equals
        	/*scope = convertion_data_and_alghoritms.symbol_table.CreateClassMethodScope(_cmn.scope,ctn.scope);
        	common_method_node cmn_equals = new common_method_node("Equals",SystemLibrary.SystemLibrary.bool_type,null,ctn,
        	                                                SemanticTree.polymorphic_state.ps_virtual,SemanticTree.field_access_level.fal_public,scope);
        	prm1 = new common_parameter("a",SystemLibrary.SystemLibrary.object_type,SemanticTree.parameter_type.value,cmn_equals,concrete_parameter_type.cpt_none,null,null);
        	
        	cmn_equals.parameters.AddElement(prm1);
        	body = new statements_list(null);
        	vdn = new local_variable("$i",ctn,cmn_equals,null);//this.convertion_data_and_alghoritms.syntax_tree_visitor.context.create_for_temp_variable(SystemLibrary.SystemLibrary.integer_type, null);
        	cmn_equals.var_definition_nodes_list.AddElement(vdn);
        	var_ref = new local_variable_reference(vdn,0,null);//this.convertion_data_and_alghoritms.syntax_tree_visitor.create_variable_reference(vdn,null);
        	as_node _as = new as_node(new common_parameter_reference(prm1,0,null),ctn,null);
        	base_function_call ass_bfc = new basic_function_call(SystemLibrary.SystemLibrary.object_type.find(compiler_string_consts.assign_name).sym_info as basic_function_node,null);
        	ass_bfc.parameters.AddElement(var_ref);
        	ass_bfc.parameters.AddElement(_as);
        	body.statements.AddElement(ass_bfc);
        	common_static_method_call csmc = new common_static_method_call(ctn.find_in_type(compiler_string_consts.eq_name).sym_info as common_method_node,null);
        	csmc.parameters.AddElement(new this_node(ctn,null));
        	csmc.parameters.AddElement(var_ref);
        	body.statements.AddElement(new return_node(csmc,null));
        	ctn.methods.AddElement(cmn_equals);
        	ctn.Scope.AddSymbol("Equals",new SymbolInfo(cmn_equals));*/
        	return ctn;
		}