Beispiel #1
0
 private void VisitCommonMethodCall(common_method_call en)
 {
     VisitExpression(en.obj);
     for (int i = 0; i < en.parameters.Count; i++)
     {
         VisitExpression(en.parameters[i]);
     }
 }
Beispiel #2
0
 private void VisitCommonMethodCall(common_method_call en)
 {
     VisitExpression(en.obj);
     for (int i = 0; i < en.parameters.Count; i++)
         VisitExpression(en.parameters[i]);
 }
		private void VisitCommonMethodCall(common_method_call expr)
		{
			VisitExpression(expr.obj);
			WriteMethodReference(expr.function_node);
            //ssyy
            if (expr.last_result_function_call)
            {
                bw.Write((byte)1);
            }
            else
            {
                bw.Write((byte)0);
            }
            //\ssyy
            bw.Write(expr.virtual_call);
            bw.Write(expr.parameters.Count);
			foreach (expression_node e in expr.parameters)
				VisitExpression(e);
		}
 private base_function_call create_not_static_method_call(function_node fn, expression_node en, location loc, bool procedure_allowed)
 {
     try_convert_typed_expression_to_function_call(ref en);
     if ((!procedure_allowed) && (fn.return_value_type == null))
     {
         AddError(loc, "FUNCTION_EXPECTED_PROCEDURE_{0}_MEET", fn);
     }
     if (fn.semantic_node_type == semantic_node_type.common_method_node)
     {
         common_method_node cmn = (common_method_node)fn;
         if (cmn.is_constructor)
         {
             AddError(loc, "CAN_NOT_CALL_CONSTRUCTOR_AS_PROCEDURE");
         }
         if (cmn.original_function != null && cmn.original_function is compiled_function_node && (cmn.original_function as compiled_function_node).ConnectedToType != null)
         {
             common_static_method_call csmc = new common_static_method_call(cmn, loc);
             return csmc;
         }
         if (cmn.polymorphic_state == SemanticTree.polymorphic_state.ps_static)
         {
             AddError(new CanNotCallStaticMethodWithExpression(en, fn));
         }
         
         common_method_call cmc = new common_method_call(cmn, en, loc);
         cmc.virtual_call = !inherited_ident_processing;
         return cmc;
     }
     if (fn.semantic_node_type == semantic_node_type.compiled_function_node)
     {
         compiled_function_node cfn = (compiled_function_node)fn;
         if (cfn.ConnectedToType != null)
         {
             compiled_static_method_call csmc = new compiled_static_method_call(cfn, loc);
             return csmc;
         }
         else
         {
             if (cfn.polymorphic_state == SemanticTree.polymorphic_state.ps_static)
             {
                 if (!cfn.is_extension_method)
                     AddError(new CanNotCallStaticMethodWithExpression(en, fn));
                 else
                     return new compiled_static_method_call(cfn, loc);
             }
             compiled_function_call cfc = new compiled_function_call(cfn, en, loc);
             cfc.virtual_call = !inherited_ident_processing;
             return cfc;
         }
     }
     if (fn.semantic_node_type == semantic_node_type.compiled_constructor_node)
     {
         AddError(loc, "CAN_NOT_CALL_CONSTRUCTOR_AS_PROCEDURE");
     }
     if (fn.semantic_node_type == semantic_node_type.common_namespace_function_node && (fn as common_namespace_function_node).ConnectedToType != null)
     {
     	common_namespace_function_call cnfc = new common_namespace_function_call(fn as common_namespace_function_node,loc);
     	//cnfc.parameters.AddElement(en);
     	return cnfc;
     }
     if (fn.semantic_node_type == semantic_node_type.indefinite_definition_node)
     {
         indefinite_function_call ifc = new indefinite_function_call(fn, loc);
         return ifc;
     }
     throw new CompilerInternalError("Invalid method kind");
 }
 private function_node GenerateSetMethod(common_property_node cpn, common_method_node accessor, location loc)
 {
     common_method_node cmn = new common_method_node(
         "set_" + cpn.name, loc, cpn.common_comprehensive_type,
         cpn.polymorphic_state, cpn.field_access_level, null);
     cpn.common_comprehensive_type.methods.AddElement(cmn);
     //cmn.return_value_type = cpn.property_type;
     cmn.is_overload = true;
     foreach (common_parameter cp in accessor.parameters)
     {
         common_parameter new_cp = new common_parameter(cp.name, cp.type, cp.parameter_type, cp.common_function, cp.concrete_parameter_type, cp.default_value, loc);
         cmn.parameters.AddElement(new_cp);
     }
     expression_node meth_call;
     if (cpn.polymorphic_state == SemanticTree.polymorphic_state.ps_common)
     {
         meth_call = new common_method_call(accessor, new this_node(cpn.common_comprehensive_type, loc), loc);
         foreach (common_parameter cp in cmn.parameters)
         {
             (meth_call as common_method_call).parameters.AddElement(new common_parameter_reference(cp, 0, loc));
         }
     }
     else
     {
         meth_call = new common_static_method_call(accessor, loc);
         foreach (common_parameter cp in cmn.parameters)
         {
             (meth_call as common_static_method_call).parameters.AddElement(new common_parameter_reference(cp, 0, loc));
         }
     }
     cmn.function_code = meth_call;
     cpn.common_comprehensive_type.scope.AddSymbol("set_" + cpn.name, new SymbolInfo(cmn));
     return cmn;
 }
        //\ssyy

        //ssyy
        public void generate_inherited_from_base_and_interface_function(common_type_node ctype, function_node func)
        {
            common_method_node gen_func = context.create_function(func.name, null) as common_method_node;
            gen_func.polymorphic_state = SemanticTree.polymorphic_state.ps_common;
            gen_func.newslot_awaited = true;
            gen_func.is_final = true;
            gen_func.is_overload = true;
            gen_func.field_access_level = SemanticTree.field_access_level.fal_public;
            gen_func.return_value_type = func.return_value_type;
            //gen_func.return_variable = func.retu

            foreach (parameter par in func.parameters)
            {
                concrete_parameter_type cpt =
                    (par.parameter_type == SemanticTree.parameter_type.value) ?
                    concrete_parameter_type.cpt_const :
                    concrete_parameter_type.cpt_var;
                common_parameter c_p = new common_parameter(par.name,
                    par.parameter_type, gen_func, cpt, null);
                c_p.type = par.type;
                c_p.set_param_is_params(par.is_params);
                c_p.inital_value = par.inital_value;
                gen_func.parameters.AddElement(c_p);
            }

            local_variable lv = new local_variable(compiler_string_consts.self_word, gen_func.cont_type, gen_func, null);
            gen_func.scope.AddSymbol(compiler_string_consts.self_word, new SymbolInfo(lv));
            gen_func.self_variable = lv;

            base_function_call bfc;
            this_node tn = null;

            common_method_node commn = func as common_method_node;
            if (commn != null)
            {
                tn = new this_node(commn.comperehensive_type as type_node, null);
                bfc = new common_method_call(commn, tn, null);
            }
            else
            {
                compiled_function_node compn = func as compiled_function_node;
                tn = new this_node(compn.comperehensive_type as type_node, null);
                bfc = new compiled_function_call(compn, tn, null);
            }

            foreach (parameter p in gen_func.parameters)
            {
                bfc.parameters.AddElement(
                    create_variable_reference(p, null));
            }

            //Это запретит чистку стека
            bfc.last_result_function_call = true;

            statements_list snlist = new statements_list(null);
            snlist.statements.AddElement(bfc);
            snlist.statements.AddElement(new empty_statement(null));
            gen_func.function_code = snlist;
            context.pop_top_function();
            //context.leave_block();
        }
        public override void visit(SyntaxTree.assign _assign)
        {
        	internal_is_assign = true;
        	addressed_expression to = convert_address_strong(_assign.to);
        	internal_is_assign = false;
            if (to == null)
            	AddError(get_location(_assign.to), "CAN_NOT_ASSIGN_TO_LEFT_PART");


            #region Вывод параметров лямбда-выражения
            var fld1 = _assign.from as SyntaxTree.function_lambda_definition;
            if (fld1 != null)
            {
                MaybeConvertFunctionLambdaDefinitionToProcedureLambdaDefinition(fld1);
                LambdaHelper.InferTypesFromVarStmt(to.type, _assign.from as SyntaxTree.function_lambda_definition, this);  //lroman//
            }
            
            #endregion
			

            //(ssyy) Вставляю проверки прямо сюда, т.к. запарился вылавливать другие случаи.
            bool flag=false;
            general_node_type node_type = general_node_type.constant_definition;
            if (convertion_data_and_alghoritms.check_for_constant_or_readonly(to, out flag, out node_type))
            {
            	if (flag)
                    AddError(to.location, "CAN_NOT_ASSIGN_TO_CONSTANT_OBJECT");
            	else
            		AddError(new CanNotAssignToReadOnlyElement(to.location,node_type));
            }

            //expression_node from = convert_strong(_assign.from);
            /// SSM исправление Саушкина 10.03.16
            expression_node from;
            var fromAsLambda = _assign.from as function_lambda_definition;
            if (fromAsLambda != null)
            {
                var lambdaVisitMode = fromAsLambda.lambda_visit_mode;
                fromAsLambda.lambda_visit_mode = LambdaVisitMode.VisitForAdvancedMethodCallProcessing;
                from = convert_strong(_assign.from);
                fromAsLambda.lambda_visit_mode = lambdaVisitMode;
            }
            else
            {
                from = convert_strong(_assign.from);
            }
            /// end

            //SSM 4.04.16
            if (to.type is undefined_type)
                to.type = from.type;

            if (stflambda.Count>0) // мы находимся внутри лямбды - возможно, вложенной
            {
                var fld = stflambda.Peek();
                if (_assign.to is ident && (_assign.to as ident).name.ToLower()=="result" && fld.RealSemTypeOfResExpr == null) // если это - первое присваивание Result
                {
                    fld.RealSemTypeOfResExpr = from.type;
                    fld.RealSemTypeOfResult = to.type;
                }
                    
            }

            location loc = get_location(_assign);
			bool oper_ass_in_prop = false;
			
            //проверка на обращение к полю записи возвращенной из функции с целью присваивания
            //нужно чтобы пользователь не мог менять временный обьект
            if (to.semantic_node_type == semantic_node_type.static_property_reference ||
                to.semantic_node_type == semantic_node_type.non_static_property_reference)
            {
                property_node pn = null;
                base_function_call prop_expr = null;
                if (to.semantic_node_type == semantic_node_type.static_property_reference)
                	pn = (to as static_property_reference).property;
                else
                	pn = (to as non_static_property_reference).property;
               
                PascalABCCompiler.SyntaxTree.Operators ot = PascalABCCompiler.SyntaxTree.Operators.Undefined;
            	switch (_assign.operator_type)
                {
                    case PascalABCCompiler.SyntaxTree.Operators.AssignmentAddition:
                		ot = PascalABCCompiler.SyntaxTree.Operators.Plus;
                		oper_ass_in_prop = true;
                		break;
                    case PascalABCCompiler.SyntaxTree.Operators.AssignmentBitwiseAND:
                		ot = PascalABCCompiler.SyntaxTree.Operators.BitwiseAND;
                		oper_ass_in_prop = true;
                		break;
                    case PascalABCCompiler.SyntaxTree.Operators.AssignmentBitwiseLeftShift:
                		ot = PascalABCCompiler.SyntaxTree.Operators.BitwiseLeftShift;
                		oper_ass_in_prop = true;
                		break;
                    case PascalABCCompiler.SyntaxTree.Operators.AssignmentBitwiseOR:
                		ot = PascalABCCompiler.SyntaxTree.Operators.BitwiseOR;
                		oper_ass_in_prop = true;
                		break;
                    case PascalABCCompiler.SyntaxTree.Operators.AssignmentBitwiseRightShift:
                		ot = PascalABCCompiler.SyntaxTree.Operators.BitwiseRightShift;
                		oper_ass_in_prop = true;
                		break;
                    case PascalABCCompiler.SyntaxTree.Operators.AssignmentBitwiseXOR:
                		ot = PascalABCCompiler.SyntaxTree.Operators.BitwiseXOR;
                		oper_ass_in_prop = true;
                		break;
                    case PascalABCCompiler.SyntaxTree.Operators.AssignmentDivision:
                		ot = PascalABCCompiler.SyntaxTree.Operators.Division;
                		oper_ass_in_prop = true;
                		break;
                    case PascalABCCompiler.SyntaxTree.Operators.AssignmentModulus:
                		ot = PascalABCCompiler.SyntaxTree.Operators.ModulusRemainder;
                		oper_ass_in_prop = true;
                		break;
                    case PascalABCCompiler.SyntaxTree.Operators.AssignmentMultiplication:
                		ot = PascalABCCompiler.SyntaxTree.Operators.Multiplication;
                		oper_ass_in_prop = true;
                		break;
                    case PascalABCCompiler.SyntaxTree.Operators.AssignmentSubtraction:
                        ot = PascalABCCompiler.SyntaxTree.Operators.Minus;
                        oper_ass_in_prop = true;
                		break;
                }
            	if (oper_ass_in_prop)
            	{
            		if (pn.get_function == null)
                	AddError(new ThisPropertyCanNotBeReaded(pn,loc));
            		if (to.semantic_node_type == semantic_node_type.non_static_property_reference)
            		{
                		prop_expr = create_not_static_method_call(pn.get_function,(to as non_static_property_reference).expression,loc,false);
                		prop_expr.parameters.AddRange((to as non_static_property_reference).fact_parametres);
            		}
            		else
            		{
            			prop_expr = create_static_method_call(pn.get_function,loc,pn.comprehensive_type,false);
            			prop_expr.parameters.AddRange((to as static_property_reference).fact_parametres);
            		}
                	from = find_operator(ot,prop_expr,from,loc);
            	}
            }
            else
            if (to is class_field_reference)
            {
                if ((to as class_field_reference).obj.type.type_special_kind == SemanticTree.type_special_kind.record &&
                    (to as class_field_reference).obj is base_function_call)
            	{
                    //исключим ситуацию обращения к массиву
                    if (!(((to as class_field_reference).obj is common_method_call) &&
                    ((to as class_field_reference).obj as common_method_call).obj.type.type_special_kind == SemanticTree.type_special_kind.array_wrapper))
                        AddError(loc, "LEFT_SIDE_CANNOT_BE_ASSIGNED_TO");
            	}
            	//else check_field_reference_for_assign(to as class_field_reference,loc);
            }
            else if (context.is_in_cycle() && !SemanticRules.AllowChangeLoopVariable && to.semantic_node_type == semantic_node_type.namespace_variable_reference)
            {
            	if (context.is_loop_variable((to as namespace_variable_reference).var))
                    AddError(to.location, "CANNOT_ASSIGN_TO_LOOP_VARIABLE");
            }
            else if (context.is_in_cycle() && !SemanticRules.AllowChangeLoopVariable && to.semantic_node_type == semantic_node_type.local_variable_reference)
            {
            	if (context.is_loop_variable((to as local_variable_reference).var))
                    AddError(to.location, "CANNOT_ASSIGN_TO_LOOP_VARIABLE");
            }
            else if (context.is_in_cycle() && !SemanticRules.AllowChangeLoopVariable && to.semantic_node_type == semantic_node_type.local_block_variable_reference)
            {
            	if (context.is_loop_variable((to as local_block_variable_reference).var))
                    AddError(to.location, "CANNOT_ASSIGN_TO_LOOP_VARIABLE");
            }
            else if (to is simple_array_indexing)
            	if ((to as simple_array_indexing).simple_arr_expr is class_field_reference && ((to as simple_array_indexing).simple_arr_expr as class_field_reference).obj != null &&
            	   ((to as simple_array_indexing).simple_arr_expr as class_field_reference).obj is constant_node)
                    AddError(loc, "LEFT_SIDE_CANNOT_BE_ASSIGNED_TO");
            if ((to.semantic_node_type == semantic_node_type.static_event_reference)
                    || (to.semantic_node_type == semantic_node_type.nonstatic_event_reference))
            {
                statement_node event_assign = null;
                if (_assign.operator_type == PascalABCCompiler.SyntaxTree.Operators.Assignment)
                {
                    //throw new CanNotAssignToEvent();
                }
                static_event_reference ser = (static_event_reference)to;
                expression_node right_del = convertion_data_and_alghoritms.convert_type(from, ser.en.delegate_type);
                switch (_assign.operator_type)
                {
                    case PascalABCCompiler.SyntaxTree.Operators.AssignmentAddition:
                        {
                            if (to.semantic_node_type == semantic_node_type.static_event_reference)
                            {
                                event_assign = convertion_data_and_alghoritms.create_simple_function_call(
                                    ser.en.add_method, loc, right_del);
                            }
                            else
                            {
                                if (ser.en.semantic_node_type == semantic_node_type.compiled_event)
                                {
                                    nonstatic_event_reference nser = (nonstatic_event_reference)ser;
                                    compiled_function_node cfn = (compiled_function_node)ser.en.add_method;
                                    compiled_function_call tmp_event_assign = new compiled_function_call(cfn, nser.obj, loc);
                                    tmp_event_assign.parameters.AddElement(right_del);
                                    event_assign = tmp_event_assign;
                                }
                                else if (ser.en.semantic_node_type == semantic_node_type.common_event)
                                {
                                    nonstatic_event_reference nser = (nonstatic_event_reference)ser;
                                    common_method_node cfn = (common_method_node)ser.en.add_method;
                                    common_method_call tmp_event_assign = new common_method_call(cfn, nser.obj, loc);
                                    tmp_event_assign.parameters.AddElement(right_del);
                                    event_assign = tmp_event_assign;
                                }
                            }
                            break;
                        }
                    case PascalABCCompiler.SyntaxTree.Operators.AssignmentSubtraction:
                        {
                            if (to.semantic_node_type == semantic_node_type.static_event_reference)
                            {
                                event_assign = convertion_data_and_alghoritms.create_simple_function_call(
                                    ser.en.remove_method, loc, right_del);
                            }
                            else
                            {
                                if (ser.en.semantic_node_type == semantic_node_type.compiled_event)
                                {
                                    nonstatic_event_reference nser = (nonstatic_event_reference)ser;
                                    compiled_function_node cfn = (compiled_function_node)ser.en.remove_method;
                                    compiled_function_call tmp_event_assign = new compiled_function_call(cfn, nser.obj, loc);
                                    tmp_event_assign.parameters.AddElement(right_del);
                                    event_assign = tmp_event_assign;
                                }
                                else if (ser.en.semantic_node_type == semantic_node_type.common_event)
                                {
                                    nonstatic_event_reference nser = (nonstatic_event_reference)ser;
                                    common_method_node cfn = (common_method_node)ser.en.remove_method;
                                    common_method_call tmp_event_assign = new common_method_call(cfn, nser.obj, loc);
                                    tmp_event_assign.parameters.AddElement(right_del);
                                    event_assign = tmp_event_assign;
                                }
                            }
                            break;
                        }
                    default:
                        {
                            AddError(loc, "ASSIGN_TO_EVENT");
                            //throw new CanNotApplyThisOperationToEvent

                            break;
                        }
                }
                return_value(event_assign);
                return;
            }

            if (_assign.operator_type == PascalABCCompiler.SyntaxTree.Operators.Assignment || oper_ass_in_prop)
            {
                if (to.semantic_node_type == semantic_node_type.static_property_reference)
                {
                    static_property_reference spr = (static_property_reference)to;
                    if (spr.property.set_function == null)
                    {
                    	AddError(new ThisPropertyCanNotBeWrited(spr.property, loc));
                    }
                    check_property_params(spr, loc);
                    function_node set_func = spr.property.set_function;
                    from = convertion_data_and_alghoritms.convert_type(from, spr.property.property_type);
                    spr.fact_parametres.AddElement(from);
                    base_function_call bfc = create_static_method_call(set_func, loc, spr.property.comprehensive_type,
                        true);
                    bfc.parameters.AddRange(spr.fact_parametres);
                    return_value((statement_node)bfc);
                    return;
                }
                else if (to.semantic_node_type == semantic_node_type.non_static_property_reference)
                {
                    non_static_property_reference nspr = (non_static_property_reference)to;
                    check_property_params(nspr, loc);
                    from = convertion_data_and_alghoritms.convert_type(from, nspr.property.property_type);
                    nspr.fact_parametres.AddElement(from);

                    //Обработка s[i]:='c'
                    if (SystemUnitAssigned)
                        if (nspr.property.comprehensive_type == SystemLibrary.SystemLibrary.string_type)
                        {
                            if (nspr.property == SystemLibrary.SystemLibrary.string_type.default_property_node)
                            {
                                if (SystemLibrary.SystemLibInitializer.StringDefaultPropertySetProcedure != null)
                                {
                                    expressions_list exl = new expressions_list();
                                    exl.AddElement(nspr.expression);
                                    exl.AddElement(nspr.fact_parametres[0]);
                                    exl.AddElement(from);
                                    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_value((statement_node)ret);
                                    return;
                                }
                            }
                        }

                    if (nspr.property.set_function == null)
                    {
                    	AddError(new ThisPropertyCanNotBeWrited(nspr.property, loc));
                    }
                    function_node set_func = nspr.property.set_function;
                    base_function_call bfc = create_not_static_method_call(set_func, nspr.expression, loc,
                        true);
                    bfc.parameters.AddRange(nspr.fact_parametres);
                    return_value((statement_node)bfc);
                    return;
                }
                else if (to is simple_array_indexing && (to as simple_array_indexing).simple_arr_expr.type.type_special_kind == SemanticTree.type_special_kind.short_string)
                {
                	expression_node expr = (to as simple_array_indexing).simple_arr_expr;
                	expression_node ind_expr = (to as simple_array_indexing).ind_expr;
                	from = convertion_data_and_alghoritms.convert_type(from,SystemLibrary.SystemLibrary.char_type);
                	ind_expr = convertion_data_and_alghoritms.create_simple_function_call(SystemLibrary.SystemLibInitializer.SetCharInShortStringProcedure.sym_info as function_node,loc,expr,ind_expr,new int_const_node((expr.type as short_string_type_node).Length,null),from);
                	return_value(find_operator(compiler_string_consts.assign_name, expr, ind_expr, get_location(_assign)));
                	return;
                }
                else if (to.type.type_special_kind == SemanticTree.type_special_kind.short_string)
                {
                    if (from.type is null_type_node)
                        AddError(get_location(_assign), "NIL_WITH_VALUE_TYPES_NOT_ALLOWED");
                    expression_node clip_expr = convertion_data_and_alghoritms.create_simple_function_call(SystemLibrary.SystemLibInitializer.ClipShortStringProcedure.sym_info as function_node, loc, convertion_data_and_alghoritms.convert_type(from, SystemLibrary.SystemLibrary.string_type), new int_const_node((to.type as short_string_type_node).Length, null));
                    statement_node en = find_operator(compiler_string_consts.assign_name, to, clip_expr, get_location(_assign));
                    return_value(en);
                    return;
                }
                else
                {

                    assign_is_converting = true;
                    statement_node en = find_operator(compiler_string_consts.assign_name, to, from, get_location(_assign));
                    assign_is_converting = false;
                    return_value(en);
                    return;
                }
            }
            else
            {
                assign_is_converting = true;
                statement_node en = find_operator(_assign.operator_type, to, from, get_location(_assign));
                assign_is_converting = false;
                return_value(en);
                return;
            }
            //throw new CompilerInternalError("Undefined assign to type");
        }
        private base_function_call_list convert_functions_to_calls(expression_node obj, function_node_list fnl, location loc, bool is_static)
        {
            base_function_call_list ret = new base_function_call_list();
            foreach (function_node fnode in fnl)
            {
                base_function_call bfc = null;
                switch (fnode.semantic_node_type)
                {
                    case semantic_node_type.common_namespace_function_node:
                        {
                            common_namespace_function_node cmfn = fnode as common_namespace_function_node;
                            common_namespace_function_call cnfc = new common_namespace_function_call(cmfn, loc);
                            if (cmfn.ConnectedToType != null)
                                cnfc.parameters.AddElement(obj);
                            if (cmfn.is_generic_function && !cmfn.is_generic_function_instance && cmfn.ConnectedToType != null && cmfn.parameters.Count == 1)
                            {
                                expressions_list parameters = new expressions_list();
                                parameters.AddElement(obj);
                                function_node inst = null;
                                try
                                {
                                    inst = generic_convertions.DeduceFunction(cmfn, parameters, true, loc);
                                }
                                catch
                                {
                                    continue;
                                }
                                cnfc = new common_namespace_function_call((common_namespace_function_node)inst, loc);
                                if (cmfn.ConnectedToType != null)
                                    cnfc.parameters.AddElement(obj);
                            }
                            /*if (cmfn.parameters.Count >= 1 && cmfn.parameters[cmfn.parameters.Count - 1].is_params)
                            {
                                convertion_data_and_alghoritms.select_function(cnfc.parameters, new SymbolInfo(cmfn), loc);
                                
                            }*/
                            bfc = cnfc;
                            break;
                        }
                    case semantic_node_type.basic_function_node:
                        {
                            //Может здесь стоит и выругаться, но я не буду пока этого делать.
                            break;
                        }
                    case semantic_node_type.common_in_function_function_node:
                        {
                            common_in_function_function_node ciffn = fnode as common_in_function_function_node;
                            int depth = convertion_data_and_alghoritms.symbol_table.GetRelativeScopeDepth(ciffn.scope,
                                context.top_function.scope);
                            common_in_function_function_call ciffc = new common_in_function_function_call(ciffn, depth, loc);
                            bfc = ciffc;
                            break;
                        }
                    case semantic_node_type.common_method_node:
                        {
                            common_method_node cmn = fnode as common_method_node;
                            //Если cmn конструктор - то плохо, но его не должно сюда попасть.
                            if (cmn.polymorphic_state != SemanticTree.polymorphic_state.ps_static)
                            {
                                if (!is_static)
                                {
                                    if (obj == null)
                                        obj = GetCurrentObjectReference(cmn.cont_type.Scope, cmn, loc);//new this_node(context.converted_type, loc);
                                    common_method_call cmc = new common_method_call(cmn, obj, loc);
                                    cmc.virtual_call = !inherited_ident_processing;
                                    bfc = cmc;
                                }
                                //ssyy!!! Мне сложно понять предназначение данного кода, но, по-видимому,
                                //следует его переписать так.
                                else if (cmn.is_constructor)
                                {
                                    if (cmn.parameters.Count == 0)
                                    {
                                    	if (cmn.cont_type.IsAbstract)
                                            AddError(loc, "ABSTRACT_CONSTRUCTOR_{0}_CALL", cmn.cont_type.name);
                                    	ret.clear();
                                        ret.AddElement(new common_constructor_call(cmn, loc));
                                        return ret;
                                    }
                                }
                            }
                            else
                            {
                                if (is_static)
                                {
                                    common_static_method_call csmc = new common_static_method_call(cmn, loc);
                                    bfc = csmc;
                                }
                            }
                            break;
                        }
                    case semantic_node_type.compiled_function_node:
                        {
                            compiled_function_node cfn = fnode as compiled_function_node;
                            if (cfn.cont_type.Scope == null && cfn is compiled_function_node)
                        	(cfn.cont_type as compiled_type_node).init_scope();
                            
                            if (cfn.polymorphic_state == SemanticTree.polymorphic_state.ps_static)
                            {
                                //ispravleno ibond
                            	//if (is_static)
                                {

                                    if (cfn.is_generic_function && !cfn.is_generic_function_instance && cfn.ConnectedToType != null && cfn.parameters.Count == 1)
                                    {
                                        expressions_list parameters = new expressions_list();
                                        parameters.AddElement(obj);
                                        function_node inst = null;
                                        try
                                        {
                                            inst = generic_convertions.DeduceFunction(cfn, parameters, true, loc);
                                        }
                                        catch
                                        {
                                            continue;
                                        }
                                        if (inst is common_namespace_function_node)
                                            bfc = new common_namespace_function_call((common_namespace_function_node)inst, loc);
                                        else if (inst is compiled_function_node)
                                            bfc = new compiled_static_method_call((compiled_function_node)inst, loc);
                                        else
                                            bfc = new compiled_static_method_call(cfn, loc);
                                    }
                                    else
                                    {
                                        compiled_static_method_call csmc = new compiled_static_method_call(cfn, loc);
                                        bfc = csmc;
                                        
                                    }
                                    if (cfn.ConnectedToType != null)
                                        bfc.parameters.AddElement(obj);
                                }
                            }
                            else
                            {
                                if (!is_static)
                                {
                                    if (obj == null)
                                        obj = GetCurrentObjectReference(cfn.cont_type.Scope, cfn, loc);//new this_node(context.converted_type, loc);
                                    compiled_function_call cfc = new compiled_function_call(cfn, obj, loc);
                                    cfc.virtual_call = !inherited_ident_processing;
                                    bfc = cfc;
                                }
                            }
                            break;
                        }
                    case semantic_node_type.compiled_constructor_node:
                        {
                            //Этот код мы вроде не должны вызывать, но если он все-же вызовется.
                            compiled_constructor_node ccn = fnode as compiled_constructor_node;
                            compiled_constructor_call ccc = new compiled_constructor_call(ccn, loc);
                            bfc = ccc;
                            break;
                        }
                    default:
                        {
                            throw new CompilerInternalError("Undefined method type.");
                        }
                }
                if (bfc != null)
                {
                    ret.AddElement(bfc);
                }
            }
            return ret;
        }
Beispiel #9
0
        /// <summary>
        /// Обрабатывает случай, когда левая часть присваивания имеет тип event.
        /// </summary>
        /// <returns>True - обработка прошла, иначе False.</returns>
        private bool ProcessAssignmentToEventIfPossible(assign _assign, addressed_expression to, expression_node from,
                                                        location loc)
        {
            if ((to.semantic_node_type == semantic_node_type.static_event_reference) ||
                (to.semantic_node_type == semantic_node_type.nonstatic_event_reference))
            {
                statement_node         event_assign = null;
                static_event_reference ser          = (static_event_reference)to;
                expression_node        right_del    = convertion_data_and_alghoritms.convert_type(from, ser.en.delegate_type);
                switch (_assign.operator_type)
                {
                case Operators.AssignmentAddition:
                {
                    if (to.semantic_node_type == semantic_node_type.static_event_reference)
                    {
                        event_assign = convertion_data_and_alghoritms.create_simple_function_call(
                            ser.en.add_method, loc, right_del);
                    }
                    else
                    {
                        if (ser.en.semantic_node_type == semantic_node_type.compiled_event)
                        {
                            nonstatic_event_reference nser             = (nonstatic_event_reference)ser;
                            compiled_function_node    cfn              = (compiled_function_node)ser.en.add_method;
                            compiled_function_call    tmp_event_assign = new compiled_function_call(cfn, nser.obj, loc);
                            tmp_event_assign.parameters.AddElement(right_del);
                            event_assign = tmp_event_assign;
                        }
                        else if (ser.en.semantic_node_type == semantic_node_type.common_event)
                        {
                            nonstatic_event_reference nser             = (nonstatic_event_reference)ser;
                            common_method_node        cfn              = (common_method_node)ser.en.add_method;
                            common_method_call        tmp_event_assign = new common_method_call(cfn, nser.obj, loc);
                            tmp_event_assign.parameters.AddElement(right_del);
                            event_assign = tmp_event_assign;
                        }
                    }
                    break;
                }

                case Operators.AssignmentSubtraction:
                {
                    if (to.semantic_node_type == semantic_node_type.static_event_reference)
                    {
                        event_assign = convertion_data_and_alghoritms.create_simple_function_call(
                            ser.en.remove_method, loc, right_del);
                    }
                    else
                    {
                        if (ser.en.semantic_node_type == semantic_node_type.compiled_event)
                        {
                            nonstatic_event_reference nser             = (nonstatic_event_reference)ser;
                            compiled_function_node    cfn              = (compiled_function_node)ser.en.remove_method;
                            compiled_function_call    tmp_event_assign = new compiled_function_call(cfn, nser.obj, loc);
                            tmp_event_assign.parameters.AddElement(right_del);
                            event_assign = tmp_event_assign;
                        }
                        else if (ser.en.semantic_node_type == semantic_node_type.common_event)
                        {
                            nonstatic_event_reference nser             = (nonstatic_event_reference)ser;
                            common_method_node        cfn              = (common_method_node)ser.en.remove_method;
                            common_method_call        tmp_event_assign = new common_method_call(cfn, nser.obj, loc);
                            tmp_event_assign.parameters.AddElement(right_del);
                            event_assign = tmp_event_assign;
                        }
                    }
                    break;
                }

                default:
                {
                    AddError(loc, "ASSIGN_TO_EVENT");
                    //throw new CanNotApplyThisOperationToEvent

                    break;
                }
                }
                return_value(event_assign);
                return(true);
            }
            return(false);
        }
Beispiel #10
0
		public void make_constructor()
		{
#if (DEBUG)
			if (converting_block()!=block_type.function_block)
			{
				throw new CompilerInternalError("Create constructor call without function");
			}
			if (_func_stack.top().node_location_kind!=SemanticTree.node_location_kind.in_class_location)
			{
				throw new CompilerInternalError("Create constructor applied to non class method");
			}
#endif
			common_function_node top_func=_func_stack.top();
			
			top_func.return_value_type=_ctn;

			common_method_node top_method=(common_method_node)top_func;

			common_method_node cmn=new common_method_node(top_func.name,_ctn,top_method.loc,_ctn,
                SemanticTree.polymorphic_state.ps_static,_fal,top_func.scope);
			cmn.is_constructor=true;
			cmn.is_overload=top_function.is_overload;

            //parameter_list pl = new parameter_list();
            foreach (common_parameter pr in top_method.parameters)
            {
                common_parameter new_par = new common_parameter(pr.name, pr.type, pr.parameter_type, cmn, pr.concrete_parameter_type,
                    pr.default_value, pr.loc);
                cmn.parameters.AddElement(new_par);
            }
            //cmn.parameters.AddRange(top_method.parameters);
			
			statements_list stl=new statements_list(top_func.loc);
			cmn.function_code=stl;
			this_node thn=new this_node(_ctn,top_func.loc);
			common_method_call csmc=new common_method_call(top_method,thn,top_func.loc);
			foreach(common_parameter cp in cmn.parameters)
			{
				common_parameter_reference cpr=new common_parameter_reference(cp,0,top_func.loc);
				csmc.parametres.AddElement(cpr);
			}
			stl.statements.AddElement(csmc);
			_ctn.methods.AddElement(cmn);

			top_method.pascal_associated_constructor=cmn;
		}
        /// <summary>
        /// Этот метод вызывается если мы встречаем простой вызов функии, например f(1).
        /// Он определяет является ли эта функция методом класса, вложенной функцией и т.д. и создает соответствующее обращение.
        /// Например, для метода класса он добавляет this, а для вложенной функции вычисляет статическую глубину.
        /// </summary>
        /// <param name="exprs">Список параметров.</param>
        /// <param name="si">Список методов.</param>
        /// <param name="loc">Расположение вызова.</param>
        /// <param name="converted_type">Тип в котором мы находимся. null, если мы вне типа.</param>
        /// <param name="top_function">Функция в которой мы находимся.</param>
        /// <param name="allow_procedure">Может ли это быть вызов процедуры. false если вызов стоит в выражении или правой части опреатора присваивания.</param>
        /// <returns>Возвращает узел вызова метода.</returns>
		public expression_node create_full_function_call(expressions_list exprs,SymbolInfo si,location loc,
			common_type_node converted_type,common_function_node top_function,bool allow_procedure)
		{
			function_node fn=select_function(exprs,si,loc);

            /*
            if (fn.compile_time_executor != null)
            {
                expression_node ex = fn.compile_time_executor(loc, exprs.ToArray());
                if (ex != null)
                {
                    return ex;
                }
            }
            */
            //allow_procedure = true;
			if ((!allow_procedure)&&(fn.return_value_type==null))
			{
                throw new SimpleSemanticError(loc, "FUNCTION_EXPECTED_PROCEDURE_{0}_MEET", fn.name);
			}

			expression_node expr_node=null;
			switch (fn.semantic_node_type)
			{
				case semantic_node_type.basic_function_node:
				case semantic_node_type.common_namespace_function_node:
				{
					expr_node=create_simple_function_call(fn,loc,exprs.ToArray());
					break;
				}
				case semantic_node_type.common_method_node:
				case semantic_node_type.compiled_function_node:
				{
					SemanticTree.IClassMemberNode icmn=(SemanticTree.IClassMemberNode)fn;
					if (icmn.polymorphic_state==SemanticTree.polymorphic_state.ps_static)
					{
						expr_node=create_simple_function_call(fn,loc,exprs.ToArray());
						break;
					}
                    //expression_node tn = new this_node(converted_type,loc);
					base_function_call cmc=null;
					switch (fn.semantic_node_type)
					{
						case semantic_node_type.common_method_node:
						{
                            //ssyy добавил
                            if (((common_method_node)fn).is_constructor)
                            {
                                common_constructor_call ccc = new common_constructor_call((common_method_node)fn, loc);
                                //(ssyy) По-видимому, здесь всегда можно присваивать false, так как при создании нового объекта мы сюда не заходим...
                                ccc._new_obj_awaited = false;
                                if (!syntax_tree_visitor.context.allow_inherited_ctor_call)
                                {
                                    throw new SimpleSemanticError(loc, "INHERITED_CONSTRUCTOR_CALL_MUST_BE_FIRST");
                                }
                                cmc = ccc;
                            }
                            else
                            //\ssyy
                            {
                                cmc = new common_method_call((common_method_node)fn, syntax_tree_visitor.GetCurrentObjectReference(((common_method_node)fn).cont_type.Scope, fn, loc), loc);
                                (cmc as common_method_call).virtual_call = !syntax_tree_visitor.inherited_ident_processing;
                            }
							break;
						}
						case semantic_node_type.compiled_function_node:
						{
                            cmc = new compiled_function_call((compiled_function_node)fn, syntax_tree_visitor.GetCurrentObjectReference(((compiled_function_node)fn).cont_type.Scope, fn, loc), loc);
                            (cmc as compiled_function_call).virtual_call = !syntax_tree_visitor.inherited_ident_processing;
							break;
						}
					}
					cmc.parameters.AddRange(exprs);
					expr_node=cmc;
					break;
				}
				case semantic_node_type.common_in_function_function_node:
				{
					common_in_function_function_node cffn=(common_in_function_function_node)fn;
					common_in_function_function_call cffc=new common_in_function_function_call(cffn,
						symtab.GetRelativeScopeDepth(cffn.function.scope,top_function.scope),loc);
					cffc.parameters.AddRange(exprs);
					expr_node=cffc;
					break;
				}
                //ssyy добавил
                case semantic_node_type.compiled_constructor_node:
                {
                    compiled_constructor_node ccn = fn as compiled_constructor_node;
                    if (ccn == null)
                    {
                        throw new CompilerInternalError("compiled_constructor_node expected");
                    }
                    compiled_constructor_call ccc = new compiled_constructor_call(ccn, loc);
                    ccc.parameters.AddRange(exprs);
                    ccc._new_obj_awaited = false;
                    if (!syntax_tree_visitor.context.allow_inherited_ctor_call)
                    {
                        throw new SimpleSemanticError(loc, "INHERITED_CONSTRUCTOR_CALL_MUST_BE_FIRST");
                    }
                    expr_node = ccc;
                    break;
                }
                case semantic_node_type.indefinite_definition_node:
                {
                    indefinite_function_call ifc = new indefinite_function_call(fn, loc);
                    ifc.parameters.AddRange(exprs);
                    expr_node = ifc;
                    break;
                }
                //\ssyy
				default:
				{
                    throw new NotSupportedError(loc);
				}
			}
			return expr_node;
		}
		private common_method_call create_common_method_call(common_method_node cmn,location loc,expression_node obj,
			params expression_node[] exprs)
		{
#if (DEBUG)
			if (cmn.polymorphic_state==SemanticTree.polymorphic_state.ps_static)
			{
				throw new CompilerInternalError("Static method can not be called with type");
			}
#endif
			common_method_call cmc=new common_method_call(cmn,obj,loc);
            cmc.virtual_call = !syntax_tree_visitor.inherited_ident_processing;
			cmc.parameters.AddRange(exprs);
			return cmc;
		}
 private expression_node CreateMethodCall()
 {
     expression_node obj = CreateExpression();
     common_method_node meth = GetMethodByOffset();
     common_method_call cmc = new common_method_call(meth, obj, null);
     //ssyy
     cmc.last_result_function_call = br.ReadByte() == 1;
     //\ssyy
     cmc.virtual_call = br.ReadBoolean();
     int num = br.ReadInt32();
     for (int i = 0; i < num; i++)
         cmc.parameters.AddElement(CreateExpression());
     return cmc;
 }
            public expression_node convert_delegates_to_delegates(location call_location, expression_node[] parameters)
            {
                if (parameters.Length != 1)
                {
                    throw new PascalABCCompiler.TreeConverter.CompilerInternalError("Invalid delegates convertion");
                }
                delegate_internal_interface dii_to=
                    (delegate_internal_interface)_to.get_internal_interface(internal_interface_kind.delegate_interface);
                delegate_internal_interface dii =
                    (delegate_internal_interface)parameters[0].type.get_internal_interface(internal_interface_kind.delegate_interface);

                expression_node pr = parameters[0];

                base_function_call ifnotnull = null;
                if (_to.semantic_node_type == semantic_node_type.compiled_type_node)
                {
                    ifnotnull = new compiled_constructor_call((compiled_constructor_node)dii_to.constructor, call_location);
                }
                else
                {
                    ifnotnull = new common_constructor_call((common_method_node)dii_to.constructor, call_location);
                }
                //ccc = new common_constructor_call(dii_to.constructor, call_location);

                expression_node par = null;
                if (parameters[0].type.semantic_node_type == semantic_node_type.compiled_type_node)
                {
                    par = new compiled_function_call((compiled_function_node)dii.invoke_method, parameters[0], call_location);
                }
                else
                {
                    par = new common_method_call((common_method_node)dii.invoke_method, parameters[0], call_location);
                }
                ifnotnull.parameters.AddElement(par);

                null_const_node ncn = new null_const_node(_to, call_location);
                null_const_node ncn2 = new null_const_node(_to, call_location);

                PascalABCCompiler.TreeConverter.SymbolInfo si = pr.type.find_in_type(PascalABCCompiler.TreeConverter.compiler_string_consts.eq_name);

                basic_function_node fn = si.sym_info as basic_function_node;
                expression_node condition = null;
                if (fn != null)
                {
                    basic_function_call condition_bfc = new basic_function_call(fn, call_location);
                    condition_bfc.parameters.AddElement(pr);
                    condition_bfc.parameters.AddElement(ncn);
                    condition = condition_bfc;
                }
                else if (si.sym_info is compiled_function_node)
                {
                    compiled_static_method_call condition_cfc = new compiled_static_method_call(si.sym_info as compiled_function_node, call_location);
                    condition_cfc.parameters.AddElement(pr);
                    condition_cfc.parameters.AddElement(ncn);
                    condition = condition_cfc;
                }

                question_colon_expression qce = new question_colon_expression(condition, ncn2, ifnotnull, call_location);

                return qce;
            }
 public static expression_node convert_delegate_to_return_value_type(location call_location, params expression_node[] parameters)
 {
     expression_node par=parameters[0];
     internal_interface ii = par.type.get_internal_interface(internal_interface_kind.delegate_interface);
     delegate_internal_interface dii = (delegate_internal_interface)ii;
     common_method_node cmn = dii.invoke_method as common_method_node;
     if (cmn != null)
     {
         expression_node exp = new common_method_call(cmn, par, call_location);
         return exp;
     }
     compiled_function_node cfn = dii.invoke_method as compiled_function_node;
     if (cfn != null)
     {
         expression_node exp = new compiled_function_call(cfn, par, call_location);
         return exp;
     }
     return null;
 }
        private void add_overloads_for_default_parameter()
        {
            List<parameter> default_params = new List<parameter>();
            foreach (parameter p in top_function.parameters)
            {
                if (p.default_value != null)
                {
                    default_params.Add(p);
                }
            }
            int num_of_defaults = default_params.Count-1;
            if (default_params.Count > 0 && converted_func_stack.size == 1)
                while (num_of_defaults >= 0)
                {

                    if (converted_type == null)
                    {
                        common_namespace_function_node cnfn = new common_namespace_function_node(top_function.name, top_function.return_value_type, null, converted_namespace, null);
                        foreach (parameter p in top_function.parameters)
                        {
                            if (p.default_value == null)
                                cnfn.parameters.AddElement(p);
                        }
                        for (int i = 0; i < num_of_defaults; i++)
                            cnfn.parameters.AddElement(default_params[i]);
                        statements_list sl = new statements_list(null);
                        common_namespace_function_call cnfc = new common_namespace_function_call(top_function as common_namespace_function_node, null);
                        foreach (common_parameter p in cnfn.parameters)
                        {
                            cnfc.parameters.AddElement(new common_parameter_reference(p, 0, null));
                        }
                        for (int i = num_of_defaults; i < default_params.Count; i++)
                            cnfc.parameters.AddElement(default_params[i].default_value);
                        if (cnfn.return_value_type != null)
                            sl.statements.AddElement(new return_node(cnfc, null));
                        else
                            sl.statements.AddElement(cnfc);
                        cnfn.function_code = sl;
                        converted_namespace.functions.AddElement(cnfn);
                    }
                    else
                    {
                        common_method_node cmn = top_function as common_method_node;
                        common_method_node cnfn = new common_method_node(top_function.name, top_function.return_value_type, null, converted_type, top_function.polymorphic_state, top_function.field_access_level, null);
                        foreach (parameter p in top_function.parameters)
                        {
                            if (p.default_value == null)
                                cnfn.parameters.AddElement(p);
                        }
                        for (int i = 0; i < num_of_defaults; i++)
                            cnfn.parameters.AddElement(default_params[i]);
                        statements_list sl = new statements_list(null);
                        common_method_call cnfc = new common_method_call(cmn, (cnfn.polymorphic_state != SemanticTree.polymorphic_state.ps_static) ? new this_node(converted_type, null) : null, null);
                        foreach (common_parameter p in cnfn.parameters)
                        {
                            cnfc.parameters.AddElement(new common_parameter_reference(p, 0, null));
                        }
                        for (int i = num_of_defaults; i < default_params.Count; i++)
                            cnfc.parameters.AddElement(default_params[i].default_value);
                        if (cnfn.return_value_type != null)
                            sl.statements.AddElement(new return_node(cnfc, null));
                        else
                            sl.statements.AddElement(cnfc);
                        cnfn.function_code = sl;
                        cnfn.is_constructor = cmn.is_constructor;
                        converted_type.methods.AddElement(cnfn);
                    }
                    num_of_defaults--;
                }
        }