private void VisitCompiledConstructorCall(compiled_constructor_call expr)
		{
			WriteCompiledConstructor(expr.function_node);
            //ssyy добавил
            if (expr._new_obj_awaited)
            {
                bw.Write((byte)1);
            }
            else
            {
                bw.Write((byte)0);
            }
            //\ssyy
            bw.Write(expr.parameters.Count);
			foreach (expression_node e in expr.parameters)
				VisitExpression(e);
		}
Esempio n. 2
0
 private void VisitCompiledConstructorCall(compiled_constructor_call en)
 {
     for (int i = 0; i < en.parameters.Count; i++)
         VisitExpression(en.parameters[i]);
 }
 private void ConvertPointersForWriteFromDll(expressions_list exprs)
 {
     for (int i = 0; i < exprs.Count; ++i)
     {
         if (exprs[i].type.IsPointer)
         {
             if (SystemLibrary.SystemLibInitializer.PointerOutputConstructor == null)
             {
                 SymbolInfo si = (SystemLibrary.SystemLibInitializer.PointerOutputType.sym_info as compiled_type_node).find_in_type(compiler_string_consts.default_constructor_name);
                 compiled_constructor_node cnode = null;
                 do
                 {
                     cnode = si.sym_info as compiled_constructor_node;
                     if (cnode.parameters.Count != 1)
                     {
                         cnode = null;
                         si = si.Next;
                     }
                 }
                 while (cnode == null);
                 SystemLibrary.SystemLibInitializer.PointerOutputConstructor = cnode;
             }
             compiled_constructor_call cnc = new compiled_constructor_call(SystemLibrary.SystemLibInitializer.PointerOutputConstructor as compiled_constructor_node, exprs[i].location);
             //common_namespace_function_call cnfc = new common_namespace_function_call(
             //    SystemLibrary.SystemLibInitializer.PointerToStringFunction.sym_info as common_namespace_function_node,
             //    exprs[i].location);
             cnc.parameters.AddElement(exprs[i]);
             exprs[i] = cnc;
         }
     }
 }
 private base_function_call create_static_method_call(function_node fn, location loc, type_node tn, bool procedure_allowed)
 {
     if ((!procedure_allowed) && (fn.return_value_type == null))
     {
         AddError(loc, "FUNCTION_EXPECTED_PROCEDURE_{0}_MEET", fn.name);
     }
     if (fn.semantic_node_type == semantic_node_type.common_method_node)
     {
         common_method_node cmn = (common_method_node)fn;
         if (cmn.polymorphic_state != SemanticTree.polymorphic_state.ps_static)
         {
             //ssyy изменил
             if (!cmn.is_constructor)
             {
                 AddError(new CanNotCallNonStaticMethodWithClass(tn, loc, fn));
             }
             if (cmn.cont_type.IsAbstract)
             	ErrorsList.Add(new SimpleSemanticError(loc, "ABSTRACT_CONSTRUCTOR_{0}_CALL", cmn.name));
             common_constructor_call csmc2 = new common_constructor_call(cmn, loc);
             return csmc2;
             //if (cmn.pascal_associated_constructor==null)
             //{
             //	throw new CanNotCallNonStaticMethodWithClass(tn,loc,fn);
             //}
             //common_constructor_call csmc2=new common_constructor_call(cmn.pascal_associated_constructor,loc);
             //return csmc2;
             //\ssyy
         }
         common_static_method_call csmc = new common_static_method_call(cmn, loc);
         return csmc;
     }
     if (fn.semantic_node_type == semantic_node_type.compiled_function_node)
     {
         compiled_function_node cfn = (compiled_function_node)fn;
         if (cfn.polymorphic_state != SemanticTree.polymorphic_state.ps_static)
         {
             AddError(new CanNotCallNonStaticMethodWithClass(tn, loc, fn));
         }
         compiled_static_method_call csmc2 = new compiled_static_method_call(cfn, loc);
         return csmc2;
     }
     if (fn.semantic_node_type == semantic_node_type.compiled_constructor_node)
     {
         compiled_constructor_node ccn = (compiled_constructor_node)fn;
         compiled_constructor_call ccc = new compiled_constructor_call(ccn, loc);
         return ccc;
     }
     if (fn.semantic_node_type == semantic_node_type.basic_function_node)
     {
         return new basic_function_call(fn as basic_function_node, loc);
     }
     if (fn.semantic_node_type == semantic_node_type.common_namespace_function_node && (fn as common_namespace_function_node).ConnectedToType != null)
     {
     	return new common_namespace_function_call(fn as common_namespace_function_node,loc);
     }
     if (fn.semantic_node_type == semantic_node_type.indefinite_definition_node)
     {
         return new indefinite_function_call(fn, loc);
     }
     throw new CompilerInternalError("Invalid method kind");
 }
        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;
        }
        //ssyy
        public void generate_inherit_constructors()
        {
            common_type_node _ctn = context.converted_type;
            if (_ctn == null)
            {
                throw new CompilerInternalError("Can generate inherited constructors only in class.");
            }
            if (_ctn.has_user_defined_constructor)
            {
                //Пользователь определил хотя бы один конструктор, никакие конструкторы не наследуем.
                return;
            }
            //Получили список процедур предка, имеющих имя Create
            SymbolInfo si = _ctn.base_type.find_in_type(compiler_string_consts.default_constructor_name, _ctn.base_type.Scope);
            delete_inherited_constructors(ref si, _ctn.base_type);
            while (si != null)
            {
                function_node fn = si.sym_info as function_node;
                compiled_constructor_node pconstr = fn as compiled_constructor_node;
                common_method_node mconstr = fn as common_method_node;
                //Если это конструктор...
                if (pconstr != null ||
                    mconstr != null && mconstr.is_constructor)
                {
                    //Генерируем унаследованный конструктор
                    location loc = null;
                    SemanticTree.polymorphic_state ps;
                    if (mconstr != null)
                    {
                        loc = mconstr.loc;
                        ps = mconstr.polymorphic_state;
                    }
                    else //значит (pconstr != null)
                    {
                        ps = pconstr.polymorphic_state;
                    }
                    if (pconstr != null)
                        context.set_field_access_level(pconstr.field_access_level);
                    else
                        context.set_field_access_level(mconstr.field_access_level);
                    common_method_node gen_constr = context.create_function(compiler_string_consts.default_constructor_name, loc) as common_method_node;
                    gen_constr.polymorphic_state = ps;
                    gen_constr.is_overload = true;
                    gen_constr.is_constructor = true;
                    gen_constr.field_access_level = fn.field_access_level;
                    gen_constr.return_value_type = _ctn;

                    foreach (parameter par in fn.parameters)
                    {
                        //(ssyy) Интересно, зачем это.
                        concrete_parameter_type cpt =
                            (par.parameter_type == SemanticTree.parameter_type.var) ?
                            concrete_parameter_type.cpt_var :
                            concrete_parameter_type.cpt_none;
                        common_parameter c_p = new common_parameter(par.name,
                            par.parameter_type, gen_constr, cpt, null);
                        c_p.type = par.type;
                        c_p.set_param_is_params(par.is_params);
                        c_p.inital_value = par.inital_value;
                        gen_constr.parameters.AddElement(c_p);
                        c_p.default_value = par.default_value;
                    }

                    base_function_call bfc;

                    if (mconstr != null)
                    {
                        common_constructor_call c1 = new common_constructor_call(mconstr, null);
                        c1._new_obj_awaited = false;
                        bfc = c1;
                    }
                    else
                    {
                        compiled_constructor_call c2 = new compiled_constructor_call(pconstr, null);
                        c2._new_obj_awaited = false;
                        bfc = c2;
                    }
                    foreach (parameter p in gen_constr.parameters)
                    {
                        bfc.parameters.AddElement(
                            create_variable_reference(p, null));
                    }
                    statements_list snlist = new statements_list(null);
                    snlist.statements.AddElement(bfc);
                    snlist.statements.AddElement(new empty_statement(null));
                    gen_constr.function_code = snlist;
                    context.leave_block();
                    if (fn.parameters.Count == 0 || fn.parameters[0].default_value != null)
                    {
                        _ctn.has_default_constructor = true;
                    }
                }
                si = si.Next;
            }
        }
        /// <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;
		}
Esempio n. 8
0
        public override function_node get_implicit_conversion_to(type_node ctn)
        {
            foreach (base_function_call fn in _proper_methods)
            {
                if (fn.simple_function_node.parameters.Count == 0
                    || (fn.simple_function_node is common_namespace_function_node && (fn.simple_function_node as common_namespace_function_node).ConnectedToType != null 
                            || fn.simple_function_node is compiled_function_node && (fn.simple_function_node as compiled_function_node).ConnectedToType != null)
                    && fn.simple_function_node.parameters.Count == 1 && !fn.simple_function_node.parameters[0].is_params)
                {
                    if (fn.simple_function_node.return_value_type == ctn)
                    {
                        convert_function_to_function_call cftfc = new convert_function_to_function_call(fn);
                        return (new convert_types_function_node(cftfc.compile_time_executor, true));
                    }
                    if (fn.simple_function_node.return_value_type == null)
                    {
                        continue;
                    }
                    //TODO: Очень внимательно рассмотреть. Если преобразование типов должно идти через compile_time_executor.
                    possible_type_convertions ptc=type_table.get_convertions(fn.simple_function_node.return_value_type, ctn);
                    if ((ptc.first == null) || (ptc.first.convertion_method == null))
                    {
                        continue;
                    }
                    expression_node ennew=type_table.type_table_function_call_maker(ptc.first.convertion_method, null, fn);
                    convert_function_to_function_call cftfc2 = new convert_function_to_function_call(ennew);
                    return (new convert_types_function_node(cftfc2.compile_time_executor, false));
                }
                else if (fn.simple_function_node.parameters.Count == 1 && fn.simple_function_node.parameters[0].is_params ||
                    (fn.simple_function_node is common_namespace_function_node && (fn.simple_function_node as common_namespace_function_node).ConnectedToType != null || fn.simple_function_node is compiled_function_node && (fn.simple_function_node as compiled_function_node).ConnectedToType != null) 
                    && fn.simple_function_node.parameters.Count == 2 && fn.simple_function_node.parameters[1].is_params)
                {
                    base_function_call copy_fn = get_function_call_copy(fn);
                    int param_num = (fn.simple_function_node is common_namespace_function_node && (fn.simple_function_node as common_namespace_function_node).ConnectedToType != null || fn.simple_function_node is compiled_function_node && (fn.simple_function_node as compiled_function_node).ConnectedToType != null) ? 1 : 0;
                	if (fn.simple_function_node.return_value_type == ctn)
                    {
                		common_namespace_function_call cnfc = new common_namespace_function_call(SystemLibrary.SystemLibInitializer.NewArrayProcedureDecl,null);
                        cnfc.parameters.AddElement(new typeof_operator(fn.simple_function_node.parameters[param_num].type, null));
                		cnfc.parameters.AddElement(new int_const_node(0,null));
                        if (copy_fn.parameters.Count < fn.simple_function_node.parameters.Count)
                            copy_fn.parameters.AddElement(cnfc);
                		convert_function_to_function_call cftfc = new convert_function_to_function_call(copy_fn);
                        return (new convert_types_function_node(cftfc.compile_time_executor, true));
                        
                    }
                    if (fn.simple_function_node.return_value_type == null)
                    {
                        continue;
                    }
                    //TODO: Очень внимательно рассмотреть. Если преобразование типов должно идти через compile_time_executor.
                    possible_type_convertions ptc=type_table.get_convertions(fn.simple_function_node.return_value_type, ctn);
                    if ((ptc.first == null) || (ptc.first.convertion_method == null))
                    {
                        continue;
                    }
                    common_namespace_function_call cnfc2 = new common_namespace_function_call(SystemLibrary.SystemLibInitializer.NewArrayProcedureDecl,null);
                    cnfc2.parameters.AddElement(new typeof_operator(fn.simple_function_node.parameters[param_num].type, null));
                	cnfc2.parameters.AddElement(new int_const_node(0,null));
                    if (copy_fn.parameters.Count < fn.simple_function_node.parameters.Count)
                        copy_fn.parameters.AddElement(cnfc2);
                    expression_node ennew=type_table.type_table_function_call_maker(ptc.first.convertion_method, null, copy_fn);
                    convert_function_to_function_call cftfc2 = new convert_function_to_function_call(ennew);
                    return (new convert_types_function_node(cftfc2.compile_time_executor, false));
                }
                else if (fn.simple_function_node.parameters.Count == 1 && fn.simple_function_node.parameters[0].default_value != null ||
                    (fn.simple_function_node is common_namespace_function_node && (fn.simple_function_node as common_namespace_function_node).ConnectedToType != null || fn.simple_function_node is compiled_function_node && (fn.simple_function_node as compiled_function_node).ConnectedToType != null)
                    && fn.simple_function_node.parameters.Count == 2 && fn.simple_function_node.parameters[1].default_value != null)
                {
                    int param_num = (fn.simple_function_node is common_namespace_function_node && (fn.simple_function_node as common_namespace_function_node).ConnectedToType != null || fn.simple_function_node is compiled_function_node && (fn.simple_function_node as compiled_function_node).ConnectedToType != null) ? 1 : 0;
                    base_function_call copy_fn = null;
                    if (fn.simple_function_node.return_value_type == ctn)
                    {
                        copy_fn = get_function_call_copy(fn);
                        copy_fn.parameters.AddElement(fn.simple_function_node.parameters[param_num].default_value);
                        convert_function_to_function_call cftfc = new convert_function_to_function_call(copy_fn);
                        return (new convert_types_function_node(cftfc.compile_time_executor, true));

                    }
                    if (fn.simple_function_node.return_value_type == null)
                    {
                        continue;
                    }
                    //TODO: Очень внимательно рассмотреть. Если преобразование типов должно идти через compile_time_executor.
                    possible_type_convertions ptc = type_table.get_convertions(fn.simple_function_node.return_value_type, ctn);
                    if ((ptc.first == null) || (ptc.first.convertion_method == null))
                    {
                        continue;
                    }
                    copy_fn = get_function_call_copy(fn);
                    copy_fn.parameters.AddElement(fn.simple_function_node.parameters[param_num].default_value);
                    expression_node ennew = type_table.type_table_function_call_maker(ptc.first.convertion_method, null, copy_fn);
                    convert_function_to_function_call cftfc2 = new convert_function_to_function_call(ennew);
                    return (new convert_types_function_node(cftfc2.compile_time_executor, false));
                }
                else if (fn.simple_function_node.parameters.Count == fn.simple_function_node.num_of_default_parameters)
                {
                    base_function_call copy_fn = get_function_call_copy(fn);
                    if (fn.simple_function_node.return_value_type == ctn)
                    {
                        foreach (parameter p in fn.simple_function_node.parameters)
                            copy_fn.parameters.AddElement(p.default_value);
                        convert_function_to_function_call cftfc = new convert_function_to_function_call(copy_fn);
                        return (new convert_types_function_node(cftfc.compile_time_executor, true));
                    }
                    if (fn.simple_function_node.return_value_type == null)
                    {
                        continue;
                    }
                    //TODO: Очень внимательно рассмотреть. Если преобразование типов должно идти через compile_time_executor.
                    possible_type_convertions ptc = type_table.get_convertions(fn.simple_function_node.return_value_type, ctn);
                    if ((ptc.first == null) || (ptc.first.convertion_method == null))
                    {
                        continue;
                    }
                    foreach (parameter p in fn.simple_function_node.parameters)
                        copy_fn.parameters.AddElement(p.default_value);
                    expression_node ennew = type_table.type_table_function_call_maker(ptc.first.convertion_method, null, copy_fn);
                    convert_function_to_function_call cftfc2 = new convert_function_to_function_call(ennew);
                    return (new convert_types_function_node(cftfc2.compile_time_executor, false));
                }
            }

            internal_interface ii = ctn.get_internal_interface(internal_interface_kind.delegate_interface);
            if (ii == null)
            {
            	if (ctn is compiled_type_node && (ctn as compiled_type_node).IsDelegate)
            	{
            		common_type_node del =
            			type_constructor.instance.create_delegate(compilation_context.instance.get_delegate_type_name(), this.proper_methods[0].simple_function_node.return_value_type, this.proper_methods[0].simple_function_node.parameters, compilation_context.instance.converted_namespace, null);
            		compilation_context.instance.converted_namespace.types.AddElement(del);
            		ii = del.get_internal_interface(internal_interface_kind.delegate_interface);
            	}
            	else
            	return null;
            }

            delegate_internal_interface dii = (delegate_internal_interface)ii;
			
            base_function_call _finded_call = null;

            foreach(base_function_call bfn in _proper_methods)
            {
                if (bfn.simple_function_node.parameters.Count != dii.parameters.Count)
                {
                    continue;
                }
                if (bfn.simple_function_node.return_value_type != dii.return_value_type)
                {
                    if (!type_table.is_derived(dii.return_value_type, bfn.simple_function_node.return_value_type)) // SSM 21/05/15
                        if (!(bfn.ret_type is lambda_any_type_node)) //lroman//
                            continue;
                }
                bool find_eq = true;
                int i=0;
                while ((find_eq == true) && (i<bfn.simple_function_node.parameters.Count))
                {
                    /*var a1 = bfn.simple_function_node.parameters[i].type != dii.parameters[i].type;
                    var a2 = bfn.simple_function_node.parameters[i].parameter_type != dii.parameters[i].parameter_type;
                    var a3 = bfn.simple_function_node.parameters[i].is_params != dii.parameters[i].is_params;*/
                    //lroman// Добавил все, что связано с lambda_any_type_node. Считаем, что этот тип равен всем типам. Это используется при выводе параметров лямбды
                    if ((bfn.simple_function_node.parameters[i].type != dii.parameters[i].type && !(bfn.simple_function_node.parameters[i].type is lambda_any_type_node)) ||
                        (bfn.simple_function_node.parameters[i].parameter_type != dii.parameters[i].parameter_type && !(bfn.simple_function_node.parameters[i].parameter_type is lambda_any_type_node)) 
                	    || bfn.simple_function_node.parameters[i].is_params != dii.parameters[i].is_params)
                    {
                        find_eq = false;
                    }
                    i++;
                }
                if (find_eq)
                {
                    _finded_call = bfn;
                    break;
                }
            }

            //Вообщето если мы можем найти более одного вызова функции в цикле выше, то это внутренняя ошибка компилятора, но мы не будем ругаться.
            if (_finded_call == null)
            {
                return null;
            }

            if ((_finded_call is common_constructor_call) || (_finded_call is compiled_constructor_call))
            {
                return null;
            }

            common_method_node cmn = dii.constructor as common_method_node;
            if (cmn != null)
            {
                common_constructor_call ccc = new common_constructor_call(cmn, null);
                ccc.parameters.AddElement(_finded_call);
                convert_function_to_function_call cftfc = new convert_function_to_function_call(ccc);
                return (new convert_types_function_node(cftfc.compile_time_executor, false));
            }

            compiled_constructor_node ccn = dii.constructor as compiled_constructor_node;
            if (ccn != null)
            {
                compiled_constructor_call ccc = new compiled_constructor_call(ccn, null);
                ccc.parameters.AddElement(_finded_call);
                convert_function_to_function_call cftfc = new convert_function_to_function_call(ccc);
                return (new convert_types_function_node(cftfc.compile_time_executor, false));
            }

            //Тут вообщето тоже внутренняя ошибка компилятора. (Не откомпилированный и не обычный конструктор).

            return null;
        }
		//Метод только для внутнреннего использования.
		//НЕ ПРЕОБРАЗУЕТ ТИПЫ. Только создает узел вызова метода.
		//Этот метод и используется для создания узлов преобразования типов.
        //TODO: Переименовать.
        public expression_node create_simple_function_call(function_node fn, location loc, params expression_node[] exprs)
        {

            if (fn.compile_time_executor != null)
            {
                expression_node ex = fn.compile_time_executor(loc, exprs);
                if (ex != null)
                {
                    return ex;
                }
            }

            switch (fn.semantic_node_type)
            {
                /*
                case semantic_node_type.empty_function_node:
				{
#if (DEBUG)
					if (exprs.Length!=1)
					{
						throw new CompilerInternalError("Epty functions with only single parameter allowed.");
					}
#endif
					return exprs[0];
				}
                */
                case semantic_node_type.basic_function_node:
                    {
                        return create_basic_function_call((basic_function_node)fn, loc, exprs);
                    }
                case semantic_node_type.common_namespace_function_node:
                    {
                        return create_common_namespace_function_call((common_namespace_function_node)fn, loc, exprs);
                    }
                case semantic_node_type.common_method_node:
                    {
                        common_method_node cmn = (common_method_node)fn;
                        if (cmn.polymorphic_state != SemanticTree.polymorphic_state.ps_static)
                        {
                            break;
                        }
                        return create_common_static_method_call(cmn, loc, exprs);
                    }
                /*
				case semantic_node_type.pseudo_function:
				{
					pseudo_function pf=(pseudo_function)fn;
					return pf.execute_pseudo_function_algorithm(loc,exprs);
				}
                */
                case semantic_node_type.common_in_function_function_node: break;
                case semantic_node_type.compiled_function_node:
                    {
                        compiled_function_node cfn = (compiled_function_node)fn;
                        if (cfn.polymorphic_state != SemanticTree.polymorphic_state.ps_static)
                        {
                            break;
                        }
                        return create_compiled_static_method_call(cfn, loc, exprs);
                    }
                case semantic_node_type.compiled_constructor_node:
                    {
                        compiled_constructor_call ccc = new compiled_constructor_call((compiled_constructor_node)fn,loc);
                        ccc.parameters.AddRange(exprs);
                        return ccc;

                    }
                case semantic_node_type.indefinite_definition_node:
                    {
                        indefinite_function_call ifc = new indefinite_function_call(fn, loc);
                        ifc.parameters.AddRange(exprs);
                        return ifc;
                    }
                default: throw new CompilerInternalError("Unknown function type");
            }
            throw new CanNotReferenceToNonStaticMethodWithType(fn.name, loc);
        }
 public expression_node create_compiled_construcor_call(compiled_constructor_node fn, location loc, params expression_node[] exprs)
 {
     compiled_constructor_call ccc = new compiled_constructor_call(fn, loc);
     ccc.parameters.AddRange(exprs);
     return ccc;
 }
		private compiled_constructor_call CreateCompiledConstructorCall()
		{
			compiled_constructor_node ccn = GetCompiledConstructor(br.ReadInt32());
			compiled_constructor_call ccc = new compiled_constructor_call(ccn,null);
            //ssyy добавил
            ccc._new_obj_awaited = (br.ReadByte() == 1);
            //\ssyy
            int num_params = br.ReadInt32();
			for (int i=0; i<num_params; i++)
				ccc.parameters.AddElement(CreateExpression());
			return ccc;
		}
            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;
            }
Esempio n. 13
0
 private expression_node ConvertArrayInitializer(type_node tn, array_initializer constant)
 {
 	type_node element_type = null;
     if (IsBoundedArray(tn))
     {
         bounded_array_interface bai = tn.get_internal_interface(internal_interface_kind.bounded_array_interface) as bounded_array_interface;
         element_type = bai.element_type;
         ordinal_type_interface oti_indexer = bai.ordinal_type_interface;
         int arr_length = oti_indexer.ordinal_type_to_int(oti_indexer.upper_value) - oti_indexer.ordinal_type_to_int(oti_indexer.lower_value) + 1;
         if (arr_length != constant.element_values.Count)
             AddError(constant.location, "ARRAY_CONST_{0}_ELEMENTS_EXPECTED", arr_length);
     }
     else
         if (IsUnsizedArray(tn))
         {
             array_internal_interface aii = tn.get_internal_interface(internal_interface_kind.unsized_array_interface) as array_internal_interface;
             element_type = aii.element_type;
             if (aii.rank > 1)
             {
             	array_initializer cnst = ConvertNDimArrayInitializer(tn,1,element_type,constant);
             	cnst.type = tn;
             	return cnst;
             }
         }
     else if (tn == SystemLibrary.SystemLibrary.complex_type && constant.element_values.Count == 2)
     {
         compiled_constructor_call cccall = new compiled_constructor_call(SystemLibrary.SystemLibrary.complex_type_constructor, null);
         cccall.parameters.AddElement(convertion_data_and_alghoritms.convert_type(constant.element_values[0], SystemLibrary.SystemLibrary.double_type));
         cccall.parameters.AddElement(convertion_data_and_alghoritms.convert_type(constant.element_values[1], SystemLibrary.SystemLibrary.double_type));
         compiled_constructor_call_as_constant cccall_cnst = new compiled_constructor_call_as_constant(cccall, null);
         return cccall_cnst;
     }
     else
         AddError(new CanNotConvertTypes(constant,constant.type,tn,constant.location));//CompilerInternalError("Unexpected array type");
     for (int i = 0; i < constant.element_values.Count; i++)
     if (constant.element_values[i] is array_initializer)
     	constant.element_values[i] = ConvertArrayInitializer(element_type, constant.element_values[i] as array_initializer);
     else if (constant.element_values[i] is record_initializer)
     {
     	if (element_type is common_type_node)
     		constant.element_values[i] = ConvertRecordInitializer(element_type as common_type_node, constant.element_values[i] as record_initializer);
     	else throw new NotSupportedError(constant.element_values[i].location);
     }
     else
     {
     	constant.element_values[i] = convertion_data_and_alghoritms.convert_type(constant.element_values[i], element_type);
     }
     constant.type = tn;
     return constant;
 }