예제 #1
0
 public exception_filter(type_node filter_type, local_block_variable_reference exception_var,
                         statement_node exception_handler, location loc) : base(loc)
 {
     _filter_type       = filter_type;
     _exception_var     = exception_var;
     _exception_handler = exception_handler;
 }
예제 #2
0
 private void VisitLocalBlockVariableReference(local_block_variable_reference en)
 {
 	IncreaseNumUseVar(en);
 }
예제 #3
0
 private void IncreaseNumUseVar(local_block_variable_reference lvr)
 {
     VarInfo vi = helper.GetVariable(lvr.var);
     if (vi == null) return;
     vi.num_use++;
     vi.act_num_use++;
     vi.cur_use++;
     //if (vi.cur_ass == 0 && !lvr.var.name.Contains("$")) helper.AddTempWarning(lvr.var,new UseWithoutAssign(lvr.var.name, lvr.location));
 }
예제 #4
0
        private void IncreaseNumAssVar(local_block_variable_reference lvr)
        {
            VarInfo vi = helper.GetVariable(lvr.var);
            vi.num_use++;
            vi.cur_ass++;
            vi.num_ass++;
            vi.last_ass_loc = lvr.location;
            if (vi.last_ass_loc == null) vi.num_ass--;
            if (vi.cur_use > 0) vi.cur_use--;

        }
 private void VisitLocalBlockVariableReference(local_block_variable_reference expr)
 {
     bw.Write(GetMemberOffset(expr.var));
     //bw.Write(expr.static_depth);
 }
 public override void visit(SyntaxTree.try_stmt _try_stmt)
 {
     context.enter_code_block_without_bind();
     context.enter_exception_handlers();
     statement_node try_statements = convert_strong(_try_stmt.stmt_list);
     context.leave_code_block();
     location loc = get_location(_try_stmt);
     exception_filters_list efl = new exception_filters_list();
     SyntaxTree.try_handler_except try_hand_except = _try_stmt.handler as SyntaxTree.try_handler_except;
     if (try_hand_except != null)
     {
         if (try_hand_except.except_block.handlers != null)
         {
             int hand_count = try_hand_except.except_block.handlers.handlers.Count;
             for (int i = 0; i < hand_count; i++)
             {
                 SyntaxTree.exception_handler eh = try_hand_except.except_block.handlers.handlers[i];
                 type_node filter_type = convert_strong(eh.type_name);
                 if (!SemanticRules.GenerateNativeCode && !(filter_type.is_generic_parameter ||
                     filter_type == SystemLibrary.SystemLibrary.exception_base_type ||
                     type_table.is_derived(SystemLibrary.SystemLibrary.exception_base_type, filter_type)))
                 {
                     AddError(get_location(eh.type_name), "EXCEPTION_TYPE_MUST_BE_SYSTEM_EXCEPTION_OR_DERIVED_FROM_EXCEPTION");
                 }
                 current_catch_excep = new int_const_node(2,null);//create_constructor_call(filter_type, new expressions_list(), null);
                 local_block_variable_reference lvr = null;
                 
                 context.enter_code_block_without_bind();
                 if (eh.variable != null)
                 {
                 	
                 	context.check_name_redefinition = false;
                 	
                 	local_block_variable lbv = context.add_var_definition(eh.variable.name, get_location(eh.variable), filter_type, SemanticTree.polymorphic_state.ps_common) as local_block_variable;
                     context.check_name_redefinition = true;
                 	lvr = new local_block_variable_reference(lbv, lbv.loc);
                 }
                 statement_node stm = convert_strong(eh.statements);
                 context.leave_code_block();
                 
                 /*if (eh.variable != null)
                 {
                     context.leave_scope();
                 }*/
                 exception_filter ef = new exception_filter(filter_type, lvr, stm, get_location(eh));
                 efl.AddElement(ef);
                 current_catch_excep = null;
             }
         }
         else
         {
             context.enter_code_block_without_bind();
             exception_filter ef = new exception_filter(null, null, convert_strong(try_hand_except.except_block.stmt_list), get_location(try_hand_except.except_block.stmt_list));
             context.leave_code_block();
             efl.AddElement(ef);
         }
         if (try_hand_except.except_block.else_stmt_list != null)
         {
             context.enter_code_block_without_bind();
             statement_node else_stm = convert_strong(try_hand_except.except_block.else_stmt_list);
             context.leave_code_block();
             type_node ftype = SystemLibrary.SystemLibrary.object_type;
             exception_filter else_ef = new exception_filter(ftype, null, else_stm, else_stm.location);
             efl.AddElement(else_ef);
         }
     }
     else
     {
     	type_node filter_type = compiled_type_node.get_type_node(NetHelper.NetHelper.FindType(compiler_string_consts.ExceptionName));
     	expression_node current_catch_excep = create_constructor_call(filter_type, new expressions_list(), null);
         local_block_variable_reference lvr = null;
         local_block_variable tmp_var = context.add_var_definition(context.BuildName("$try_temp" + UniqueNumStr()), null, SystemLibrary.SystemLibrary.bool_type, null) as local_block_variable;
         statements_list stm = new statements_list(null);
         SyntaxTree.try_handler_finally try_hndlr_finally = _try_stmt.handler as SyntaxTree.try_handler_finally;
         context.enter_code_block_without_bind();
         statement_node finally_stmt = convert_strong(try_hndlr_finally.stmt_list);
         context.leave_code_block();
         stm.statements.AddElement(finally_stmt);
         basic_function_call bfc = new basic_function_call(SystemLibrary.SystemLibrary.bool_not as basic_function_node,null);
         bfc.parameters.AddElement(new local_block_variable_reference(tmp_var,null));
         stm.statements.AddElement(new if_node(bfc,new rethrow_statement_node(null),null,null));
     	exception_filter ef = new exception_filter(filter_type, lvr, stm, null);
         efl.AddElement(ef);
         bfc = new basic_function_call(SystemLibrary.SystemLibrary.bool_assign as basic_function_node,null);
         bfc.parameters.AddElement(new local_block_variable_reference(tmp_var,null));
         bfc.parameters.AddElement(new bool_const_node(true,null));
         
         (try_statements as statements_list).statements.AddElement(bfc);
         (try_statements as statements_list).statements.AddElement(new throw_statement_node(current_catch_excep,null));
         return_value(new try_block(try_statements, null, efl, loc));
         context.leave_exception_handlers();
         return;
     }
     statement_node finally_st = null;
     SyntaxTree.try_handler_finally try_handler_finally = _try_stmt.handler as SyntaxTree.try_handler_finally;
     if (try_handler_finally != null)
     {
         context.enter_code_block_without_bind();
         finally_st = convert_strong(try_handler_finally.stmt_list);
         context.leave_code_block();
     }
     try_block tb = new try_block(try_statements, finally_st, efl, loc);
     context.leave_exception_handlers();
     return_value(tb);
 }
        /// <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 expression_node CreateLocalBlockVariableReference()
 {
     local_block_variable lv = GetLocalBlockVariableByOffset(br.ReadInt32());
     local_block_variable_reference lvr = new local_block_variable_reference(lv, null);
     return lvr;
 }
예제 #9
0
 public exception_filter(type_node filter_type, local_block_variable_reference exception_var,
     statement_node exception_handler, location loc) : base(loc)
 {
     _filter_type = filter_type;
     _exception_var = exception_var;
     _exception_handler = exception_handler;
 }
        internal expression_node GetInitalValueForVariable(var_definition_node vdn, expression_node userInitalValue)
        {
            if (userInitalValue != null)
            {
            	if (CurrentStatementList != null)
                {
                    //Инициализировать надо в текущем стейтменте
                    location lid = ((local_block_variable)vdn).loc;
                    local_block_variable_reference lbvr = new local_block_variable_reference((local_block_variable)vdn, lid);
                    if (vdn.type.type_special_kind == SemanticTree.type_special_kind.set_type)
                	{
                		userInitalValue = syntax_tree_visitor.get_init_call_for_set_as_constr(vdn,userInitalValue);
                	//userInitalValue.type = SystemLibrary.SystemLibInitializer.TypedSetType.sym_info as type_node;
                	}
                    else
                    if (userInitalValue is array_initializer)
                	{
                		array_initializer arr = userInitalValue as array_initializer;
                		if (vdn.type.element_type.type_special_kind == SemanticTree.type_special_kind.short_string)
                		{
                			for (int i=0; i<arr.element_values.Count; i++)
                			{
                				//arr.element_values[i] = syntax_tree_visitor.find_operator(compiler_string_consts.assign_name, varref2, arr.element_values[i], null);
                				arr.element_values[i] = convertion_data_and_alghoritms.create_simple_function_call(SystemLibrary.SystemLibInitializer.ClipShortStringProcedure.sym_info as function_node,null,convertion_data_and_alghoritms.convert_type(arr.element_values[i],SystemLibrary.SystemLibrary.string_type),new int_const_node((vdn.type.element_type as short_string_type_node).Length,null));
                			}
                		}
                	}
                    CurrentStatementList.statements.AddElement(syntax_tree_visitor.find_operator(compiler_string_consts.assign_name, lbvr, userInitalValue, lid));
                    if (vdn.type.type_special_kind == SemanticTree.type_special_kind.set_type)
                	{
                 		lbvr.type = SystemLibrary.SystemLibInitializer.TypedSetType.sym_info as type_node;
                	}
                    return null;
                }
                if (userInitalValue is constant_node)
                {
                    if (vdn.type.type_special_kind == SemanticTree.type_special_kind.short_string)
                	{
						expression_node varref2 = convertion_data_and_alghoritms.CreateVariableReference(vdn, null);
						userInitalValue = syntax_tree_visitor.find_operator(compiler_string_consts.assign_name, varref2, userInitalValue, null);
                	}
                	return userInitalValue;
                }
                if (userInitalValue is array_initializer)
                {
                	array_initializer arr = userInitalValue as array_initializer;
                	if (vdn.type.element_type.type_special_kind == SemanticTree.type_special_kind.short_string)
                	{
                		expression_node varref2 = convertion_data_and_alghoritms.CreateVariableReference(vdn, null);
                		for (int i=0; i<arr.element_values.Count; i++)
                		{
                			//arr.element_values[i] = syntax_tree_visitor.find_operator(compiler_string_consts.assign_name, varref2, arr.element_values[i], null);
                			arr.element_values[i] = convertion_data_and_alghoritms.create_simple_function_call(SystemLibrary.SystemLibInitializer.ClipShortStringProcedure.sym_info as function_node,null,convertion_data_and_alghoritms.convert_type(arr.element_values[i],SystemLibrary.SystemLibrary.string_type),new int_const_node((vdn.type.element_type as short_string_type_node).Length,null));
                		}
                	}
                	return userInitalValue;
                }
                expression_node varref = convertion_data_and_alghoritms.CreateVariableReference(vdn, userInitalValue.location);
                if (vdn.type.type_special_kind == SemanticTree.type_special_kind.set_type)
                {
                	userInitalValue = syntax_tree_visitor.get_init_call_for_set_as_constr(vdn,userInitalValue);
                	//userInitalValue.type = SystemLibrary.SystemLibInitializer.TypedSetType.sym_info as type_node;
                }
                else if (vdn.type.type_special_kind == SemanticTree.type_special_kind.short_string)
                {
					expression_node cmc = convertion_data_and_alghoritms.create_simple_function_call(SystemLibrary.SystemLibInitializer.ClipShortStringProcedure.sym_info as function_node,null,convertion_data_and_alghoritms.convert_type(userInitalValue,SystemLibrary.SystemLibrary.string_type),new int_const_node((vdn.type as short_string_type_node).Length,null));
        			userInitalValue = cmc;
                }
                userInitalValue = syntax_tree_visitor.find_operator(compiler_string_consts.assign_name, varref, userInitalValue, userInitalValue.location);
                if (vdn.type.type_special_kind == SemanticTree.type_special_kind.set_type)
                {
                 	varref.type = SystemLibrary.SystemLibInitializer.TypedSetType.sym_info as type_node;
                }
                return userInitalValue;
            }
            type_node tp = vdn.type;
            if (syntax_tree_visitor.SystemUnitAssigned && SystemLibrary.SystemLibInitializer.TextFileType.Found && tp.name == compiler_string_consts.text_file_name_type_name)
                if (tp == SystemLibrary.SystemLibInitializer.TextFileType.TypeNode)
                    SystemLibrary.SystemLibInitializer.TextFileType.TypeNode.type_special_kind = PascalABCCompiler.SemanticTree.type_special_kind.text_file;
            //(ssyy) Вставил switch и обработку BinaryFile
            switch (tp.type_special_kind)
            {
                case SemanticTree.type_special_kind.typed_file:
                    userInitalValue = syntax_tree_visitor.get_init_call_for_typed_file(vdn, tp.element_type);
                    break;
                case SemanticTree.type_special_kind.set_type:
                    userInitalValue = syntax_tree_visitor.get_init_call_for_set(vdn);
                    break;
                case SemanticTree.type_special_kind.binary_file:
                    userInitalValue = syntax_tree_visitor.get_init_call_for_binary_file(vdn);
                    break;
                case SemanticTree.type_special_kind.text_file:
                    userInitalValue = syntax_tree_visitor.get_init_call_for_text_file(vdn);
                    break;
                default:
                    if (tp is short_string_type_node)
                        userInitalValue = SystemLibrary.SystemLibrary.empty_string;//syntax_tree_visitor.get_init_call_for_short_string(vdn);
                    else
                        if (tp == SystemLibrary.SystemLibrary.string_type && SemanticRules.InitStringAsEmptyString)
                            userInitalValue = SystemLibrary.SystemLibrary.empty_string;
                    break;
            }
            return userInitalValue;
        }