/// <summary> /// Временный узел, который используется при выведении типов параметров /// </summary> /// <param name="def"></param> /// <param name="visitor"></param> /// <returns></returns> public static typed_expression GetTempFunctionNodeForTypeInference(SyntaxTree.function_lambda_definition def, syntax_tree_visitor visitor) { var res = new common_namespace_function_node(def.lambda_name, visitor.get_location(def), null, null); if (def.return_type != null) { res.return_value_type = visitor.convert_strong(def.return_type); } else { res.return_value_type = null; } res.parameters.clear(); if (def.formal_parameters != null && def.formal_parameters.params_list.Count != 0) { for (int i = 0; i < def.formal_parameters.params_list.Count; i++) { var tt = visitor.convert_strong(def.formal_parameters.params_list[i].vars_type); // SSM 29/12/18 for (int j = 0; j < def.formal_parameters.params_list[i].idents.idents.Count; j++) { var new_param = new common_parameter(null, SemanticTree.parameter_type.value, res, concrete_parameter_type.cpt_none, visitor.get_location(def.formal_parameters.params_list[i].idents.idents[0])); new_param.type = tt; res.parameters.AddElement(new_param); } } } var hhh = new delegated_methods(); hhh.proper_methods.AddElement(new common_namespace_function_call(res, visitor.get_location(def))); return(new typed_expression(hhh, visitor.get_location(def))); }
/// <summary> /// Вывод типа параметров лямбд и типа возвращаемого значения при присваивании лямбды переменной /// </summary> public static void InferTypesFromVarStmt(type_node leftType, function_lambda_definition lambdaDef, syntax_tree_visitor visitor, Operators op = Operators.Undefined) { if (lambdaDef == null) { return; } if (leftType != null) { delegate_internal_interface dii_left = (delegate_internal_interface)leftType.get_internal_interface(internal_interface_kind.delegate_interface); if (dii_left == null) { if (leftType != SystemLibrary.SystemLibrary.system_delegate_type) { if (op != Operators.Undefined) { var sil = leftType.find_in_type(name_reflector.get_name(op)); if (sil != null && sil.Count > 0) { foreach (SymbolInfo si in sil) { if (si.sym_info is function_node) { function_node fn = si.sym_info as function_node; if (fn.parameters.Count == 2) { dii_left = (delegate_internal_interface)fn.parameters[1].type.get_internal_interface(internal_interface_kind.delegate_interface); if (dii_left != null) { break; } if (fn.parameters[1].type.is_generic_parameter) { compiled_type_node ctn = leftType as compiled_type_node; common_type_node ctn2 = leftType as common_type_node; if (ctn != null && ctn.is_generic_type_instance && fn.parameters[0].type.is_generic_type_instance && ctn.original_generic == fn.parameters[0].type.original_generic) { dii_left = (delegate_internal_interface)ctn.generic_params[0].get_internal_interface(internal_interface_kind.delegate_interface); if (dii_left != null) { break; } } if (ctn2 != null && ctn2.is_generic_type_instance && ctn2.instance_params.Count > 0 && fn.parameters[0].type.is_generic_type_instance && ctn2.original_generic == fn.parameters[0].type.original_generic) { dii_left = (delegate_internal_interface)ctn2.instance_params[0].get_internal_interface(internal_interface_kind.delegate_interface); if (dii_left != null) { break; } } } } } } } } if (dii_left == null) { visitor.AddError(visitor.get_location(lambdaDef), "ILLEGAL_LAMBDA_VARIABLE_TYPE"); } } else { return; } } int leftTypeParamsNumber = dii_left.parameters.Count; int lambdaDefParamsCount = 0; if (lambdaDef.formal_parameters != null && lambdaDef.formal_parameters.params_list.Count != 0) { for (int i = 0; i < lambdaDef.formal_parameters.params_list.Count; i++) { lambdaDefParamsCount += lambdaDef.formal_parameters.params_list[i].idents.idents.Count; } if (lambdaDefParamsCount != leftTypeParamsNumber) { visitor.AddError(visitor.get_location(lambdaDef), "ILLEGAL_LAMBDA_PARAMETERS_NUMBER"); } bool flag = true; SyntaxTree.formal_parameters lambdaDefParamsTypes = new formal_parameters(); for (int i = 0; i < lambdaDef.formal_parameters.params_list.Count; i++) { for (int j = 0; j < lambdaDef.formal_parameters.params_list[i].idents.idents.Count; j++) { var param = new SyntaxTree.typed_parameters(); param.idents = new ident_list(); param.idents.Add(lambdaDef.formal_parameters.params_list[i].idents.idents[j]); param.vars_type = lambdaDef.formal_parameters.params_list[i].vars_type; param.source_context = lambdaDef.formal_parameters.source_context; lambdaDefParamsTypes.Add(param); } } for (int i = 0; i < leftTypeParamsNumber && flag; i++) { if (lambdaDefParamsTypes.params_list[i].vars_type is SyntaxTree.lambda_inferred_type) { if ((lambdaDefParamsTypes.params_list[i].vars_type as SyntaxTree.lambda_inferred_type).real_type is lambda_any_type_node) { var curLeftParType = dii_left.parameters[i].type; lambdaDefParamsTypes.params_list[i].vars_type = new SyntaxTree.lambda_inferred_type(); (lambdaDefParamsTypes.params_list[i].vars_type as SyntaxTree.lambda_inferred_type).real_type = curLeftParType; continue; } } var lambdaPar = visitor.convert_strong(lambdaDefParamsTypes.params_list[i].vars_type); if (!convertion_data_and_alghoritms.eq_type_nodes(dii_left.parameters[i].type, lambdaPar)) { visitor.AddError(visitor.get_location(lambdaDef), "ILLEGAL_LAMBDA_VARIABLE_TYPE"); } } lambdaDef.formal_parameters = lambdaDefParamsTypes; } if (lambdaDef.return_type != null && lambdaDef.return_type is lambda_inferred_type) { if (dii_left.return_value_type != null) { (lambdaDef.return_type as lambda_inferred_type).real_type = dii_left.return_value_type; } else // SSM 23/07/16 - попытка бороться с var p: Shape->() := a->a.Print() { // lambdaDef.usedkeyword == 1 // function var b = lambdaDef.usedkeyword == 0 && TryConvertFuncLambdaBodyWithMethodCallToProcLambdaBody(lambdaDef); // пытаться конвертировать только если мы явно не указали, что это функция if (!b) { visitor.AddError(visitor.get_location(lambdaDef), "UNABLE_TO_CONVERT_FUNCTIONAL_TYPE_TO_PROCEDURAL_TYPE"); } } } } else { if (lambdaDef.formal_parameters != null) { for (int i = 0; i < lambdaDef.formal_parameters.params_list.Count; i++) { if (lambdaDef.formal_parameters.params_list[i].vars_type is lambda_inferred_type) { visitor.AddError(visitor.get_location(lambdaDef), "IMPOSSIBLE_TO_INFER_TYPES_IN_LAMBDA"); } } } } }
/// <summary> /// Вывод типа параметров лямбд и типа возвращаемого значения при присваивании лямбды переменной /// </summary> public static void InferTypesFromVarStmt(type_node leftType, function_lambda_definition lambdaDef, syntax_tree_visitor visitor) { if (lambdaDef == null) { return; } if (leftType != null) { delegate_internal_interface dii_left = (delegate_internal_interface)leftType.get_internal_interface(internal_interface_kind.delegate_interface); if (dii_left == null) { if (leftType != SystemLibrary.SystemLibrary.system_delegate_type) { visitor.AddError(visitor.get_location(lambdaDef), "ILLEGAL_LAMBDA_VARIABLE_TYPE"); } else { return; } } int leftTypeParamsNumber = dii_left.parameters.Count; int lambdaDefParamsCount = 0; if (lambdaDef.formal_parameters != null && lambdaDef.formal_parameters.params_list.Count != 0) { for (int i = 0; i < lambdaDef.formal_parameters.params_list.Count; i++) { lambdaDefParamsCount += lambdaDef.formal_parameters.params_list[i].idents.idents.Count; } if (lambdaDefParamsCount != leftTypeParamsNumber) { visitor.AddError(visitor.get_location(lambdaDef), "ILLEGAL_LAMBDA_PARAMETERS_NUMBER"); } bool flag = true; SyntaxTree.formal_parameters lambdaDefParamsTypes = new formal_parameters(); for (int i = 0; i < lambdaDef.formal_parameters.params_list.Count; i++) { for (int j = 0; j < lambdaDef.formal_parameters.params_list[i].idents.idents.Count; j++) { var param = new SyntaxTree.typed_parameters(); param.idents = new ident_list(); param.idents.Add(lambdaDef.formal_parameters.params_list[i].idents.idents[j]); param.vars_type = lambdaDef.formal_parameters.params_list[i].vars_type; param.source_context = lambdaDef.formal_parameters.source_context; lambdaDefParamsTypes.Add(param); } } for (int i = 0; i < leftTypeParamsNumber && flag; i++) { if (lambdaDefParamsTypes.params_list[i].vars_type is SyntaxTree.lambda_inferred_type) { if ((lambdaDefParamsTypes.params_list[i].vars_type as SyntaxTree.lambda_inferred_type).real_type is lambda_any_type_node) { var curLeftParType = dii_left.parameters[i].type; lambdaDefParamsTypes.params_list[i].vars_type = new SyntaxTree.lambda_inferred_type(); (lambdaDefParamsTypes.params_list[i].vars_type as SyntaxTree.lambda_inferred_type).real_type = curLeftParType; continue; } } var lambdaPar = visitor.convert_strong(lambdaDefParamsTypes.params_list[i].vars_type); if (!convertion_data_and_alghoritms.eq_type_nodes(dii_left.parameters[i].type, lambdaPar)) { visitor.AddError(visitor.get_location(lambdaDef), "ILLEGAL_LAMBDA_VARIABLE_TYPE"); } } lambdaDef.formal_parameters = lambdaDefParamsTypes; } if (lambdaDef.return_type != null && lambdaDef.return_type is lambda_inferred_type) { if (dii_left.return_value_type != null) { (lambdaDef.return_type as lambda_inferred_type).real_type = dii_left.return_value_type; } else // SSM 23/07/16 - попытка бороться с var p: Shape->() := a->a.Print() { var b = TryConvertFuncLambdaBodyWithMethodCallToProcLambdaBody(lambdaDef); if (!b) { throw new SimpleSemanticError(visitor.get_location(lambdaDef), "UNABLE_TO_CONVERT_FUNCTIONAL_TYPE_TO_PROCEDURAL_TYPE"); } } } } else { if (lambdaDef.formal_parameters != null) { for (int i = 0; i < lambdaDef.formal_parameters.params_list.Count; i++) { if (lambdaDef.formal_parameters.params_list[i].vars_type is lambda_inferred_type) { visitor.AddError(visitor.get_location(lambdaDef), "IMPOSSIBLE_TO_INFER_TYPES_IN_LAMBDA"); } } } } }
/// <summary> /// Вывод типа параметров лямбд и типа возвращаемого значения при присваивании лямбды переменной /// </summary> public static void InferTypesFromVarStmt(type_node leftType, function_lambda_definition lambdaDef, syntax_tree_visitor visitor) { if (lambdaDef == null) return; if (leftType != null) { delegate_internal_interface dii_left = (delegate_internal_interface)leftType.get_internal_interface(internal_interface_kind.delegate_interface); if (dii_left == null) visitor.AddError(visitor.get_location(lambdaDef), "ILLEGAL_LAMBDA_VARIABLE_TYPE"); int leftTypeParamsNumber = dii_left.parameters.Count; int lambdaDefParamsCount = 0; if (lambdaDef.formal_parameters != null && lambdaDef.formal_parameters.params_list.Count != 0) { for (int i = 0; i < lambdaDef.formal_parameters.params_list.Count; i++) lambdaDefParamsCount += lambdaDef.formal_parameters.params_list[i].idents.idents.Count; if (lambdaDefParamsCount != leftTypeParamsNumber) visitor.AddError(visitor.get_location(lambdaDef), "ILLEGAL_LAMBDA_PARAMETERS_NUMBER"); bool flag = true; SyntaxTree.formal_parameters lambdaDefParamsTypes = new formal_parameters(); for (int i = 0; i < lambdaDef.formal_parameters.params_list.Count; i++) for (int j = 0; j < lambdaDef.formal_parameters.params_list[i].idents.idents.Count; j++) { var param = new SyntaxTree.typed_parameters(); param.idents = new ident_list(); param.idents.Add(lambdaDef.formal_parameters.params_list[i].idents.idents[j]); param.vars_type = lambdaDef.formal_parameters.params_list[i].vars_type; lambdaDefParamsTypes.Add(param); } for (int i = 0; i < leftTypeParamsNumber && flag; i++) { if (lambdaDefParamsTypes.params_list[i].vars_type is SyntaxTree.lambda_inferred_type) { if ((lambdaDefParamsTypes.params_list[i].vars_type as SyntaxTree.lambda_inferred_type).real_type is lambda_any_type_node) { var curLeftParType = dii_left.parameters[i].type; lambdaDefParamsTypes.params_list[i].vars_type = new SyntaxTree.lambda_inferred_type(); (lambdaDefParamsTypes.params_list[i].vars_type as SyntaxTree.lambda_inferred_type).real_type = curLeftParType; continue; } } var lambdaPar = visitor.convert_strong(lambdaDefParamsTypes.params_list[i].vars_type); if (!convertion_data_and_alghoritms.eq_type_nodes(dii_left.parameters[i].type, lambdaPar)) { visitor.AddError(visitor.get_location(lambdaDef), "ILLEGAL_LAMBDA_VARIABLE_TYPE"); } } lambdaDef.formal_parameters = lambdaDefParamsTypes; } if (lambdaDef.return_type != null && lambdaDef.return_type is lambda_inferred_type) { if (dii_left.return_value_type != null) (lambdaDef.return_type as lambda_inferred_type).real_type = dii_left.return_value_type; else // SSM 23/07/16 - попытка бороться с var p: Shape->() := a->a.Print() { var b = TryConvertFuncLambdaBodyWithMethodCallToProcLambdaBody(lambdaDef); if (!b) throw new SimpleSemanticError(visitor.get_location(lambdaDef), "UNABLE_TO_CONVERT_FUNCTIONAL_TYPE_TO_PROCEDURAL_TYPE"); } } } else { if (lambdaDef.formal_parameters != null) for (int i = 0; i < lambdaDef.formal_parameters.params_list.Count; i++) if (lambdaDef.formal_parameters.params_list[i].vars_type is lambda_inferred_type) visitor.AddError(visitor.get_location(lambdaDef), "IMPOSSIBLE_TO_INFER_TYPES_IN_LAMBDA"); } }
internal static statements_list TryConvertSections(statements_list semantic_stmts, SyntaxTree.statement_list syntax_stmts, syntax_tree_visitor syntax_tree_visitor) { try { location loc = semantic_stmts.location; statements_list omp_stmts = new statements_list(loc); statements_list head_stmts = new statements_list(loc); syntax_tree_visitor.convertion_data_and_alghoritms.statement_list_stack_push(head_stmts); if (!InParallelSectionCreated) CreateInParallelVariable(syntax_tree_visitor, out InParallelSection); //если omp доступен то (выполнять паралельно) иначе (выполнять последовательно операторы) if_node ifnode = CreateIfCondition(syntax_tree_visitor, omp_stmts, semantic_stmts, loc); head_stmts.statements.AddElement(ifnode); //генерим ветку в случае когда доступен omp if (!GenerateOMPParallelSectionsCall(semantic_stmts, syntax_stmts, omp_stmts, syntax_tree_visitor)) { syntax_tree_visitor.convertion_data_and_alghoritms.statement_list_stack_pop(); return null; } syntax_tree_visitor.convertion_data_and_alghoritms.statement_list_stack_pop(); return head_stmts; } catch (OpenMPException e) { Exception ex = new Exception(e.ToString()); syntax_tree_visitor.convertion_data_and_alghoritms.statement_list_stack_pop(); syntax_tree_visitor.WarningsList.Add(new OMP_BuildigError(ex, syntax_tree_visitor.get_location(new SyntaxTree.syntax_tree_node(e.SC)))); } catch (Exception e) { syntax_tree_visitor.convertion_data_and_alghoritms.statement_list_stack_pop(); syntax_tree_visitor.WarningsList.Add(new OMP_BuildigError(e, semantic_stmts.location)); } return null; }
//Проверки на доступность OMP и директиву проводятся перед вызовом. internal static statements_list TryConvertFor(statements_list for_head_stmts, SyntaxTree.for_node for_node, for_node fn, var_definition_node loop_variable, expression_node fromInclusive, expression_node toInclusive, syntax_tree_visitor syntax_tree_visitor) { try { location loc = fn.location; statements_list omp_stmts = new statements_list(loc); statements_list head_stmts = new statements_list(loc); syntax_tree_visitor.convertion_data_and_alghoritms.statement_list_stack_push(head_stmts); if (!InParallelSectionCreated) CreateInParallelVariable(syntax_tree_visitor, out InParallelSection); //если omp доступен то (выполнять паралельно) иначе (выполнять for) if_node ifnode = CreateIfCondition(syntax_tree_visitor, omp_stmts, for_head_stmts, loc); head_stmts.statements.AddElement(ifnode); //генерим ветку в случае когда доступен omp if (!GenerateOMPParallelForCall(fn.body, for_node, loop_variable, omp_stmts, syntax_tree_visitor, fromInclusive, toInclusive)) { syntax_tree_visitor.convertion_data_and_alghoritms.statement_list_stack_pop(); return null; } syntax_tree_visitor.convertion_data_and_alghoritms.statement_list_stack_pop(); return head_stmts; } catch (OpenMPException e) { Exception ex = new Exception(e.ToString()); syntax_tree_visitor.convertion_data_and_alghoritms.statement_list_stack_pop(); syntax_tree_visitor.WarningsList.Add(new OMP_BuildigError(ex, syntax_tree_visitor.get_location(new SyntaxTree.syntax_tree_node(e.SC)))); } catch (Exception e) { syntax_tree_visitor.convertion_data_and_alghoritms.statement_list_stack_pop(); syntax_tree_visitor.WarningsList.Add(new OMP_BuildigError(e, fn.location)); } return null; }
public static void Substitute(syntax_tree_visitor _visitor, declarations decls, statement_list _statementList) { var tree = new CapturedVariablesTreeBuilder(_visitor).BuildTree(_statementList); var substs = new CapturedVariablesSubstitutionClassGenerator(tree.RootNode).GenerateSubstitutions(); new CapturedVariablesSubstitutor(tree.IdentsReferences, substs.GeneratedScopeClassesInfo, substs.LambdasToBeAddedAsMethods, substs.SubstitutionsInfo, tree.CapturedVarsNodesDictionary, substs.ConvertingClassNonPublicMembersMapping, _visitor) .Substitute(_statementList); if (_visitor.context.converting_block() == block_type.function_block && tree.ProcedureScope != null) { if (decls != null && decls.defs != null) { foreach (var def in decls.defs.Where(d => d is const_definition || d is consts_definitions_list || d is variable_definitions)) { var constDef = def as const_definition; if (constDef != null) { var finder = new FindMainIdentsVisitor(); finder.ProcessNode(constDef.const_value); foreach (var v in finder.vars) { var si = _visitor.context.find(v.name); if (si == null) { continue; } if(tree.ProcedureScope.VariablesDefinedInScope.Any(var => var.SymbolInfo == si)) { _visitor.AddError(new UsingCapturedParameterIsNotAllowedInInitializers(_visitor.get_location(v))); } } continue; } var constDefList = def as consts_definitions_list; if (constDefList != null) { foreach (var cd in constDefList.const_defs) { var finder = new FindMainIdentsVisitor(); finder.ProcessNode(cd.const_value); foreach (var v in finder.vars) { var si = _visitor.context.find(v.name); if (si == null) { continue; } if (tree.ProcedureScope.VariablesDefinedInScope.Any(var => var.SymbolInfo == si)) { _visitor.AddError(new UsingCapturedParameterIsNotAllowedInInitializers(_visitor.get_location(v))); } } } continue; } var varDefList = def as variable_definitions; if (varDefList != null) { foreach (var d in varDefList.var_definitions) { var finder = new FindMainIdentsVisitor(); finder.ProcessNode(d.inital_value); foreach (var v in finder.vars) { var si = _visitor.context.find(v.name); if (si == null) { continue; } if (tree.ProcedureScope.VariablesDefinedInScope.Any(var => var.SymbolInfo == si)) { _visitor.AddError(new UsingCapturedParameterIsNotAllowedInInitializers(_visitor.get_location(v))); } } } } } } } }