static void RestoreSymbols(SymbolInfo si, PascalABCCompiler.TreeRealization.wrapped_definition_node wdn, string name) { if (wdn.is_synonim) si.sym_info = wdn.PCUReader.CreateTypeSynonim(wdn.offset, name); else if (si.scope is ClassScope) si.sym_info = wdn.PCUReader.CreateInterfaceInClassMember(wdn.offset, name); else si.sym_info = wdn.PCUReader.CreateImplementationMember(wdn.offset, false); }
public static void RestoreSymbols(SymbolInfo si, string name) { while (si != null) { if (si.sym_info != null) if (si.sym_info.semantic_node_type == PascalABCCompiler.TreeRealization.semantic_node_type.wrap_def) { PascalABCCompiler.TreeRealization.wrapped_definition_node wdn = (PascalABCCompiler.TreeRealization.wrapped_definition_node)si.sym_info; RestoreSymbols(si, wdn, name); } si = si.Next; } }
public static void RestoreSymbolsInterfaceMember(SymbolInfo si, string name) { while (si != null) { if (si.sym_info!=null) if (si.sym_info.semantic_node_type == PascalABCCompiler.TreeRealization.semantic_node_type.wrap_def) { PascalABCCompiler.TreeRealization.wrapped_definition_node wdn = (PascalABCCompiler.TreeRealization.wrapped_definition_node)si.sym_info; si.sym_info = wdn.PCUReader.CreateInterfaceMember(wdn.offset, name); } si = si.Next; } }
public void reset() { _cmn = null; _ctn = null; _func_stack.clear(); var_defs.Clear(); _main_procedure = null; _last_created_function = null; _cycles_stack.clear(); _num_of_for_cycles = 0; _fal = SemanticTree.field_access_level.fal_private; rec_num = 1; var_defs_stack.Clear(); type_stack.Clear(); clear_special_local_vars(); _scope_stack.Clear(); }
private addressed_expression address_expression_reciving(SyntaxTree.ident id_right, SymbolInfo si, expression_node en) { if (si != null && si.sym_info != null && si.sym_info.semantic_node_type == semantic_node_type.indefinite_definition_node) { return new indefinite_reference(si.sym_info as indefinite_definition_node, get_location(id_right)); } definition_node dn = null; if (!internal_is_assign) dn = context.check_name_node_type(id_right.name, si, get_location(id_right), general_node_type.variable_node, general_node_type.property_node, general_node_type.event_node); else dn = context.check_name_node_type(id_right.name, si, get_location(id_right), general_node_type.variable_node, general_node_type.property_node, general_node_type.event_node, general_node_type.constant_definition); if (dn.general_node_type == general_node_type.constant_definition) { AddError(get_location(id_right), "CAN_NOT_ASSIGN_TO_CONSTANT_OBJECT"); } switch (dn.general_node_type) { case general_node_type.variable_node: { return create_class_field_reference(en, dn, id_right); } case general_node_type.property_node: { property_node pn = (property_node)dn; if (pn.polymorphic_state == SemanticTree.polymorphic_state.ps_static) { AddError(new CanNotReferenceToStaticPropertyWithExpression(pn, get_location(id_right), pn.comprehensive_type)); } try_convert_typed_expression_to_function_call(ref en); non_static_property_reference pr = new non_static_property_reference(pn, en, get_location(id_right)); return pr; } case general_node_type.event_node: { if (dn.semantic_node_type == semantic_node_type.compiled_event) { compiled_event ce = (compiled_event)dn; if (ce.is_static) { //throw new NonStaticAndStaticEvevnt(); } nonstatic_event_reference ser = new nonstatic_event_reference(en, ce, get_location(id_right)); return ser; } else if (dn.semantic_node_type == semantic_node_type.common_event) { common_event ce = (common_event)dn; if (ce.is_static) { //throw new NonStaticAndStaticEvevnt(); } nonstatic_event_reference ser = new nonstatic_event_reference(en, ce, get_location(id_right)); return ser; } break; } default : return null; } throw new CompilerInternalError("Undefined expression to address reciving"); }
internal expression_node convert_typed_expression_to_function_call(typed_expression te) { delegated_methods dm = te.type as delegated_methods; if (dm == null) { return te; } base_function_call bfc = dm.empty_param_method; if (bfc == null) { return te; } if (bfc.type == null) return te; function_node fn = bfc.simple_function_node; common_namespace_function_node cnfn = fn as common_namespace_function_node; if ((fn.parameters.Count == 1 || cnfn != null && fn.parameters.Count == 2 && cnfn.ConnectedToType != null) && (fn.parameters[fn.parameters.Count - 1].is_params || fn.parameters[fn.parameters.Count - 1].default_value != null)) { fn = convertion_data_and_alghoritms.select_function(bfc.parameters, new SymbolInfo(fn), bfc.location); if (fn.polymorphic_state == SemanticTree.polymorphic_state.ps_static || fn is common_namespace_function_node || fn is basic_function_node) bfc = convertion_data_and_alghoritms.create_simple_function_call(fn, bfc.location, bfc.parameters.ToArray()) as base_function_call; else { expression_node obj = null; if (bfc is common_method_call) obj = (bfc as common_method_call).obj; else if (bfc is compiled_function_call) obj = (bfc as compiled_function_call).obj; bfc = convertion_data_and_alghoritms.create_method_call(fn, bfc.location, obj, bfc.parameters.ToArray()) as base_function_call; } } else { function_node[] empty_param_methods = dm.empty_param_methods; SymbolInfo si = new SymbolInfo(empty_param_methods[0]); SymbolInfo root_si = si; for (int i = 1; i < empty_param_methods.Length; i++) { si.Next = new SymbolInfo(empty_param_methods[i]); si = si.Next; } compiled_function_node cfn = fn as compiled_function_node; if ((fn.parameters.Count == 1 || cfn != null && fn.parameters.Count == 2 && cfn.ConnectedToType != null) && (fn.parameters[fn.parameters.Count - 1].is_params || fn.parameters[fn.parameters.Count - 1].default_value != null)) { fn = convertion_data_and_alghoritms.select_function(bfc.parameters, root_si, bfc.location); bfc = create_static_method_call_with_params(fn, bfc.location, fn.return_value_type, true, bfc.parameters); } else if (fn.parameters.Count == 1 && cfn != null && cfn.ConnectedToType != null) { fn = convertion_data_and_alghoritms.select_function(bfc.parameters, root_si, bfc.location); bfc = create_static_method_call_with_params(fn, bfc.location, fn.return_value_type, true, bfc.parameters); } } return bfc; }
private addressed_expression create_addressed_with_type_expression(type_node tn, SyntaxTree.ident id_right, SymbolInfo si_right) { definition_node dn = null; if (!internal_is_assign) dn = context.check_name_node_type(id_right.name, si_right, get_location(id_right), general_node_type.variable_node, general_node_type.property_node, general_node_type.event_node); else dn = context.check_name_node_type(id_right.name, si_right, get_location(id_right), general_node_type.variable_node, general_node_type.property_node, general_node_type.event_node,general_node_type.constant_definition); if (dn.general_node_type == general_node_type.constant_definition) AddError(get_location(id_right), "CAN_NOT_ASSIGN_TO_CONSTANT_OBJECT"); switch (dn.general_node_type) { case general_node_type.variable_node: { return create_class_static_field_reference(tn, dn, id_right); } case general_node_type.property_node: { property_node pn = (property_node)dn; if (pn.polymorphic_state != SemanticTree.polymorphic_state.ps_static) { AddError(new CanNotReferenceToNonStaticPropertyWithType(pn, get_location(id_right), tn)); } static_property_reference pr = new static_property_reference(pn, get_location(id_right)); return pr; } case general_node_type.event_node: { if (dn.semantic_node_type == semantic_node_type.compiled_event) { compiled_event ce = (compiled_event)dn; if (!ce.is_static) { //throw new NonStaticAndStaticEvevnt(); } static_event_reference ser = new static_event_reference(ce, get_location(id_right)); return ser; } else if (dn.semantic_node_type == semantic_node_type.common_event) { common_event ce = (common_event)dn; if (!ce.is_static) { //throw new NonStaticAndStaticEvevnt(); } static_event_reference ser = new static_event_reference(ce, get_location(id_right)); return ser; } else if (dn.semantic_node_type == semantic_node_type.common_namespace_event) { common_namespace_event cne = dn as common_namespace_event; static_event_reference ser = new static_event_reference(cne, get_location(id_right)); return ser; } break; } default : return null; } throw new CompilerInternalError("Invalid right type expression"); }
private expression_node make_dec_call(SymbolInfo si, SyntaxTree.expression_list parameters, location loc) { if (parameters == null) throw new NoFunctionWithSameParametresNum(loc,false,si.sym_info as function_node); if (parameters.expressions.Count == 1 || parameters.expressions.Count == 2) { expression_node param0 = convert_strong(parameters.expressions[0]); if (!param0.is_addressed) { bool is_pascal_array_ref = false; if (param0.semantic_node_type == semantic_node_type.common_method_call) { common_method_call cmc = (common_method_call)param0; 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 = convertion_data_and_alghoritms.convert_type(right, (ii as bounded_array_interface).ordinal_type_interface.elems_type); right = convertion_data_and_alghoritms.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)); param0 = new simple_array_indexing(left, right, cmc.type, cmc.location); is_pascal_array_ref = true; } } if (!is_pascal_array_ref) { throw new ThisExpressionCanNotBePassedAsVarParameter(param0); } } else if (param0 is compiled_function_call) { compiled_function_call cfc = param0 as compiled_function_call; if ((cfc.function_node.return_value_type == SystemLibrary.SystemLibrary.char_type && cfc.function_node.cont_type == SystemLibrary.SystemLibrary.string_type && cfc.function_node == cfc.function_node.cont_type.default_property_node.get_function)) { expressions_list exl = new expressions_list(); exl.AddElement(cfc.obj); exl.AddElement(cfc.parameters[0]); basic_function_call bfc2 = new basic_function_call(SystemLibrary.SystemLibrary.int_sub as basic_function_node,loc); bfc2.parameters.AddElement(param0); expression_node _param1 = null; if (parameters.expressions.Count == 2) { _param1 = convert_strong(parameters.expressions[1]); } if (_param1 != null) bfc2.parameters.AddElement(convertion_data_and_alghoritms.convert_type(_param1,SystemLibrary.SystemLibrary.integer_type)); else bfc2.parameters.AddElement(new int_const_node(1,null)); expressions_list el = new expressions_list(); el.AddElement(convertion_data_and_alghoritms.convert_type(bfc2,SystemLibrary.SystemLibrary.ushort_type)); function_node chr_func = convertion_data_and_alghoritms.select_function(el, SystemLibrary.SystemLibInitializer.ChrUnicodeFunction.SymbolInfo, loc); exl.AddElement(convertion_data_and_alghoritms.create_simple_function_call(chr_func, loc, el.ToArray())); function_node fn = convertion_data_and_alghoritms.select_function(exl, SystemLibrary.SystemLibInitializer.StringDefaultPropertySetProcedure.SymbolInfo, loc); expression_node ret = convertion_data_and_alghoritms.create_simple_function_call(fn, loc, exl.ToArray()); return ret; } else { throw new ThisExpressionCanNotBePassedAsVarParameter(param0); } } else throw new ThisExpressionCanNotBePassedAsVarParameter(param0); } else check_on_loop_variable(param0); expression_node param1 = null; int type_flag = 0; bool is_uint=false; bool is_enum=false; if (parameters.expressions.Count == 2) { param1 = convert_strong(parameters.expressions[1]); param1 = convertion_data_and_alghoritms.convert_type(param1,SystemLibrary.SystemLibrary.integer_type); } basic_function_call ass = null; basic_function_call bfc = null; if (param0.type == SystemLibrary.SystemLibrary.integer_type) { ass = new basic_function_call(SystemLibrary.SystemLibrary.int_assign as basic_function_node,loc); bfc = new basic_function_call(SystemLibrary.SystemLibrary.int_sub as basic_function_node,loc); } else if (param0.type == SystemLibrary.SystemLibrary.char_type) { ass = new basic_function_call(SystemLibrary.SystemLibrary.char_assign as basic_function_node,loc); bfc = new basic_function_call(SystemLibrary.SystemLibrary.int_sub as basic_function_node,loc); } else if (param0.type == SystemLibrary.SystemLibrary.byte_type) { ass = new basic_function_call(SystemLibrary.SystemLibrary.byte_assign as basic_function_node,loc); bfc = new basic_function_call(SystemLibrary.SystemLibrary.int_sub as basic_function_node,loc); } else if (param0.type == SystemLibrary.SystemLibrary.sbyte_type) { ass = new basic_function_call(SystemLibrary.SystemLibrary.sbyte_assign as basic_function_node,loc); bfc = new basic_function_call(SystemLibrary.SystemLibrary.int_sub as basic_function_node,loc); } else if (param0.type == SystemLibrary.SystemLibrary.short_type) { ass = new basic_function_call(SystemLibrary.SystemLibrary.short_assign as basic_function_node,loc); bfc = new basic_function_call(SystemLibrary.SystemLibrary.int_sub as basic_function_node,loc); } else if (param0.type == SystemLibrary.SystemLibrary.ushort_type) { ass = new basic_function_call(SystemLibrary.SystemLibrary.ushort_assign as basic_function_node,loc); bfc = new basic_function_call(SystemLibrary.SystemLibrary.int_sub as basic_function_node,loc); } else if (param0.type == SystemLibrary.SystemLibrary.uint_type) { ass = new basic_function_call(SystemLibrary.SystemLibrary.uint_assign as basic_function_node,loc); bfc = new basic_function_call(SystemLibrary.SystemLibrary.uint_sub as basic_function_node,loc); type_flag = 2; is_uint = true; } else if (param0.type == SystemLibrary.SystemLibrary.int64_type) { ass = new basic_function_call(SystemLibrary.SystemLibrary.long_assign as basic_function_node,loc); bfc = new basic_function_call(SystemLibrary.SystemLibrary.long_sub as basic_function_node,loc); type_flag = 1; } else if (param0.type == SystemLibrary.SystemLibrary.uint64_type) { ass = new basic_function_call(SystemLibrary.SystemLibrary.ulong_assign as basic_function_node,loc); bfc = new basic_function_call(SystemLibrary.SystemLibrary.ulong_sub as basic_function_node,loc); type_flag = 2; } else if (param0.type == SystemLibrary.SystemLibrary.bool_type) { if (param1 == null) { ass = new basic_function_call(SystemLibrary.SystemLibrary.bool_assign as basic_function_node,loc); bfc = new basic_function_call(SystemLibrary.SystemLibrary.bool_not as basic_function_node,loc); type_flag = 4; } else { basic_function_call mod_expr = new basic_function_call(SystemLibrary.SystemLibrary.int_mod as basic_function_node,loc); mod_expr.parameters.AddElement(convertion_data_and_alghoritms.convert_type(param1,SystemLibrary.SystemLibrary.integer_type)); mod_expr.parameters.AddElement(new int_const_node(2,loc)); basic_function_call condition = new basic_function_call(SystemLibrary.SystemLibrary.int_eq as basic_function_node,loc); condition.parameters.AddElement(mod_expr); condition.parameters.AddElement(new int_const_node(0,loc)); basic_function_call not_expr = new basic_function_call(SystemLibrary.SystemLibrary.bool_not as basic_function_node,loc); not_expr.parameters.AddElement(param0); question_colon_expression qce = new question_colon_expression(condition, param0, not_expr, loc); ass = new basic_function_call(SystemLibrary.SystemLibrary.bool_assign as basic_function_node,loc); ass.parameters.AddElement(param0); ass.parameters.AddElement(qce); type_flag = 5; } } else if (param0.type.type_special_kind == PascalABCCompiler.SemanticTree.type_special_kind.diap_type || param0.type.IsEnum) { ass = new basic_function_call(SystemLibrary.SystemLibrary.int_assign as basic_function_node,loc); bfc = new basic_function_call(SystemLibrary.SystemLibrary.int_sub as basic_function_node,loc); if (param0.type.type_special_kind == PascalABCCompiler.SemanticTree.type_special_kind.diap_type) { type_node bt = param0.type.base_type; if (bt == SystemLibrary.SystemLibrary.int64_type) type_flag = 1; else if (bt == SystemLibrary.SystemLibrary.uint64_type) type_flag = 2; else if (bt == SystemLibrary.SystemLibrary.uint_type) { type_flag =2; is_uint = true; } else if (bt.IsEnum) is_enum = true; } else if (param0.type.IsEnum) is_enum = true; } else throw new NoFunctionWithSameArguments(loc,false); if (type_flag != 5) { if (param1 != null) switch (type_flag) { case 0: param1 = convertion_data_and_alghoritms.convert_type(param1, SystemLibrary.SystemLibrary.integer_type); break; case 3: case 1: param1 = convertion_data_and_alghoritms.convert_type(param1, SystemLibrary.SystemLibrary.int64_type); break; case 2: param1 = convertion_data_and_alghoritms.convert_type(param1, SystemLibrary.SystemLibrary.uint64_type); break; } //bfc.parameters.AddElement(param0); if (param0.type != SystemLibrary.SystemLibrary.char_type && !is_enum && param0.type != SystemLibrary.SystemLibrary.bool_type) switch (type_flag) { case 0: bfc.parameters.AddElement(convertion_data_and_alghoritms.convert_type(param0, SystemLibrary.SystemLibrary.integer_type)); break; case 3: case 1: bfc.parameters.AddElement(convertion_data_and_alghoritms.convert_type(param0, SystemLibrary.SystemLibrary.int64_type)); break; case 2: bfc.parameters.AddElement(convertion_data_and_alghoritms.convert_type(param0, SystemLibrary.SystemLibrary.uint64_type)); break; } else bfc.parameters.AddElement(param0); if (param1 == null) { if (type_flag == 0 || type_flag == 3) bfc.parameters.AddElement(new int_const_node(1, null)); else if (type_flag == 1) bfc.parameters.AddElement(new long_const_node(1, null)); else if (type_flag == 2) bfc.parameters.AddElement(new ulong_const_node(1, null)); } else bfc.parameters.AddElement(param1); ass.parameters.AddElement(param0); if (is_uint) ass.parameters.AddElement(convertion_data_and_alghoritms.convert_type(bfc, SystemLibrary.SystemLibrary.uint_type)); else ass.parameters.AddElement(bfc); } return ass; } throw new NoFunctionWithSameParametresNum(loc,false,si.sym_info as function_node); }
private expression_node make_dispose_call(SymbolInfo si, SyntaxTree.expression_list parameters, location loc) { if (parameters == null) { AddError(new NoFunctionWithSameParametresNum(loc, false, si.sym_info as function_node)); return null; } if (parameters.expressions.Count == 1) { expression_node param0 = convert_strong(parameters.expressions[0]); if (!param0.type.IsPointer || param0.type == SystemLibrary.SystemLibrary.pointer_type) AddError(new NoFunctionWithSameArguments(loc, true)); if (!param0.is_addressed) { bool is_pascal_array_ref = false; if (param0.semantic_node_type == semantic_node_type.common_method_call) { common_method_call cmc = (common_method_call)param0; 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 = convertion_data_and_alghoritms.convert_type(right, (ii as bounded_array_interface).ordinal_type_interface.elems_type); right = convertion_data_and_alghoritms.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)); param0 = new simple_array_indexing(left, right, cmc.type, cmc.location); is_pascal_array_ref = true; } } if (!is_pascal_array_ref) { AddError(new ThisExpressionCanNotBePassedAsVarParameter(param0)); return null; } } else { AddError(new ThisExpressionCanNotBePassedAsVarParameter(param0)); return null; } } function_node fn = si.sym_info as function_node; common_namespace_function_call cnfc = new common_namespace_function_call(fn as common_namespace_function_node, loc); cnfc.parameters.AddElement(param0); return cnfc; } else { AddError(new NoFunctionWithSameParametresNum(loc, false, si.sym_info as function_node)); return null; } }
//ssyy //Удаляет конструкторы предков в списке si private void delete_inherited_constructors(ref SymbolInfo si, type_node tn) { SymbolInfo last_sym = null; SymbolInfo cur_sym = si; while (cur_sym != null) { type_node comph_type = null; bool is_ctor = false; common_method_node mnode = cur_sym.sym_info as common_method_node; if (mnode != null) { comph_type = mnode.cont_type; is_ctor = mnode.is_constructor; } else { compiled_function_node tnode = cur_sym.sym_info as compiled_function_node; if (tnode != null) { comph_type = tnode.cont_type; is_ctor = tnode.method_info.IsConstructor; } } //Итак, comph_type - класс, содержащий si.sym_info; //is_ctor - является ли оно конструктором if (is_ctor && comph_type != tn) { //Удаляем if (last_sym == null) { si = si.Next; } else { last_sym.Next = cur_sym.Next; } } else { last_sym = cur_sym; } cur_sym = cur_sym.Next; } }
private expression_node ident_value_reciving(SymbolInfo si, SyntaxTree.ident _ident) { //SymbolInfo si=blocks.find(_ident.name); location lloc = get_location(_ident); definition_node dn = context.check_name_node_type(_ident.name, si, get_location(_ident), general_node_type.variable_node, general_node_type.function_node, general_node_type.property_node, general_node_type.constant_definition, general_node_type.event_node); switch (dn.general_node_type) { case general_node_type.constant_definition: { constant_definition_node cdn = (constant_definition_node)dn; if (cdn.const_value is array_const || cdn.const_value is record_constant || cdn.const_value is common_namespace_function_call_as_constant) { return create_constant_reference(cdn,lloc); } if (cdn.const_value == null) AddError(new UndefinedNameReference(cdn.name,get_location(_ident))); constant_node cn = cdn.const_value.get_constant_copy(get_location(_ident)); if (cn != null) return cn; return cdn.const_value; } case general_node_type.variable_node: { local_variable lv = dn as local_variable; if (lv != null && (lv.function is common_method_node)) { //self variable if ((lv.function as common_method_node).self_variable == lv) //return new this_node((lv.function as common_method_node).cont_type, lloc); return new this_node(lv.type, lloc); //return GetCurrentObjectReference((lv.function as common_method_node).cont_type.Scope, lloc); } return create_variable_reference(dn, lloc); } case general_node_type.function_node: { //return convertion_data_and_alghoritms.create_full_function_call(new expressions_list(), // si,lloc,blocks.converted_type,blocks.top_function,false); if (!(si.sym_info is common_in_function_function_node)) return make_delegate_wrapper(null, si, lloc, ((si.sym_info is common_method_node) && ((common_method_node)si.sym_info).IsStatic)); return convertion_data_and_alghoritms.create_full_function_call(new expressions_list(), si,lloc,context.converted_type,context.top_function,false); } case general_node_type.property_node: { property_node pn = (property_node)dn; function_node fn = pn.get_function; if (fn == null) { AddError(new ThisPropertyCanNotBeReaded(pn, lloc)); } if (pn.polymorphic_state == SemanticTree.polymorphic_state.ps_static) { return create_static_method_call(fn, lloc, pn.comprehensive_type, false); } check_property_no_params(pn, lloc); //this_node thisnode = new this_node(context.converted_type, lloc); if (pn.comprehensive_type.Scope == null && pn is compiled_property_node) (pn.comprehensive_type as compiled_type_node).init_scope(); return create_not_static_method_call(fn, GetCurrentObjectReference(pn.comprehensive_type.Scope, fn, lloc), lloc, false); } case general_node_type.event_node: { if (dn.semantic_node_type == semantic_node_type.compiled_event) { compiled_event ce = (compiled_event)dn; if (ce.is_static) { static_event_reference ser = new static_event_reference(ce, get_location(_ident)); return ser; } nonstatic_event_reference nser = new nonstatic_event_reference( new this_node(context.converted_type, lloc), ce, lloc); return nser; } else if (dn.semantic_node_type == semantic_node_type.common_event) { common_event ce = (common_event)dn; if (ce.is_static) { static_event_reference ser = new static_event_reference(ce, get_location(_ident)); return ser; } nonstatic_event_reference nser = new nonstatic_event_reference( new this_node(context.converted_type, lloc), ce, lloc); return nser; } else if (dn.semantic_node_type == semantic_node_type.common_namespace_event) { common_namespace_event cne = (common_namespace_event)dn; if (_compiled_unit.namespaces.IndexOf(cne.namespace_node) != -1) { static_event_reference ser = new static_event_reference(cne, get_location(_ident)); return ser; } else AddError(get_location(_ident), "EVENT_{0}_MUST_BE_IN_LEFT_PART", cne.name); } break; } } return null; }
private addressed_expression ident_address_reciving(SymbolInfo si, SyntaxTree.ident _ident) { location lloc = get_location(_ident); definition_node dn = null; if (!internal_is_assign) dn = context.check_name_node_type(_ident.name, si, lloc, general_node_type.variable_node, general_node_type.property_node, general_node_type.event_node); else dn = context.check_name_node_type(_ident.name, si, lloc, general_node_type.variable_node, general_node_type.property_node, general_node_type.event_node, general_node_type.constant_definition); if (dn.general_node_type == general_node_type.constant_definition) AddError(get_location(_ident), "CAN_NOT_ASSIGN_TO_CONSTANT_OBJECT"); switch (dn.general_node_type) { case general_node_type.variable_node: { local_variable lv = dn as local_variable; if (lv != null && (lv.function is common_method_node)) { //self variable if ((lv.function as common_method_node).self_variable == lv) AddError(lloc, "VARIABLE_{0}_READONLY", lv.name); } return create_variable_reference(dn, lloc); } case general_node_type.property_node: { property_node pn = (property_node)dn; if (pn.polymorphic_state == SemanticTree.polymorphic_state.ps_static) { static_property_reference spr = new static_property_reference(pn, lloc); return spr; } //this_node thisnode=new this_node(context.converted_type,lloc); if (pn.comprehensive_type.Scope == null && pn is compiled_property_node) (pn.comprehensive_type as compiled_type_node).init_scope(); non_static_property_reference nspr = new non_static_property_reference(pn, GetCurrentObjectReference(pn.comprehensive_type.Scope, pn, lloc), lloc); return nspr; } case general_node_type.event_node: { if (dn.semantic_node_type == semantic_node_type.compiled_event) { compiled_event ce = (compiled_event)dn; if (ce.is_static) { static_event_reference ser = new static_event_reference(ce, get_location(_ident)); return ser; } nonstatic_event_reference nser = new nonstatic_event_reference( GetCurrentObjectReference(ce.comprehensive_type.Scope, ce, lloc), ce, lloc); return nser; } else if (dn.semantic_node_type == semantic_node_type.common_event) { common_event ce = (common_event)dn; if (ce.is_static) { static_event_reference ser = new static_event_reference(ce, get_location(_ident)); return ser; } nonstatic_event_reference nser = new nonstatic_event_reference( GetCurrentObjectReference(ce.comprehensive_type.Scope, ce, lloc), ce, lloc); return nser; } else if (dn.semantic_node_type == semantic_node_type.common_namespace_event) { common_namespace_event cne = (common_namespace_event)dn; static_event_reference ser = new static_event_reference(cne, get_location(_ident)); return ser; } break; } } return null; }
private base_function_call_list create_possible_delegates_list(expression_node obj, SymbolInfo si, location loc, bool is_static) { if (si == null) { return new base_function_call_list(); } function_node_list fnl = new function_node_list(); while (si != null) { function_node fn = si.sym_info as function_node; if (si.sym_info is compiled_property_node) { fn = (si.sym_info as compiled_property_node).get_function; } else if (si.sym_info is common_property_node) { fn = (si.sym_info as common_property_node).get_function; } if (convertion_data_and_alghoritms.find_eq_method_in_list(fn, fnl) == null) { if (!(obj != null && fn.polymorphic_state == SemanticTree.polymorphic_state.ps_static && !fn.is_extension_method)) { if (fn.is_extension_method) { if (obj != null && (fn.parameters[0].type == obj.type || type_table.compare_types(fn.parameters[0].type, obj.type) == type_compare.greater_type)) fnl.AddElementFirst(fn); else fnl.AddElement(fn); } else fnl.AddElement(fn); } } else { } si = si.Next; } return convert_functions_to_calls(obj, fnl, loc, is_static); }
private bool FunctionExsistsInSymbolInfo(function_node fn, SymbolInfo si) { while (si != null) { if (si.sym_info is function_node) if (convertion_data_and_alghoritms.function_eq_params(fn, si.sym_info as function_node)) return true; si = si.Next; } return false; }
public common_function_node create_function(string name,location def_loc) { check_function_name(name,def_loc); common_function_node cfn=null; switch (converting_block()) { case block_type.function_block: { common_function_node top_func = _func_stack.top(); SymbolTable.Scope scope = convertion_data_and_alghoritms.symbol_table.CreateScope(top_func.scope); common_in_function_function_node ciffn; ciffn=new common_in_function_function_node(name,def_loc,top_func,scope); top_func.functions_nodes_list.AddElement(ciffn); _last_created_function=new SymbolInfo(ciffn); top_func.scope.AddSymbol(name,_last_created_function); cfn=ciffn; break; } case block_type.type_block: { common_method_node cmmn; SymbolTable.Scope scope = convertion_data_and_alghoritms.symbol_table.CreateClassMethodScope(_cmn.scope, _ctn.Scope); //TODO:сделать static и virtual. //TODO: interface and implementation scopes. cmmn=new common_method_node(name,def_loc,_ctn,SemanticTree.polymorphic_state.ps_common,_fal,scope); _last_created_function=new SymbolInfo(cmmn); _ctn.Scope.AddSymbol(name,_last_created_function); _ctn.methods.AddElement(cmmn); local_variable lv = new local_variable(compiler_string_consts.self_word, _ctn, cmmn, def_loc); cmmn.scope.AddSymbol(compiler_string_consts.self_word, new SymbolInfo(lv)); cmmn.self_variable = lv; cmmn.var_definition_nodes_list.AddElement(lv); cfn=cmmn; break; } case block_type.namespace_block: { common_namespace_function_node cnfnn; SymbolTable.Scope scope = convertion_data_and_alghoritms.symbol_table.CreateScope(_cmn.scope); cnfnn=new common_namespace_function_node(name,def_loc,_cmn,scope); _cmn.functions.AddElement(cnfnn); _last_created_function=new SymbolInfo(cnfnn); _cmn.scope.AddSymbol(name,_last_created_function); cfn=cnfnn; break; } } _func_stack.push(cfn); return cfn; }
internal void visit_method_call(SyntaxTree.method_call _method_call) { // frninja 01/03/16 - for iterator capturing (yield) if (_method_call.dereferencing_value is yield_unknown_ident) { var nodeToVisit = new method_call(ProcessUnknownIdent(_method_call.dereferencing_value as yield_unknown_ident), _method_call.parameters); visit(nodeToVisit); return; } // end frninja //lroman if (_method_call.dereferencing_value is closure_substituting_node) { var nodeToVisit = new method_call(((closure_substituting_node) _method_call.dereferencing_value).substitution, _method_call.parameters); visit(nodeToVisit); return; } bool proc_wait = procedure_wait; bool lambdas_are_in_parameters = false; //lroman// var syntax_nodes_parameters = _method_call.parameters == null ? new List<expression>() : _method_call.parameters.expressions; if (procedure_wait) { procedure_wait = false; } //throw new ArgumentNullException("test"); motivation mot = motivation_keeper.motivation; expression_node expr_node = null; expressions_list exprs = new expressions_list(); SyntaxTree.ident id = null; SymbolInfo si = null; type_node to_type = null; SyntaxTree.addressed_value deref_value = _method_call.dereferencing_value; int templ_args_count = 0; //bool needs_generic_type_search = false; SyntaxTree.ident_with_templateparams iwt = deref_value as SyntaxTree.ident_with_templateparams; if (iwt != null) { deref_value = iwt.name; templ_args_count = iwt.template_params.params_list.Count; //needs_generic_type_search = _method_call.parameters.expressions.Count == 1; } SyntaxTree.inherited_ident inh_id = deref_value as SyntaxTree.inherited_ident; if (inh_id != null) { inherited_ident_processing = true; si = find_in_base(inh_id); if (si != null) if (si.sym_info is common_method_node) { if ((si.sym_info as common_method_node).polymorphic_state == SemanticTree.polymorphic_state.ps_virtual_abstract) AddError(get_location(inh_id), "CANNOT_CALL_ABSTRACT_METHOD"); } else if (si.sym_info is compiled_function_node) { if ((si.sym_info as compiled_function_node).polymorphic_state == SemanticTree.polymorphic_state.ps_virtual_abstract) AddError(get_location(inh_id), "CANNOT_CALL_ABSTRACT_METHOD"); } id = inh_id; } else { id = deref_value as SyntaxTree.ident; if (id != null) { if (templ_args_count != 0) { //Ищем generics si = context.find(id.name + compiler_string_consts.generic_params_infix + templ_args_count.ToString()); if (si != null) { si = new SymbolInfo(get_generic_instance(si, iwt.template_params.params_list)); iwt = null; } } if (si == null) { SyntaxTree.operator_name_ident oni = id as SyntaxTree.operator_name_ident; if (oni != null) { si = context.find(name_reflector.get_name(oni.operator_type)); } else { si = context.find(id.name); if (templ_args_count != 0) { SymbolInfo conv = ConvertTypeToInstance(si, iwt.template_params.params_list, get_location(id)); if (conv != null) { si = conv; iwt = null; } } } } } else { SyntaxTree.dot_node _dot_node = deref_value as SyntaxTree.dot_node; if (_dot_node != null) { bool skip_first_parameter = false; //lroman// bool has_extension_overload = false; semantic_node sn = convert_semantic_strong(_dot_node.left); //SyntaxTree.ident id_right = ConvertOperatorNameToIdent(_dot_node.right as SyntaxTree.ident); SyntaxTree.ident id_right = _dot_node.right as SyntaxTree.ident; switch (sn.general_node_type) { case general_node_type.expression: { expression_node exp = (expression_node)sn; if (exp is typed_expression) try_convert_typed_expression_to_function_call(ref exp); SyntaxTree.operator_name_ident oni_right = id_right as SyntaxTree.operator_name_ident; if (oni_right != null) { si = exp.type.find_in_type(name_reflector.get_name(oni_right.operator_type), context.CurrentScope); } else { si = exp.type.find_in_type(id_right.name, context.CurrentScope); if (si != null && si.sym_info != null && si.sym_info.semantic_node_type == semantic_node_type.wrap_def) BasePCUReader.RestoreSymbols(si, id_right.name); } //definition_node ddn=check_name_node_type(id_right.name,si,get_location(id_right), // general_node_type.function_node,general_node_type.variable_node); location subloc = get_location(id_right); if (si == null) { AddError(new UndefinedNameReference(id_right.name, subloc)); } if (si.sym_info.general_node_type != general_node_type.function_node) { if (si.sym_info.general_node_type == general_node_type.type_node) { to_type = ((type_node)(si.sym_info)); } else { dot_node_as_expression_dot_ident(exp, id_right, motivation.expression_evaluation, _dot_node.left); exp = ret.get_expression(); internal_interface ii = exp.type.get_internal_interface(internal_interface_kind.delegate_interface); if (ii == null) { AddError(subloc, "EXPECTED_DELEGATE"); } delegate_internal_interface dii = ii as delegate_internal_interface; si = new SymbolInfo(dii.invoke_method); } } if (to_type != null) { if ((_method_call.parameters == null) || (_method_call.parameters.expressions.Count != 1)) { AddError(get_location(_method_call), "ONLY_ONE_PARAMETER_OF_TYPE_CONVERSION_ALLOWED" ); } } SymbolInfo tmp_si = si; while (si != null) { if (si.sym_info is common_namespace_function_node) { common_namespace_function_node cnfn = si.sym_info as common_namespace_function_node; if (cnfn.ConnectedToType != null && !cnfn.IsOperator) { exprs.AddElementFirst(exp); skip_first_parameter = true; break; } } if (si.sym_info is compiled_function_node) { compiled_function_node cfn = si.sym_info as compiled_function_node; if (cfn.ConnectedToType != null) { exprs.AddElementFirst(exp); skip_first_parameter = true; if (cfn.is_generic_function) { //generic_convertions.DeduceFunction(cfn, exprs); //si.sym_info = cfn.get_instance(new List<type_node>(new type_node[] { exp.type }), true, get_location(_method_call)); } break; } } si = si.Next; } si = tmp_si; if (skip_first_parameter) { SymbolInfo new_si = null; bool has_obj_methods = false; List<SymbolInfo> si_list = new List<SymbolInfo>(); while (si != null) { if (si.sym_info is common_namespace_function_node) { common_namespace_function_node cnfn = si.sym_info as common_namespace_function_node; if (cnfn.polymorphic_state != SemanticTree.polymorphic_state.ps_static || cnfn.ConnectedToType != null) si_list.Add(si); if (cnfn.polymorphic_state != SemanticTree.polymorphic_state.ps_static && cnfn.ConnectedToType == null) has_obj_methods = true; } else if (si.sym_info is compiled_function_node) { compiled_function_node cfn = si.sym_info as compiled_function_node; if (cfn.polymorphic_state != SemanticTree.polymorphic_state.ps_static || cfn.ConnectedToType != null) si_list.Add(si); if (cfn.polymorphic_state != SemanticTree.polymorphic_state.ps_static && cfn.ConnectedToType == null) has_obj_methods = true; } else if (si.sym_info is common_method_node) { common_method_node cfn = si.sym_info as common_method_node; if (cfn.polymorphic_state != SemanticTree.polymorphic_state.ps_static) si_list.Add(si); if (cfn.polymorphic_state != SemanticTree.polymorphic_state.ps_static) has_obj_methods = true; } si = si.Next; } for (int i = 0; i < si_list.Count; i++) { if (new_si == null) { new_si = si_list[i]; si = new_si; } else { si.Next = si_list[i]; si = si.Next; } } if (si != null) si.Next = null; si = new_si; } if (_method_call.parameters != null) { foreach (SyntaxTree.expression en in _method_call.parameters.expressions) { #region Отмечаем флаг в лямбдах, говорящий о том, что в первый раз будем их "обходить" для вывода типов //lroman// if (en is SyntaxTree.function_lambda_definition) { lambdas_are_in_parameters = true; ((SyntaxTree.function_lambda_definition)en).lambda_visit_mode = LambdaVisitMode.VisitForInitialMethodCallProcessing; } //lroman// #endregion var cen = convert_strong(en); exprs.AddElement(cen); } } expression_node subexpr1 = null; if (to_type != null) { subexpr1 = convertion_data_and_alghoritms.explicit_convert_type(exprs[0], to_type); } else { if (iwt != null) { si = get_generic_functions(si, true, subloc); si = get_function_instances(si, iwt.template_params.params_list, id_right.name, subloc, si.Next == null); } #region Если встретились лямбды в фактических параметрах, то выбираем нужную функцию из перегруженных, выводим типы, отмечаем флаг в лямбдах, говорящий о том, что мы их реально обходим //lroman// if (lambdas_are_in_parameters) { LambdaHelper.processingLambdaParametersForTypeInference++; // SSM 21.05.14 - попытка обработать перегруженные функции с параметрами-лямбдами с различными возвращаемыми значениями function_node_list spf = null; try { ThrowCompilationError = false; function_node ffn = convertion_data_and_alghoritms.select_function(exprs, si, subloc, syntax_nodes_parameters); if (ffn == null) { if (skip_first_parameter) { expressions_list ex_list = new expressions_list(); ex_list.AddRange(exprs); ex_list.remove_at(0); ffn = convertion_data_and_alghoritms.select_function(ex_list, si, subloc, syntax_nodes_parameters); if (ffn == null) { ThrowCompilationError = true; throw LastError(); } RemoveLastError(); skip_first_parameter = false; exprs = ex_list; ThrowCompilationError = true; } else { ThrowCompilationError = true; throw LastError(); } } ThrowCompilationError = true; int exprCounter = 0; if (skip_first_parameter) { exprCounter++; } foreach (SyntaxTree.expression en in _method_call.parameters.expressions) { if (!(en is SyntaxTree.function_lambda_definition)) { exprCounter++; continue; } else { var enLambda = (SyntaxTree.function_lambda_definition)en; LambdaHelper.InferTypesFromVarStmt(ffn.parameters[exprCounter].type, enLambda, this); enLambda.lambda_visit_mode = LambdaVisitMode.VisitForAdvancedMethodCallProcessing; exprs[exprCounter] = convert_strong(en); enLambda.lambda_visit_mode = LambdaVisitMode.VisitForInitialMethodCallProcessing; exprCounter++; } } } catch (SeveralFunctionsCanBeCalled sf) { spf = sf.set_of_possible_functions; // Возможны несколько перегруженных версий - надо выводить дальше в надежде что какие-то уйдут и останется одна } Exception lastmultex = null; if (spf != null) // пытаемся инстанцировать одну за другой и ошибки гасим try { // exprs - глобальная, поэтому надо копировать int spfnum = -1; // первый номер правильно инстанцированной. Если потом встретился второй, то тоже ошибка // SSM 4.08.15. Сейчас меняю эту логику. Если будет много кандидатов, но ровно один с совпадающим типом возвращаемого значения, то его и надо выбирать. // не забыть, что аналогичный код есть в create_constructor_call!!!!!!! int GoodVersionsCount = 0; int GoodVersionsCountWithSameResType = 0; for (int i = 0; i < spf.Count; i++) // цикл по версиям { function_node fnn = spf[i]; try { int exprCounter = 0; if (skip_first_parameter) { exprCounter++; } expressions_list exprs1 = new expressions_list(); exprs1.AddRange(exprs); // сделали копию foreach (SyntaxTree.expression en in _method_call.parameters.expressions) { if (!(en is SyntaxTree.function_lambda_definition)) { exprCounter++; continue; } else { var fld = en as SyntaxTree.function_lambda_definition; var lambdaName = fld.lambda_name; //lroman Сохранять имя необходимо var fl = fld.lambda_visit_mode; // запомнили типы параметров лямбды - SSM object[] realparamstype = new object[fld.formal_parameters.params_list.Count]; // здесь хранятся выведенные типы лямбд или null если типы явно заданы for (var k = 0; k < fld.formal_parameters.params_list.Count; k++) { var laminftypeK = fld.formal_parameters.params_list[k].vars_type as SyntaxTree.lambda_inferred_type; if (laminftypeK == null) realparamstype[k] = null; else realparamstype[k] = laminftypeK.real_type; } // запоминаем реальный тип возвращаемого значения если он не указан явно (это должен быть any_type или null если он указан явно) - он может измениться при следующем вызове, поэтому мы его восстановим var restype = fld.return_type as SyntaxTree.lambda_inferred_type; object realrestype = null; if (restype != null) realrestype = restype.real_type; LambdaHelper.InferTypesFromVarStmt(fnn.parameters[exprCounter].type, fld, this); fld.lambda_visit_mode = LambdaVisitMode.VisitForAdvancedMethodCallProcessing; //lroman fld.lambda_name = LambdaHelper.GetAuxiliaryLambdaName(lambdaName); // поправляю имя. Думаю, назад возвращать не надо. ПРОВЕРИТЬ! //contextChanger.SaveContextAndUpToNearestDefSect(); try { exprs1[exprCounter] = convert_strong(en); type_node resexprtype = fld.RealSemTypeOfResExpr as type_node; type_node resformaltype = fld.RealSemTypeOfResult as type_node; var bbb = resexprtype == resformaltype; // только в одном случае должно быть true - эту версию и надо выбирать. Если в нескольких, то неоднозначность if (bbb) { GoodVersionsCountWithSameResType += 1; spfnum = i; // здесь запоминаем индекс потому что он точно подойдет. Тогда ниже он запоминаться не будет. } /*compiled_type_node tt; tt = fnn.parameters[exprCounter].type as compiled_type_node; if (tt != null && tt.compiled_type.FullName.ToLower().StartsWith("system.func")) { resformaltype = tt.instance_params[tt.instance_params.Count - 1]; // Последний параметр в записи Func<T,T1,...TN> - тип возвращаемого значения var bbb = resexprtype == resformaltype; // только в одном случае должно быть true - эту версию и надо выбирать. Если в нескольких, то неоднозначность if (bbb) { GoodVersionsCountWithSameResType += 1; spfnum = i; // здесь запоминаем индекс потому что он точно подойдет. Тогда ниже он запоминаться не будет. } }*/ } catch { throw; } finally { LambdaHelper.RemoveLambdaInfoFromCompilationContext(context, en as function_lambda_definition); // восстанавливаем сохраненный тип возвращаемого значения if (restype != null) restype.real_type = realrestype; // восстанавливаем сохраненные типы параметров лямбды, которые не были заданы явно for (var k = 0; k < fld.formal_parameters.params_list.Count; k++) { var laminftypeK = fld.formal_parameters.params_list[k].vars_type as SyntaxTree.lambda_inferred_type; if (laminftypeK != null) laminftypeK.real_type = realparamstype[k]; } fld.lambda_name = lambdaName; //lroman Восстанавливаем имена fld.lambda_visit_mode = fl; } //contextChanger.RestoreCurrentContext(); exprCounter++; } } /*if (spfnum >= 0) // два удачных инстанцирования - плохо. Может, одно - с более близким типом возвращаемого значения, тогда это плохо - надо доделать, но пока так { spfnum = -2; break; }*/ if (GoodVersionsCountWithSameResType == 0) spfnum = i; // здесь запоминаем индекс только если нет подошедших, совпадающих по типу возвращаемого значения GoodVersionsCount += 1; for (int j = 0; j < exprs.Count; j++) // копируем назад если всё хорошо exprs[j] = exprs1[j]; } catch (Exception e) { // если сюда попали, значит, не вывели типы в лямбде и надо эту инстанцию пропускать //contextChanger.RestoreCurrentContext(); lastmultex = e; } } // конец цикла по версиям if (GoodVersionsCount > 1 && GoodVersionsCountWithSameResType != 1) // подошло много, но не было ровно одной с совпадающим типом возвращаемого значения throw new SeveralFunctionsCanBeCalled(subloc, spf); if (GoodVersionsCount == 0) // было много, но ни одна не подошла из-за лямбд { throw lastmultex; //throw new NoFunctionWithSameArguments(subloc2, false); } int kk = 0; if (skip_first_parameter) kk++; foreach (SyntaxTree.expression en in _method_call.parameters.expressions) //lroman окончательно подставить типы в лямбды { if (!(en is SyntaxTree.function_lambda_definition)) { kk++; continue; } else { LambdaHelper.InferTypesFromVarStmt(spf[spfnum].parameters[kk].type, en as SyntaxTree.function_lambda_definition, this); exprs[kk] = convert_strong(en); kk++; } } } // SSM 21.05.14 end LambdaHelper.processingLambdaParametersForTypeInference--; } //lroman// #endregion function_node fn = null; if (!skip_first_parameter || si.Next == null) fn = convertion_data_and_alghoritms.select_function(exprs, si, subloc, syntax_nodes_parameters); else { try { ThrowCompilationError = false; fn = convertion_data_and_alghoritms.select_function(exprs, si, subloc, syntax_nodes_parameters); if (fn == null && skip_first_parameter) { if (si.Next == null) { ThrowCompilationError = true; throw LastError(); } RemoveLastError(); skip_first_parameter = false; si = tmp_si; exprs.remove_at(0); fn = convertion_data_and_alghoritms.select_function(exprs, si, subloc, syntax_nodes_parameters); if (fn == null) { ThrowCompilationError = true; throw LastError(); } // else // RemoveLastError(); // ошибка уже убрана чуть выше } } catch (Exception ex) { ThrowCompilationError = true; if (skip_first_parameter) { si = tmp_si; exprs.remove_at(0); fn = convertion_data_and_alghoritms.select_function(exprs, si, subloc, syntax_nodes_parameters); } else throw ex; } ThrowCompilationError = true; } SemanticTree.IGenericInstance igi = fn as SemanticTree.IGenericInstance; if (igi != null) { //проверяем на соответствие ограничителям int num_err; //CompilationErrorWithLocation err = generic_parameter_eliminations.check_type_list( } base_function_call bfc = create_not_static_method_call(fn, exp, get_location(id_right), proc_wait); bfc.parameters.AddRange(exprs); subexpr1 = bfc; } switch (mot) { case motivation.expression_evaluation: { return_value(subexpr1); return; } case motivation.semantic_node_reciving: { return_semantic_value(subexpr1); return; } default: { AddError(subexpr1.location, "EXPRESSION_IS_NOT_ADDRESSED"); return; } } } case general_node_type.namespace_node: { namespace_node nsn = (namespace_node)sn; if (templ_args_count != 0) { //Ищем generics si = context.find(id_right.name + compiler_string_consts.generic_params_infix + templ_args_count.ToString()); if (si != null) { si = new SymbolInfo(get_generic_instance(si, iwt.template_params.params_list)); iwt = null; } } if (si == null) { SyntaxTree.operator_name_ident oni_right = id_right as SyntaxTree.operator_name_ident; if (oni_right != null) { si = nsn.find(name_reflector.get_name(oni_right.operator_type)); } else { si = nsn.find(id_right.name); if (templ_args_count != 0) { SymbolInfo conv = ConvertTypeToInstance(si, iwt.template_params.params_list, get_location(id_right)); if (conv != null) { si = conv; iwt = null; } } } } id = id_right; break; } case general_node_type.unit_node: { unit_node un = (unit_node)sn; SyntaxTree.operator_name_ident oni_right = id_right as SyntaxTree.operator_name_ident; if (oni_right != null) { si = un.find_only_in_namespace(name_reflector.get_name(oni_right.operator_type)); } else { si = un.find_only_in_namespace(id_right.name); } id = id_right; break; } case general_node_type.type_node: { type_node tn = (type_node)sn; /*if (tn == SystemLibrary.SystemLibrary.void_type) { throw new VoidNotValid(get_location(id_right)); }*/ check_for_type_allowed(tn,get_location(id_right)); SyntaxTree.operator_name_ident oni_right = id_right as SyntaxTree.operator_name_ident; if (oni_right != null) { si = tn.find_in_type(name_reflector.get_name(oni_right.operator_type), context.CurrentScope); } else { si = tn.find_in_type(id_right.name, context.CurrentScope);//CurrentScope delete_inherited_constructors(ref si, tn); delete_extension_methods(ref si, tn); // SSM 2.2.2016 Пока временно закомментировал - в старом коде этого не было. Из-за этого не работает System.Linq.Enumerable.Select } //definition_node ddn2=check_name_node_type(id_right.name,si,get_location(id_right), // general_node_type.function_node); expression_node exp = null; location subloc = get_location(id_right); if (si == null) { AddError( new UndefinedNameReference(id_right.name, subloc)); } if (si.sym_info.general_node_type != general_node_type.function_node) { if (si.sym_info.general_node_type == general_node_type.type_node) { to_type = ((type_node)(si.sym_info)); } else { dot_node_as_type_ident(tn, id_right, motivation.expression_evaluation); exp = ret.get_expression(); internal_interface ii = exp.type.get_internal_interface(internal_interface_kind.delegate_interface); if (ii == null) { AddError(subloc, "EXPECTED_DELEGATE"); } delegate_internal_interface dii = ii as delegate_internal_interface; si = new SymbolInfo(dii.invoke_method); } } if (to_type != null) { if ((_method_call.parameters == null) || (_method_call.parameters.expressions.Count != 1)) { AddError(get_location(_method_call), "ONLY_ONE_PARAMETER_OF_TYPE_CONVERSION_ALLOWED" ); } } if (_method_call.parameters != null) { foreach (SyntaxTree.expression en in _method_call.parameters.expressions) { #region Отмечаем флаг в лямбдах, говорящий о том, что в первый раз будем их "обходить" для вывода типов //lroman// if (en is SyntaxTree.function_lambda_definition) { lambdas_are_in_parameters = true; ((SyntaxTree.function_lambda_definition)en).lambda_visit_mode = LambdaVisitMode.VisitForInitialMethodCallProcessing; } //lroman// #endregion exprs.AddElement(convert_strong(en)); } } expression_node subexpr2 = null; if (to_type != null) { subexpr2 = convertion_data_and_alghoritms.explicit_convert_type(exprs[0], to_type); } else { if (iwt != null) { si = get_generic_functions(si, true, subloc); si = get_function_instances(si, iwt.template_params.params_list, id_right.name, subloc, si.Next == null); } #region Если встретились лямбды в фактических параметрах, то выбираем нужную функцию из перегруженных, выводим типы, отмечаем флаг в лямбдах, говорящий о том, что мы их реально обходим //lroman// if (lambdas_are_in_parameters) { LambdaHelper.processingLambdaParametersForTypeInference++; // SSM 21.05.14 - попытка обработать перегруженные функции с параметрами-лямбдами с различными возвращаемыми значениями function_node_list spf = null; try { function_node ffn = convertion_data_and_alghoritms.select_function(exprs, si, subloc, syntax_nodes_parameters); int exprCounter = 0; if (skip_first_parameter) { exprCounter++; } foreach (SyntaxTree.expression en in _method_call.parameters.expressions) { if (!(en is SyntaxTree.function_lambda_definition)) { exprCounter++; continue; } else { var enLambda = (SyntaxTree.function_lambda_definition)en; LambdaHelper.InferTypesFromVarStmt(ffn.parameters[exprCounter].type, enLambda, this); enLambda.lambda_visit_mode = LambdaVisitMode.VisitForAdvancedMethodCallProcessing; exprs[exprCounter] = convert_strong(en); enLambda.lambda_visit_mode = LambdaVisitMode.VisitForInitialMethodCallProcessing; exprCounter++; } } } catch (SeveralFunctionsCanBeCalled sf) { spf = sf.set_of_possible_functions; // Возможны несколько перегруженных версий - надо выводить дальше в надежде что какие-то уйдут и останется одна } Exception lastmultex = null; if (spf != null) // пытаемся инстанцировать одну за другой и ошибки гасим try { // exprs - глобальная, поэтому надо копировать int spfnum = -1; // первый номер правильно инстанцированной. Если потом встретился второй, то тоже ошибка // SSM 4.08.15. Сейчас меняю эту логику. Если будет много кандидатов, но ровно один с совпадающим типом возвращаемого значения, то его и надо выбирать. // не забыть, что аналогичный код есть в create_constructor_call!!!!!!! int GoodVersionsCount = 0; int GoodVersionsCountWithSameResType = 0; for (int i = 0; i < spf.Count; i++) // цикл по версиям { function_node fnn = spf[i]; try { int exprCounter = 0; if (skip_first_parameter) { exprCounter++; } expressions_list exprs1 = new expressions_list(); exprs1.AddRange(exprs); // сделали копию foreach (SyntaxTree.expression en in _method_call.parameters.expressions) { if (!(en is SyntaxTree.function_lambda_definition)) { exprCounter++; continue; } else { var fld = en as SyntaxTree.function_lambda_definition; var lambdaName = fld.lambda_name; //lroman Сохранять имя необходимо var fl = fld.lambda_visit_mode; // запомнили типы параметров лямбды - SSM object[] realparamstype = new object[fld.formal_parameters.params_list.Count]; // здесь хранятся выведенные типы лямбд или null если типы явно заданы for (var k = 0; k < fld.formal_parameters.params_list.Count; k++) { var laminftypeK = fld.formal_parameters.params_list[k].vars_type as SyntaxTree.lambda_inferred_type; if (laminftypeK == null) realparamstype[k] = null; else realparamstype[k] = laminftypeK.real_type; } // запоминаем реальный тип возвращаемого значения если он не указан явно (это должен быть any_type или null если он указан явно) - он может измениться при следующем вызове, поэтому мы его восстановим var restype = fld.return_type as SyntaxTree.lambda_inferred_type; object realrestype = null; if (restype != null) realrestype = restype.real_type; LambdaHelper.InferTypesFromVarStmt(fnn.parameters[exprCounter].type, fld, this); fld.lambda_visit_mode = LambdaVisitMode.VisitForAdvancedMethodCallProcessing; //lroman fld.lambda_name = LambdaHelper.GetAuxiliaryLambdaName(lambdaName); // поправляю имя. Думаю, назад возвращать не надо. ПРОВЕРИТЬ! //contextChanger.SaveContextAndUpToNearestDefSect(); try { exprs1[exprCounter] = convert_strong(en); type_node resexprtype = fld.RealSemTypeOfResExpr as type_node; type_node resformaltype = fld.RealSemTypeOfResult as type_node; var bbb = resexprtype == resformaltype; // только в одном случае должно быть true - эту версию и надо выбирать. Если в нескольких, то неоднозначность if (bbb) { GoodVersionsCountWithSameResType += 1; spfnum = i; // здесь запоминаем индекс потому что он точно подойдет. Тогда ниже он запоминаться не будет. } /*compiled_type_node tt; tt = fnn.parameters[exprCounter].type as compiled_type_node; if (tt != null && tt.compiled_type.FullName.ToLower().StartsWith("system.func")) { resformaltype = tt.instance_params[tt.instance_params.Count - 1]; // Последний параметр в записи Func<T,T1,...TN> - тип возвращаемого значения var bbb = resexprtype == resformaltype; // только в одном случае должно быть true - эту версию и надо выбирать. Если в нескольких, то неоднозначность if (bbb) { GoodVersionsCountWithSameResType += 1; spfnum = i; // здесь запоминаем индекс потому что он точно подойдет. Тогда ниже он запоминаться не будет. } }*/ } catch { throw; } finally { LambdaHelper.RemoveLambdaInfoFromCompilationContext(context, en as function_lambda_definition); // восстанавливаем сохраненный тип возвращаемого значения if (restype != null) restype.real_type = realrestype; // восстанавливаем сохраненные типы параметров лямбды, которые не были заданы явно for (var k = 0; k < fld.formal_parameters.params_list.Count; k++) { var laminftypeK = fld.formal_parameters.params_list[k].vars_type as SyntaxTree.lambda_inferred_type; if (laminftypeK != null) laminftypeK.real_type = realparamstype[k]; } fld.lambda_name = lambdaName; //lroman Восстанавливаем имена fld.lambda_visit_mode = fl; } //contextChanger.RestoreCurrentContext(); exprCounter++; } } /*if (spfnum >= 0) // два удачных инстанцирования - плохо. Может, одно - с более близким типом возвращаемого значения, тогда это плохо - надо доделать, но пока так { spfnum = -2; break; }*/ if (GoodVersionsCountWithSameResType == 0) spfnum = i; // здесь запоминаем индекс только если нет подошедших, совпадающих по типу возвращаемого значения GoodVersionsCount += 1; for (int j = 0; j < exprs.Count; j++) // копируем назад если всё хорошо exprs[j] = exprs1[j]; } catch (Exception e) { // если сюда попали, значит, не вывели типы в лямбде и надо эту инстанцию пропускать //contextChanger.RestoreCurrentContext(); lastmultex = e; } } // конец цикла по версиям if (GoodVersionsCount > 1 && GoodVersionsCountWithSameResType != 1) // подошло много, но не было ровно одной с совпадающим типом возвращаемого значения throw new SeveralFunctionsCanBeCalled(subloc, spf); if (GoodVersionsCount == 0) // было много, но ни одна не подошла из-за лямбд { throw lastmultex; //throw new NoFunctionWithSameArguments(subloc2, false); } int kk = 0; if (skip_first_parameter) kk++; foreach (SyntaxTree.expression en in _method_call.parameters.expressions) //lroman окончательно подставить типы в лямбды { if (!(en is SyntaxTree.function_lambda_definition)) { kk++; continue; } else { LambdaHelper.InferTypesFromVarStmt(spf[spfnum].parameters[kk].type, en as SyntaxTree.function_lambda_definition, this); exprs[kk] = convert_strong(en); kk++; } } } // SSM 21.05.14 end LambdaHelper.processingLambdaParametersForTypeInference--; } //lroman// #endregion function_node fn = convertion_data_and_alghoritms.select_function(exprs, si, subloc, syntax_nodes_parameters); if (!debug && fn == SystemLibrary.SystemLibrary.assert_method) { // return_value(new empty_statement(null)); // return; } /*if ((proc_wait==false)&&(fn.return_value_type==null)) { throw new FunctionExpectedProcedureMeet(fn,get_location(id_right)); }*/ base_function_call bfc2 = null; if (exp == null) { bfc2 = create_static_method_call(fn, subloc, tn, proc_wait); } else { bfc2 = create_not_static_method_call(fn, exp, subloc, proc_wait); } bfc2.parameters.AddRange(exprs); subexpr2 = bfc2; } switch (mot) { case motivation.expression_evaluation: { return_value(subexpr2); return; } case motivation.semantic_node_reciving: { return_semantic_value(subexpr2); return; } default: { AddError(subexpr2.location, "EXPRESSION_IS_NOT_ADDRESSED"); return; } } } } } else { SyntaxTree.expression expr = deref_value as SyntaxTree.expression; if (expr != null) { //throw new CompilerInternalError("Not supported"); expression_node exp_int = convert_strong(expr); location sloc = get_location(expr); internal_interface ii = exp_int.type.get_internal_interface(internal_interface_kind.delegate_interface); if (ii == null) { AddError(sloc, "EXPECTED_DELEGATE"); } delegate_internal_interface dii = (delegate_internal_interface)ii; si = new SymbolInfo(dii.invoke_method); if (_method_call.parameters != null) { foreach (SyntaxTree.expression en in _method_call.parameters.expressions) { #region Отмечаем флаг в лямбдах, говорящий о том, что в первый раз будем их "обходить" для вывода типов //lroman// if (en is SyntaxTree.function_lambda_definition) { lambdas_are_in_parameters = true; ((SyntaxTree.function_lambda_definition)en).lambda_visit_mode = LambdaVisitMode.VisitForInitialMethodCallProcessing; } //lroman// #endregion exprs.AddElement(convert_strong(en)); } } location subloc = sloc; #region Если встретились лямбды в фактических параметрах, то выбираем нужную функцию из перегруженных, выводим типы, отмечаем флаг в лямбдах, говорящий о том, что мы их реально обходим //lroman// if (lambdas_are_in_parameters) { LambdaHelper.processingLambdaParametersForTypeInference++; // SSM 21.05.14 - попытка обработать перегруженные функции с параметрами-лямбдами с различными возвращаемыми значениями function_node_list spf = null; try { function_node ffn = convertion_data_and_alghoritms.select_function(exprs, si, subloc, syntax_nodes_parameters); int exprCounter = 0; foreach (SyntaxTree.expression en in _method_call.parameters.expressions) { if (!(en is SyntaxTree.function_lambda_definition)) { exprCounter++; continue; } else { var enLambda = (SyntaxTree.function_lambda_definition)en; LambdaHelper.InferTypesFromVarStmt(ffn.parameters[exprCounter].type, enLambda, this); enLambda.lambda_visit_mode = LambdaVisitMode.VisitForAdvancedMethodCallProcessing; exprs[exprCounter] = convert_strong(en); enLambda.lambda_visit_mode = LambdaVisitMode.VisitForInitialMethodCallProcessing; exprCounter++; } } } catch (SeveralFunctionsCanBeCalled sf) { spf = sf.set_of_possible_functions; // Возможны несколько перегруженных версий - надо выводить дальше в надежде что какие-то уйдут и останется одна } Exception lastmultex = null; if (spf != null) // пытаемся инстанцировать одну за другой и ошибки гасим try { // exprs - глобальная, поэтому надо копировать int spfnum = -1; // первый номер правильно инстанцированной. Если потом встретился второй, то тоже ошибка // SSM 4.08.15. Сейчас меняю эту логику. Если будет много кандидатов, но ровно один с совпадающим типом возвращаемого значения, то его и надо выбирать. // не забыть, что аналогичный код есть в create_constructor_call!!!!!!! int GoodVersionsCount = 0; int GoodVersionsCountWithSameResType = 0; for (int i = 0; i < spf.Count; i++) // цикл по версиям { function_node fnn = spf[i]; try { int exprCounter = 0; expressions_list exprs1 = new expressions_list(); exprs1.AddRange(exprs); // сделали копию foreach (SyntaxTree.expression en in _method_call.parameters.expressions) { if (!(en is SyntaxTree.function_lambda_definition)) { exprCounter++; continue; } else { var fld = en as SyntaxTree.function_lambda_definition; var lambdaName = fld.lambda_name; //lroman Сохранять имя необходимо var fl = fld.lambda_visit_mode; // запомнили типы параметров лямбды - SSM object[] realparamstype = new object[fld.formal_parameters.params_list.Count]; // здесь хранятся выведенные типы лямбд или null если типы явно заданы for (var k = 0; k < fld.formal_parameters.params_list.Count; k++) { var laminftypeK = fld.formal_parameters.params_list[k].vars_type as SyntaxTree.lambda_inferred_type; if (laminftypeK == null) realparamstype[k] = null; else realparamstype[k] = laminftypeK.real_type; } // запоминаем реальный тип возвращаемого значения если он не указан явно (это должен быть any_type или null если он указан явно) - он может измениться при следующем вызове, поэтому мы его восстановим var restype = fld.return_type as SyntaxTree.lambda_inferred_type; object realrestype = null; if (restype != null) realrestype = restype.real_type; LambdaHelper.InferTypesFromVarStmt(fnn.parameters[exprCounter].type, fld, this); fld.lambda_visit_mode = LambdaVisitMode.VisitForAdvancedMethodCallProcessing; //lroman fld.lambda_name = LambdaHelper.GetAuxiliaryLambdaName(lambdaName); // поправляю имя. Думаю, назад возвращать не надо. ПРОВЕРИТЬ! //contextChanger.SaveContextAndUpToNearestDefSect(); try { exprs1[exprCounter] = convert_strong(en); type_node resexprtype = fld.RealSemTypeOfResExpr as type_node; type_node resformaltype = fld.RealSemTypeOfResult as type_node; var bbb = resexprtype == resformaltype; // только в одном случае должно быть true - эту версию и надо выбирать. Если в нескольких, то неоднозначность if (bbb) { GoodVersionsCountWithSameResType += 1; spfnum = i; // здесь запоминаем индекс потому что он точно подойдет. Тогда ниже он запоминаться не будет. } /*compiled_type_node tt; tt = fnn.parameters[exprCounter].type as compiled_type_node; if (tt != null && tt.compiled_type.FullName.ToLower().StartsWith("system.func")) { resformaltype = tt.instance_params[tt.instance_params.Count - 1]; // Последний параметр в записи Func<T,T1,...TN> - тип возвращаемого значения var bbb = resexprtype == resformaltype; // только в одном случае должно быть true - эту версию и надо выбирать. Если в нескольких, то неоднозначность if (bbb) { GoodVersionsCountWithSameResType += 1; spfnum = i; // здесь запоминаем индекс потому что он точно подойдет. Тогда ниже он запоминаться не будет. } }*/ } catch { throw; } finally { LambdaHelper.RemoveLambdaInfoFromCompilationContext(context, en as function_lambda_definition); // восстанавливаем сохраненный тип возвращаемого значения if (restype != null) restype.real_type = realrestype; // восстанавливаем сохраненные типы параметров лямбды, которые не были заданы явно for (var k = 0; k < fld.formal_parameters.params_list.Count; k++) { var laminftypeK = fld.formal_parameters.params_list[k].vars_type as SyntaxTree.lambda_inferred_type; if (laminftypeK != null) laminftypeK.real_type = realparamstype[k]; } fld.lambda_name = lambdaName; //lroman Восстанавливаем имена fld.lambda_visit_mode = fl; } //contextChanger.RestoreCurrentContext(); exprCounter++; } } /*if (spfnum >= 0) // два удачных инстанцирования - плохо. Может, одно - с более близким типом возвращаемого значения, тогда это плохо - надо доделать, но пока так { spfnum = -2; break; }*/ if (GoodVersionsCountWithSameResType == 0) spfnum = i; // здесь запоминаем индекс только если нет подошедших, совпадающих по типу возвращаемого значения GoodVersionsCount += 1; for (int j = 0; j < exprs.Count; j++) // копируем назад если всё хорошо exprs[j] = exprs1[j]; } catch (Exception e) { // если сюда попали, значит, не вывели типы в лямбде и надо эту инстанцию пропускать //contextChanger.RestoreCurrentContext(); lastmultex = e; } } // конец цикла по версиям if (GoodVersionsCount > 1 && GoodVersionsCountWithSameResType != 1) // подошло много, но не было ровно одной с совпадающим типом возвращаемого значения throw new SeveralFunctionsCanBeCalled(subloc, spf); if (GoodVersionsCount == 0) // было много, но ни одна не подошла из-за лямбд { throw lastmultex; //throw new NoFunctionWithSameArguments(subloc2, false); } int kk = 0; foreach (SyntaxTree.expression en in _method_call.parameters.expressions) //lroman окончательно подставить типы в лямбды { if (!(en is SyntaxTree.function_lambda_definition)) { kk++; continue; } else { LambdaHelper.InferTypesFromVarStmt(spf[spfnum].parameters[kk].type, en as SyntaxTree.function_lambda_definition, this); exprs[kk] = convert_strong(en); kk++; } } } // SSM 21.05.14 end LambdaHelper.processingLambdaParametersForTypeInference--; } //lroman// #endregion function_node del_func = convertion_data_and_alghoritms.select_function(exprs, si, sloc, syntax_nodes_parameters); base_function_call bbfc = create_not_static_method_call(del_func, exp_int, sloc, proc_wait); bbfc.parameters.AddRange(exprs); switch (mot) { case motivation.expression_evaluation: { return_value(bbfc); return; } case motivation.semantic_node_reciving: { return_semantic_value(bbfc); return; } default: { AddError(bbfc.location, "EXPRESSION_IS_NOT_ADDRESSED"); return; } } } else { throw new CompilerInternalError("Unexpected method name kind"); } } } } //definition_node dn=check_name_node_type(id.name,si,get_location(_method_call),general_node_type.function_node); expression_node exp2 = null; location subloc2 = get_location(id); List<TreeConverter.SymbolInfo> sibak = new List<TreeConverter.SymbolInfo>(); TreeConverter.SymbolInfo ssi=si; while (ssi != null) { ssi = ssi.Next; sibak.Add(ssi); } if (si == null) { AddError(new UndefinedNameReference(id.name, subloc2)); } is_format_allowed = false; if (SystemUnitAssigned) if (SystemLibrary.SystemLibInitializer.read_procedure.Equal(si) || SystemLibrary.SystemLibInitializer.readln_procedure.Equal(si)) { expression_node bfcint = make_read_call(si, _method_call.parameters, subloc2); if (!proc_wait) AddError(subloc2, "FUNCTION_EXPECTED_PROCEDURE_{0}_MEET", (si.sym_info as function_node).name); switch (mot) { case motivation.expression_evaluation: { return_value(bfcint); return; } case motivation.semantic_node_reciving: { return_semantic_value(bfcint); return; } default: { AddError(bfcint.location, "EXPRESSION_IS_NOT_ADDRESSED"); return; } } return; } else if (SystemLibrary.SystemLibInitializer.write_procedure.Equal(si) || SystemLibrary.SystemLibInitializer.writeln_procedure.Equal(si) || SystemLibrary.SystemLibInitializer.StrProcedure.Equal(si)) { is_format_allowed = true; } else if (SystemLibrary.SystemLibInitializer.ArrayCopyFunction.Equal(si)) { if (_method_call.parameters != null && _method_call.parameters.expressions.Count == 1) { expression_node param0 = convert_strong(_method_call.parameters.expressions[0]); if (param0.type.type_special_kind == SemanticTree.type_special_kind.array_kind) { location loc = get_location(_method_call); expression_node en = convertion_data_and_alghoritms.create_simple_function_call(SystemLibrary.SystemLibInitializer.ArrayCopyFunction.sym_info as function_node,loc,param0); function_node fn = convertion_data_and_alghoritms.get_empty_conversion(en.type, param0.type, false); en = convertion_data_and_alghoritms.create_simple_function_call(fn, loc, en); return_value(en); return; } } } else if (SystemLibrary.SystemLibInitializer.SetLengthProcedure.Equal(si) || SystemLibrary.SystemLibrary.resize_func == si.sym_info as function_node) { if (_method_call.parameters != null && _method_call.parameters.expressions.Count >= 2) { expression_node param0 = convert_strong(_method_call.parameters.expressions[0]); if (!param0.is_addressed) AddError(new ThisExpressionCanNotBePassedAsVarParameter(param0)); if (param0.type.type_special_kind == SemanticTree.type_special_kind.short_string) { expression_node param1 = convert_strong(_method_call.parameters.expressions[1]); param1 = convertion_data_and_alghoritms.convert_type(param1,SystemLibrary.SystemLibrary.integer_type); base_function_call cnfn = null; if (SystemLibrary.SystemLibInitializer.SetLengthForShortStringProcedure.sym_info is common_namespace_function_node) cnfn = new common_namespace_function_call(SystemLibrary.SystemLibInitializer.SetLengthForShortStringProcedure.sym_info as common_namespace_function_node, get_location(_method_call)); else cnfn = new compiled_static_method_call(SystemLibrary.SystemLibInitializer.SetLengthForShortStringProcedure.sym_info as compiled_function_node, get_location(_method_call)); cnfn.parameters.AddElement(param0); cnfn.parameters.AddElement(param1); cnfn.parameters.AddElement(new int_const_node((param0.type as short_string_type_node).Length,null)); switch (mot) { case motivation.expression_evaluation: { return_value(cnfn); return; } case motivation.semantic_node_reciving: { return_semantic_value(cnfn); return; } default: { AddError(cnfn.location, "EXPRESSION_IS_NOT_ADDRESSED"); return; } } } else if (param0.type.type_special_kind == SemanticTree.type_special_kind.array_kind) { int rank = 1; if (param0.type is compiled_type_node) rank = (param0.type as compiled_type_node).rank; else if (param0.type is common_type_node) rank = (param0.type as common_type_node).rank; if (_method_call.parameters.expressions.Count-1 != rank) AddError(get_location(_method_call), "{0}_PARAMETERS_EXPECTED", rank+1); if (rank > 1) { type_node tn = param0.type.element_type; location loc = get_location(_method_call); typeof_operator to = new typeof_operator(tn, loc); List<expression_node> lst = new List<expression_node>(); //размер for (int i=1; i<_method_call.parameters.expressions.Count; i++) { expression_node expr = convert_strong(_method_call.parameters.expressions[i]);; expr = convertion_data_and_alghoritms.convert_type(expr, SystemLibrary.SystemLibrary.integer_type); if (expr is int_const_node && (expr as int_const_node).constant_value < 0) AddError(expr.location,"NEGATIVE_ARRAY_LENGTH_({0})_NOT_ALLOWED", (expr as int_const_node).constant_value); lst.Add(expr); } //это вызов спецфункции expression_node retv = convertion_data_and_alghoritms.create_simple_function_call(SystemLibrary.SystemLibInitializer.NewArrayProcedureDecl, loc, to, new int_const_node(lst.Count,loc)); common_namespace_function_call cnfc = retv as common_namespace_function_call; foreach (expression_node e in lst) cnfc.parameters.AddElement(e); expression_node en = convertion_data_and_alghoritms.create_simple_function_call(SystemLibrary.SystemLibInitializer.CopyWithSizeFunction.sym_info as function_node,loc,param0,cnfc); function_node fn = convertion_data_and_alghoritms.get_empty_conversion(en.type, retv.type, false); en = convertion_data_and_alghoritms.create_simple_function_call(fn, loc, en); basic_function_call bfc = new basic_function_call(tn.find(compiler_string_consts.assign_name).sym_info as basic_function_node,loc,param0,en); return_value(bfc); return; } } } } else if (SystemLibrary.SystemLibInitializer.InsertProcedure.Equal(si)) { if (_method_call.parameters != null && _method_call.parameters.expressions.Count == 3) { //expression_node param0 = convert_strong(_method_call.parameters.expressions[0]); expression_node param1 = convert_strong(_method_call.parameters.expressions[1]); //expression_node param2 = convert_strong(_method_call.parameters.expressions[2]); if (param1.type.type_special_kind == SemanticTree.type_special_kind.short_string) { expression_node param0 = convert_strong(_method_call.parameters.expressions[0]); expression_node param2 = convert_strong(_method_call.parameters.expressions[2]); param0 = convertion_data_and_alghoritms.convert_type(param0,SystemLibrary.SystemLibrary.string_type); param2 = convertion_data_and_alghoritms.convert_type(param2,SystemLibrary.SystemLibrary.integer_type); base_function_call cnfn = null; if (SystemLibrary.SystemLibInitializer.InsertInShortStringProcedure.sym_info is common_namespace_function_node) cnfn = new common_namespace_function_call(SystemLibrary.SystemLibInitializer.InsertInShortStringProcedure.sym_info as common_namespace_function_node, get_location(_method_call)); else cnfn = new compiled_static_method_call(SystemLibrary.SystemLibInitializer.InsertInShortStringProcedure.sym_info as compiled_function_node, get_location(_method_call)); cnfn.parameters.AddElement(param0); cnfn.parameters.AddElement(param1); cnfn.parameters.AddElement(param2); cnfn.parameters.AddElement(new int_const_node((param1.type as short_string_type_node).Length,null)); switch (mot) { case motivation.expression_evaluation: { return_value(cnfn); return; } case motivation.semantic_node_reciving: { return_semantic_value(cnfn); return; } default: { AddError(cnfn.location, "EXPRESSION_IS_NOT_ADDRESSED"); return; } } } } } else if (SystemLibrary.SystemLibInitializer.DeleteProcedure.Equal(si)) { if (_method_call.parameters != null && _method_call.parameters.expressions.Count == 3) { //expression_node param0 = convert_strong(_method_call.parameters.expressions[0]); expression_node param0 = convert_strong(_method_call.parameters.expressions[0]); //expression_node param2 = convert_strong(_method_call.parameters.expressions[2]); if (param0.type.type_special_kind == SemanticTree.type_special_kind.short_string) { expression_node param1 = convert_strong(_method_call.parameters.expressions[1]); expression_node param2 = convert_strong(_method_call.parameters.expressions[2]); param1 = convertion_data_and_alghoritms.convert_type(param1,SystemLibrary.SystemLibrary.integer_type); param2 = convertion_data_and_alghoritms.convert_type(param2,SystemLibrary.SystemLibrary.integer_type); base_function_call cnfn = null; if (SystemLibrary.SystemLibInitializer.DeleteProcedure.sym_info is common_namespace_function_node) cnfn = new common_namespace_function_call(SystemLibrary.SystemLibInitializer.DeleteProcedure.sym_info as common_namespace_function_node, get_location(_method_call)); else cnfn = new compiled_static_method_call(SystemLibrary.SystemLibInitializer.DeleteProcedure.sym_info as compiled_function_node, get_location(_method_call)); cnfn.parameters.AddElement(param0); cnfn.parameters.AddElement(param1); cnfn.parameters.AddElement(param2); switch (mot) { case motivation.expression_evaluation: { return_value(cnfn); return; } case motivation.semantic_node_reciving: { return_semantic_value(cnfn); return; } default: { AddError(cnfn.location, "EXPRESSION_IS_NOT_ADDRESSED"); return; } } } } } else if (SystemLibrary.SystemLibInitializer.IncludeProcedure.Equal(si) || SystemLibrary.SystemLibInitializer.ExcludeProcedure.Equal(si)) { if (_method_call.parameters != null && _method_call.parameters.expressions.Count == 2) { expression_node param0 = convert_strong(_method_call.parameters.expressions[0]); expression_node param1 = convert_strong(_method_call.parameters.expressions[1]); expressions_list args = new expressions_list(); args.AddElement(param0); args.AddElement(param1); CheckSpecialFunctionCall(si,args,get_location(_method_call)); expression_node en_cnfn = null; if (SystemLibrary.SystemLibInitializer.IncludeProcedure.sym_info is common_namespace_function_node) { common_namespace_function_call cnfn = null; if (SystemLibrary.SystemLibInitializer.IncludeProcedure.Equal(si)) cnfn = new common_namespace_function_call(SystemLibrary.SystemLibInitializer.IncludeProcedure.sym_info as common_namespace_function_node, get_location(_method_call)); else cnfn = new common_namespace_function_call(SystemLibrary.SystemLibInitializer.ExcludeProcedure.sym_info as common_namespace_function_node, get_location(_method_call)); cnfn.parameters.AddElement(param0); cnfn.parameters.AddElement(param1); en_cnfn = cnfn; } else { compiled_static_method_call cnfn = null; if (SystemLibrary.SystemLibInitializer.IncludeProcedure.Equal(si)) cnfn = new compiled_static_method_call(SystemLibrary.SystemLibInitializer.IncludeProcedure.sym_info as compiled_function_node, get_location(_method_call)); else cnfn = new compiled_static_method_call(SystemLibrary.SystemLibInitializer.ExcludeProcedure.sym_info as compiled_function_node, get_location(_method_call)); cnfn.parameters.AddElement(param0); cnfn.parameters.AddElement(param1); en_cnfn = cnfn; } switch (mot) { case motivation.expression_evaluation: { return_value(en_cnfn); return; } case motivation.semantic_node_reciving: { return_semantic_value(en_cnfn); return; } default: { AddError(en_cnfn.location, "EXPRESSION_IS_NOT_ADDRESSED"); return; } } } } else if (SystemLibrary.SystemLibInitializer.IncProcedure.Equal(si)) { expression_node bfcint = make_inc_call(si, _method_call.parameters, subloc2); if (!proc_wait) AddError(subloc2, "FUNCTION_EXPECTED_PROCEDURE_{0}_MEET", (si.sym_info as function_node).name); switch (mot) { case motivation.expression_evaluation: { return_value(bfcint); return; } case motivation.semantic_node_reciving: { return_semantic_value(bfcint); return; } default: { AddError(bfcint.location, "EXPRESSION_IS_NOT_ADDRESSED"); return; } } return; } else if (SystemLibrary.SystemLibInitializer.DecProcedure.Equal(si)) { expression_node bfcint = make_dec_call(si, _method_call.parameters, subloc2); if (!proc_wait) AddError(subloc2, "FUNCTION_EXPECTED_PROCEDURE_{0}_MEET", (si.sym_info as function_node).name); switch (mot) { case motivation.expression_evaluation: { return_value(bfcint); return; } case motivation.semantic_node_reciving: { return_semantic_value(bfcint); return; } default: { AddError(bfcint.location, "EXPRESSION_IS_NOT_ADDRESSED"); return; } } return; } else if (SystemLibrary.SystemLibInitializer.SuccFunction.Equal(si)) { expression_node bfcint = make_succ_call(si, _method_call.parameters, subloc2); switch (mot) { case motivation.expression_evaluation: { return_value(bfcint); return; } case motivation.semantic_node_reciving: { return_semantic_value(bfcint); return; } default: { AddError(bfcint.location, "EXPRESSION_IS_NOT_ADDRESSED"); return; } } return; } else if (SystemLibrary.SystemLibInitializer.PredFunction.Equal(si)) { expression_node bfcint = make_pred_call(si, _method_call.parameters, subloc2); switch (mot) { case motivation.expression_evaluation: { return_value(bfcint); return; } case motivation.semantic_node_reciving: { return_semantic_value(bfcint); return; } default: { AddError(bfcint.location, "EXPRESSION_IS_NOT_ADDRESSED"); return; } } return; } else if (SystemLibrary.SystemLibInitializer.OrdFunction.Equal(si)) { expression_node bfcint = make_ord_call(si, _method_call.parameters, subloc2); switch (mot) { case motivation.expression_evaluation: { return_value(bfcint); return; } case motivation.semantic_node_reciving: { return_semantic_value(bfcint); return; } default: { AddError(bfcint.location, "EXPRESSION_IS_NOT_ADDRESSED"); return; } } return; } else if (SystemLibrary.SystemLibInitializer.LowFunction.Equal(si)) { if (_method_call.parameters != null && _method_call.parameters.expressions.Count == 1) { expression_node param0 = convert_strong(_method_call.parameters.expressions[0]); if (param0.type.type_special_kind == SemanticTree.type_special_kind.array_wrapper) { bounded_array_interface bai = param0.type.get_internal_interface(internal_interface_kind.bounded_array_interface) as bounded_array_interface; expression_node en = new int_const_node(bai.ordinal_type_interface.ordinal_type_to_int(bai.ordinal_type_interface.lower_value),get_location(_method_call)); switch (mot) { case motivation.expression_evaluation: { return_value(en); return; } case motivation.semantic_node_reciving: { return_semantic_value(en); return; } default: { AddError(en.location, "EXPRESSION_IS_NOT_ADDRESSED"); return; } } } } } else if (SystemLibrary.SystemLibInitializer.HighFunction.Equal(si)) { if (_method_call.parameters != null && _method_call.parameters.expressions.Count == 1) { expression_node param0 = convert_strong(_method_call.parameters.expressions[0]); if (param0.type.type_special_kind == SemanticTree.type_special_kind.array_wrapper) { bounded_array_interface bai = param0.type.get_internal_interface(internal_interface_kind.bounded_array_interface) as bounded_array_interface; expression_node en = new int_const_node(bai.ordinal_type_interface.ordinal_type_to_int(bai.ordinal_type_interface.upper_value),get_location(_method_call)); switch (mot) { case motivation.expression_evaluation: { return_value(en); return; } case motivation.semantic_node_reciving: { return_semantic_value(en); return; } default: { AddError(en.location, "EXPRESSION_IS_NOT_ADDRESSED"); return; } } } } } else if (si == SystemLibrary.SystemLibInitializer.NewProcedure) { expression_node bfcint = make_new_call(si, _method_call.parameters, subloc2); if (!proc_wait) AddError(subloc2, "FUNCTION_EXPECTED_PROCEDURE_{0}_MEET", (si.sym_info as function_node).name); switch (mot) { case motivation.expression_evaluation: { return_value(bfcint); return; } case motivation.semantic_node_reciving: { return_semantic_value(bfcint); return; } default: { AddError(bfcint.location, "EXPRESSION_IS_NOT_ADDRESSED"); return; } } return; } else if (si == SystemLibrary.SystemLibInitializer.DisposeProcedure) { //if (convertion_data_and_alghoritms.select_function(convert_expression_list(_method_call.parameters.expressions), si, subloc2) == SystemLibrary.SystemLibInitializer.DisposeProcedure.sym_info) //{ expression_node bfcint = make_dispose_call(si, _method_call.parameters, subloc2); if (!proc_wait) AddError(subloc2, "FUNCTION_EXPECTED_PROCEDURE_{0}_MEET", (si.sym_info as function_node).name); switch (mot) { case motivation.expression_evaluation: { return_value(bfcint); return; } case motivation.semantic_node_reciving: { return_semantic_value(bfcint); return; } default: { AddError(bfcint.location, "EXPRESSION_IS_NOT_ADDRESSED"); return; } } return; // } } else if (!debug && SystemLibrary.SystemLibInitializer.AssertProcedure.Equal(si)) { // return_value(new empty_statement(null)); // return; } /*else if (SystemLibrary.SystemLibInitializer.IncProcedure != null && SystemLibrary.SystemLibInitializer.IncProcedure.Equal(si)) { expression_node bfcint = make_inc_call(si, _method_call.parameters, subloc2); }*/ if (si.sym_info.general_node_type != general_node_type.function_node) { if (si.sym_info.general_node_type == general_node_type.type_node) { to_type = ((type_node)(si.sym_info)); /*if (to_type == SystemLibrary.SystemLibrary.void_type) { throw new VoidNotValid(subloc2); }*/ check_for_type_allowed(to_type,subloc2); } else { exp2 = ident_value_reciving(si, id); internal_interface ii = exp2.type.get_internal_interface(internal_interface_kind.delegate_interface); if (ii == null) { AddError(subloc2, "EXPECTED_DELEGATE"); } if (exp2 is nonstatic_event_reference) { nonstatic_event_reference nser = exp2 as nonstatic_event_reference; common_event ce = nser.en as common_event; if (ce != null) exp2 = new class_field_reference(ce.field,new this_node(ce.cont_type,null),null); else AddError(get_location(_method_call), "EVENT_{0}_MUST_BE_IN_LEFT_PART", nser.en.name); } else if (exp2 is static_event_reference) { static_event_reference nser = exp2 as static_event_reference; common_event ce = nser.en as common_event; if (ce != null) exp2 = new static_class_field_reference(ce.field, null); else if (nser.en is common_namespace_event && _compiled_unit.namespaces.IndexOf((nser.en as common_namespace_event).namespace_node) != -1) exp2 = new namespace_variable_reference((nser.en as common_namespace_event).field, null); else AddError(get_location(_method_call), "EVENT_{0}_MUST_BE_IN_LEFT_PART", nser.en.name); } delegate_internal_interface dii = ii as delegate_internal_interface; si = new SymbolInfo(dii.invoke_method); } } if (to_type != null) { if ((_method_call.parameters == null) || (_method_call.parameters.expressions.Count != 1)) { AddError(get_location(_method_call), "ONLY_ONE_PARAMETER_OF_TYPE_CONVERSION_ALLOWED"); } } if (_method_call.parameters != null) { foreach (SyntaxTree.expression en in _method_call.parameters.expressions) { bool tmp = is_format_allowed; #region Отмечаем флаг в лямбдах, говорящий о том, что в первый раз будем их "обходить" для вывода типов //lroman// if (en is SyntaxTree.function_lambda_definition) { lambdas_are_in_parameters = true; ((SyntaxTree.function_lambda_definition)en).lambda_visit_mode = LambdaVisitMode.VisitForInitialMethodCallProcessing; } //lroman// #endregion exprs.AddElement(convert_strong(en)); is_format_allowed = tmp; } } is_format_allowed = false; CheckSpecialFunctionCall(si, exprs,get_location(_method_call)); ssi=si; foreach (SymbolInfo sii in sibak) { ssi.Next = sii; ssi = sii; } if (to_type != null) { //(ssyy) К вызову функции здесь явно не приводим, т.к. это излишне. expression_node ee = exprs[0]; bool del = to_type is common_type_node && (to_type as common_type_node).IsDelegate; if (!del) try_convert_typed_expression_to_function_call(ref ee); else ee = convert_strong(_method_call.parameters.expressions[0]); expr_node = convertion_data_and_alghoritms.explicit_convert_type(ee, to_type); //expression_node expr = convert_if_typed_expression_to_function_call(exprs[0]); //expr_node = convertion_data_and_alghoritms.explicit_convert_type(expr, to_type); } else { if (exp2 == null) { location mcloc = get_location(_method_call); if (iwt != null) { si = get_generic_functions(si, true, mcloc); si = get_function_instances(si, iwt.template_params.params_list, id.name, mcloc, si.Next == null); } #region Если встретились лямбды в фактических параметрах, то выбираем нужную функцию из перегруженных, выводим типы, отмечаем флаг в лямбдах, говорящий о том, что мы их реально обходим //lroman// if (lambdas_are_in_parameters) { LambdaHelper.processingLambdaParametersForTypeInference++; // SSM 21.05.14 - попытка обработать перегруженные функции с параметрами-лямбдами с различными возвращаемыми значениями function_node_list spf = null; try { function_node fn = convertion_data_and_alghoritms.select_function(exprs, si, subloc2, syntax_nodes_parameters); int exprCounter = 0; foreach (SyntaxTree.expression en in _method_call.parameters.expressions) { if (!(en is SyntaxTree.function_lambda_definition)) { exprCounter++; continue; } else { var enLambda = (SyntaxTree.function_lambda_definition) en; LambdaHelper.InferTypesFromVarStmt(fn.parameters[exprCounter].type, enLambda, this); enLambda.lambda_visit_mode = LambdaVisitMode.VisitForAdvancedMethodCallProcessing; exprs[exprCounter] = convert_strong(en); enLambda.lambda_visit_mode = LambdaVisitMode.VisitForInitialMethodCallProcessing; exprCounter++; } } } catch (SeveralFunctionsCanBeCalled sf) { spf = sf.set_of_possible_functions; // Возможны несколько перегруженных версий - надо выводить дальше в надежде что какие-то уйдут и останется одна } Exception lastmultex = null; if (spf != null) // пытаемся инстанцировать одну за другой и ошибки гасим try { // exprs - глобальная, поэтому надо копировать int spfnum = -1; // первый номер правильно инстанцированной. Если потом встретился второй, то тоже ошибка // SSM 4.08.15. Сейчас меняю эту логику. Если будет много кандидатов, но ровно один с совпадающим типом возвращаемого значения, то его и надо выбирать. // не забыть, что аналогичный код есть в create_constructor_call!!!!!!! И еще выше по коду!!! кошмар!!! int GoodVersionsCount = 0; int GoodVersionsCountWithSameResType = 0; for (int i = 0; i < spf.Count; i++) // цикл по версиям { function_node fn = spf[i]; try // внутренний try регенерирует исключение, а этот гасит { int exprCounter = 0; expressions_list exprs1 = new expressions_list(); exprs1.AddRange(exprs); // сделали копию foreach (SyntaxTree.expression en in _method_call.parameters.expressions) { if (!(en is SyntaxTree.function_lambda_definition)) { exprCounter++; continue; } else { var fld = en as SyntaxTree.function_lambda_definition; var lambdaName = fld.lambda_name; //lroman Сохранять имя необходимо var fl = fld.lambda_visit_mode; // запомнили типы параметров лямбды - SSM object[] realparamstype = new object[fld.formal_parameters.params_list.Count]; // здесь хранятся выведенные типы лямбд или null если типы явно заданы for (var k = 0; k < fld.formal_parameters.params_list.Count; k++) { var laminftypeK = fld.formal_parameters.params_list[k].vars_type as SyntaxTree.lambda_inferred_type; if (laminftypeK == null) realparamstype[k] = null; else realparamstype[k] = laminftypeK.real_type; } // запоминаем реальный тип возвращаемого значения если он не указан явно (это должен быть any_type или null если он указан явно) - он может измениться при следующем вызове, поэтому мы его восстановим var restype = fld.return_type as SyntaxTree.lambda_inferred_type; object realrestype = null; if (restype != null) realrestype = restype.real_type; LambdaHelper.InferTypesFromVarStmt(fn.parameters[exprCounter].type, fld, this); fld.lambda_visit_mode = LambdaVisitMode.VisitForAdvancedMethodCallProcessing; //lroman fld.lambda_name = LambdaHelper.GetAuxiliaryLambdaName(lambdaName); // поправляю имя. Думаю, назад возвращать не надо. ПРОВЕРИТЬ! //contextChanger.SaveContextAndUpToNearestDefSect(); try { exprs1[exprCounter] = convert_strong(en); // SSM 7/08/15 type_node resexprtype = fld.RealSemTypeOfResExpr as type_node; type_node resformaltype = fld.RealSemTypeOfResult as type_node; var bbb = resexprtype == resformaltype; // только в одном случае должно быть true - эту версию и надо выбирать. Если в нескольких, то неоднозначность if (bbb) { GoodVersionsCountWithSameResType += 1; spfnum = i; // здесь запоминаем индекс потому что он точно подойдет. Тогда ниже он запоминаться не будет. } /*var tt = fn.parameters[exprCounter].type as compiled_type_node; if (tt != null && tt.compiled_type.FullName.ToLower().StartsWith("system.func")) { resformaltype = tt.instance_params[tt.instance_params.Count - 1]; // Последний параметр в записи Func<T,T1,...TN> - тип возвращаемого значения var bbb = resexprtype == resformaltype; // только в одном случае должно быть true - эту версию и надо выбирать. Если в нескольких, то неоднозначность if (bbb) { GoodVersionsCountWithSameResType += 1; spfnum = i; // здесь запоминаем индекс потому что он точно подойдет. Тогда ниже он запоминаться не будет. } }*/ } catch { throw; } finally { LambdaHelper.RemoveLambdaInfoFromCompilationContext(context, en as function_lambda_definition); // восстанавливаем сохраненный тип возвращаемого значения if (restype != null) restype.real_type = realrestype; // восстанавливаем сохраненные типы параметров лямбды, которые не были заданы явно for (var k = 0; k < fld.formal_parameters.params_list.Count; k++) { var laminftypeK = fld.formal_parameters.params_list[k].vars_type as SyntaxTree.lambda_inferred_type; if (laminftypeK != null) laminftypeK.real_type = realparamstype[k]; } fld.lambda_name = lambdaName; //lroman Восстанавливаем имена fld.lambda_visit_mode = fl; } //contextChanger.RestoreCurrentContext(); exprCounter++; } } /*if (spfnum >= 0) // два удачных инстанцирования - плохо. Может, одно - с более близким типом возвращаемого значения, тогда это плохо - надо доделать, но пока так { spfnum = -2; break; }*/ if (GoodVersionsCountWithSameResType==0) spfnum = i; // здесь запоминаем индекс только если нет подошедших, совпадающих по типу возвращаемого значения GoodVersionsCount += 1; for (int j = 0; j < exprs.Count; j++) // копируем назад если всё хорошо exprs[j] = exprs1[j]; } catch (Exception e) { // если сюда попали, значит, не вывели типы в лямбде и надо эту инстанцию пропускать //contextChanger.RestoreCurrentContext(); lastmultex = e; } } //--------------- конец цикла по версиям if (GoodVersionsCount>1 && GoodVersionsCountWithSameResType!=1) // подошло много, но не было ровно одной с совпадающим типом возвращаемого значения throw new SeveralFunctionsCanBeCalled(subloc2, spf); if (GoodVersionsCount == 0) // было много, но ни одна не подошла из-за лямбд { throw lastmultex; //throw new NoFunctionWithSameArguments(subloc2, false); } var kk = 0; foreach (SyntaxTree.expression en in _method_call.parameters.expressions) //lroman окончательно подставить типы в лямбды { if (!(en is SyntaxTree.function_lambda_definition)) { kk++; continue; } else { LambdaHelper.InferTypesFromVarStmt(spf[spfnum].parameters[kk].type, en as SyntaxTree.function_lambda_definition, this); exprs[kk] = convert_strong(en); kk++; } } } // SSM 21.05.14 end LambdaHelper.processingLambdaParametersForTypeInference--; } //lroman// #endregion expr_node = convertion_data_and_alghoritms.create_full_function_call(exprs, si, mcloc, context.converted_type, context.top_function, proc_wait); } else { function_node fn = convertion_data_and_alghoritms.select_function(exprs, si, subloc2, syntax_nodes_parameters); base_function_call bbffcc = create_not_static_method_call(fn, exp2, subloc2, proc_wait); bbffcc.parameters.AddRange(exprs); expr_node = bbffcc; } } /*if ((proc_wait==false)&&(expr_node.type==null)) { throw new FunctionExpectedProcedureMeet((function_node)dn,get_location(_method_call)); }*/ switch (mot) { case motivation.expression_evaluation: { return_value(expr_node); return; } case motivation.semantic_node_reciving: { return_semantic_value(expr_node); return; } case motivation.address_reciving: { AddError(get_location(_method_call), "LEFT_SIDE_CANNOT_BE_ASSIGNED_TO"); return; } default: { //throw new CompilerInternalError("Can not recive address from method call");//! AddError(get_location(_method_call), "EXPECTED_VARIABLE"); return; } } //throw new CompilerInternalError("Error in creation method call"); }
//remove extension methods when static methods called private void delete_extension_methods(ref SymbolInfo si, type_node tn) { List<SymbolInfo> si_list = new List<SymbolInfo>(); SymbolInfo tmp_si = si; while (tmp_si != null) { var fn = tmp_si.sym_info as function_node; if (fn != null) { if (fn.is_extension_method) { compiled_function_node cfn = fn as compiled_function_node; if (cfn != null && cfn.cont_type == tn) si_list.Add(tmp_si); } else si_list.Add(tmp_si); } else si_list.Add(tmp_si); /*if (!(fn != null && fn.is_extension_method)) si_list.Add(tmp_si);*/ tmp_si = tmp_si.Next; } /*tmp_si = si; while (tmp_si != null) { var fn = tmp_si.sym_info as function_node; if (fn != null && fn.is_extension_method) { var b = false; foreach (var x in si_list) { var xn = x.sym_info as function_node; if (convertion_data_and_alghoritms.function_eq_params(fn, xn)) { b = true; break; } } if (!b) si_list.Add(tmp_si); } tmp_si = tmp_si.Next; }*/ SymbolInfo new_si = null; for (int i = 0; i < si_list.Count; i++) { if (new_si == null) { new_si = si_list[i]; si = new_si; } else { si.Next = si_list[i]; si = si.Next; } } if (si != null) si.Next = null; si = new_si; }
private semantic_node ident_semantic_reciving(SymbolInfo si_left, SyntaxTree.ident _ident) { //SymbolInfo si_left=blocks.find(_ident.name); location lloc = get_location(_ident); if (si_left == null) { AddError(new UndefinedNameReference(_ident.name, lloc)); } definition_node dn = context.check_name_node_type(_ident.name, si_left, get_location(_ident), general_node_type.constant_definition, general_node_type.function_node, general_node_type.namespace_node, general_node_type.property_node, general_node_type.type_node, general_node_type.variable_node, general_node_type.unit_node); switch (dn.general_node_type) { case general_node_type.constant_definition: case general_node_type.function_node: case general_node_type.property_node: case general_node_type.variable_node: { return ident_value_reciving(si_left, _ident); } case general_node_type.namespace_node: { //throw new CompilerInternalError("Unsupported now."); return dn; } case general_node_type.type_node: { type_node tn = dn as type_node; //dot_node_as_type_ident(tn,id_right,mot); return tn; } case general_node_type.unit_node: { //throw new CompilerInternalError("Unsupproted now."); //throw new NotSupportedError(get_location(_ident)); return dn; } } return null; }
private void CheckSpecialFunctionCall(SymbolInfo si, expressions_list exprs, location loc) { if (SystemUnitAssigned) { bool write_proc = SystemLibrary.SystemLibInitializer.write_procedure.Equal(si); if (write_proc && exprs.Count > 1) { //возможно это запись в типизированый файл if (exprs[0].type.type_special_kind == SemanticTree.type_special_kind.typed_file) //да, точно это типизированый файл! { //Проверим типы параметров вызова на совпадение с типом элементов файла type_node element_type = exprs[0].type.element_type; for (int i = 1; i < exprs.Count; i++) convertion_data_and_alghoritms.check_convert_type(exprs[i], element_type, exprs[i].location); if (element_type.type_special_kind == SemanticTree.type_special_kind.short_string) { for (int i=1; i<exprs.Count; i++) { //common_namespace_function_call cmc = new common_namespace_function_call(SystemLibrary.SystemLibInitializer.ClipShortStringProcedure.sym_info as common_namespace_function_node,null); //cmc.parameters.AddElement(exprs[i]); //cmc.parameters.AddElement(new int_const_node((element_type as short_string_type_node).Length,null)); expression_node cmc = convertion_data_and_alghoritms.create_simple_function_call(SystemLibrary.SystemLibInitializer.ClipShortStringProcedure.sym_info as function_node,null,convertion_data_and_alghoritms.convert_type(exprs[i],SystemLibrary.SystemLibrary.string_type),new int_const_node((element_type as short_string_type_node).Length,null)); exprs[i] = cmc; } } //if (exprs[i].type != element_type) // throw new ExpectedExprHaveTypeTypedFile(element_type, exprs[i].type, false, get_location(_method_call.parameters.expressions[i])); } else //(ssyy) а может быть, в бинарный! if (exprs[0].type.type_special_kind == SemanticTree.type_special_kind.binary_file) { //(ssyy) действительно, бинарный for (int i = 1; i < exprs.Count; i++) { if (!CanUseThisTypeForBinaryFiles(exprs[i].type)) { AddError(exprs[i].location, "CAN_NOT_WRITE_REFERENCE_DATA_TO_BINARY_FILE"); } } } else { if (SystemLibrary.SystemLibInitializer.write_procedure.sym_info is common_namespace_function_node) ConvertPointersForWrite(exprs); else ConvertPointersForWriteFromDll(exprs); } } else if (write_proc || SystemLibrary.SystemLibInitializer.writeln_procedure.Equal(si)) { //(ssyy) Преобразуем указатели в строки для вывода write/writeln if (SystemLibrary.SystemLibInitializer.writeln_procedure.sym_info is common_namespace_function_node) ConvertPointersForWrite(exprs); else ConvertPointersForWriteFromDll(exprs); } else if (SystemLibrary.SystemLibInitializer.IncludeProcedure.Equal(si) || SystemLibrary.SystemLibInitializer.ExcludeProcedure.Equal(si)) { if (exprs.Count != 2) AddError( new NoFunctionWithSameArguments(loc, true)); type_node element_type = exprs[0].type.element_type; if (exprs[0].type.type_special_kind != SemanticTree.type_special_kind.base_set_type && exprs[0].type.type_special_kind != SemanticTree.type_special_kind.set_type) { AddError( new NoFunctionWithSameArguments(loc, true)); } if (element_type != null) convertion_data_and_alghoritms.check_convert_type(exprs[1], element_type, exprs[1].location); else convertion_data_and_alghoritms.check_convert_type(exprs[1], exprs[0].type, exprs[0].location); if (!exprs[0].is_addressed) AddError( new ThisExpressionCanNotBePassedAsVarParameter(exprs[0])); } else if (SystemLibrary.SystemLibInitializer.InSetProcedure.Equal(si)) { if (exprs.Count != 2) AddError( new NoFunctionWithSameArguments(loc, true)); type_node element_type = exprs[1].type.element_type; if (element_type != null) { //exprs[0] = convertion_data_and_alghoritms.convert_type(exprs[0], element_type, exprs[0].location); convertion_data_and_alghoritms.check_convert_type(exprs[0], element_type, exprs[0].location); } else convertion_data_and_alghoritms.check_convert_type(exprs[0], exprs[1].type, exprs[0].location); } else if (SystemLibrary.SystemLibInitializer.SetUnionProcedure.Equal(si) || SystemLibrary.SystemLibInitializer.SetIntersectProcedure.Equal(si) || SystemLibrary.SystemLibInitializer.SetSubtractProcedure.Equal(si)) { if (exprs.Count != 2) AddError( new NoFunctionWithSameArguments(loc, true)); convertion_data_and_alghoritms.check_convert_type(exprs[1], exprs[0].type, exprs[1].location); } if (si == SystemLibrary.SystemLibInitializer.NewProcedure || si == SystemLibrary.SystemLibInitializer.DisposeProcedure) { if (exprs[0].type == SystemLibrary.SystemLibrary.pointer_type) AddError(exprs[0].location, "EXPECTED_TYPED_POINTER_IN_PROCEDURE{0}", (si.sym_info as function_node).name); } } }
internal typed_expression make_delegate_wrapper(expression_node obj, SymbolInfo si, location loc, bool is_static) { base_function_call_list fnl = create_possible_delegates_list(obj, si, loc, is_static); if (fnl.Count == 0) { if (is_static) { AddError(loc, "EXPECTED_STATIC_METHOD"); } else { AddError(loc, "EXPECTED_NON_STATIC_METHOD"); } } delegated_methods dm = new delegated_methods(); dm.proper_methods.AddRange(fnl); typed_expression te = new typed_expression(dm, loc); return te; }
private expression_node make_pred_call(SymbolInfo si, SyntaxTree.expression_list parameters, location loc) { if (parameters == null) { AddError(new NoFunctionWithSameParametresNum(loc, false, si.sym_info as function_node)); return null; } if (parameters.expressions.Count == 1) { expression_node param0 = convert_strong(parameters.expressions[0]); if (param0 is typed_expression) param0 = convert_typed_expression_to_function_call(param0 as typed_expression); basic_function_call bfc = null; int type_flag = 0; expressions_list el = new expressions_list(); el.AddElement(param0); function_node fn = null; try { fn = convertion_data_and_alghoritms.select_function(el,si,loc); } catch(Exception e) { } if (fn != null) { if (fn is common_namespace_function_node) { common_namespace_function_call cnfc = new common_namespace_function_call(fn as common_namespace_function_node, loc); cnfc.parameters.AddElement(param0); return cnfc; } else { compiled_static_method_call cnfc = new compiled_static_method_call(fn as compiled_function_node, loc); cnfc.parameters.AddElement(param0); return cnfc; } } else if (param0.type.type_special_kind == PascalABCCompiler.SemanticTree.type_special_kind.diap_type || param0.type.IsEnum) { el = new expressions_list(); el.AddElement(new int_const_node(1,null)); fn = convertion_data_and_alghoritms.select_function(el,si,loc); //bfc = new basic_function_call(SystemLibrary.SystemLibrary.int_add as basic_function_node,loc); //bfc.ret_type = param0.type; if (fn is common_namespace_function_node) { common_namespace_function_call cnfc = new common_namespace_function_call(fn as common_namespace_function_node, loc); cnfc.parameters.AddElement(param0); cnfc.type = param0.type; return cnfc; } else { compiled_static_method_call cnfc = new compiled_static_method_call(fn as compiled_function_node, loc); cnfc.parameters.AddElement(param0); cnfc.type = param0.type; return cnfc; } } else AddError(new NoFunctionWithSameArguments(loc,false)); bfc.parameters.AddElement(param0); if (type_flag == 0 || type_flag == 3) bfc.parameters.AddElement(new int_const_node(1,null)); else if (type_flag == 1) bfc.parameters.AddElement(new long_const_node(1,null)); else if (type_flag == 2) bfc.parameters.AddElement(new ulong_const_node(1,null)); return bfc; } AddError(new NoFunctionWithSameParametresNum(loc,false,si.sym_info as function_node)); return null; }
public type_node get_generic_instance(SymbolInfo si, List<SyntaxTree.type_definition> type_pars) { type_node node = si.sym_info as type_node; compiled_type_node comp_node = node as compiled_type_node; List<generic_parameter_eliminations> lgpe = null; if (!context.skip_check_where_sections) { lgpe = (comp_node == null) ? (node as common_type_node).parameters_eliminations : comp_node.parameters_eliminations; } List<type_node> tparams = visit_type_list_with_check(type_pars, lgpe, !context.skip_check_where_sections); return node.get_instance(tparams); }
private expression_node make_read_call(SymbolInfo si, SyntaxTree.expression_list parameters, location loc) { // вызов read(a,b,c) разбивается на несколько вызовов, последний возвращается узлом, а остальные добавляются здесь в теле expressions_list exl = new expressions_list(); expression_node last_call = null; expressions_list exl = new expressions_list(); expression_node file = null; bool read_from_file = false; bool read_from_text_file = false; bool read_from_typed_file = false; bool read_from_binary_file = false; bool readln_string_file = false; if (parameters != null) // если список параметров не пуст { if (parameters.expressions.Count >= 1) { expression_node param0 = convert_strong(parameters.expressions[0]); if (param0.type != null) { if (SystemLibrary.SystemLibInitializer.TextFileType.Found && param0.type == SystemLibrary.SystemLibInitializer.TextFileType.sym_info) { file = param0; read_from_text_file = true; } if (param0.type.type_special_kind == SemanticTree.type_special_kind.typed_file && parameters.expressions.Count > 1 //это можно внести во внутрь )//и побросать приличные исключения { if (!SystemLibrary.SystemLibInitializer.read_procedure.FromDll) { if (si == SystemLibrary.SystemLibInitializer.read_procedure.SymbolInfo) { file = param0; read_from_typed_file = true; } } else if (SystemLibrary.SystemLibInitializer.read_procedure.Equal(si)) { file = param0; read_from_typed_file = true; } } if (param0.type.type_special_kind == SemanticTree.type_special_kind.binary_file && parameters.expressions.Count > 1 //это можно внести во внутрь )//и побросать приличные исключения { if (!SystemLibrary.SystemLibInitializer.read_procedure.FromDll) { if (si == SystemLibrary.SystemLibInitializer.read_procedure.SymbolInfo) { file = param0; read_from_binary_file = true; } } else if (SystemLibrary.SystemLibInitializer.read_procedure.Equal(si)) { file = param0; read_from_binary_file = true; } } } read_from_file = read_from_text_file || read_from_typed_file || read_from_binary_file; } bool first_iteration = true; foreach (SyntaxTree.expression ex in parameters.expressions) { if (first_iteration && read_from_file) { first_iteration = false; continue; } if (last_call != null && convertion_data_and_alghoritms.statement_list_stack.size > 0) convertion_data_and_alghoritms.statement_list_stack.top().statements.AddElement(last_call); expression_node en = convert_strong(ex); check_on_loop_variable(en); //if (en.type == null) //throw new CanNotRead(en.location); exl.clear(); if (read_from_file) exl.AddElement(file); if (read_from_typed_file) { if (SystemLibrary.SystemLibInitializer.TypedFileReadProcedure == null) AddError(new NotSupportedError(loc)); if (en.type != file.type.element_type) AddError(new ExpectedExprHaveTypeTypedFile(file.type.element_type, en.type, true, get_location(ex))); bool is_char_getter = false; if (!en.is_addressed) { if (en is compiled_function_call) { compiled_function_call cfc = en as compiled_function_call; if ((cfc.function_node.return_value_type == SystemLibrary.SystemLibrary.char_type && cfc.function_node.cont_type == SystemLibrary.SystemLibrary.string_type && cfc.function_node == cfc.function_node.cont_type.default_property_node.get_function)) { en = new simple_array_indexing((en as compiled_function_call).obj, (en as compiled_function_call).parameters[0], SystemLibrary.SystemLibrary.char_type, en.location); is_char_getter = true; } } } function_node fn = convertion_data_and_alghoritms.select_function(exl, SystemLibrary.SystemLibInitializer.TypedFileReadProcedure.SymbolInfo, loc); expression_node expr = convertion_data_and_alghoritms.create_simple_function_call(fn, get_location(ex), file); //expression_node expr = convertion_data_and_alghoritms.create_full_function_call(exl, SystemLibrary.SystemLibInitializer.TypedFileReadProcedure.SymbolInfo, loc, context.converted_type, context.top_function, true); expr = convertion_data_and_alghoritms.explicit_convert_type(expr, file.type.element_type); if (is_char_getter) expr = convertion_data_and_alghoritms.create_simple_function_call(SystemLibrary.SystemLibInitializer.StringDefaultPropertySetProcedure.sym_info as function_node, loc, (en as simple_array_indexing).simple_arr_expr, (en as simple_array_indexing).ind_expr, expr); else expr = find_operator(compiler_string_consts.assign_name, en, expr, loc); last_call = expr; } else if (read_from_binary_file) { if (SystemLibrary.SystemLibInitializer.BinaryFileReadProcedure == null) AddError(new NotSupportedError(loc)); if (!CanUseThisTypeForBinaryFiles(en.type)) { AddError(en.location, "CAN_NOT_READ_REFERENCE_DATA_FROM_BINARY_FILE"); } exl.AddElement(new typeof_operator(en.type, loc)); function_node fn = convertion_data_and_alghoritms.select_function(exl, SystemLibrary.SystemLibInitializer.BinaryFileReadProcedure.SymbolInfo, loc); expression_node expr = convertion_data_and_alghoritms.create_simple_function_call(fn, get_location(ex), exl.ToArray()); expr = convertion_data_and_alghoritms.explicit_convert_type(expr, en.type); expr = find_operator(compiler_string_consts.assign_name, en, expr, loc); last_call = expr; } else { exl.AddElement(en); try { function_node fn = null; if (en.type.type_special_kind == SemanticTree.type_special_kind.short_string) { exl.AddElement(new int_const_node((en.type as short_string_type_node).Length,null)); if (!read_from_file) last_call = convertion_data_and_alghoritms.create_simple_function_call(SystemLibrary.SystemLibInitializer.read_short_string_procedure.sym_info as function_node,get_location(ex),exl.ToArray()); else last_call = convertion_data_and_alghoritms.create_simple_function_call(SystemLibrary.SystemLibInitializer.read_short_string_from_file_procedure.sym_info as function_node,get_location(ex),exl.ToArray()); } else if (en.type.type_special_kind == SemanticTree.type_special_kind.diap_type) { exl.remove(en); en.type = en.type.base_type; exl.AddElement(en); fn = convertion_data_and_alghoritms.select_function(exl, SystemLibrary.SystemLibInitializer.read_procedure.SymbolInfo, loc); last_call = convertion_data_and_alghoritms.create_simple_function_call(fn, get_location(ex), exl.ToArray()); } else { if (SystemLibrary.SystemLibInitializer.readln_procedure.Equal(si) && parameters.expressions.Count == 2 && en.type == SystemLibrary.SystemLibrary.string_type) { fn = convertion_data_and_alghoritms.select_function(exl, SystemLibrary.SystemLibInitializer.readln_procedure.SymbolInfo, loc); readln_string_file = true; } else fn = convertion_data_and_alghoritms.select_function(exl, SystemLibrary.SystemLibInitializer.read_procedure.SymbolInfo, loc); last_call = convertion_data_and_alghoritms.create_simple_function_call(fn, get_location(ex), exl.ToArray()); } //last_call = convertion_data_and_alghoritms.create_full_function_call(exl, SystemLibrary.SystemLibInitializer.read_procedure.SymbolInfo, loc, context.converted_type, context.top_function, true); } catch (NoFunctionWithSameArguments) { AddError(en.location, "CAN_NOT_READ"); } } first_iteration = false; } } if ((parameters == null) || (parameters.expressions.Count == 0)) // read(), readln() { if (SystemLibrary.SystemLibInitializer.read_procedure.Equal(si)) { if (read_from_file) exl.AddElement(file); function_node fn = convertion_data_and_alghoritms.select_function(exl, SystemLibrary.SystemLibInitializer.read_procedure.SymbolInfo, loc); if (read_from_file) last_call = convertion_data_and_alghoritms.create_simple_function_call(fn, loc, file); else last_call = convertion_data_and_alghoritms.create_simple_function_call(fn, loc); } } if (SystemLibrary.SystemLibInitializer.readln_procedure.Equal(si)) // readln(...) { if (!readln_string_file) { if (last_call != null && convertion_data_and_alghoritms.statement_list_stack.size > 0) convertion_data_and_alghoritms.statement_list_stack.top().statements.AddElement(last_call); exl.clear(); if (read_from_file) exl.AddElement(file); function_node fn = convertion_data_and_alghoritms.select_function(exl, SystemLibrary.SystemLibInitializer.readln_procedure.SymbolInfo, loc); if (read_from_file) last_call = convertion_data_and_alghoritms.create_simple_function_call(fn, loc, file); else last_call = convertion_data_and_alghoritms.create_simple_function_call(fn, loc); } } return last_call; }
public SymbolInfo ConvertTypeToInstance(SymbolInfo si, List<SyntaxTree.type_definition> type_pars, location loc) { if (si == null) return null; template_class tclass = si.sym_info as template_class; if (tclass == null) { generic_indicator gi = si.sym_info as generic_indicator; if (gi != null) { AddError(loc, "TYPE_{0}_HAS_{1}_GENERIC_PARAMETERS", gi.generic.name, gi.generic.generic_params.Count); } return null; } //Формируем список параметров инстанцирования List<type_node> tparams = visit_type_list(type_pars); type_node t = instance_any(tclass, tparams, loc); return new SymbolInfo(t); }
private expression_node create_static_expression(type_node tn, SyntaxTree.ident id_right, SymbolInfo si_right) { definition_node dn = context.check_name_node_type(id_right.name, si_right, get_location(id_right), general_node_type.variable_node, general_node_type.function_node, general_node_type.property_node, general_node_type.constant_definition); switch (dn.general_node_type) { case general_node_type.variable_node: { return create_class_static_field_reference(tn, dn, id_right); } case general_node_type.constant_definition: { constant_definition_node cdn = (constant_definition_node)dn; return cdn.const_value.get_constant_copy(get_location(id_right)); } case general_node_type.function_node: { //TODO: Передается пустой список выражений. /* function_node fn=convertion_data_and_alghoritms.select_function(new expressions_list(), si_right,get_location(id_right)); return create_static_method_call(fn,get_location(id_right),tn,false); */ //if (!(si_right.sym_info is common_in_function_function_node)) if (dn is compiled_function_node) { if ((dn as compiled_function_node).ConnectedToType == tn) AddError(new UndefinedNameReference(id_right.name, get_location(id_right))); } else if (dn is common_namespace_function_node) { if ((dn as common_namespace_function_node).ConnectedToType == tn) AddError(new UndefinedNameReference(id_right.name, get_location(id_right))); } if (dn.semantic_node_type == semantic_node_type.indefinite_definition_node) { return new indefinite_reference(dn as indefinite_definition_node, get_location(id_right)); } return make_delegate_wrapper(null, si_right, get_location(id_right), true); } case general_node_type.property_node: { property_node pn = (property_node)dn; if (pn.polymorphic_state != SemanticTree.polymorphic_state.ps_static) { AddError(new CanNotReferenceToNonStaticPropertyWithType(pn, get_location(id_right), tn)); } function_node fn = pn.get_function; if (fn == null) { AddError(new ThisPropertyCanNotBeReaded(pn, get_location(id_right))); } location lloc = get_location(id_right); check_property_no_params(pn, lloc); return create_static_method_call(fn, lloc, tn, false); } } throw new CompilerInternalError("Error in creating static expression."); }
public void lambda_header_visit(SymbolInfo si, SyntaxTree.function_header _function_header, type_node tn1) { type_node tn = null; if (_function_header.return_type == null) { if (context.top_function.IsOperator) AddError(get_location(_function_header), "FUNCTION_NEED_RETURN_TYPE"); } if (_function_header.return_type != null) { check_parameter_on_complex_type(_function_header.return_type); if (tn1 != null) tn = tn1; else tn = convert_strong(_function_header.return_type); //if (tn == SystemLibrary.SystemLibrary.void_type) // AddError(new VoidNotValid(get_location(_function_header.return_type))); check_for_type_allowed(tn, get_location(_function_header.return_type)); } //(ssyy) moved up, так как при проверке аттрибута override надо знать тип возвращаемого значения context.top_function.return_value_type = tn; assign_doc_info(context.top_function, _function_header); if (_function_header.attributes != null) { make_attributes_for_declaration(_function_header, context.top_function); } if (context.converted_type != null && has_dll_import_attribute(context.top_function)) AddError(get_dll_import_attribute(context.top_function).location, "DLLIMPORT_ATTRIBUTE_CANNOT_BE_APPLIED_TO_METHOD"); if (_function_header.name.class_name != null) with_class_name = true; if (_function_header.class_keyword && !has_static_attr(_function_header.proc_attributes.proc_attributes)) { SyntaxTree.procedure_attribute pa = new SyntaxTree.procedure_attribute(PascalABCCompiler.SyntaxTree.proc_attribute.attr_static); pa.source_context = _function_header.source_context; _function_header.proc_attributes.proc_attributes.Add(pa); } weak_node_test_and_visit(_function_header.proc_attributes); if (context.top_function.IsOperator) { common_method_node cmmn = context.top_function as common_method_node; //if (cmmn == null) //{ // throw new OverloadOperatorMustBeStaticFunction(get_location(_function_header), context.top_function); //} if (cmmn != null && cmmn.polymorphic_state != SemanticTree.polymorphic_state.ps_static) { AddError(get_location(_function_header), "OVERLOADED_OPERATOR_MUST_BE_STATIC_FUNCTION"); } if (cmmn != null && (cmmn.name == compiler_string_consts.implicit_operator_name || cmmn.name == compiler_string_consts.explicit_operator_name)) if (!convertion_data_and_alghoritms.eq_type_nodes(tn, cmmn.comperehensive_type as type_node) && !convertion_data_and_alghoritms.eq_type_nodes(cmmn.comperehensive_type as type_node, cmmn.parameters[0].type)) { AddError(get_location(_function_header.return_type), "RETURN_VALUE_SHOULD_HAVE_TYPE_{0}", (cmmn.comperehensive_type as type_node).PrintableName); } else if (convertion_data_and_alghoritms.eq_type_nodes(tn, cmmn.parameters[0].type)) { AddError(get_location(_function_header), "CIRCURAL_TYPE_CONVERSION_DEFINITION"); } } with_class_name = false; if (context.top_function != null && context.top_function is common_namespace_function_node && (context.top_function as common_namespace_function_node).ConnectedToType != null && !context.top_function.IsOperator) { concrete_parameter_type cpt = concrete_parameter_type.cpt_none; SemanticTree.parameter_type pt = PascalABCCompiler.SemanticTree.parameter_type.value; if ((context.top_function as common_namespace_function_node).ConnectedToType.is_value_type) { cpt = concrete_parameter_type.cpt_var; pt = PascalABCCompiler.SemanticTree.parameter_type.var; } common_parameter cp = new common_parameter(compiler_string_consts.self_word, (context.top_function as common_namespace_function_node).ConnectedToType, pt, context.top_function, cpt, null, null); context.top_function.parameters.AddElementFirst(cp); context.top_function.scope.AddSymbol(compiler_string_consts.self_word, new SymbolInfo(cp)); } CheckOverrideOrReintroduceExpectedWarning(get_location(_function_header)); bool unique = context.close_function_params(body_exists); if (context.top_function.return_value_type == null) AddError(get_location(_function_header), "FUNCTION_NEED_RETURN_TYPE"); if (_function_header.where_defs != null) { if (unique) { visit_where_list(_function_header.where_defs); } else { AddError(get_location(_function_header.where_defs), "WHERE_SECTION_MUST_BE_ONLY_IN_FIRST_DECLARATION"); } } convertion_data_and_alghoritms.create_function_return_variable(context.top_function, si); /*if (_function_header.name != null && context.converted_compiled_type != null && context.top_function is common_namespace_function_node) { if (context.FindMethodToOverride(context.top_function as common_namespace_function_node) != null) AddError(new CanNotDeclareExtensionMethodAsOverrided(get_location(_function_header))); }*/ //TODO: Разобрать подробнее. if (!body_exists) { if ((context.top_function.semantic_node_type == semantic_node_type.common_method_node) || ((context.func_stack_size_is_one()) && (_is_interface_part))) { context.leave_block(); } } body_exists = false; }
private expression_node expression_value_reciving(SyntaxTree.ident id_right, SymbolInfo si, expression_node en, bool expected_delegate) { definition_node dn = context.check_name_node_type(id_right.name, si, get_location(id_right), general_node_type.variable_node, general_node_type.function_node, general_node_type.property_node, general_node_type.constant_definition); switch (dn.general_node_type) { /*case general_node_type.constant_defenition: { constant_definition_node cdn=(constant_definition_node)dn; return cdn.const_value; }*/ case general_node_type.variable_node: { return create_class_field_reference(en, dn, id_right); } case general_node_type.function_node: { if (dn.semantic_node_type == semantic_node_type.indefinite_definition_node) { return new indefinite_reference(dn as indefinite_definition_node, get_location(id_right)); } if (expected_delegate) return make_delegate_wrapper(en, si, get_location(id_right), false); else { function_node fn = convertion_data_and_alghoritms.select_function(new expressions_list(), si, get_location(id_right)); return create_not_static_method_call(fn, en, get_location(id_right), false); } } case general_node_type.property_node: { property_node pn = (property_node)dn; if (pn.polymorphic_state == SemanticTree.polymorphic_state.ps_static) { AddError(new CanNotReferenceToStaticPropertyWithExpression(pn, get_location(id_right), pn.comprehensive_type)); } function_node fn = pn.get_function; if (fn == null) { AddError(new ThisPropertyCanNotBeReaded(pn, get_location(id_right))); } location lloc = get_location(id_right); check_property_no_params(pn, lloc); return create_not_static_method_call(fn, en, lloc, false); } case general_node_type.constant_definition: { //throw new ConstMemberCannotBeAccessedWithAnInstanceReference((class_constant_definition)dn, get_location(id_right)); return ((constant_definition_node)dn).const_value; } } throw new CompilerInternalError("Invalid class member"); }
internal SymbolInfo get_function_instances(SymbolInfo si, List<SyntaxTree.type_definition> type_pars, string name, location loc, bool stop_on_error) { List<type_node> tparams = visit_type_list(type_pars); for (int i = 0; i < tparams.Count; i++) { CompilationErrorWithLocation err = generic_parameter_eliminations.check_type_generic_useful(tparams[i], loc); if (err != null) { AddError( err); } } SymbolInfo start = null; SymbolInfo tek = null; while (si != null) { function_node fn = si.sym_info as function_node; if (fn != null) { function_node inst = fn.get_instance(tparams, stop_on_error, loc); if (inst != null) { SymbolInfo s = new SymbolInfo(inst); if (start == null) { start = tek = s; } else { tek.Next = s; tek = s; } } } si = si.Next; } if (start == null) { AddError(loc, "NO_FUNCTIONS_{0}_CAN_BE_USED_WITH_THIS_SPECIFICATION", name); } return start; }
public override void add_generated_name(string name, SymbolInfo si) { //ничего не делаем }
private SymbolInfo get_generic_functions(SymbolInfo funcs, bool stop_on_none, location loc) { SymbolInfo start = null; SymbolInfo cur = null; while (funcs != null) { function_node f = funcs.sym_info as function_node; if (f.is_generic_function) { //Проверяем на совпадение bool found = false; SymbolInfo fsi = start; while (fsi != null && fsi != funcs) { if (convertion_data_and_alghoritms.function_eq_params(fsi.sym_info as function_node, f)) { found = true; break; } fsi = fsi.Next; } if (!found) { if (start == null) { start = funcs; } else { cur.Next = funcs; } cur = funcs; } } funcs = funcs.Next; } if (start == null) { if (stop_on_none) { AddError(loc, "TRIANGLE_BRACKETS_NOT_ALLOWED_WITH_COMMON_FUNCTIONS"); } return null; } cur.Next = null; return start; }