Exemplo n.º 1
0
 private void VisitCommonInFuncFuncCall(common_in_function_function_call en)
 {
     for (int i = 0; i < en.parameters.Count; i++)
     {
         VisitExpression(en.parameters[i]);
     }
 }
Exemplo n.º 2
0
 private void VisitCommonInFuncFuncCall(common_in_function_function_call en)
 {
     for (int i = 0; i < en.parameters.Count; i++)
         VisitExpression(en.parameters[i]);
 }
		private void VisitCommonInFuncFuncCall(common_in_function_function_call expr)
		{
			bw.Write(GetMemberOffset(expr.function_node));
			bw.Write(expr.parameters.Count);
			foreach (expression_node e in expr.parameters)
				VisitExpression(e);
		}
        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;
        }
        /// <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_in_function_function_call create_common_in_function_function_call(common_in_function_function_node cfn,
			int static_depth,location loc,params expression_node[] exprs)
		{

			common_in_function_function_call cc=new common_in_function_function_call(cfn,static_depth,loc);
			cc.parameters.AddRange(exprs);
			return cc;
		}
		private expression_node CreateCommonInFuncFuncCall()
		{
			common_in_function_function_node cff = GetNestedFunctionByOffset(br.ReadInt32());
			int num_param = br.ReadInt32();
			common_in_function_function_call cffc = new common_in_function_function_call(cff,0,null);
			for (int i=0; i<num_param; i++)
				cffc.parameters.AddElement(CreateExpression());
			return cffc;
		}