/// <summary> /// Конструктор узла. /// </summary> /// <param name="ret_type">Тип возвращаемого значения функции.</param> public function_lambda_node(parameter_list parameters, type_node ret_type, statement_node body) { _parameters = parameters; _ret_type = ret_type; _body = body; }
/// <summary> /// Конструктор узла. /// </summary> /// <param name="mi">Оборачиваемый метод.</param> private compiled_function_node(System.Reflection.MethodInfo mi) { _mi=mi; type_node ret_val=null; if (_mi.ReturnType!=null) { ret_val=compiled_type_node.get_type_node(mi.ReturnType); if (ret_val == SystemLibrary.SystemLibrary.void_type) { ret_val = null; } } System.Reflection.ParameterInfo[] pinf=mi.GetParameters(); parameter_list pal = new parameter_list(); //if (!(_mi.IsGenericMethod)) { int i = 1; foreach (System.Reflection.ParameterInfo pi in pinf) { Type t = null; type_node par_type = null; SemanticTree.parameter_type pt = SemanticTree.parameter_type.value; // if (pi.ParameterType.Name.EndsWith("&") == true) //(ssyy) Лучше так: if (pi.ParameterType.IsByRef) { //t = pi.ParameterType.Assembly.GetType(pi.ParameterType.FullName.Substring(0, pi.ParameterType.FullName.Length - 1)); //(ssyy) Лучше так: t = pi.ParameterType.GetElementType(); par_type = compiled_type_node.get_type_node(t); pt = SemanticTree.parameter_type.var; } else { if (pi.Position == 0) { par_type = compiled_type_node.get_type_node(pi.ParameterType); if (NetHelper.NetHelper.IsExtensionMethod(mi)) { connected_to_type = par_type as compiled_type_node; } } } string name = pi.Name; compiled_parameter crpar = new compiled_parameter(pi); crpar.SetParameterType(pt); pal.AddElement(crpar); if (pi.IsOptional && pi.DefaultValue != null) _num_of_default_parameters++; i++; } } //else if (_mi.IsGenericMethod) { _generic_params_count = mi.GetGenericArguments().Length; } _is_extension_method = NetHelper.NetHelper.IsExtensionMethod(mi); this.return_value_type=ret_val; this.parameters.AddRange(pal); }
//TODO: Возможно объеденить с compiled_function_node private compiled_constructor_node(System.Reflection.ConstructorInfo con_info) { _con_info=con_info; compiled_constructors[con_info] = this; //type_node ret_val=null; System.Reflection.ParameterInfo[] pinf=_con_info.GetParameters(); parameter_list pal=new parameter_list(); foreach(System.Reflection.ParameterInfo pi in pinf) { Type t=null; type_node par_type=null; SemanticTree.parameter_type pt=SemanticTree.parameter_type.value; if (pi.ParameterType.IsByRef) { t=pi.ParameterType.GetElementType(); par_type=compiled_type_node.get_type_node(t); pt=SemanticTree.parameter_type.var; } else { par_type=compiled_type_node.get_type_node(pi.ParameterType); } string name=pi.Name; compiled_parameter crpar=new compiled_parameter(pi); crpar.SetParameterType(pt); pal.AddElement(crpar); if (pi.IsOptional && pi.DefaultValue != null) _num_of_default_parameters++; } this.return_value_type=compiled_type_node.get_type_node(_con_info.DeclaringType); this.parameters.AddRange(pal); }
private common_type_node convert_function_type(SyntaxTree.formal_parameters syn_parametres, SyntaxTree.type_definition return_type, location loc, string type_name, common_type_node del_type) { //TODO: Добавить аттрибуты функции. Или не надо? //TODO: Сообщать о том что class keyword и of object игнорируется. parameter_list parameters = new parameter_list(); bool params_met=false; if (syn_parametres != null) { parameter_list temp_params = new parameter_list(); foreach (SyntaxTree.typed_parameters tpars in syn_parametres.params_list) { temp_params.clear(); SemanticTree.parameter_type pt = SemanticTree.parameter_type.value; concrete_parameter_type cpt = concrete_parameter_type.cpt_none; switch (tpars.param_kind) { //TODO: Params parameter. case SyntaxTree.parametr_kind.var_parametr: { pt = SemanticTree.parameter_type.var; cpt = concrete_parameter_type.cpt_var; break; } case PascalABCCompiler.SyntaxTree.parametr_kind.const_parametr: { pt = SemanticTree.parameter_type.value; cpt = concrete_parameter_type.cpt_const; break; } case PascalABCCompiler.SyntaxTree.parametr_kind.out_parametr: { pt = SemanticTree.parameter_type.var; cpt = concrete_parameter_type.cpt_var; break; } } foreach (SyntaxTree.ident id in tpars.idents.idents) { common_parameter cp = new common_parameter(id.name, pt, null, cpt, get_location(id)); parameters.AddElement(cp); if (tpars.param_kind == SyntaxTree.parametr_kind.params_parametr) { cp.intrenal_is_params = true; } temp_params.AddElement(cp); } if (tpars.param_kind == SyntaxTree.parametr_kind.params_parametr) { if (tpars.idents.idents.Count > 1) { AddError(get_location(tpars.idents.idents[1]), "ONLY_ONE_PARAMS_PARAMETER_ALLOWED"); } } SyntaxTree.array_type arr = tpars.vars_type as SyntaxTree.array_type; if (tpars.vars_type is SyntaxTree.class_definition || /*tpars.vars_type is SyntaxTree.enum_type_definition ||*/ (arr != null && arr.indexers != null && arr.indexers.indexers.Count > 0 && arr.indexers.indexers[0] != null)) { AddError(get_location(tpars.vars_type), "STRUCT_TYPE_DEFINITION_IN_FORMAL_PARAM"); } type_node tp = convert_strong(tpars.vars_type); /*if (depended_from_generic_parameter(tp)) // SSM 25/07/13 - закомментировал и пока всё работает { AddError(new DelegateCanNotUseComprehensiveGenericParameter(get_location(tpars.vars_type))); }*/ if (tpars.param_kind == SyntaxTree.parametr_kind.params_parametr) { internal_interface ii = tp.get_internal_interface(internal_interface_kind.unsized_array_interface); if (ii == null) { AddError(get_location(tpars.vars_type), "ONLY_UNSIZED_ARRAY_PARAMS_PARAMETER_ALLOWED"); } } foreach (common_parameter ccp in temp_params) { ccp.type = tp; } if (params_met) { AddError(get_location(tpars), "ONLY_LAST_PARAMETER_CAN_BE_PARAMS"); } if (tpars.param_kind == PascalABCCompiler.SyntaxTree.parametr_kind.params_parametr) { params_met = true; // if (default_value_met) // { // AddError(new FunctionWithParamsParameterCanNotHaveDefaultParameters(get_location(tp))); // } } } } type_node ret_val_type = null; if (return_type != null) { ret_val_type = convert_strong(return_type); /*if (depended_from_generic_parameter(ret_val_type)) // SSM 25/07/13 - закомментировал и пока всё работает { AddError(new DelegateCanNotUseComprehensiveGenericParameter(get_location(return_type))); }*/ } common_type_node del; if (del_type == null) { del = convertion_data_and_alghoritms.type_constructor.create_delegate(type_name, ret_val_type, parameters, context.converted_namespace, loc); } else { del = del_type; convertion_data_and_alghoritms.type_constructor.init_delegate(del, ret_val_type, parameters, loc); } context.converted_namespace.types.AddElement(del); return del; }
//TODO: Если одного из акцессоров нет? public override void visit(SyntaxTree.simple_property _simple_property) { if (_simple_property.accessors == null) AddError(get_location(_simple_property), "PROPERTYACCESSOR_{0}_OR_{1}_EXPECTED", compiler_string_consts.PascalReadAccessorName, compiler_string_consts.PascalWriteAccessorName); if (_simple_property.property_type == null) AddError(get_location(_simple_property.property_name), "TYPE_NAME_EXPECTED"); common_property_node pn = context.add_property(_simple_property.property_name.name, get_location(_simple_property.property_name)); assign_doc_info(pn, _simple_property); //pn.polymorphic_state=SemanticTree.polymorphic_state.ps_common; //pn.loc=get_location(_simple_property.property_name); if (_simple_property.attr == SyntaxTree.definition_attribute.Static) pn.polymorphic_state = SemanticTree.polymorphic_state.ps_static; parameter_list pal_big = new parameter_list(); //TODO: Спросить у Саши как получить тип параметра - var,const и т.д. if (_simple_property.parameter_list != null) { foreach (SyntaxTree.property_parameter pp in _simple_property.parameter_list.parameters) { parameter_list pal_small = new parameter_list(); foreach (SyntaxTree.ident id in pp.names.idents) { common_parameter cp = new common_parameter(id.name, SemanticTree.parameter_type.value, null, concrete_parameter_type.cpt_none, get_location(id)); pal_small.AddElement(cp); } type_node tn = convert_strong(pp.type); foreach (parameter pr in pal_small) { pr.type = tn; } pal_big.AddRange(pal_small); } } pn.parameters.AddRange(pal_big); pn.internal_property_type = convert_strong(_simple_property.property_type); if (_simple_property.accessors != null) { convertion_data_and_alghoritms.check_node_parser_error(_simple_property.accessors); SymbolInfo si = null; //definition_node dn = null; if (_simple_property.accessors.read_accessor != null) { convertion_data_and_alghoritms.check_node_parser_error(_simple_property.accessors.read_accessor); if (_simple_property.accessors.read_accessor.accessor_name == null) { if (!context.converted_type.IsInterface) { AddError(get_location(_simple_property.accessors.read_accessor), "ACCESSOR_NAME_EXPECTED"); } pn.internal_get_function = GenerateGetSetMethodForInterfaceProperty(pn, get_location(_simple_property.accessors.read_accessor), true); } else { convertion_data_and_alghoritms.check_node_parser_error(_simple_property.accessors.read_accessor.accessor_name); si = context.converted_type.find_in_type(_simple_property.accessors.read_accessor.accessor_name.name, context.CurrentScope); location loc1 = get_location(_simple_property.accessors.read_accessor.accessor_name); if (si == null) { AddError(new UndefinedNameReference(_simple_property.accessors.read_accessor.accessor_name.name, loc1)); } //dn = check_name_node_type(_simple_property.accessors.read_accessor.accessor_name.name, // si, loc1, general_node_type.function_node, general_node_type.variable_node); function_node read_accessor = si.sym_info as function_node; if (read_accessor != null) { bool good_func = true; bool one_func = si.Next == null; while (si != null) { good_func = true; if (read_accessor.parameters.Count != pn.parameters.Count) { good_func = false; if (one_func) { AddError(new PropertyAndReadAccessorParamsCountConvergence(read_accessor, pn, loc1)); } } //TODO: Сверять типы параметров - var, const и т.д. else { for (int i1 = 0; good_func && i1 < read_accessor.parameters.Count; i1++) { if (read_accessor.parameters[i1].parameter_type != pn.parameters[i1].parameter_type || read_accessor.parameters[i1].type != pn.parameters[i1].type) { good_func = false; if (one_func) { AddError(loc1, "PROPERTY_{0}_AND_READ_ACCESSOR_{1}_PARAMS_TYPE_CONVERGENCE", pn.name, read_accessor.name); } } } if (read_accessor.return_value_type == null) { good_func = false; if (one_func) { AddError(loc1, "PROPERTY_READ_ACCESSOR_CAN_NOT_BE_PROCEDURE"); } } if (read_accessor.return_value_type != pn.property_type) { good_func = false; if (one_func) { AddError(loc1, "PROPERTY_{0}_AND_READ_ACCESSOR_{1}_RETURN_VALUE_TYPE_CONVERGENCE", pn.name, read_accessor.name); } } if (read_accessor is common_method_node && (read_accessor as common_method_node).is_constructor) { AddError(loc1, "ACCESSOR_CAN_BE_FIELD_OR_METHOD_ONLY"); } } if (good_func) { break; } si = si.Next; if (si != null) { read_accessor = si.sym_info as function_node; } } if (!good_func) { AddError(loc1, "NO_OVERLOAD_FUNCTION_{0}_USEFUL_FOR_ACCESSOR", read_accessor.name); } read_accessor = GenerateGetMethod(pn,read_accessor as common_method_node,pn.loc); } else { class_field cfield = si.sym_info as class_field; if (cfield == null) { AddError(loc1, "ACCESSOR_CAN_BE_FIELD_OR_METHOD_ONLY"); } if (_simple_property.parameter_list != null) { AddError(loc1, "INDEX_PROPERTY_ACCESSOR_CAN_NOT_BE_VARIABLE"); } if (cfield.type != pn.internal_property_type) { AddError(loc1, "PROPERTY_TYPE_MISMATCH_ACCESSOR_FIELD_TYPE"); } if (pn.polymorphic_state == SemanticTree.polymorphic_state.ps_static && cfield.polymorphic_state != SemanticTree.polymorphic_state.ps_static) AddError(get_location(_simple_property.accessors.read_accessor.accessor_name), "ACCESSOR_{0}_MUST_BE_STATIC", cfield.name); if (pn.polymorphic_state != SemanticTree.polymorphic_state.ps_static && cfield.polymorphic_state == SemanticTree.polymorphic_state.ps_static) AddError(get_location(_simple_property.accessors.read_accessor.accessor_name), "ACCESSOR_{0}_CANNOT_BE_STATIC", cfield.name); read_accessor = GenerateGetMethodForField(pn, compiler_string_consts.GetGetAccessorName(pn.name), cfield, loc1); } //Вот здесь уже можем добавить акцессор для чтения. pn.internal_get_function = read_accessor; } if (pn.internal_get_function != null && pn.polymorphic_state == SemanticTree.polymorphic_state.ps_static && pn.internal_get_function.polymorphic_state != SemanticTree.polymorphic_state.ps_static) AddError(get_location(_simple_property.accessors.read_accessor.accessor_name), "ACCESSOR_{0}_MUST_BE_STATIC", pn.internal_get_function.name); if (pn.internal_get_function != null && pn.polymorphic_state != SemanticTree.polymorphic_state.ps_static && pn.internal_get_function.polymorphic_state == SemanticTree.polymorphic_state.ps_static) AddError(get_location(_simple_property.accessors.read_accessor.accessor_name), "ACCESSOR_{0}_CANNOT_BE_STATIC", pn.internal_get_function.name); } if (_simple_property.accessors.write_accessor != null) { convertion_data_and_alghoritms.check_node_parser_error(_simple_property.accessors.write_accessor); if (_simple_property.accessors.write_accessor.accessor_name == null) { if (!context.converted_type.IsInterface) { AddError(get_location(_simple_property.accessors.write_accessor), "ACCESSOR_NAME_EXPECTED"); } pn.internal_set_function = GenerateGetSetMethodForInterfaceProperty(pn, get_location(_simple_property.accessors.write_accessor), false); } else { convertion_data_and_alghoritms.check_node_parser_error(_simple_property.accessors.write_accessor.accessor_name); si = context.converted_type.find_in_type(_simple_property.accessors.write_accessor.accessor_name.name, context.CurrentScope); location loc2 = get_location(_simple_property.accessors.write_accessor.accessor_name); if (si == null) { AddError( new UndefinedNameReference(_simple_property.accessors.write_accessor.accessor_name.name, loc2)); } //dn = check_name_node_type(_simple_property.accessors.write_accessor.accessor_name.name, // si, loc2, general_node_type.function_node, general_node_type.variable_node); function_node write_accessor = si.sym_info as function_node; if (write_accessor != null) { bool good_func = true; bool one_func = si.Next == null; while (si != null) { good_func = true; if (write_accessor.parameters.Count != pn.parameters.Count + 1) { good_func = false; if (one_func) { AddError( new PropertyAndWriteAccessorParamsCountConvergence(write_accessor, pn, loc2)); } } else { //TODO: Сверять типы параметров - var, const и т.д. for (int i2 = 0; good_func && i2 < pn.parameters.Count; i2++) { if (write_accessor.parameters[i2].parameter_type != pn.parameters[i2].parameter_type || write_accessor.parameters[i2].type != pn.parameters[i2].type) { good_func = false; if (one_func) { AddError(loc2, "PROPERTY_{0}_AND_WRITE_ACCESSOR_{1}_PARAMS_TYPE_CONVERGENCE", pn.name ,write_accessor.name); } } } if (write_accessor.parameters[write_accessor.parameters.Count - 1].type != pn.property_type || write_accessor.parameters[write_accessor.parameters.Count - 1].parameter_type != PascalABCCompiler.SemanticTree.parameter_type.value) { good_func = false; if (one_func) { AddError(loc2, "PROPERTY_{0}_AND_WRITE_ACCESSOR_LAST_PARAMETER_TYPE_CONVERGENCE", pn.name); } } if (write_accessor.return_value_type != null) { good_func = false; if (one_func) { AddError(loc2, "PROPERTY_WRITE_ACCESSOR_CAN_NOT_BE_FUNCTION"); } } } if (good_func) { break; } si = si.Next; if (si != null) { write_accessor = si.sym_info as function_node; } } if (!good_func) { AddError(loc2, "NO_OVERLOAD_FUNCTION_{0}_USEFUL_FOR_ACCESSOR", write_accessor.name); } if (write_accessor is common_method_node && (write_accessor as common_method_node).is_constructor) { AddError(loc2, "ACCESSOR_CAN_BE_FIELD_OR_METHOD_ONLY"); } write_accessor = GenerateSetMethod(pn, write_accessor as common_method_node, pn.loc); } else { class_field cfield = si.sym_info as class_field; if (cfield == null) { AddError(loc2, "ACCESSOR_CAN_BE_FIELD_OR_METHOD_ONLY"); } if (_simple_property.parameter_list != null) { AddError(loc2, "INDEX_PROPERTY_ACCESSOR_CAN_NOT_BE_VARIABLE"); } if (cfield.type != pn.internal_property_type) { AddError(loc2, "PROPERTY_TYPE_MISMATCH_ACCESSOR_FIELD_TYPE"); } if (pn.polymorphic_state == SemanticTree.polymorphic_state.ps_static && cfield.polymorphic_state != SemanticTree.polymorphic_state.ps_static) AddError(get_location(_simple_property.accessors.write_accessor.accessor_name), "ACCESSOR_{0}_MUST_BE_STATIC", cfield.name); if (pn.polymorphic_state != SemanticTree.polymorphic_state.ps_static && cfield.polymorphic_state == SemanticTree.polymorphic_state.ps_static) AddError(get_location(_simple_property.accessors.write_accessor.accessor_name), "ACCESSOR_{0}_CANNOT_BE_STATIC", cfield.name); write_accessor = GenerateSetMethodForField(pn, compiler_string_consts.GetSetAccessorName(pn.name), cfield, loc2); } //Вот здесь уже можем добавить акцессор для чтения. pn.internal_set_function = write_accessor; } if (pn.internal_set_function != null && pn.polymorphic_state == SemanticTree.polymorphic_state.ps_static && pn.internal_set_function.polymorphic_state != SemanticTree.polymorphic_state.ps_static) AddError(get_location(_simple_property.accessors.write_accessor.accessor_name), "ACCESSOR_{0}_MUST_BE_STATIC", pn.internal_set_function.name); if (pn.internal_set_function != null && pn.polymorphic_state != SemanticTree.polymorphic_state.ps_static && pn.internal_set_function.polymorphic_state == SemanticTree.polymorphic_state.ps_static) AddError(get_location(_simple_property.accessors.write_accessor.accessor_name), "ACCESSOR_{0}_CANNOT_BE_STATIC", pn.internal_set_function.name); } } make_attributes_for_declaration(_simple_property,pn); //TODO: Можно сделать множество свойств по умолчанию. if (_simple_property.array_default != null) { if (pn.parameters.Count == 0) { AddError(pn.loc, "DEFAULT_PROPERTY_MUST_BE_INDEXED"); } if (context.converted_type.default_property_node != null) { AddError(pn.loc, "DUPLICATE_DEFAULT_PROPERTY_IN_CLASS"); } context.converted_type.default_property = pn; } }
/// <summary> /// Возвращает список преобразований типов для вызова метода. /// </summary> /// <param name="factparams">Список фактических параметров.</param> /// <param name="formalparams">Список формальных параметров.</param> /// <param name="is_alone_method_defined">Для единственного метода у которого типы параметров совпадают, но в качестве var параметра мы передаем константное значение мы можем сгенерировать более подробное сообщение об ошибке.</param> /// <returns>Список преобразований типов.</returns> internal possible_type_convertions_list get_conversions(expressions_list factparams, parameter_list formalparams,bool is_alone_method_defined, location locg) { //TODO:Явно указывать capacity при создании. possible_type_convertions_list tc = new possible_type_convertions_list(); possible_type_convertions ptc; if (factparams.Count>formalparams.Count) { if ( (formalparams.Count==0) || (!(formalparams[formalparams.Count-1].is_params)) ) { return null; } } type_node for_par_type = null; array_internal_interface aii=null; if (formalparams.Count > 0) { parameter pr=formalparams[formalparams.Count - 1]; if (pr.is_params && //это для возможности вызова сразу с массивом[], типа просто не обращаем внимаение на params !(factparams.Count == formalparams.Count && factparams[factparams.Count - 1].type == formalparams[formalparams.Count - 1].type)) { //TODO: Добавить проверку на правильность. aii = (array_internal_interface) pr.type.get_internal_interface(internal_interface_kind.unsized_array_interface); for_par_type = aii.element_type; tc.snl = new statement_node_list(); location loc=null; if (factparams.Count > 0) loc = factparams[factparams.Count-1].location; //var_definition_node vdn=syntax_tree_visitor.context.add_var_definition_in_entry_scope(get_temp_arr_name(),loc); var_definition_node vdn = null; if (syntax_tree_visitor.context.converted_func_stack.size > 0) { common_function_node cfn = syntax_tree_visitor.context.converted_func_stack.first(); if (cfn.is_generic_function) { vdn = syntax_tree_visitor.context.add_var_definition(get_temp_arr_name(), loc); } else vdn = syntax_tree_visitor.context.add_var_definition_in_entry_scope(get_temp_arr_name(), loc); } else if (syntax_tree_visitor.context.converted_type != null) vdn = syntax_tree_visitor.context.add_field(get_temp_arr_name(), loc, pr.type, polymorphic_state.ps_static); else vdn = syntax_tree_visitor.context.add_var_definition_in_entry_scope(get_temp_arr_name(), loc); syntax_tree_visitor.context.close_var_definition_list(pr.type,null); expression_node fst=null; /*switch (syntax_tree_visitor.context.converting_block()) { case block_type.function_block: { fst=new local_variable_reference((local_variable)vdn,0,loc); break; } case block_type.namespace_block: { fst=new namespace_variable_reference((namespace_variable)vdn,loc); break; } }*/ switch (vdn.semantic_node_type) { case semantic_node_type.local_variable: { fst = new local_variable_reference((local_variable)vdn, 0, loc); break; } case semantic_node_type.namespace_variable: { fst = new namespace_variable_reference((namespace_variable)vdn, loc); break; } case semantic_node_type.local_block_variable: { fst = new local_block_variable_reference((local_block_variable)vdn, loc); break; } case semantic_node_type.class_field: { class_field cf = vdn as class_field; cf.polymorphic_state = polymorphic_state.ps_static; fst = new static_class_field_reference(cf, loc); break; } default: throw new CompilerInternalError("Invalid node type"); } tc.var_ref = fst; int del=factparams.Count-formalparams.Count+1; int_const_node icn=new int_const_node(del,loc); expression_node bfc = create_simple_function_call(SystemLibrary.SystemLibrary.resize_func, loc, fst, icn); tc.snl.AddElement(bfc); /*if (factparams.Count == 0) { possible_type_convertions ptci=new possible_type_convertions(); ptci.first=null; ptci.second=null; ptci.from=null; ptci.to = for_par_type; tc.AddElement(ptci); }*/ } } for(int i=0;i<factparams.Count;i++) { type_node formal_param_type = null; if ((for_par_type!=null)&&(i >= formalparams.Count-1)) { formal_param_type = for_par_type; } else { formal_param_type = formalparams[i].type; } if (possible_equal_types(factparams[i].type, formal_param_type)) { if ((i<formalparams.Count)&&(formalparams[i].parameter_type==SemanticTree.parameter_type.var)) { bool is_pascal_array_ref = false; bool is_ok = false; if (factparams[i].is_addressed==false) { if (factparams[i].semantic_node_type == semantic_node_type.common_method_call) { common_method_call cmc = (common_method_call)factparams[i]; internal_interface ii = cmc.obj.type.get_internal_interface(internal_interface_kind.bounded_array_interface); if (ii != null) { if (cmc.function_node.name == compiler_string_consts.get_val_pascal_array_name) { bounded_array_interface bai = (bounded_array_interface)ii; class_field cf = bai.int_array; expression_node left = new class_field_reference(cf, cmc.obj, cmc.location); expression_node right = cmc.parameters[0]; //right = convert_type(right, SystemLibrary.SystemLibrary.integer_type); right = convert_type(right, (ii as bounded_array_interface).ordinal_type_interface.elems_type); right = create_simple_function_call(SystemLibrary.SystemLibrary.int_sub, cmc.location, right, new int_const_node(bai.ordinal_type_interface.ordinal_type_to_int(bai.ordinal_type_interface.lower_value),cmc.location)); factparams[i] = new simple_array_indexing(left, right, cmc.type, cmc.location); is_pascal_array_ref = true; } } } if (!is_pascal_array_ref) { //Если мы попали сюда, то мы пытаемся передать по ссылке значение, //которое не мохет быть передано по ссылке. Например, передать //по ссылки из одной функции в другую константный параметр. if (is_alone_method_defined) { if (syntax_tree_visitor.assign_is_converting) { AddError(factparams[i].location, "CAN_NOT_ASSIGN_TO_LEFT_PART"); } else { if (formalparams[i] is common_parameter && (formalparams[i] as common_parameter).concrete_parameter_type == concrete_parameter_type.cpt_const /*&& factparams[i] is common_parameter_reference*/) { is_ok = true; } else if (formalparams[i] is common_parameter && (formalparams[i] as common_parameter).concrete_parameter_type == concrete_parameter_type.cpt_const) ; //throw new ThisExpressionCanNotBePassedAsConstParameter(factparams[i].location); else if (is_string_getter(factparams[i])) { if (factparams[i] is compiled_function_call) factparams[i] = make_unmanaged_string_getter(factparams[i] as compiled_function_call); else factparams[i] = make_unmanaged_shortstring_getter(factparams[i] as base_function_call); is_ok = true; } else AddError(new ThisExpressionCanNotBePassedAsVarParameter(factparams[i])); } } else if (is_string_getter(factparams[i])) { if (factparams[i] is compiled_function_call) factparams[i] = make_unmanaged_string_getter(factparams[i] as compiled_function_call); else factparams[i] = make_unmanaged_shortstring_getter(factparams[i] as base_function_call); is_ok = true; } if (!is_ok) return null; } } } //Разобраться: может лучше добавлять null к списку. possible_type_convertions ptci=new possible_type_convertions(); ptci.first=null; ptci.second=null; ptci.from=factparams[i].type; ptci.to = formal_param_type; tc.AddElement(ptci); if ((for_par_type != null) && (i >= formalparams.Count - 1)) { expression_node to = new simple_array_indexing(tc.var_ref,//factparams[formalparams.Count - 1], new int_const_node(i - formalparams.Count + 1, factparams[i].location), aii.element_type, factparams[i].location); expression_node from = factparams[i]; statement_node stat = syntax_tree_visitor.find_operator(compiler_string_consts.assign_name, to, from, factparams[i].location); tc.snl.AddElement(stat); } continue; } if ((i<formalparams.Count)&&(formalparams[i].parameter_type==SemanticTree.parameter_type.var)) { return null; } else { ptc = type_table.get_convertions(factparams[i].type, formal_param_type); if (ptc.first==null) { if (type_table.is_derived(formal_param_type, factparams[i].type)) { possible_type_convertions ptci=new possible_type_convertions(); ptci.first=null; ptci.second=null; ptci.from=factparams[i].type; ptci.to = formal_param_type; tc.AddElement(ptci); if ((for_par_type != null) && (i >= formalparams.Count - 1)) { expression_node to = new simple_array_indexing(tc.var_ref,//factparams[formalparams.Count - 1], new int_const_node(i - formalparams.Count + 1, factparams[i].location), aii.element_type, factparams[i].location); expression_node from = factparams[i]; statement_node stat = syntax_tree_visitor.find_operator(compiler_string_consts.assign_name, to, from, factparams[i].location); tc.snl.AddElement(stat); } } else { if (is_alone_method_defined) { AddError(new CanNotConvertTypes(factparams[i], factparams[i].type, formal_param_type, locg)); } return null; } } else { tc.AddElement(ptc); if ((for_par_type != null) && (i >= formalparams.Count - 1)) { expression_node to = new simple_array_indexing(tc.var_ref,//factparams[formalparams.Count - 1], new int_const_node(i - formalparams.Count + 1, factparams[i].location), aii.element_type, factparams[i].location); expression_node from = create_simple_function_call(ptc.first.convertion_method, factparams[i].location, factparams[i]); statement_node stat = syntax_tree_visitor.find_operator(compiler_string_consts.assign_name, to, from, factparams[i].location); tc.snl.AddElement(stat); } } } } if (tc.snl != null) foreach (statement_node sn in tc.snl) sn.location = null; return tc; }
private definition_node CreateInterfaceProperty(string name, int offset) { definition_node dn = null; if (members.TryGetValue(offset, out dn)) return dn as common_property_node; common_property_node prop = null; int name_ref = br.ReadInt32(); type_node type = GetTypeReference(); common_method_node get_meth = null; if (br.ReadByte() == 1) get_meth = GetClassMethod(br.ReadInt32()); common_method_node set_meth = null; if (br.ReadByte() == 1) set_meth = GetClassMethod(br.ReadInt32()); int num = br.ReadInt32(); parameter_list pl = new parameter_list(); for (int i = 0; i < num; i++) pl.AddElement(GetParameter()); common_type_node cont = (common_type_node)GetTypeReference(br.ReadInt32()); SemanticTree.field_access_level fal = (SemanticTree.field_access_level)br.ReadByte(); SemanticTree.polymorphic_state ps = (SemanticTree.polymorphic_state)br.ReadByte(); attributes_list attrs = GetAttributes(); location loc = ReadDebugInfo(); if (name==null) name = GetStringInClass(cont, name_ref); prop = new common_property_node(name, cont, type, get_meth, set_meth, loc, fal, ps); prop.attributes.AddRange(attrs); prop.parameters.AddRange(pl); cont.properties.AddElement(prop); //members[offset] = prop; AddMember(prop, offset); return prop; }
protected parameter_list make_parameters(parameter_list orig_pl, common_function_node fn) { parameter_list pl = new parameter_list(); //TODO: разобраться с concrete_parameter_type foreach (parameter p in orig_pl) { common_parameter cp = new common_parameter( p.name, generic_convertions.determine_type(p.type, _instance_params, false), p.parameter_type, fn, concrete_parameter_type.cpt_none, p.inital_value, null); cp.intrenal_is_params = p.is_params; cp.is_special_name = p.is_special_name; cp.is_ret_value = p.is_ret_value; cp.default_value = p.default_value; pl.AddElement(cp); } return pl; }
public void init_delegate(common_type_node ctn, type_node return_value_type, parameter_list parameters, location loc) { common_method_node constructor=new common_method_node(compiler_string_consts.default_constructor_name,null,loc,ctn,SemanticTree.polymorphic_state.ps_common, SemanticTree.field_access_level.fal_public, convertion_data_and_alghoritms.symbol_table.CreateScope(ctn.scope)); constructor.is_constructor = true; constructor.return_value_type = ctn; constructor.function_code=new runtime_statement(SemanticTree.runtime_statement_type.ctor_delegate,loc); common_method_node invoke=new common_method_node(compiler_string_consts.invoke_method_name, return_value_type,loc,ctn,SemanticTree.polymorphic_state.ps_virtual, SemanticTree.field_access_level.fal_public, convertion_data_and_alghoritms.symbol_table.CreateScope(ctn.scope)); ctn.add_name(compiler_string_consts.invoke_method_name,new SymbolInfo(invoke)); for (int i=0; i<parameters.Count; i++) { if (parameters[i] is compiled_parameter) { parameters[i] = new common_parameter(parameters[i].name,parameters[i].type,parameters[i].parameter_type,invoke,concrete_parameter_type.cpt_none,null,null); } } invoke.parameters.AddRange(parameters); invoke.function_code = new runtime_statement(SemanticTree.runtime_statement_type.invoke_delegate, loc); common_method_node begin_invoke = new common_method_node(compiler_string_consts.begin_invoke_method_name, begin_invoke_result_type, loc, ctn, SemanticTree.polymorphic_state.ps_virtual, SemanticTree.field_access_level.fal_public, convertion_data_and_alghoritms.symbol_table.CreateScope(ctn.scope)); ctn.add_name(compiler_string_consts.begin_invoke_method_name,new SymbolInfo(begin_invoke)); parameter_list begin_invoke_params=new parameter_list(); begin_invoke_params.AddRange(parameters); common_parameter cp=new common_parameter(compiler_string_consts.callback_string,begin_invoke_parameter_type, SemanticTree.parameter_type.value,begin_invoke,concrete_parameter_type.cpt_none, null,loc); begin_invoke_params.AddElement(cp); cp = new common_parameter(compiler_string_consts.object_in_par_string, SystemLibrary.SystemLibrary.object_type, SemanticTree.parameter_type.value,begin_invoke, concrete_parameter_type.cpt_none, null, loc); begin_invoke_params.AddElement(cp); begin_invoke.parameters.AddRange(begin_invoke_params); begin_invoke.function_code = new runtime_statement(SemanticTree.runtime_statement_type.begin_invoke_delegate, loc); common_method_node end_invoke = new common_method_node(compiler_string_consts.end_invoke_method_name, return_value_type, loc, ctn, SemanticTree.polymorphic_state.ps_virtual, SemanticTree.field_access_level.fal_public, convertion_data_and_alghoritms.symbol_table.CreateScope(ctn.scope)); ctn.add_name(compiler_string_consts.end_invoke_method_name,new SymbolInfo(end_invoke)); cp = new common_parameter(compiler_string_consts.result_string, begin_invoke_result_type, SemanticTree.parameter_type.value, end_invoke, concrete_parameter_type.cpt_none, null, loc); end_invoke.parameters.AddElement(cp); end_invoke.function_code = new runtime_statement(SemanticTree.runtime_statement_type.end_invoke_delegate, loc); ctn.methods.AddElement(constructor); ctn.methods.AddElement(invoke); ctn.methods.AddElement(begin_invoke); ctn.methods.AddElement(end_invoke); SystemLibrary.SystemLibrary.init_reference_type(ctn); delegate_internal_interface dii = new delegate_internal_interface(return_value_type, invoke, constructor); dii.parameters.AddRange(parameters); ctn.add_internal_interface(dii); AddOperatorsToDelegate(ctn, loc); }
public common_type_node create_delegate(string name, type_node return_value_type, parameter_list parameters, common_namespace_node cmn, location loc) { common_type_node ctn = create_delegate_without_init(name, cmn, loc); init_delegate(ctn, return_value_type, parameters, loc); return ctn; }