public LambdaResultTypeInferrer(function_header lambdaHeader, proc_block lambdaBody, syntax_tree_visitor syntaxTreeVisitor) { this.lambdaBody = lambdaBody; this.lambdaHeader = lambdaHeader; this.syntaxTreeVisitor = syntaxTreeVisitor; resultExpressionsTypes = new List<Tuple<type_node, expression, expression_node>>(); }
//private special_operation_kind _current_operation_kind= special_operation_kind.none; public convertion_data_and_alghoritms(syntax_tree_visitor stv) { type_table.type_table_function_call_maker = create_simple_function_call; _stv=stv; _type_constructor = new type_constructor(this); SystemLibrary.SystemLibrary.type_constructor = _type_constructor; }
public CapturedVariablesSubstitutor(Dictionary<SubstitutionKey, List<ident>> identsReferences, Dictionary<int, CapturedVariablesSubstitutionClassGenerator.ScopeClassDefinition> generatedScopeClassesInfo, List<CapturedVariablesTreeNodeLambdaScope> lambdasToBeAddedAsMethods, Dictionary<SubstitutionKey, dot_node> substitutionsInfo, Dictionary<int, CapturedVariablesTreeNode> capturedVarsTreeNodesDictionary, Dictionary<string, Tuple<string, class_field, semantic_node>> mappingForNonPublicFieldsOfClass, syntax_tree_visitor visitor) { _identsReferences = identsReferences; _generatedScopeClassesInfo = generatedScopeClassesInfo; _substitutionsInfo = substitutionsInfo; _capturedVarsTreeNodesDictionary = capturedVarsTreeNodesDictionary; _lambdasToBeAddedAsMethods = lambdasToBeAddedAsMethods; _mappingForNonPublicFieldsOfClass = mappingForNonPublicFieldsOfClass; _visitor = visitor; }
public returner(syntax_tree_visitor stv) { syntax_tree_visitor = stv; }
/// <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"); } }
public CapturedVariablesTreeBuilder(syntax_tree_visitor visitor) { _visitor = visitor; _scopesCapturedVarsNodesDictionary = new Dictionary<int, CapturedVariablesTreeNode>(); _identsReferences = new Dictionary<SubstitutionKey, List<ident>>(); }
private static void CreateInParallelVariable(syntax_tree_visitor syntax_tree_visitor, out string VarName) { //сохраняем контекст ContextInfo contextInfo = new ContextInfo(syntax_tree_visitor); VarName = "$InParallelSection"; try { //создание и конвертирование переменной SyntaxTree.var_def_statement vds = new PascalABCCompiler.SyntaxTree.var_def_statement(); SyntaxTree.variable_definitions var_def = new PascalABCCompiler.SyntaxTree.variable_definitions(vds, null); SyntaxTree.ident_list idl = new PascalABCCompiler.SyntaxTree.ident_list(); vds.vars = idl; idl.Add(new SyntaxTree.ident(VarName)); SyntaxTree.named_type_reference ntr = new PascalABCCompiler.SyntaxTree.named_type_reference(); vds.vars_type = ntr; ntr.names.Add(new PascalABCCompiler.SyntaxTree.ident("boolean")); vds.inital_value = new PascalABCCompiler.SyntaxTree.ident("false"); syntax_tree_visitor.visit(var_def); } finally { //восстанавливаем контекст contextInfo.RestoreContext(syntax_tree_visitor); } InParallelSectionCreated = true; }
private static if_node CreateIfCondition(syntax_tree_visitor syntax_tree_visitor, statements_list ifthen, statements_list ifelse, location loc) { //сохраняем контекст ContextInfo contextInfo = new ContextInfo(syntax_tree_visitor); if_node res = null; try { SyntaxTree.if_node if_node = new PascalABCCompiler.SyntaxTree.if_node(); SyntaxTree.un_expr une = new PascalABCCompiler.SyntaxTree.un_expr(); une.operation_type = SyntaxTree.Operators.LogicalNOT; une.subnode = new SyntaxTree.ident(InParallelSection); if_node.condition = une; if_node.then_body = new SyntaxTree.empty_statement(); if_node.then_body = new SyntaxTree.empty_statement(); res = syntax_tree_visitor.convert_strong(if_node) as if_node; res.then_body = ifthen; res.else_body = ifelse; res.location = loc; } finally { //восстанавливаем контекст contextInfo.RestoreContext(syntax_tree_visitor); } return res; }
public void RestoreContext(syntax_tree_visitor syntax_tree_visitor) { SemanticRules.ThrowErrorWithoutSave = SemanticRulesThrowErrorWithoutSave; syntax_tree_visitor.convertion_data_and_alghoritms.statement_list_stack = statement_list_stack; syntax_tree_visitor.context.converted_type = converted_type; syntax_tree_visitor.context.var_defs = current_var_defs; syntax_tree_visitor.context.set_field_access_level(curr_fal); syntax_tree_visitor.context.block_stack = block_stack; syntax_tree_visitor.context.CyclesStack = cycle_stack; syntax_tree_visitor.context.member_decls = current_member_decls; syntax_tree_visitor.context.func_stack = function_node_stack; syntax_tree_visitor.context.last_created_function = current_last_created_function; }
public void SaveContext(syntax_tree_visitor syntax_tree_visitor) { converted_type = syntax_tree_visitor.context.converted_type; syntax_tree_visitor.context.converted_type = null; statement_list_stack = syntax_tree_visitor.convertion_data_and_alghoritms.statement_list_stack; syntax_tree_visitor.convertion_data_and_alghoritms.statement_list_stack = new statement_list_stack(); curr_fal = syntax_tree_visitor.context.get_field_access_level(); current_var_defs = syntax_tree_visitor.context.var_defs; syntax_tree_visitor.context.var_defs = new List<var_definition_node>(); block_stack = syntax_tree_visitor.context.block_stack; syntax_tree_visitor.context.block_stack = new Stack<code_block>(); cycle_stack = syntax_tree_visitor.context.CyclesStack; syntax_tree_visitor.context.CyclesStack = new statement_node_stack(); current_member_decls = syntax_tree_visitor.context.member_decls; syntax_tree_visitor.context.member_decls = new Hashtable(); function_node_stack = syntax_tree_visitor.context.func_stack; syntax_tree_visitor.context.func_stack = new common_function_node_stack(); current_last_created_function = syntax_tree_visitor.context.last_created_function; SemanticRulesThrowErrorWithoutSave = SemanticRules.ThrowErrorWithoutSave; SemanticRules.ThrowErrorWithoutSave = true; }
private static bool GenerateOMPParallelSectionsCall(statements_list stmts, SyntaxTree.statement_list syntax_stmts, statements_list omp_stmts, syntax_tree_visitor syntax_tree_visitor) { SyntaxTree.expression_list delegates = new PascalABCCompiler.SyntaxTree.expression_list(); SyntaxTree.statement_list stlInit = new PascalABCCompiler.SyntaxTree.statement_list(); SyntaxTree.statement_list stlFinal = new PascalABCCompiler.SyntaxTree.statement_list(); VarInfoContainer Vars = new VarInfoContainer(); string ClassName = syntax_tree_visitor.context.get_free_name("$section_class{0}"); List<SyntaxTree.statement> Sections = new List<PascalABCCompiler.SyntaxTree.statement>(); foreach (SyntaxTree.statement syntax_statement in syntax_stmts.subnodes) { if (syntax_statement is SyntaxTree.empty_statement) continue; //А зачем? ;-) if (syntax_statement is SyntaxTree.var_statement) { //выдать предупреждение. Это не нормально для параллельных секций syntax_tree_visitor.visit(syntax_statement as SyntaxTree.var_statement); } else { //ищем используемые переменные VarFinderSyntaxVisitor VFvis = new VarFinderSyntaxVisitor(syntax_statement, syntax_tree_visitor.context, false); SyntaxTree.compiler_directive dir = syntax_tree_visitor.DirectivesToNodesLinks[syntax_stmts]; //if (DirInfosTable[dir].ErrorName == "WARNING_IN_CLAUSE_PARAMETERS_REPEATED_VARS") // syntax_tree_visitor.AddWarning(new Errors.CommonWarning(StringResources.Get(DirInfosTable[dir].ErrorName), syntax_stmts.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), syntax_stmts.source_context.FileName, DirInfosTable[dir].SC.begin_position.line_num, DirInfosTable[dir].SC.begin_position.column_num)); //} //else if (DirInfosTable[dir].ErrorName != null) { syntax_tree_visitor.AddWarning(new Errors.CommonWarning(PascalABCCompiler.StringResources.Get(DirInfosTable[dir].ErrorName), syntax_stmts.source_context.FileName, DirInfosTable[dir].SC.begin_position.line_num, DirInfosTable[dir].SC.begin_position.column_num)); } Vars.UnionWith(GetVarInfoContainer(VFvis, null, DirInfosTable[dir].Privates, syntax_tree_visitor, dir)); Sections.Add(syntax_statement); } } //сохраняем контекст ContextInfo contextInfo = new ContextInfo(syntax_tree_visitor); try { //создание и конвертирование класса SyntaxTree.class_members member; SyntaxTree.type_declarations Decls = CreateClass(ClassName, out member, Vars); for (int i = 0; i < Sections.Count; ++i) member.members.Add(CreateMethod("method" + i.ToString(), Sections[i], "", member, Vars)); syntax_tree_visitor.visit(Decls); } finally { //восстанавливаем контекст contextInfo.RestoreContext(syntax_tree_visitor); } //создаем инициализацию и финализацию int NameNum = 0; string ObjName = GetFreeName("$section_obj", ref NameNum, syntax_tree_visitor.context); stlInit.subnodes.AddRange(CreateInitPart(ClassName, ObjName, Vars).subnodes); stlFinal.subnodes.AddRange(CreateFinalPart(ObjName, Vars).subnodes); SyntaxTree.procedure_call pc = new PascalABCCompiler.SyntaxTree.procedure_call(); SyntaxTree.method_call mc = new PascalABCCompiler.SyntaxTree.method_call(); mc.dereferencing_value = CreateTPLFunctionReference("Invoke"); pc.func_name = mc; SyntaxTree.expression_list exl = new PascalABCCompiler.SyntaxTree.expression_list(); //foreach (string str in ObjNames) for (int i=0; i<Sections.Count; ++i) exl.Add(new SyntaxTree.dot_node(new SyntaxTree.ident(ObjName), new SyntaxTree.ident("Method"+i.ToString()))); mc.parameters = exl; stlInit.subnodes.Add(CreateNestedRegionBorder(true)); stlInit.subnodes.Add(pc); stlInit.subnodes.AddRange(stlFinal.subnodes); stlInit.subnodes.Add(CreateNestedRegionBorder(false)); statement_node st = syntax_tree_visitor.ret.visit(stlInit); omp_stmts.statements.AddElement(st); return true; }
public compilation_context(convertion_data_and_alghoritms convertion_data_and_alghoritms, syntax_tree_visitor syntax_tree_visitor) { this.convertion_data_and_alghoritms = convertion_data_and_alghoritms; this.syntax_tree_visitor = syntax_tree_visitor; _instance = this; }
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; }
public SubtreeCreator(syntax_tree_visitor visitor) { _syntaxTreeVisitor = visitor; }
private static VarInfoContainer GetVarInfoContainer(VarFinderSyntaxVisitor VFVis, List<ReductionDirective> Reductions, List<string> PrivateVars, syntax_tree_visitor visitor, SyntaxTree.compiler_directive dir) { if (Reductions == null) Reductions = new List<ReductionDirective>(); if (PrivateVars == null) PrivateVars = new List<string>(); VarInfoContainer Result = new VarInfoContainer(); //константы копируются сразу Result.Constants = VFVis.Constants; //список переменных для редукции //ищем переменные с такими именами, проверяем их наличие, тип и если все хорошо - добавляем в список foreach (ReductionDirective rd in Reductions) foreach (string rdVarName in rd.variables) { if (LoopVariables.Contains(rdVarName)) { visitor.AddWarning(new PascalABCCompiler.Errors.CommonWarning(String.Format(PascalABCCompiler.StringResources.Get("OMPERROR_REDUCTION_WITH_LOOPVAR_{0}"), rdVarName), visitor.CurrentDocument.file_name, dir.source_context.begin_position.line_num, dir.source_context.begin_position.column_num)); continue; } SymbolInfo si = visitor.context.find(rdVarName); if (si == null) { visitor.AddWarning(new PascalABCCompiler.Errors.CommonWarning(String.Format(PascalABCCompiler.StringResources.Get("OMPERROR_UNKNOWN_VARNAME_{0}"), rdVarName), visitor.CurrentDocument.file_name, dir.source_context.begin_position.line_num, dir.source_context.begin_position.column_num)); continue; } if (!(si.sym_info is SemanticTree.IVAriableDefinitionNode)) { visitor.AddWarning(new PascalABCCompiler.Errors.CommonWarning(String.Format(PascalABCCompiler.StringResources.Get("OMPERROR_NAME_IS_NOT_VAR_{0}"), rdVarName), visitor.CurrentDocument.file_name, dir.source_context.begin_position.line_num, dir.source_context.begin_position.column_num)); continue; } if (!IsValidVarForReduction(si.sym_info as SemanticTree.IVAriableDefinitionNode)) { visitor.AddWarning(new PascalABCCompiler.Errors.CommonWarning(String.Format(PascalABCCompiler.StringResources.Get("OMPERROR_IS_NOT_POSSIBLE_REDUCTION_WITH_THIS_VAR_{0}"), rdVarName), visitor.CurrentDocument.file_name, dir.source_context.begin_position.line_num, dir.source_context.begin_position.column_num)); continue; } Result.ReductionVariables.Add(si.sym_info as SemanticTree.IVAriableDefinitionNode); Result.ReductionActions.Add(rd.Oper); //for (int i = 0; i < VFVis.Variables.Count; ++i) // if (VFVis.Variables[i].name.ToLower() == rdVarName.ToLower()) // { // Result.ReductionVariables.Add(VFVis.Variables[i]); // Result.ReductionActions.Add(rd.Oper); // break; // } } //приватные переменные - аналогично, но без проверки на тип foreach (string privateVar in PrivateVars) { SymbolInfo si = visitor.context.find(privateVar); if (si == null) { visitor.AddWarning(new PascalABCCompiler.Errors.CommonWarning(String.Format(PascalABCCompiler.StringResources.Get("OMPERROR_UNKNOWN_VARNAME_{0}"), privateVar), visitor.CurrentDocument.file_name, dir.source_context.begin_position.line_num, dir.source_context.begin_position.column_num)); continue; } if (!(si.sym_info is SemanticTree.IVAriableDefinitionNode)) { visitor.AddWarning(new PascalABCCompiler.Errors.CommonWarning(String.Format(PascalABCCompiler.StringResources.Get("OMPERROR_NAME_IS_NOT_VAR_{0}"), privateVar), visitor.CurrentDocument.file_name, dir.source_context.begin_position.line_num, dir.source_context.begin_position.column_num)); continue; } Result.PrivateVariables.Add(si.sym_info as SemanticTree.IVAriableDefinitionNode); } //по всем переменным: //если она не приватная и по ней нет редукции - переписываем ее в список разделяемых foreach (SemanticTree.IVAriableDefinitionNode var in VFVis.Variables) { bool NotShared = false; foreach (SemanticTree.IVAriableDefinitionNode rdn in Result.ReductionVariables) if (rdn.name.ToLower() == var.name.ToLower()) { NotShared = true; break; } if (!NotShared) foreach (SemanticTree.IVAriableDefinitionNode prVar in Result.PrivateVariables) if (prVar.name.ToLower() == var.name.ToLower()) { NotShared = true; break; } if (!NotShared) Result.SharedVariables.Add(var); } return Result; }
//инициализация OpenMP public static void InitOpenMP(List<SyntaxTree.compiler_directive> directives, syntax_tree_visitor visitor, SyntaxTree.compilation_unit cu) { //Из-за переноса этой проверки в секцию инициализации - оно не всегда успевает инициализироваться до выполнения этого кода. //Будем надеяться, что условие никогда не выполнится. Без постороннего вмешательства (замена файлов старыми версиями) - не должно. //if (SystemLibrary.SystemLibInitializer.OMP_Available == null || SystemLibrary.SystemLibInitializer.OMP_Available.NotFound) //{ // visitor.AddWarning(new Errors.CommonWarning(PascalABCCompiler.StringResources.Get("OMPERROR_OMP_NOT_AVAILABLE"), cu.file_name, cu.source_context.begin_position.line_num, cu.source_context.begin_position.column_num)); // return; //} foreach (SyntaxTree.compiler_directive dir in directives) { if (dir.Name.text.ToLower() == "omp") { string DirText = dir.Directive.text.ToLower(); DirectiveInfo dirInf = new DirectiveInfo(dir); DirInfosTable.Add(dir, dirInf); if (dirInf.Kind == DirectiveKind.ParallelFor) ForsFound = true; else if (dirInf.Kind == DirectiveKind.ParallelSections) SectionsFound = true; else if (dirInf.Kind == DirectiveKind.Critical) LocksFound = true; else { visitor.AddWarning(new Errors.CommonWarning(PascalABCCompiler.StringResources.Get(dirInf.ErrorName), dir.Directive.source_context.FileName, dirInf.SC.begin_position.line_num, dirInf.SC.begin_position.column_num)); } } } //уже не нужно //if (ForsFound && SystemLibrary.SystemLibInitializer.OMP_ParallelFor.NotFound) //{ // visitor.AddWarning(new Errors.CommonWarning(PascalABCCompiler.StringResources.Get("OMPERROR_PARALLELIZATION_FOR_NOT_AVAILABLE"), cu.file_name, cu.source_context.begin_position.line_num, cu.source_context.begin_position.column_num)); // ForsFound = false; //} //if (SectionsFound && SystemLibrary.SystemLibInitializer.OMP_ParallelSections.NotFound) //{ // visitor.AddWarning(new Errors.CommonWarning(PascalABCCompiler.StringResources.Get("OMPERROR_PARALLELIZATION_SECTIONS_NOT_AVAILABLE"), cu.file_name, cu.source_context.begin_position.line_num, cu.source_context.begin_position.column_num)); // SectionsFound = false; //} //"оторванные" директивы: //можно использовать директивы синхронизации и вне параллельных областей. //if (!SectionsFound && !ForsFound && LocksFound) //{ // visitor.AddWarning(new Errors.CommonWarning(PascalABCCompiler.StringResources.Get("OMPERROR_USING_CRITICAL_SECTIONS_OUTSIDE_PARALLEL_STRUCTURES"), cu.file_name, cu.source_context.begin_position.line_num, cu.source_context.begin_position.column_num)); // LocksFound = false; //} }
/// <summary> /// Вывод типа возвращаемого значения лямбды /// </summary> public static void InferResultType(function_header funcHeader, proc_block procBody, syntax_tree_visitor visitor) { var retType = funcHeader.return_type as lambda_inferred_type; if (retType != null && retType.real_type is lambda_any_type_node) retType.real_type = new LambdaResultTypeInferrer(funcHeader, procBody, visitor).InferResultType(); }
//инициализация критических секций с созданием класса private static void InitCriticals(syntax_tree_visitor visitor) { //генерируем класс SyntaxTree.type_declarations TypeDecls = new PascalABCCompiler.SyntaxTree.type_declarations(); SyntaxTree.type_declaration TypeDecl = new PascalABCCompiler.SyntaxTree.type_declaration(); TypeDecls.types_decl.Add(TypeDecl); LocksName = visitor.context.get_free_name("$locks_container{0}"); TypeDecl.type_name = new PascalABCCompiler.SyntaxTree.ident(LocksName); SyntaxTree.class_definition ClassDef = new PascalABCCompiler.SyntaxTree.class_definition(); TypeDecl.type_def = ClassDef; SyntaxTree.class_body ClassBody = new PascalABCCompiler.SyntaxTree.class_body(); ClassDef.body = ClassBody; SyntaxTree.class_members ClassMember = new PascalABCCompiler.SyntaxTree.class_members(); ClassBody.class_def_blocks.Add(ClassMember); ClassMember.access_mod = new PascalABCCompiler.SyntaxTree.access_modifer_node(PascalABCCompiler.SyntaxTree.access_modifer.public_modifer); List<string> ProcessedNames = new List<string>(); foreach (KeyValuePair<SyntaxTree.compiler_directive, DirectiveInfo> pair in DirInfosTable) { if (pair.Value.Kind == DirectiveKind.Critical) { string LockName = "$default"; if (pair.Value.Name.Length != 0) LockName = pair.Value.Name; if (ProcessedNames.Contains(LockName)) continue; ProcessedNames.Add(LockName); SyntaxTree.var_def_statement vds = new PascalABCCompiler.SyntaxTree.var_def_statement(); SyntaxTree.ident_list idl = new PascalABCCompiler.SyntaxTree.ident_list(); vds.vars = idl; idl.Add(new SyntaxTree.ident(LockName)); SyntaxTree.named_type_reference ntr = new PascalABCCompiler.SyntaxTree.named_type_reference(); vds.vars_type = ntr; ntr.Add(new SyntaxTree.ident("object")); SyntaxTree.new_expr ne = new PascalABCCompiler.SyntaxTree.new_expr(); vds.inital_value = ne; ne.type = ntr; vds.var_attr = PascalABCCompiler.SyntaxTree.definition_attribute.Static; ClassMember.members.Add(vds); } } //сохраняем контекст ContextInfo contextInfo = new ContextInfo(visitor); try { visitor.visit(TypeDecls); LocksInitialized = true; } finally { //восстанавливаем контекст contextInfo.RestoreContext(visitor); } }
/// <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, null, 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++) 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, null); new_param.type = visitor.convert_strong(def.formal_parameters.params_list[i].vars_type); res.parameters.AddElement(new_param); } } var hhh = new delegated_methods(); hhh.proper_methods.AddElement(new common_namespace_function_call(res, null)); return new typed_expression(hhh, null); }
public static void TryConvertCritical(ref SyntaxTree.statement st, syntax_tree_visitor visitor, SyntaxTree.compiler_directive directive) { if (!LocksInitialized) InitCriticals(visitor); string LockName = "$default"; if (DirInfosTable[directive].Name.Length != 0) LockName = DirInfosTable[directive].Name; SyntaxTree.lock_stmt LockStmt = new PascalABCCompiler.SyntaxTree.lock_stmt(); LockStmt.lock_object = new SyntaxTree.dot_node(new SyntaxTree.ident(LocksName), new SyntaxTree.ident(LockName)); LockStmt.stmt = st; st = LockStmt; }
//Проверки на доступность 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; }
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; }
/// <summary> /// Вывод типа возвращаемого значения лямбды /// </summary> public static void InferResultType(function_header funcHeader, proc_block procBody, syntax_tree_visitor visitor) { var retType = funcHeader.return_type as lambda_inferred_type; if (retType != null && retType.real_type is lambda_any_type_node) { retType.real_type = new LambdaResultTypeInferrer(funcHeader, procBody, visitor).InferResultType(); } }
public ContextInfo(syntax_tree_visitor syntax_tree_visitor) { SaveContext(syntax_tree_visitor); }
/// <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))); }
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))); } } } } } } } }