private void VisitCompiledStaticMethodCall(compiled_static_method_call en) { for (int i = 0; i < en.parameters.Count; i++) { VisitExpression(en.parameters[i]); } }
public override void visit(SyntaxTree.bin_expr _bin_expr) { expression_node left = convert_strong(_bin_expr.left); expression_node right = convert_strong(_bin_expr.right); expression_node res = find_operator(_bin_expr.operation_type, left, right, get_location(_bin_expr)); //ssyy, 15.05.2009 switch (_bin_expr.operation_type) { case PascalABCCompiler.SyntaxTree.Operators.Equal: case PascalABCCompiler.SyntaxTree.Operators.NotEqual: if (left.type.is_generic_parameter && right.type.is_generic_parameter) { compiled_static_method_call cfc = new compiled_static_method_call( SystemLibrary.SystemLibrary.object_equals_method, get_location(_bin_expr)); cfc.parameters.AddElement(left); cfc.parameters.AddElement(right); if (_bin_expr.operation_type == PascalABCCompiler.SyntaxTree.Operators.NotEqual) { res = new basic_function_call(SystemLibrary.SystemLibrary.bool_not as basic_function_node, get_location(_bin_expr), cfc); } else { res = cfc; } } else if (left is static_event_reference) { if ((left as static_event_reference).en is compiled_event) AddError(left.location, "EVENT_{0}_MUST_BE_IN_LEFT_PART", (left as static_event_reference).en.name); if (context.converted_type != null && context.converted_type != ((left as static_event_reference).en as common_event).cont_type) AddError(left.location, "EVENT_{0}_MUST_BE_IN_LEFT_PART", (left as static_event_reference).en.name); } else if (right is static_event_reference) { if ((right as static_event_reference).en is compiled_event) AddError(right.location, "EVENT_{0}_MUST_BE_IN_LEFT_PART", (right as static_event_reference).en.name); if (context.converted_type != null && context.converted_type != ((right as static_event_reference).en as common_event).cont_type) AddError(right.location, "EVENT_{0}_MUST_BE_IN_LEFT_PART", (right as static_event_reference).en.name); } break; } return_value(res); }
public static expression_node set_multassign_executor(location call_location, params expression_node[] parameters) { //return inline_assign_operator(SystemLibrary._byte_plusassign, SystemLibrary.byte_assign, SystemLibrary.int_add, call_location, parameters); if (!SemanticRules.UseExtendedAssignmentOperatorsForPrimitiveTypes) SystemLibrary.syn_visitor.AddError(new OperatorCanNotBeAppliedToThisType(compiler_string_consts.plusassign_name, parameters[0])); //basic_function_call operationc = new basic_function_call((basic_function_node)operation, call_location); base_function_call cnfc = null; if (SystemLibInitializer.SetIntersectProcedure.sym_info is common_namespace_function_node) cnfc = new common_namespace_function_call(SystemLibInitializer.SetIntersectProcedure.sym_info as common_namespace_function_node, call_location); else cnfc = new compiled_static_method_call(SystemLibInitializer.SetIntersectProcedure.sym_info as compiled_function_node, call_location); cnfc.parameters.AddElement(parameters[0]); cnfc.parameters.AddElement(parameters[1]); //operationc.parameters.AddElement(SystemLibrary.syn_visitor.convertion_data_and_alghoritms.convert_type(parameters[1], parameters[0].type)); basic_function_call assignc = new basic_function_call(parameters[0].type.find_in_type(compiler_string_consts.assign_name).sym_info as basic_function_node, call_location); assignc.parameters.AddElement(parameters[0]); assignc.parameters.AddElement(cnfc); //assignc.parameters.AddElement(SystemLibrary.syn_visitor.convertion_data_and_alghoritms.convert_type(operationc, parameters[0].type)); return assignc; }
private void VisitCompiledStaticMethodCall(compiled_static_method_call expr) { WriteCompiledMethod(expr.function_node); bw.Write(expr.template_parametres_list.Count); foreach (type_node tn in expr.template_parametres_list) WriteTypeReference(tn); bw.Write(expr.parameters.Count); foreach (expression_node e in expr.parameters) VisitExpression(e); }
private static expression_node set_length_compile_time_executor(location call_location, params expression_node[] pars) { array_internal_interface aii = (array_internal_interface) pars[0].type.get_internal_interface(PascalABCCompiler.TreeRealization.internal_interface_kind.unsized_array_interface); if (aii == null) { throw new SimpleSemanticError(call_location, "CAN_NOT_APPLY_SETLENGTH_TO_THIS_OPERAND_TYPE"); } compiled_static_method_call csmc = new compiled_static_method_call(_resize_func, call_location); csmc.parameters.AddRange(pars); csmc.template_parametres_list.AddElement(aii.element_type); return csmc; }
private base_function_call create_not_static_method_call(function_node fn, expression_node en, location loc, bool procedure_allowed) { try_convert_typed_expression_to_function_call(ref en); if ((!procedure_allowed) && (fn.return_value_type == null)) { AddError(loc, "FUNCTION_EXPECTED_PROCEDURE_{0}_MEET", fn); } if (fn.semantic_node_type == semantic_node_type.common_method_node) { common_method_node cmn = (common_method_node)fn; if (cmn.is_constructor) { AddError(loc, "CAN_NOT_CALL_CONSTRUCTOR_AS_PROCEDURE"); } if (cmn.original_function != null && cmn.original_function is compiled_function_node && (cmn.original_function as compiled_function_node).ConnectedToType != null) { common_static_method_call csmc = new common_static_method_call(cmn, loc); return csmc; } if (cmn.polymorphic_state == SemanticTree.polymorphic_state.ps_static) { AddError(new CanNotCallStaticMethodWithExpression(en, fn)); } common_method_call cmc = new common_method_call(cmn, en, loc); cmc.virtual_call = !inherited_ident_processing; return cmc; } if (fn.semantic_node_type == semantic_node_type.compiled_function_node) { compiled_function_node cfn = (compiled_function_node)fn; if (cfn.ConnectedToType != null) { compiled_static_method_call csmc = new compiled_static_method_call(cfn, loc); return csmc; } else { if (cfn.polymorphic_state == SemanticTree.polymorphic_state.ps_static) { if (!cfn.is_extension_method) AddError(new CanNotCallStaticMethodWithExpression(en, fn)); else return new compiled_static_method_call(cfn, loc); } compiled_function_call cfc = new compiled_function_call(cfn, en, loc); cfc.virtual_call = !inherited_ident_processing; return cfc; } } if (fn.semantic_node_type == semantic_node_type.compiled_constructor_node) { AddError(loc, "CAN_NOT_CALL_CONSTRUCTOR_AS_PROCEDURE"); } if (fn.semantic_node_type == semantic_node_type.common_namespace_function_node && (fn as common_namespace_function_node).ConnectedToType != null) { common_namespace_function_call cnfc = new common_namespace_function_call(fn as common_namespace_function_node,loc); //cnfc.parameters.AddElement(en); return cnfc; } if (fn.semantic_node_type == semantic_node_type.indefinite_definition_node) { indefinite_function_call ifc = new indefinite_function_call(fn, loc); return ifc; } throw new CompilerInternalError("Invalid method kind"); }
private 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 override void visit(SyntaxTree.pascal_set_constant _pascal_set_constant) { //throw new NotSupportedError(get_location(_pascal_set_constant)); if (SystemLibrary.SystemLibInitializer.TypedSetType == null || SystemLibrary.SystemLibInitializer.CreateSetProcedure == null) AddError(new NotSupportedError(get_location(_pascal_set_constant))); expressions_list consts = new expressions_list(); type_node el_type = null; type_node_list types = new type_node_list(); if (_pascal_set_constant.values != null && _pascal_set_constant.values != null) foreach (SyntaxTree.expression e in _pascal_set_constant.values.expressions) { if (e is SyntaxTree.nil_const) ErrorsList.Add(new SimpleSemanticError(get_location(e), "NIL_IN_SET_CONSTRUCTOR_NOT_ALLOWED")); else if (e is SyntaxTree.diapason_expr) { consts.AddElement(convert_diap_for_set((e as SyntaxTree.diapason_expr), out el_type)); if (el_type.IsPointer) ErrorsList.Add(new SimpleSemanticError(get_location(e), "POINTERS_IN_SETS_NOT_ALLOWED")); types.AddElement(el_type); } else { expression_node en = convert_strong(e); if (en is typed_expression) en = convert_typed_expression_to_function_call(en as typed_expression); if (en.type.type_special_kind == SemanticTree.type_special_kind.short_string) en.type = SystemLibrary.SystemLibrary.string_type; consts.AddElement(en); types.AddElement(en.type); } } expressions_list consts_copy = new expressions_list(); consts_copy.AddRange(consts); type_node ctn = null; if (consts.Count > 0) { el_type = convertion_data_and_alghoritms.select_base_type(types); ctn = context.create_set_type(el_type, get_location(_pascal_set_constant)); } else ctn = SystemLibrary.SystemLibInitializer.TypedSetType.sym_info as type_node; function_node fn = convertion_data_and_alghoritms.select_function(consts, SystemLibrary.SystemLibInitializer.CreateSetProcedure.SymbolInfo, (SystemLibrary.SystemLibInitializer.CreateSetProcedure.sym_info is common_namespace_function_node)?(SystemLibrary.SystemLibInitializer.CreateSetProcedure.sym_info as common_namespace_function_node).loc:null); if (fn is common_namespace_function_node) { common_namespace_function_call cnfc = new common_namespace_function_call(fn as common_namespace_function_node, get_location(_pascal_set_constant)); add_set_initializer(cnfc, consts_copy); cnfc.ret_type = ctn; for (int i = 0; i < consts.Count; i++) cnfc.parameters.AddElement(consts[i]); return_value(cnfc); } else { compiled_static_method_call cnfc = new compiled_static_method_call(fn as compiled_function_node, get_location(_pascal_set_constant)); add_set_initializer(cnfc, consts_copy); cnfc.ret_type = ctn; for (int i = 0; i < consts.Count; i++) cnfc.parameters.AddElement(consts[i]); return_value(cnfc); } //return_value(new common_namespace_function_call_as_constant(cnfc,cnfc.location)); }
public void create_main_function(string[] used_stand_modules, Dictionary<string, object> config) { add_needed_cctors(); common_namespace_function_node temp = _main_function; _main_function = new common_namespace_function_node("Main", null, null, (common_namespace_node)_main_function.comprehensive_namespace, null); location loc = temp.loc; statements_list sl = new statements_list(loc); _main_function.function_code = sl; // if (units[0].MainArgsParameter!=null) // { // _main_function.parameters.AddElement(units[0].MainArgsParameter); // sl.statements.AddElement(units[0].MainArgsAssignExpr); // } // if (units[0].IsConsoleApplicationVariableAssignExpr!=null) // { // sl.statements.AddElement(units[0].IsConsoleApplicationVariableAssignExpr); // } statements_list sl2 = sl; sl = new statements_list(null); common_namespace_function_node init_func = new common_namespace_function_node("$_Init_",null,null,(common_namespace_node)_main_function.comprehensive_namespace,null); ((common_namespace_node)_main_function.comprehensive_namespace).functions.AddElement(init_func); namespace_variable init_var = new namespace_variable("$is_init",SystemLibrary.SystemLibrary.bool_type,(common_namespace_node)_main_function.comprehensive_namespace,null); ((common_namespace_node)_main_function.comprehensive_namespace).variables.AddElement(init_var); if (SystemLibrary.SystemLibInitializer.ConfigVariable.Found) { namespace_variable conf_nv = null; compiled_variable_definition conf_cf = null; if (SystemLibrary.SystemLibInitializer.ConfigVariable.sym_info is namespace_variable) conf_nv = SystemLibrary.SystemLibInitializer.ConfigVariable.sym_info as namespace_variable; else conf_cf = SystemLibrary.SystemLibInitializer.ConfigVariable.sym_info as compiled_variable_definition; foreach (string config_var in config.Keys) { var config_value = config[config_var]; compiled_function_call cfc = new compiled_function_call(compiled_function_node.get_compiled_method(NetHelper.NetHelper.AddToDictionaryMethod), (conf_nv != null) ? (expression_node)new namespace_variable_reference(conf_nv, null) : (expression_node)new static_compiled_variable_reference(conf_cf, null), null); cfc.parameters.AddElement(new string_const_node(config_var, null)); switch (Type.GetTypeCode(config_value.GetType())) { case TypeCode.String: cfc.parameters.AddElement(new string_const_node((string)config_value, null)); break; case TypeCode.Int32: cfc.parameters.AddElement(new int_const_node((int)config_value, null)); break; case TypeCode.Boolean: cfc.parameters.AddElement(new bool_const_node((bool)config_value, null)); break; case TypeCode.Double: cfc.parameters.AddElement(new double_const_node((double)config_value, null)); break; default: throw new NotSupportedException("Config value type is nort supported"); } sl.statements.AddElement(cfc); } } if (units[0].MainArgsParameter!=null) { _main_function.parameters.AddElement(units[0].MainArgsParameter); sl.statements.AddElementFirst(units[0].MainArgsAssignExpr); } if (units[0].IsConsoleApplicationVariableAssignExpr!=null) { sl.statements.AddElementFirst(units[0].IsConsoleApplicationVariableAssignExpr); } for (int i = 0; i < units.Count; i++) { if (units[i].main_function != null) { if (units[i].main_function.name != TreeConverter.compiler_string_consts.temp_main_function_name) { common_namespace_function_call cnfc = new common_namespace_function_call(units[i].main_function, loc); sl.statements.AddElement(cnfc); } else { common_namespace_function_call cnfc = new common_namespace_function_call(units[i].main_function, loc); sl2.statements.AddElement(cnfc); } } } //if (units.Count == 1) for (int i = 0; i < used_stand_modules.Length; i++) { Type t = NetHelper.NetHelper.FindRtlType(used_stand_modules[i] + "." + used_stand_modules[i]); if (t == null) continue; compiled_type_node ctn = compiled_type_node.get_type_node(t); System.Reflection.MethodInfo mi = ctn.compiled_type.GetMethod("__InitModule__"); if (mi == null) { continue; } compiled_static_method_call csmc = new compiled_static_method_call(compiled_function_node.get_compiled_method(mi), null); sl.statements.AddElement(csmc); } for (int i = units.Count - 1; i >= 0; i--) { if (units[i].finalization_method != null) { common_namespace_function_call cnfc = new common_namespace_function_call(units[i].finalization_method, loc); sl2.statements.AddElement(cnfc); } } //if (units.Count == 1) for (int i = 0; i < used_stand_modules.Length; i++) { Type t = NetHelper.NetHelper.FindRtlType(used_stand_modules[i] + "." + used_stand_modules[i]); if (t == null) continue; compiled_type_node ctn = compiled_type_node.get_type_node(t); System.Reflection.MethodInfo mi = ctn.compiled_type.GetMethod("__FinalizeModule__"); if (mi == null) continue; compiled_static_method_call csmc = new compiled_static_method_call(compiled_function_node.get_compiled_method(mi), null); sl2.statements.AddElement(csmc); } sl2 = new statements_list(loc); basic_function_call bfc = new basic_function_call(SystemLibrary.SystemLibrary.bool_assign as basic_function_node,null); bfc.parameters.AddElement(new namespace_variable_reference(init_var,null)); bfc.parameters.AddElement(new bool_const_node(true,null)); sl.statements.AddElementFirst(bfc); bfc = new basic_function_call(SystemLibrary.SystemLibrary.bool_not as basic_function_node,null); bfc.parameters.AddElement(new namespace_variable_reference(init_var,null)); sl2.statements.AddElement(new if_node(bfc,sl,null,null)); init_func.function_code = sl2; sl = new statements_list(null); sl.statements.AddElement(new common_namespace_function_call(init_func,null)); common_namespace_function_node init_variables_func = new common_namespace_function_node("$_InitVariables_", null, null, (common_namespace_node)_main_function.comprehensive_namespace, null); init_variables_func.function_code = new statements_list(null); ((common_namespace_node)_main_function.comprehensive_namespace).functions.AddElement(init_variables_func); sl.statements.AddElement(new common_namespace_function_call(init_variables_func,null)); _init_code = sl; }
public expression_node convert_delegates_to_delegates(location call_location, expression_node[] parameters) { if (parameters.Length != 1) { throw new PascalABCCompiler.TreeConverter.CompilerInternalError("Invalid delegates convertion"); } delegate_internal_interface dii_to= (delegate_internal_interface)_to.get_internal_interface(internal_interface_kind.delegate_interface); delegate_internal_interface dii = (delegate_internal_interface)parameters[0].type.get_internal_interface(internal_interface_kind.delegate_interface); expression_node pr = parameters[0]; base_function_call ifnotnull = null; if (_to.semantic_node_type == semantic_node_type.compiled_type_node) { ifnotnull = new compiled_constructor_call((compiled_constructor_node)dii_to.constructor, call_location); } else { ifnotnull = new common_constructor_call((common_method_node)dii_to.constructor, call_location); } //ccc = new common_constructor_call(dii_to.constructor, call_location); expression_node par = null; if (parameters[0].type.semantic_node_type == semantic_node_type.compiled_type_node) { par = new compiled_function_call((compiled_function_node)dii.invoke_method, parameters[0], call_location); } else { par = new common_method_call((common_method_node)dii.invoke_method, parameters[0], call_location); } ifnotnull.parameters.AddElement(par); null_const_node ncn = new null_const_node(_to, call_location); null_const_node ncn2 = new null_const_node(_to, call_location); PascalABCCompiler.TreeConverter.SymbolInfo si = pr.type.find_in_type(PascalABCCompiler.TreeConverter.compiler_string_consts.eq_name); basic_function_node fn = si.sym_info as basic_function_node; expression_node condition = null; if (fn != null) { basic_function_call condition_bfc = new basic_function_call(fn, call_location); condition_bfc.parameters.AddElement(pr); condition_bfc.parameters.AddElement(ncn); condition = condition_bfc; } else if (si.sym_info is compiled_function_node) { compiled_static_method_call condition_cfc = new compiled_static_method_call(si.sym_info as compiled_function_node, call_location); condition_cfc.parameters.AddElement(pr); condition_cfc.parameters.AddElement(ncn); condition = condition_cfc; } question_colon_expression qce = new question_colon_expression(condition, ncn2, ifnotnull, call_location); return qce; }
private static bool GenerateOMPParallelForCall(statement_node body, SyntaxTree.for_node for_node, var_definition_node loop_variable, statements_list omp_stmts, syntax_tree_visitor syntax_tree_visitor, expression_node fromInclusive, expression_node toInclusive) { SyntaxTree.statement syntax_body = for_node.statements; expression_node omp_call = null; base_function_call bfc = body as base_function_call; if (bfc != null && bfc.parameters.Count == 1 && bfc.parameters[0] is variable_reference && ((variable_reference)bfc.parameters[0]).VariableDefinition == loop_variable && ((bfc.function.parameters[0].type as type_node).PrintableName.ToLower() == "integer")) { //если тело цикла - вызов функции с одни параметром - переменной цикла, //если при этом у вызываемой функции тип параметра - integer, а не какой-нибудь object, как это бывает с write и вообще может быть с перегрузкой //то генерировать класс не надо. //генерируем вызов и все omp_call = syntax_tree_visitor.CreateDelegateCall(bfc); if (omp_call == null) { syntax_tree_visitor.AddWarning(new OMP_ConstructionNotSupportedNow(body.location)); syntax_tree_visitor.convertion_data_and_alghoritms.statement_list_stack_pop(); return false; } base_function_call omp_parallel_for_call = null; if (SystemLibrary.SystemLibInitializer.OMP_ParallelFor.sym_info is common_namespace_function_node) omp_parallel_for_call = new common_namespace_function_call(SystemLibrary.SystemLibInitializer.OMP_ParallelFor.sym_info as common_namespace_function_node, body.location); else omp_parallel_for_call = new compiled_static_method_call(SystemLibrary.SystemLibInitializer.OMP_ParallelFor.sym_info as compiled_function_node, body.location); omp_parallel_for_call.parameters.AddElement(fromInclusive); omp_parallel_for_call.parameters.AddElement(toInclusive); omp_parallel_for_call.parameters.AddElement(omp_call); omp_stmts.statements.AddElement(omp_parallel_for_call); } else { //ищем используемые переменные, получаем редукцию из директивы и составляем список переменных по типам VarFinderSyntaxVisitor VFvis = new VarFinderSyntaxVisitor(syntax_body, syntax_tree_visitor.context, true); SyntaxTree.compiler_directive dir = syntax_tree_visitor.DirectivesToNodesLinks[for_node]; //if (DirInfosTable[dir].ErrorName == "WARNING_IN_CLAUSE_PARAMETERS_REPEATED_VARS") // syntax_tree_visitor.AddWarning(new Errors.CommonWarning(StringResources.Get(DirInfosTable[dir].ErrorName), for_node.source_context.FileName, DirInfosTable[dir].SC.begin_position.line_num, DirInfosTable[dir].SC.begin_position.column_num)); //else if (DirInfosTable[dir].ErrorName == "ERROR_IN_CLAUSE_PARAMETERS") //{ // syntax_tree_visitor.AddWarning(new Errors.CommonWarning(StringResources.Get(DirInfosTable[dir].ErrorName), for_node.source_context.FileName, DirInfosTable[dir].SC.begin_position.line_num, DirInfosTable[dir].SC.begin_position.column_num)); //} //else if (DirInfosTable[dir].ErrorName !=null)//== "ERROR_IN_CLAUSE") { syntax_tree_visitor.AddWarning(new Errors.CommonWarning(PascalABCCompiler.StringResources.Get(DirInfosTable[dir].ErrorName), for_node.source_context.FileName, DirInfosTable[dir].SC.begin_position.line_num, DirInfosTable[dir].SC.begin_position.column_num)); } VarInfoContainer Vars = GetVarInfoContainer(VFvis, DirInfosTable[dir].Reductions, DirInfosTable[dir].Privates, syntax_tree_visitor, dir); //сохраняем контекст ContextInfo contextInfo = new ContextInfo(syntax_tree_visitor); string ClassName = syntax_tree_visitor.context.get_free_name("$for_class{0}"); try { //создаем и конвертируем класс SyntaxTree.class_members member; SyntaxTree.type_declarations Decls = CreateClass(ClassName, out member, Vars); member.members.Add(CreateMethod("Method", syntax_body, for_node.loop_variable.name, member, Vars)); syntax_tree_visitor.visit(Decls); } finally { //восстанавливаем контекст contextInfo.RestoreContext(syntax_tree_visitor); } //создаем инициализацию, вызов и финализацию string ObjName = syntax_tree_visitor.context.get_free_name("$for_obj{0}"); SyntaxTree.dot_node dn = new SyntaxTree.dot_node(new SyntaxTree.ident(ObjName), new SyntaxTree.ident("Method")); SyntaxTree.statement_list stl = CreateInitPart(ClassName, ObjName, Vars); stl.subnodes.Add(CreateNestedRegionBorder(true)); stl.subnodes.Add(CreateOMPParallelForCall(dn, for_node.initial_value, for_node.finish_value)); stl.subnodes.Add(CreateNestedRegionBorder(false)); stl.subnodes.AddRange(CreateFinalPart(ObjName, Vars).subnodes); omp_stmts.statements.AddElement(syntax_tree_visitor.ret.visit(stl)); } return true; }
private void AddTypeCheckToStaticConstructor(common_type_node generic_def) { statements_list stl = new statements_list(null); GenericParameterAbilities gpa; foreach (common_type_node param in generic_def.generic_params) { if (syntax_tree_visitor.generic_param_abilities.TryGetValue(param, out gpa)) { if (gpa.useful_for_pointers) { stl.statements.AddElement(CreateTypeCheckCall(SystemLibrary.SystemLibInitializer.CheckCanUsePointerOnTypeProcedure.sym_info, param)); } if (gpa.useful_for_binary_files) { stl.statements.AddElement(CreateTypeCheckCall(SystemLibrary.SystemLibInitializer.CheckCanUseTypeForBinaryFilesProcedure.sym_info, param)); } if (gpa.useful_for_typed_files) { stl.statements.AddElement(CreateTypeCheckCall(SystemLibrary.SystemLibInitializer.CheckCanUseTypeForTypedFilesProcedure.sym_info, param)); } } if (SemanticRules.RuntimeInitVariablesOfGenericParameters) { basic_function_call bfc = new basic_function_call( SystemLibrary.SystemLibrary.byte_assign as basic_function_node, null); bfc.parameters.AddElement(new static_class_field_reference(param.runtime_initialization_marker, null)); base_function_call dcall = null; if (SystemLibrary.SystemLibInitializer.RuntimeDetermineTypeFunction.sym_info is common_namespace_function_node) dcall = new common_namespace_function_call( SystemLibrary.SystemLibInitializer.RuntimeDetermineTypeFunction.sym_info as common_namespace_function_node, null); else dcall = new compiled_static_method_call( SystemLibrary.SystemLibInitializer.RuntimeDetermineTypeFunction.sym_info as compiled_function_node, null); dcall.parameters.AddElement(new typeof_operator(param, null)); bfc.parameters.AddElement(dcall); stl.statements.AddElement(bfc); } } if (stl.statements.Count == 0) return; string stat_ctor_name = compiler_string_consts.static_ctor_prefix + compiler_string_consts.default_constructor_name; SymbolInfo si = generic_def.scope.FindOnlyInScope(stat_ctor_name); common_method_node stat_ctor; if (si == null) { stat_ctor = new common_method_node(stat_ctor_name, null, null, generic_def, SemanticTree.polymorphic_state.ps_static, SemanticTree.field_access_level.fal_public, null); stat_ctor.is_constructor = true; generic_def.add_name(stat_ctor_name, new SymbolInfo(stat_ctor)); generic_def.methods.AddElement(stat_ctor); } else { stat_ctor = si.sym_info as common_method_node; } if (stat_ctor.function_code != null) { stl.statements.AddElement(stat_ctor.function_code); } else { stl.statements.AddElement(new return_node(null, null)); } stat_ctor.function_code = stl; }
private base_function_call CreateTypeCheckCall(definition_node func, type_node tp) { if (func is common_namespace_function_node) { common_namespace_function_call cnfc = new common_namespace_function_call( func as common_namespace_function_node, null); expression_node ex = new typeof_operator(tp, null); cnfc.parameters.AddElement(ex); return cnfc; } else { compiled_static_method_call cnfc = new compiled_static_method_call( func as compiled_function_node, null); expression_node ex = new typeof_operator(tp, null); cnfc.parameters.AddElement(ex); return cnfc; } }
private expression_node clip_expression_if_need(expression_node expr, type_node tn) { if (!(tn is short_string_type_node) && tn.type_special_kind != SemanticTree.type_special_kind.set_type) return expr; if (tn is short_string_type_node) { return convertion_data_and_alghoritms.create_simple_function_call(SystemLibrary.SystemLibInitializer.ClipShortStringProcedure.sym_info as function_node,null,convertion_data_and_alghoritms.convert_type(expr,SystemLibrary.SystemLibrary.string_type),new int_const_node((tn as short_string_type_node).Length,null)); } else if (tn.type_special_kind == SemanticTree.type_special_kind.set_type && tn.element_type != null) { ordinal_type_interface oti = tn.element_type.get_internal_interface(internal_interface_kind.ordinal_interface) as ordinal_type_interface; if (oti != null) { base_function_call cmc = null; if (SystemLibrary.SystemLibInitializer.ClipFunction.sym_info is common_namespace_function_node) cmc = new common_namespace_function_call(SystemLibrary.SystemLibInitializer.ClipFunction.sym_info as common_namespace_function_node, null); else cmc = new compiled_static_method_call(SystemLibrary.SystemLibInitializer.ClipFunction.sym_info as compiled_function_node, null); cmc.parameters.AddElement(expr); cmc.parameters.AddElement(oti.lower_value.get_constant_copy(null)); cmc.parameters.AddElement(oti.upper_value.get_constant_copy(null)); cmc.ret_type = tn; return cmc; } else if (tn.element_type.type_special_kind == SemanticTree.type_special_kind.short_string) { base_function_call cmc = null; if (SystemLibrary.SystemLibInitializer.ClipShortStringInSetFunction.sym_info is common_namespace_function_node) cmc = new common_namespace_function_call(SystemLibrary.SystemLibInitializer.ClipShortStringInSetFunction.sym_info as common_namespace_function_node, null); else cmc = new compiled_static_method_call(SystemLibrary.SystemLibInitializer.ClipShortStringInSetFunction.sym_info as compiled_function_node, null); cmc.parameters.AddElement(expr); cmc.parameters.AddElement(new int_const_node((tn.element_type as short_string_type_node).Length, null)); cmc.ret_type = tn; return cmc; } } return expr; }
private compiled_static_method_call CreateCompiledStaticMethodCall() { compiled_function_node cfn = GetCompiledMethod(br.ReadInt32()); compiled_static_method_call csmc = new compiled_static_method_call(cfn,null); int num_params = br.ReadInt32(); for (int i = 0; i < num_params; i++) csmc.template_parametres_list.AddElement(GetTypeReference()); num_params = br.ReadInt32(); for (int i=0; i<num_params; i++) csmc.parameters.AddElement(CreateExpression()); return csmc; }
private expression_node convert_diap_for_set(SyntaxTree.diapason_expr _diapason_expr, out type_node elem_type) { expression_node left = convert_strong(_diapason_expr.left); if (left is typed_expression) left = convert_typed_expression_to_function_call(left as typed_expression); expression_node right = convert_strong(_diapason_expr.right); if (right is typed_expression) right = convert_typed_expression_to_function_call(right as typed_expression); internal_interface ii = left.type.get_internal_interface(internal_interface_kind.ordinal_interface); if (ii == null) { AddError(new OrdinalTypeExpected(left.location)); } internal_interface iir = right.type.get_internal_interface(internal_interface_kind.ordinal_interface); if (iir == null) { AddError(new OrdinalTypeExpected(right.location)); } type_node_list tnl = new type_node_list(); tnl.AddElement(left.type); tnl.AddElement(right.type); elem_type = convertion_data_and_alghoritms.select_base_type(tnl); expression_node l = convertion_data_and_alghoritms.explicit_convert_type(left, PascalABCCompiler.SystemLibrary.SystemLibrary.integer_type); expression_node r = convertion_data_and_alghoritms.explicit_convert_type(right, PascalABCCompiler.SystemLibrary.SystemLibrary.integer_type); if (PascalABCCompiler.SystemLibrary.SystemLibInitializer.CreateDiapason.sym_info is common_namespace_function_node) { common_namespace_function_node cnfn = PascalABCCompiler.SystemLibrary.SystemLibInitializer.CreateDiapason.sym_info as common_namespace_function_node; if (elem_type == PascalABCCompiler.SystemLibrary.SystemLibrary.char_type || elem_type == PascalABCCompiler.SystemLibrary.SystemLibrary.bool_type || elem_type.IsEnum) cnfn = PascalABCCompiler.SystemLibrary.SystemLibInitializer.CreateObjDiapason.sym_info as common_namespace_function_node; common_namespace_function_call cnfc = new common_namespace_function_call(cnfn, get_location(_diapason_expr)); if (elem_type != PascalABCCompiler.SystemLibrary.SystemLibrary.char_type && elem_type != PascalABCCompiler.SystemLibrary.SystemLibrary.bool_type && !elem_type.IsEnum) { cnfc.parameters.AddElement(l); cnfc.parameters.AddElement(r); } else { cnfc.parameters.AddElement(left); cnfc.parameters.AddElement(right); } return cnfc; } else { compiled_function_node cnfn = PascalABCCompiler.SystemLibrary.SystemLibInitializer.CreateDiapason.sym_info as compiled_function_node; if (elem_type == PascalABCCompiler.SystemLibrary.SystemLibrary.char_type || elem_type == PascalABCCompiler.SystemLibrary.SystemLibrary.bool_type || elem_type.IsEnum) cnfn = PascalABCCompiler.SystemLibrary.SystemLibInitializer.CreateObjDiapason.sym_info as compiled_function_node; compiled_static_method_call cnfc = new compiled_static_method_call(cnfn, get_location(_diapason_expr)); if (elem_type != PascalABCCompiler.SystemLibrary.SystemLibrary.char_type && elem_type != PascalABCCompiler.SystemLibrary.SystemLibrary.bool_type && !elem_type.IsEnum) { cnfc.parameters.AddElement(l); cnfc.parameters.AddElement(r); } else { cnfc.parameters.AddElement(left); cnfc.parameters.AddElement(right); } return cnfc; } }
private compiled_static_method_call create_compiled_static_method_call(compiled_function_node cfn, location loc, params expression_node[] exprs) { #if (DEBUG) if (cfn.polymorphic_state!=SemanticTree.polymorphic_state.ps_static) { throw new CompilerInternalError("Not static method can not be called as static"); } #endif compiled_static_method_call csmc=new compiled_static_method_call(cfn,loc); csmc.parameters.AddRange(exprs); return csmc; }
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"); }
internal void add_clip_for_set(common_function_node cfn) { statements_list sl = cfn.function_code as statements_list; if (sl == null) return; foreach (common_parameter prm in cfn.parameters) { if (prm.type.type_special_kind == SemanticTree.type_special_kind.set_type && prm.parameter_type == SemanticTree.parameter_type.value || prm.is_params && prm.type.element_type.type_special_kind == SemanticTree.type_special_kind.set_type) { if (!prm.is_params) { ordinal_type_interface oti = prm.type.element_type.get_internal_interface(internal_interface_kind.ordinal_interface) as ordinal_type_interface; if (oti == null) if (prm.type.element_type.type_special_kind == SemanticTree.type_special_kind.short_string) { base_function_call cmc2 = null; if (SystemLibrary.SystemLibInitializer.ClipShortStringInSetProcedure.sym_info is common_namespace_function_node) cmc2 = new common_namespace_function_call(SystemLibrary.SystemLibInitializer.ClipShortStringInSetProcedure.sym_info as common_namespace_function_node, null); else cmc2 = new compiled_static_method_call(SystemLibrary.SystemLibInitializer.ClipShortStringInSetProcedure.sym_info as compiled_function_node, null); cmc2.parameters.AddElement(new common_parameter_reference(prm,0,null)); cmc2.parameters.AddElement(new int_const_node((prm.type.element_type as short_string_type_node).Length,null)); sl.statements.AddElementFirst(cmc2); continue; } else continue; base_function_call cmc = null; if (SystemLibrary.SystemLibInitializer.ClipProcedure.sym_info is common_namespace_function_node) cmc = new common_namespace_function_call(SystemLibrary.SystemLibInitializer.ClipProcedure.sym_info as common_namespace_function_node, null); else cmc = new compiled_static_method_call(SystemLibrary.SystemLibInitializer.ClipProcedure.sym_info as compiled_function_node, null); cmc.parameters.AddElement(new common_parameter_reference(prm,0,null)); cmc.parameters.AddElement(oti.lower_value); cmc.parameters.AddElement(oti.upper_value); sl.statements.AddElementFirst(cmc); } else { var_definition_node var = context.create_for_temp_variable(prm.type.element_type,null); expression_node in_what = new common_parameter_reference(prm,0,null); statements_list what_do = new statements_list(null); ordinal_type_interface oti = prm.type.element_type.element_type.get_internal_interface(internal_interface_kind.ordinal_interface) as ordinal_type_interface; bool short_str = false; if (oti == null) if (prm.type.element_type.element_type.type_special_kind == SemanticTree.type_special_kind.short_string) { short_str = true; } else continue; base_function_call cmc = null; if (!short_str) { if (SystemLibrary.SystemLibInitializer.ClipProcedure.sym_info is common_namespace_function_node) cmc = new common_namespace_function_call(SystemLibrary.SystemLibInitializer.ClipProcedure.sym_info as common_namespace_function_node, null); else cmc = new compiled_static_method_call(SystemLibrary.SystemLibInitializer.ClipProcedure.sym_info as compiled_function_node, null); } else { if (SystemLibrary.SystemLibInitializer.ClipShortStringInSetProcedure.sym_info is common_namespace_function_node) cmc = new common_namespace_function_call(SystemLibrary.SystemLibInitializer.ClipShortStringInSetProcedure.sym_info as common_namespace_function_node, null); else cmc = new compiled_static_method_call(SystemLibrary.SystemLibInitializer.ClipShortStringInSetProcedure.sym_info as compiled_function_node, null); } if (var is local_block_variable) cmc.parameters.AddElement(new local_block_variable_reference(var as local_block_variable,null)); else cmc.parameters.AddElement(new local_variable_reference(var as local_variable,0,null)); if (!short_str) { cmc.parameters.AddElement(oti.lower_value); cmc.parameters.AddElement(oti.upper_value); } else { cmc.parameters.AddElement(new int_const_node((prm.type.element_type.element_type as short_string_type_node).Length,null)); } what_do.statements.AddElement(cmc); foreach_node fn = new foreach_node(var,in_what,what_do,null); sl.statements.AddElementFirst(fn); } } else if (prm.type.type_special_kind == SemanticTree.type_special_kind.short_string && prm.parameter_type == SemanticTree.parameter_type.value || prm.is_params && prm.type.element_type.type_special_kind == SemanticTree.type_special_kind.short_string) { if (!prm.is_params) { base_function_call cmc = null; if (SystemLibrary.SystemLibInitializer.ClipShortStringProcedure.sym_info is common_namespace_function_node) cmc = new common_namespace_function_call(SystemLibrary.SystemLibInitializer.ClipShortStringProcedure.sym_info as common_namespace_function_node, null); else cmc = new compiled_static_method_call(SystemLibrary.SystemLibInitializer.ClipShortStringProcedure.sym_info as compiled_function_node, null); cmc.parameters.AddElement(new common_parameter_reference(prm, 0, null)); cmc.parameters.AddElement(new int_const_node((prm.type as short_string_type_node).Length, null)); concrete_parameter_type tmp_cpt = prm.concrete_parameter_type; prm.concrete_parameter_type = concrete_parameter_type.cpt_none; sl.statements.AddElementFirst(find_operator(compiler_string_consts.assign_name, new common_parameter_reference(prm, 0, null), cmc, null)); prm.concrete_parameter_type = tmp_cpt; } else { common_parameter_reference cpr = new common_parameter_reference(prm, 0, null); compiled_function_node get_func = (prm.type.find_in_type("Length").sym_info as compiled_property_node).get_function as compiled_function_node; local_variable var = context.create_for_temp_variable(SystemLibrary.SystemLibrary.integer_type, null) as local_variable; local_variable len_var = context.create_for_temp_variable(SystemLibrary.SystemLibrary.integer_type, null) as local_variable; statements_list body = new statements_list(null); //compiled_property_node item_prop = prm.type.find_in_type("Item").sym_info as compiled_property_node; base_function_call cmc = null; if (SystemLibrary.SystemLibInitializer.ClipShortStringProcedure.sym_info is common_namespace_function_node) cmc = new common_namespace_function_call(SystemLibrary.SystemLibInitializer.ClipShortStringProcedure.sym_info as common_namespace_function_node, null); else cmc = new compiled_static_method_call(SystemLibrary.SystemLibInitializer.ClipShortStringProcedure.sym_info as compiled_function_node, null); expression_node cond = new basic_function_call(SystemLibrary.SystemLibrary.int_sm as basic_function_node, null, new local_variable_reference(var, 0, null), new local_variable_reference(len_var, 0, null)); //compiled_function_call get_item = new compiled_function_call(item_prop.get_function as compiled_function_node,cpr,null); //get_item.parameters.AddElement(new local_variable_reference(var,0,null)); cmc.parameters.AddElement(new simple_array_indexing(cpr, new local_variable_reference(var, 0, null), prm.type.element_type, null)); cmc.parameters.AddElement(new int_const_node((prm.type.element_type as short_string_type_node).Length, null)); body.statements.AddElement(find_operator(compiler_string_consts.assign_name, new simple_array_indexing(cpr, new local_variable_reference(var, 0, null), prm.type.element_type, null), cmc, null)); body.statements.AddElement(new basic_function_call(SystemLibrary.SystemLibrary.int_assign as basic_function_node, null, new local_variable_reference(var, 0, null), new basic_function_call(SystemLibrary.SystemLibrary.int_add as basic_function_node, null, new local_variable_reference(var, 0, null), new int_const_node(1, null)))); while_node wn = new while_node(cond, body, null); sl.statements.AddElementFirst(wn); sl.statements.AddElementFirst(new basic_function_call(SystemLibrary.SystemLibrary.int_assign as basic_function_node, null, new local_variable_reference(len_var, 0, null), new compiled_function_call(get_func, cpr, null))); } } } }
private base_function_call create_static_method_call(function_node fn, location loc, type_node tn, bool procedure_allowed) { if ((!procedure_allowed) && (fn.return_value_type == null)) { AddError(loc, "FUNCTION_EXPECTED_PROCEDURE_{0}_MEET", fn.name); } if (fn.semantic_node_type == semantic_node_type.common_method_node) { common_method_node cmn = (common_method_node)fn; if (cmn.polymorphic_state != SemanticTree.polymorphic_state.ps_static) { //ssyy изменил if (!cmn.is_constructor) { AddError(new CanNotCallNonStaticMethodWithClass(tn, loc, fn)); } if (cmn.cont_type.IsAbstract) ErrorsList.Add(new SimpleSemanticError(loc, "ABSTRACT_CONSTRUCTOR_{0}_CALL", cmn.name)); common_constructor_call csmc2 = new common_constructor_call(cmn, loc); return csmc2; //if (cmn.pascal_associated_constructor==null) //{ // throw new CanNotCallNonStaticMethodWithClass(tn,loc,fn); //} //common_constructor_call csmc2=new common_constructor_call(cmn.pascal_associated_constructor,loc); //return csmc2; //\ssyy } common_static_method_call csmc = new common_static_method_call(cmn, loc); return csmc; } if (fn.semantic_node_type == semantic_node_type.compiled_function_node) { compiled_function_node cfn = (compiled_function_node)fn; if (cfn.polymorphic_state != SemanticTree.polymorphic_state.ps_static) { AddError(new CanNotCallNonStaticMethodWithClass(tn, loc, fn)); } compiled_static_method_call csmc2 = new compiled_static_method_call(cfn, loc); return csmc2; } if (fn.semantic_node_type == semantic_node_type.compiled_constructor_node) { compiled_constructor_node ccn = (compiled_constructor_node)fn; compiled_constructor_call ccc = new compiled_constructor_call(ccn, loc); return ccc; } if (fn.semantic_node_type == semantic_node_type.basic_function_node) { return new basic_function_call(fn as basic_function_node, loc); } if (fn.semantic_node_type == semantic_node_type.common_namespace_function_node && (fn as common_namespace_function_node).ConnectedToType != null) { return new common_namespace_function_call(fn as common_namespace_function_node,loc); } if (fn.semantic_node_type == semantic_node_type.indefinite_definition_node) { return new indefinite_function_call(fn, loc); } throw new CompilerInternalError("Invalid method kind"); }
private expression_node convert_strong_to_constant_or_function_call_for_varinit(expression_node exp, type_node tn) { if (exp is constant_node) return convert_strong_to_constant_node(exp, tn); if (exp is array_initializer) { //if (tn.type_special_kind != SemanticTree.type_special_kind.array_wrapper) { //exp.type = DeduceType(exp.type,exp.location); exp = ConvertArrayInitializer(tn, exp as array_initializer); return exp; //return convertion_data_and_alghoritms.convert_type(exp,tn); } // else // { // exp.type = tn; // return exp; // } } else if (exp is compiled_static_method_call && (exp.type.type_special_kind == SemanticTree.type_special_kind.set_type || exp.type.type_special_kind == SemanticTree.type_special_kind.base_set_type)) { if (!(tn == exp.type) && !type_table.is_derived(tn, exp.type) && !(convertion_data_and_alghoritms.can_convert_type(exp, tn))) { AddError(new CanNotConvertTypes(exp, exp.type, tn, exp.location)); } if (tn.element_type != null) { ordinal_type_interface oti = tn.element_type.get_internal_interface(internal_interface_kind.ordinal_interface) as ordinal_type_interface; if (oti != null) { compiled_static_method_call cmc = new compiled_static_method_call(SystemLibrary.SystemLibInitializer.ClipFunction.sym_info as compiled_function_node, null); cmc.parameters.AddElement(exp); cmc.parameters.AddElement(oti.lower_value.get_constant_copy(null)); cmc.parameters.AddElement(oti.upper_value.get_constant_copy(null)); cmc.ret_type = tn; return new compiled_static_method_call_as_constant(cmc, null); } else if (tn.element_type.type_special_kind == SemanticTree.type_special_kind.short_string) { compiled_static_method_call cmc = new compiled_static_method_call(SystemLibrary.SystemLibInitializer.ClipShortStringInSetFunction.sym_info as compiled_function_node, null); cmc.parameters.AddElement(exp); cmc.parameters.AddElement(new int_const_node((tn.element_type as short_string_type_node).Length, null)); cmc.ret_type = tn; return new compiled_static_method_call_as_constant(cmc, null); } } return new compiled_static_method_call_as_constant(exp as compiled_static_method_call, null); } else if (exp is common_namespace_function_call && (exp.type.type_special_kind == SemanticTree.type_special_kind.set_type || exp.type.type_special_kind == SemanticTree.type_special_kind.base_set_type)) { if (!(tn == exp.type) && !type_table.is_derived(tn, exp.type) && !(convertion_data_and_alghoritms.can_convert_type(exp, tn))) { AddError(new CanNotConvertTypes(exp, exp.type, tn, exp.location)); } if (tn.element_type != null) { ordinal_type_interface oti = tn.element_type.get_internal_interface(internal_interface_kind.ordinal_interface) as ordinal_type_interface; if (oti != null) { common_namespace_function_call cmc = new common_namespace_function_call(SystemLibrary.SystemLibInitializer.ClipFunction.sym_info as common_namespace_function_node, null); cmc.parameters.AddElement(exp); cmc.parameters.AddElement(oti.lower_value.get_constant_copy(null)); cmc.parameters.AddElement(oti.upper_value.get_constant_copy(null)); cmc.ret_type = tn; return new common_namespace_function_call_as_constant(cmc, null); } else if (tn.element_type.type_special_kind == SemanticTree.type_special_kind.short_string) { common_namespace_function_call cmc = new common_namespace_function_call(SystemLibrary.SystemLibInitializer.ClipShortStringInSetFunction.sym_info as common_namespace_function_node, null); cmc.parameters.AddElement(exp); cmc.parameters.AddElement(new int_const_node((tn.element_type as short_string_type_node).Length, null)); cmc.ret_type = tn; return new common_namespace_function_call_as_constant(cmc, null); } } return new common_namespace_function_call_as_constant(exp as common_namespace_function_call, null); } else if (exp is record_initializer) { if (tn is common_type_node) exp = ConvertRecordInitializer(tn as common_type_node, exp as record_initializer); else if (tn is compiled_type_node) throw new NotSupportedError(exp.location); return exp; } switch (SemanticRules.VariableInitializationParams) { case VariableInitializationParams.ConstructorCall: if ((exp is common_constructor_call) || (exp is compiled_constructor_call)) return convertion_data_and_alghoritms.convert_type(exp, tn); break; case VariableInitializationParams.Expression: if (exp.type != null) return convertion_data_and_alghoritms.convert_type(exp, tn); break; } return convert_strong_to_constant_node(exp, tn); }
//TODO: Добавить приведение типов. public override void visit(SyntaxTree.case_node _case_node) { convertion_data_and_alghoritms.check_node_parser_error(_case_node); switch_node sn = new switch_node(get_location(_case_node)); expression_node en = convert_strong(_case_node.param); if (en is typed_expression) en = convert_typed_expression_to_function_call(en as typed_expression); type_node case_expr_type = en.type; internal_interface ii = en.type.get_internal_interface(internal_interface_kind.ordinal_interface); if (ii == null && en.type != SystemLibrary.SystemLibrary.string_type) { AddError(new OrdinalOrStringTypeExpected(en.location)); } if (ii != null) { ordinal_type_interface oti = (ordinal_type_interface)ii; en = convertion_data_and_alghoritms.create_simple_function_call(oti.value_to_int, en.location, en); sn.condition = en; foreach (SyntaxTree.case_variant cv in _case_node.conditions.variants) { convertion_data_and_alghoritms.check_node_parser_error(cv); case_variant_node sem_cv = new case_variant_node(get_location(cv)); sn.case_variants.AddElement(sem_cv); foreach (SyntaxTree.expression expr in cv.conditions.expressions) { convertion_data_and_alghoritms.check_node_parser_error(expr); SyntaxTree.diapason_expr diap = expr as SyntaxTree.diapason_expr; if (diap == null) { expression_node cn = convert_strong(expr); int_const_node icn = convert_const_to_switch(cn, oti, case_expr_type, get_location(expr)); is_case_variant_intersection_with_another(sn, icn, get_location(expr)); sem_cv.case_constants.AddElement(icn); } else { convertion_data_and_alghoritms.check_node_parser_error(diap.left); expression_node left = convert_strong(diap.left); /* constant_node cons_left = left as constant_node; if (cons_left==null) { throw new ConstantExpressionExpected(get_location(diap.left)); } */ int_const_node icn_left = convert_const_to_switch(left, oti, case_expr_type, get_location(diap.left)); convertion_data_and_alghoritms.check_node_parser_error(diap.right); expression_node right = convert_strong(diap.right); /* constant_node cons_right = right as constant_node; if (cons_right == null) { throw new ConstantExpressionExpected(get_location(diap.right)); } */ int_const_node icn_right = convert_const_to_switch(right, oti, case_expr_type, get_location(diap.right)); //ssyy if (icn_left.constant_value > icn_right.constant_value) { AddError(get_location(diap.right), "LEFT_RANGE_GREATER_THEN_RIGHT"); } //\ssyy case_range_node crn = new case_range_node(icn_left, icn_right, get_location(diap)); is_case_range_intersection_with_another(sn, crn, get_location(expr)); sem_cv.case_ranges.AddElement(crn); } } context.enter_code_block_with_bind(); statement_node stmn = convert_strong(cv.exec_if_true); context.leave_code_block(); sem_cv.case_statement = stmn; //sn.case_variants.AddElement(sem_cv); } context.enter_code_block_with_bind(); statement_node else_statement = convert_weak(_case_node.else_statement); context.leave_code_block(); sn.default_statement = else_statement; return_value(sn); } else { if_node main_ifn = null; if_node ifn = null; compiled_function_node str_eq_meth = SystemLibrary.SystemLibrary.string_type.find_in_type("=").sym_info as compiled_function_node; Dictionary<string, string> case_constants = new Dictionary<string, string>(); foreach (SyntaxTree.case_variant cv in _case_node.conditions.variants) { convertion_data_and_alghoritms.check_node_parser_error(cv); location loc = get_location(cv); expression_node eq_node = null; List<compiled_static_method_call> eq_calls = new List<compiled_static_method_call>(); foreach (SyntaxTree.expression expr in cv.conditions.expressions) { expression_node cn = convert_strong(expr); if (cn.type != SystemLibrary.SystemLibrary.string_type) AddError(new CanNotConvertTypes(cn, cn.type, SystemLibrary.SystemLibrary.string_type, cn.location)); string_const_node scn = convert_string_const_to_switch(cn, cn.location); if (!case_constants.ContainsKey(scn.constant_value)) case_constants.Add(scn.constant_value, scn.constant_value); else AddError(cn.location, "CASE_CONSTANT_VARIANT_COINCIDE_WITH_ANOTHER"); compiled_static_method_call eq_call = new compiled_static_method_call(str_eq_meth, cn.location); eq_call.parameters.AddElement(en); eq_call.parameters.AddElement(cn); eq_calls.Add(eq_call); } foreach (compiled_static_method_call eq_call in eq_calls) { if (eq_node == null) eq_node = eq_call; else eq_node = new basic_function_call(SystemLibrary.SystemLibrary.bool_or as basic_function_node, null, eq_node, eq_call); } context.enter_code_block_with_bind(); statement_node stmn = convert_strong(cv.exec_if_true); context.leave_code_block(); if (ifn != null) { ifn.else_body = new if_node(eq_node, stmn, null, loc); ifn = ifn.else_body as if_node; } else ifn = new if_node(eq_node, stmn, null, loc); if (main_ifn == null) main_ifn = ifn; } context.enter_code_block_with_bind(); statement_node else_statement = convert_weak(_case_node.else_statement); context.leave_code_block(); if (ifn == null) { ifn = new if_node(en, new statements_list(null), null, get_location(_case_node)); main_ifn = ifn; } ifn.else_body = else_statement; return_value(main_ifn); } }
private constant_node convert_strong_to_constant_node(expression_node expr, type_node tn) { location loc = expr.location; constant_node constant = null; try_convert_typed_expression_to_function_call(ref expr); if (expr is null_const_node) { if (!(tn is null_type_node) && !type_table.is_with_nil_allowed(tn)) AddError(loc, "NIL_WITH_VALUE_TYPES_NOT_ALLOWED"); return null_const_node.get_const_node_with_type(tn, expr as null_const_node); } if (expr is compiled_static_method_call) { compiled_static_method_call csmc = expr as compiled_static_method_call; if (/*csmc.parameters.Count == 0 &&*/ csmc.type != null && csmc.type != SystemLibrary.SystemLibrary.void_type) constant = new compiled_static_method_call_as_constant(csmc, expr.location); } else if (expr is common_namespace_function_call && (expr as common_namespace_function_call).function_node == SystemLibrary.SystemLibInitializer.CreateSetProcedure.sym_info as common_namespace_function_node) { common_namespace_function_call cnfc = expr as common_namespace_function_call; expressions_list exprs = get_set_initializer(cnfc); check_set_for_constant(cnfc); foreach (expression_node en in exprs) { if (en is common_namespace_function_call) { common_namespace_function_call cnfc2 = en as common_namespace_function_call; check_set_for_constant(cnfc2); } else if (!(en is constant_node)) AddError(loc, "CONSTANT_EXPRESSION_EXPECTED"); } constant = new common_namespace_function_call_as_constant(cnfc, loc); } else if (expr is common_namespace_function_call) { common_namespace_function_call cnfc=expr as common_namespace_function_call; //if (cnfc.function_node.namespace_node == context.converted_namespace) // throw new ConstantExpressionExpected(loc); constant = new common_namespace_function_call_as_constant(expr as common_namespace_function_call, loc); } else if (expr is basic_function_call) { basic_function_call cnfc=expr as basic_function_call; //if (cnfc.function_node.namespace_node == context.converted_namespace) // throw new ConstantExpressionExpected(loc); constant = new basic_function_call_as_constant(expr as basic_function_call, loc); } else if (expr is typed_expression) { expr = convertion_data_and_alghoritms.convert_type(expr, tn); if (expr is common_constructor_call) { constant = new common_constructor_call_as_constant(expr as common_constructor_call, null); } else if (expr is typed_expression) { if (const_def_type != null) { expr = convertion_data_and_alghoritms.convert_type(expr, const_def_type); tn = const_def_type; constant = new common_constructor_call_as_constant(expr as common_constructor_call, null); } else { base_function_call bfc = ((expr as typed_expression).type as delegated_methods).proper_methods[0]; common_type_node del = convertion_data_and_alghoritms.type_constructor.create_delegate(context.get_delegate_type_name(), bfc.simple_function_node.return_value_type, bfc.simple_function_node.parameters, context.converted_namespace, null); context.converted_namespace.types.AddElement(del); tn = del; expr = convertion_data_and_alghoritms.explicit_convert_type(expr, del); expr.type = tn; constant = new common_constructor_call_as_constant(expr as common_constructor_call, null); } } } else if (expr is namespace_constant_reference) { constant = (expr as namespace_constant_reference).constant.const_value; convertion_data_and_alghoritms.check_convert_type(constant,tn,expr.location); if ((tn.type_special_kind == SemanticTree.type_special_kind.set_type || tn.type_special_kind == SemanticTree.type_special_kind.base_set_type) && tn.element_type != null) { ordinal_type_interface oti = tn.element_type.get_internal_interface(internal_interface_kind.ordinal_interface) as ordinal_type_interface; if (oti != null) { common_namespace_function_call cmc = new common_namespace_function_call(SystemLibrary.SystemLibInitializer.ClipFunction.sym_info as common_namespace_function_node,null); cmc.parameters.AddElement(expr); cmc.parameters.AddElement(oti.lower_value.get_constant_copy(null)); cmc.parameters.AddElement(oti.upper_value.get_constant_copy(null)); cmc.ret_type = tn; constant = new common_namespace_function_call_as_constant(cmc,null); } else if (tn.element_type.type_special_kind == SemanticTree.type_special_kind.short_string) { common_namespace_function_call cmc = new common_namespace_function_call(SystemLibrary.SystemLibInitializer.ClipShortStringInSetFunction.sym_info as common_namespace_function_node,null); cmc.parameters.AddElement(expr); cmc.parameters.AddElement(new int_const_node((tn.element_type as short_string_type_node).Length,null)); cmc.ret_type = tn; constant = new common_namespace_function_call_as_constant(cmc,null); } } else if (tn.type_special_kind == SemanticTree.type_special_kind.short_string) { /*common_namespace_function_call cmc = new common_namespace_function_call(SystemLibrary.SystemLibInitializer.ClipShortStringProcedure.sym_info as common_namespace_function_node,null); cmc.parameters.AddElement(expr); cmc.parameters.AddElement(new int_const_node((tn 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(expr,SystemLibrary.SystemLibrary.string_type),new int_const_node((tn as short_string_type_node).Length,null)); constant = new common_namespace_function_call_as_constant(cmc as common_namespace_function_call,null); } /*expression_node e = convertion_data_and_alghoritms.convert_type(constant.get_constant_copy(expr.location), tn); switch (e.semantic_node_type) { case semantic_node_type.compiled_constructor_call: constant = new compiled_constructor_call_as_constant(e as compiled_constructor_call, loc); break; default: constant = e as constant_node; break; }*/ /*if (constant.get_object_value() != null) { //if (const_def_type != null) { expression_node e = convertion_data_and_alghoritms.convert_type(constant.get_constant_copy(expr.location), tn); switch (e.semantic_node_type) { case semantic_node_type.compiled_constructor_call: constant = new compiled_constructor_call_as_constant(e as compiled_constructor_call, loc); break; default: constant = e as constant_node; break; } } } else { //if (const_def_type != null) { expression_node e = convertion_data_and_alghoritms.convert_type(expr, tn); switch (e.semantic_node_type) { case semantic_node_type.compiled_constructor_call: constant = new compiled_constructor_call_as_constant(e as compiled_constructor_call, loc); break; default: constant = e as constant_node; break; } } }*/ return constant; } else if (expr is function_constant_reference) { constant = (expr as function_constant_reference).constant.const_value; convertion_data_and_alghoritms.check_convert_type(constant,tn,expr.location); if ((tn.type_special_kind == SemanticTree.type_special_kind.set_type || tn.type_special_kind == SemanticTree.type_special_kind.base_set_type) && tn.element_type != null) { ordinal_type_interface oti = tn.element_type.get_internal_interface(internal_interface_kind.ordinal_interface) as ordinal_type_interface; if (oti != null) { common_namespace_function_call cmc = new common_namespace_function_call(SystemLibrary.SystemLibInitializer.ClipFunction.sym_info as common_namespace_function_node,null); cmc.parameters.AddElement(expr); cmc.parameters.AddElement(oti.lower_value.get_constant_copy(null)); cmc.parameters.AddElement(oti.upper_value.get_constant_copy(null)); cmc.ret_type = tn; constant = new common_namespace_function_call_as_constant(cmc,null); } else if (tn.element_type.type_special_kind == SemanticTree.type_special_kind.short_string) { common_namespace_function_call cmc = new common_namespace_function_call(SystemLibrary.SystemLibInitializer.ClipShortStringInSetFunction.sym_info as common_namespace_function_node,null); cmc.parameters.AddElement(expr); cmc.parameters.AddElement(new int_const_node((tn.element_type as short_string_type_node).Length,null)); cmc.ret_type = tn; constant = new common_namespace_function_call_as_constant(cmc,null); } } else if (tn.type_special_kind == SemanticTree.type_special_kind.short_string) { /*common_namespace_function_call cmc = new common_namespace_function_call(SystemLibrary.SystemLibInitializer.ClipShortStringProcedure.sym_info as common_namespace_function_node,null); cmc.parameters.AddElement(expr); cmc.parameters.AddElement(new int_const_node((tn 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(expr,SystemLibrary.SystemLibrary.string_type),new int_const_node((tn as short_string_type_node).Length,null)); constant = new common_namespace_function_call_as_constant(cmc as common_namespace_function_call,null); } /*expression_node e = convertion_data_and_alghoritms.convert_type(constant.get_constant_copy(expr.location), tn); switch (e.semantic_node_type) { case semantic_node_type.compiled_constructor_call: constant = new compiled_constructor_call_as_constant(e as compiled_constructor_call, loc); break; default: constant = e as constant_node; break; }*/ /*if (constant.get_object_value() != null) { //if (const_def_type != null) { expression_node e = convertion_data_and_alghoritms.convert_type(constant.get_constant_copy(expr.location), tn); switch (e.semantic_node_type) { case semantic_node_type.compiled_constructor_call: constant = new compiled_constructor_call_as_constant(e as compiled_constructor_call, loc); break; default: constant = e as constant_node; break; } } } else { //if (const_def_type != null) { expression_node e = convertion_data_and_alghoritms.convert_type(expr, tn); switch (e.semantic_node_type) { case semantic_node_type.compiled_constructor_call: constant = new compiled_constructor_call_as_constant(e as compiled_constructor_call, loc); break; default: constant = e as constant_node; break; } } }*/ return constant; } else if (expr is static_compiled_variable_reference && !(expr as static_compiled_variable_reference).var.IsLiteral) { constant = new compiled_static_field_reference_as_constant(expr as static_compiled_variable_reference, null); return constant; } else { constant = expr as constant_node; if (tn.type_special_kind == SemanticTree.type_special_kind.short_string) { /*common_namespace_function_call cmc = new common_namespace_function_call(SystemLibrary.SystemLibInitializer.ClipShortStringProcedure.sym_info as common_namespace_function_node,null); cmc.parameters.AddElement(expr); cmc.parameters.AddElement(new int_const_node((tn 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(expr, SystemLibrary.SystemLibrary.string_type), new int_const_node((tn as short_string_type_node).Length, null)); if (cmc is common_namespace_function_call) constant = new common_namespace_function_call_as_constant(cmc as common_namespace_function_call, null); else constant = new compiled_static_method_call_as_constant(cmc as compiled_static_method_call, null); } //else //constant = convertion_data_and_alghoritms.convert_type(constant, tn) as constant_node; if (expr is static_compiled_variable_reference) { compiled_class_constant_definition cccd = NetHelper.NetHelper.ConvertToConstant(((static_compiled_variable_reference)expr).var); if (cccd != null) constant = cccd.const_value; else constant = new compiled_static_field_reference_as_constant(expr as static_compiled_variable_reference, null); } } if (constant == null) AddError(loc, "CONSTANT_EXPRESSION_EXPECTED"); if (IsBoundedArray(tn) || IsUnsizedArray(tn)) { if (!(constant is array_const)) AddError(loc, "ARRAY_CONST_EXPECTED"); constant = ConvertArrayConst(tn, constant as array_const); } else if (tn is common_type_node) { if (tn.type_special_kind != SemanticTree.type_special_kind.set_type && tn.type_special_kind != SemanticTree.type_special_kind.base_set_type && tn.type_special_kind != SemanticTree.type_special_kind.diap_type) { if (!tn.is_value) { if (expr is common_constructor_call) return constant; if (expr is common_constructor_call_as_constant) return expr as common_constructor_call_as_constant; convertion_data_and_alghoritms.check_convert_type(expr,tn,expr.location); //AddError(new CanNotConvertTypes(expr,expr.type,tn,expr.location)); //throw new NotSupportedError(loc); } if ((tn as common_type_node).IsEnum) { convertion_data_and_alghoritms.check_convert_type(expr,tn,expr.location); enum_const_node ecn = expr as enum_const_node; if (ecn == null) AddError(expr.location, "CONSTANT_EXPRESSION_EXPECTED"); return ecn; } if (!(constant is record_constant)) AddError(loc, "RECORD_CONST_EXPECTED"); constant = ConvertRecordConst(tn as common_type_node, constant as record_constant); } else if (tn.type_special_kind == SemanticTree.type_special_kind.diap_type) { constant = expr as constant_node; if (constant == null) AddError(expr.location, "CONSTANT_EXPRESSION_EXPECTED"); //constant = (expr as namespace_constant_reference).constant.const_value; convertion_data_and_alghoritms.check_convert_type(constant,tn,expr.location); ordinal_type_interface oti = tn.get_internal_interface(internal_interface_kind.ordinal_interface) as ordinal_type_interface; bool success = false; int val = convertion_data_and_alghoritms.convert_type_to_int_constant(constant, out success); if (success) { int left = convertion_data_and_alghoritms.convert_type_to_int_constant(oti.lower_value, out success); if (success) { int right = convertion_data_and_alghoritms.convert_type_to_int_constant(oti.upper_value, out success); if (success) if (val < left || val > right) AddError(loc, "OUT_OF_RANGE"); } } } else { //obrezka konstantnogo mnozhestva if (!(tn == expr.type) && !type_table.is_derived(tn,expr.type)) { AddError(new CanNotConvertTypes(expr,expr.type,tn,expr.location)); } if (tn.element_type != null) { ordinal_type_interface oti = tn.element_type.get_internal_interface(internal_interface_kind.ordinal_interface) as ordinal_type_interface; if (oti != null) { base_function_call cmc = null; if (SystemLibrary.SystemLibInitializer.ClipFunction.sym_info is common_namespace_function_node) cmc = new common_namespace_function_call(SystemLibrary.SystemLibInitializer.ClipFunction.sym_info as common_namespace_function_node, null); else cmc = new compiled_static_method_call(SystemLibrary.SystemLibInitializer.ClipFunction.sym_info as compiled_function_node, null); cmc.parameters.AddElement(expr); cmc.parameters.AddElement(oti.lower_value.get_constant_copy(null)); cmc.parameters.AddElement(oti.upper_value.get_constant_copy(null)); cmc.ret_type = tn; if (cmc is common_namespace_function_call) constant = new common_namespace_function_call_as_constant(cmc as common_namespace_function_call, null); else constant = new compiled_static_method_call_as_constant(cmc as compiled_static_method_call, null); } else if (tn.element_type.type_special_kind == SemanticTree.type_special_kind.short_string) { base_function_call cmc = null; if (SystemLibrary.SystemLibInitializer.ClipShortStringInSetFunction.sym_info is common_namespace_function_node) cmc = new common_namespace_function_call(SystemLibrary.SystemLibInitializer.ClipShortStringInSetFunction.sym_info as common_namespace_function_node, null); else cmc = new compiled_static_method_call(SystemLibrary.SystemLibInitializer.ClipShortStringInSetFunction.sym_info as compiled_function_node, null); cmc.parameters.AddElement(expr); cmc.parameters.AddElement(new int_const_node((tn.element_type as short_string_type_node).Length,null)); cmc.ret_type = tn; if (cmc is common_namespace_function_call) constant = new common_namespace_function_call_as_constant(cmc as common_namespace_function_call, null); else constant = new compiled_static_method_call_as_constant(cmc as compiled_static_method_call, null); } } } } else { expression_node exprc = convertion_data_and_alghoritms.convert_type(constant, tn); switch (exprc.semantic_node_type) { case semantic_node_type.compiled_constructor_call: constant = new compiled_constructor_call_as_constant(exprc as compiled_constructor_call, loc); break; case semantic_node_type.compiled_static_method_call: constant = new compiled_static_method_call_as_constant(exprc as compiled_static_method_call, loc); break; case semantic_node_type.basic_function_call: constant = new basic_function_call_as_constant(exprc as basic_function_call, loc); break; default: constant = exprc as constant_node; break; } } return constant; }
private void VisitCompiledStaticCall(compiled_static_method_call expr) { bw.Write(GetMemberOffset(expr.function_node)); /*bw.Write(expr.template_parametres_list.Count); foreach (type_node tn in expr.template_parametres_list) WriteTypeReference(tn);*/ bw.Write(expr.parameters.Count); foreach (expression_node e in expr.parameters) VisitExpression(e); }
private base_function_call_list convert_functions_to_calls(expression_node obj, function_node_list fnl, location loc, bool is_static) { base_function_call_list ret = new base_function_call_list(); foreach (function_node fnode in fnl) { base_function_call bfc = null; switch (fnode.semantic_node_type) { case semantic_node_type.common_namespace_function_node: { common_namespace_function_node cmfn = fnode as common_namespace_function_node; common_namespace_function_call cnfc = new common_namespace_function_call(cmfn, loc); if (cmfn.ConnectedToType != null) cnfc.parameters.AddElement(obj); if (cmfn.is_generic_function && !cmfn.is_generic_function_instance && cmfn.ConnectedToType != null && cmfn.parameters.Count == 1) { expressions_list parameters = new expressions_list(); parameters.AddElement(obj); function_node inst = null; try { inst = generic_convertions.DeduceFunction(cmfn, parameters, true, loc); } catch { continue; } cnfc = new common_namespace_function_call((common_namespace_function_node)inst, loc); if (cmfn.ConnectedToType != null) cnfc.parameters.AddElement(obj); } /*if (cmfn.parameters.Count >= 1 && cmfn.parameters[cmfn.parameters.Count - 1].is_params) { convertion_data_and_alghoritms.select_function(cnfc.parameters, new SymbolInfo(cmfn), loc); }*/ bfc = cnfc; break; } case semantic_node_type.basic_function_node: { //Может здесь стоит и выругаться, но я не буду пока этого делать. break; } case semantic_node_type.common_in_function_function_node: { common_in_function_function_node ciffn = fnode as common_in_function_function_node; int depth = convertion_data_and_alghoritms.symbol_table.GetRelativeScopeDepth(ciffn.scope, context.top_function.scope); common_in_function_function_call ciffc = new common_in_function_function_call(ciffn, depth, loc); bfc = ciffc; break; } case semantic_node_type.common_method_node: { common_method_node cmn = fnode as common_method_node; //Если cmn конструктор - то плохо, но его не должно сюда попасть. if (cmn.polymorphic_state != SemanticTree.polymorphic_state.ps_static) { if (!is_static) { if (obj == null) obj = GetCurrentObjectReference(cmn.cont_type.Scope, cmn, loc);//new this_node(context.converted_type, loc); common_method_call cmc = new common_method_call(cmn, obj, loc); cmc.virtual_call = !inherited_ident_processing; bfc = cmc; } //ssyy!!! Мне сложно понять предназначение данного кода, но, по-видимому, //следует его переписать так. else if (cmn.is_constructor) { if (cmn.parameters.Count == 0) { if (cmn.cont_type.IsAbstract) AddError(loc, "ABSTRACT_CONSTRUCTOR_{0}_CALL", cmn.cont_type.name); ret.clear(); ret.AddElement(new common_constructor_call(cmn, loc)); return ret; } } } else { if (is_static) { common_static_method_call csmc = new common_static_method_call(cmn, loc); bfc = csmc; } } break; } case semantic_node_type.compiled_function_node: { compiled_function_node cfn = fnode as compiled_function_node; if (cfn.cont_type.Scope == null && cfn is compiled_function_node) (cfn.cont_type as compiled_type_node).init_scope(); if (cfn.polymorphic_state == SemanticTree.polymorphic_state.ps_static) { //ispravleno ibond //if (is_static) { if (cfn.is_generic_function && !cfn.is_generic_function_instance && cfn.ConnectedToType != null && cfn.parameters.Count == 1) { expressions_list parameters = new expressions_list(); parameters.AddElement(obj); function_node inst = null; try { inst = generic_convertions.DeduceFunction(cfn, parameters, true, loc); } catch { continue; } if (inst is common_namespace_function_node) bfc = new common_namespace_function_call((common_namespace_function_node)inst, loc); else if (inst is compiled_function_node) bfc = new compiled_static_method_call((compiled_function_node)inst, loc); else bfc = new compiled_static_method_call(cfn, loc); } else { compiled_static_method_call csmc = new compiled_static_method_call(cfn, loc); bfc = csmc; } if (cfn.ConnectedToType != null) bfc.parameters.AddElement(obj); } } else { if (!is_static) { if (obj == null) obj = GetCurrentObjectReference(cfn.cont_type.Scope, cfn, loc);//new this_node(context.converted_type, loc); compiled_function_call cfc = new compiled_function_call(cfn, obj, loc); cfc.virtual_call = !inherited_ident_processing; bfc = cfc; } } break; } case semantic_node_type.compiled_constructor_node: { //Этот код мы вроде не должны вызывать, но если он все-же вызовется. compiled_constructor_node ccn = fnode as compiled_constructor_node; compiled_constructor_call ccc = new compiled_constructor_call(ccn, loc); bfc = ccc; break; } default: { throw new CompilerInternalError("Undefined method type."); } } if (bfc != null) { ret.AddElement(bfc); } } return ret; }
private void VisitCompiledStaticMethodCall(compiled_static_method_call en) { for (int i = 0; i < en.parameters.Count; i++) VisitExpression(en.parameters[i]); }
public static expression_node short_string_addassign_executor(location call_location, params expression_node[] parameters) { if (!SemanticRules.UseExtendedAssignmentOperatorsForPrimitiveTypes) SystemLibrary.syn_visitor.AddError(new OperatorCanNotBeAppliedToThisType(compiler_string_consts.plusassign_name, parameters[0])); compiled_static_method_call csmc = new compiled_static_method_call(SystemLibrary.string_add as compiled_function_node, call_location); csmc.parameters.AddElement(parameters[0]); csmc.parameters.AddElement(parameters[1]); basic_function_call assignc = new basic_function_call(parameters[0].type.find_in_type(compiler_string_consts.assign_name).sym_info as basic_function_node, call_location); assignc.parameters.AddElement(parameters[0]); base_function_call cnfc = null; if (SystemLibInitializer.ClipShortStringProcedure.sym_info is common_namespace_function_node) cnfc = new common_namespace_function_call(SystemLibInitializer.ClipShortStringProcedure.sym_info as common_namespace_function_node, call_location); else cnfc = new compiled_static_method_call(SystemLibInitializer.ClipShortStringProcedure.sym_info as compiled_function_node, call_location); cnfc.parameters.AddElement(csmc); cnfc.parameters.AddElement(new int_const_node((parameters[0].type as short_string_type_node).Length,call_location)); assignc.parameters.AddElement(cnfc); return assignc; }