private void internal_reset() { PascalABCCompiler.SystemLibrary.SystemLibInitializer.initialization_properties init_properties = new PascalABCCompiler.SystemLibrary.SystemLibInitializer.initialization_properties(); init_properties.break_executor = make_break_node; init_properties.continue_executor = make_continue_node; init_properties.exit_executor = make_exit_node; _system_unit = SystemLibrary.SystemLibInitializer.make_system_unit(convertion_data_and_alghoritms.symbol_table, init_properties); SystemLibrary.SystemLibrary.system_unit = _system_unit; generic_convertions.reset_generics(); _record_created = false; RefTypesForCheckPointersTypeForDotNetFramework.Clear(); reset_for_interface(); _is_interface_part = false; with_class_name=false; generic_param_abilities.Clear(); current_converted_method_not_in_class_defined = false; assign_is_converting = false; motivation_keeper.reset(); SystemLibrary.SystemLibInitializer.NeedsToRestore.Clear(); type_section_converting = false; #region MikhailoMMX, реинициализация класса OpenMP OpenMP.InternalReset(); CurrentParallelPosition = ParallelPosition.Outside; #endregion lambdaProcessingState = LambdaProcessingState.None; //lroman CapturedVariablesSubstitutionClassGenerator.Reset(); }
public override void visit(SyntaxTree.statement_list _statement_list) { #region MikhailoMMX, обработка omp parallel section bool isGenerateParallel = false; bool isGenerateSequential = true; if (OpenMP.SectionsFound) //если в программе есть хоть одна директива parallel sections - проверяем: if (DirectivesToNodesLinks.ContainsKey(_statement_list) && OpenMP.IsParallelSectionsDirective(DirectivesToNodesLinks[_statement_list])) { //перед этим узлом есть директива parallel sections if (CurrentParallelPosition == ParallelPosition.Outside) //входим в самый внешний параллельный sections { //сгенерировать сначала последовательную ветку, затем параллельную //устанавливаем флаг и продолжаем конвертирование, считая, что конвертируем последовательную ветку isGenerateParallel = true; CurrentParallelPosition = ParallelPosition.InsideSequential; //в конце за счет флага вернем состояние обратно и сгенерируем и параллельную ветку тоже } else //уже генерируем одну из веток if (CurrentParallelPosition == ParallelPosition.InsideParallel) { isGenerateParallel = true; isGenerateSequential = false; } //else //флаг isGenerateParallel не установлен, параллельная ветка не сгенерируется } #endregion statements_list stl = new statements_list(get_location(_statement_list), get_location_with_check(_statement_list.left_logical_bracket), get_location_with_check(_statement_list.right_logical_bracket)); convertion_data_and_alghoritms.statement_list_stack_push(stl); foreach (SyntaxTree.statement syntax_statement in _statement_list.subnodes) { try { if (syntax_statement is SyntaxTree.var_statement) visit(syntax_statement as SyntaxTree.var_statement); else if (MustVisitBody) { //(ssyy) TODO Сделать по-другому!!! statement_node semantic_statement = convert_strong(syntax_statement); //(ssyy) Проверка для C if (semantic_statement != null) { //Обработать по другому - комментарий не мой - SSM //if (context.CurrentScope.AddStatementsToFront) // stl.statements.AddElementFirst(semantic_statement); //else stl.statements.AddElement(semantic_statement); } context.allow_inherited_ctor_call = false; } } catch (Errors.Error ex) { if (ThrowCompilationError) throw ex; else ErrorsList.Add(ex); } } convertion_data_and_alghoritms.statement_list_stack.pop(); #region MikhailoMMX, обработка omp parallel sections //флаг был установлен только если это самый внешний parallel sections и нужно сгенерировать обе ветки //или если это вложенный parallel sections, нужно сгенерировать обе ветки, но без проверки на OMP_Available //Последовательная ветка только что сгенерирована, теперь меняем состояние и генерируем параллельную if (isGenerateParallel) { CurrentParallelPosition = ParallelPosition.InsideParallel; statements_list omp_stl = OpenMP.TryConvertSections(stl, _statement_list, this); CurrentParallelPosition = ParallelPosition.Outside; if (omp_stl != null) { return_value(omp_stl); return; } } #endregion return_value(stl); }
public override void visit(SyntaxTree.for_node _for_node) { #region MikhailoMMX, обработка omp parallel for bool isGenerateParallel = false; bool isGenerateSequential = true; if (OpenMP.ForsFound) { OpenMP.LoopVariables.Push(_for_node.loop_variable.name.ToLower()); //если в программе есть хоть одна директива parallel for - проверяем: if (DirectivesToNodesLinks.ContainsKey(_for_node) && OpenMP.IsParallelForDirective(DirectivesToNodesLinks[_for_node])) { //перед этим узлом есть директива parallel for if (CurrentParallelPosition == ParallelPosition.Outside) //входим в самый внешний параллельный for { if (_for_node.create_loop_variable || (_for_node.type_name != null)) { //сгенерировать сначала последовательную ветку, затем параллельную //устанавливаем флаг и продолжаем конвертирование, считая, что конвертируем последовательную ветку isGenerateParallel = true; CurrentParallelPosition = ParallelPosition.InsideSequential; //в конце за счет флага вернем состояние обратно и сгенерируем и параллельную ветку тоже } else WarningsList.Add(new OMP_BuildigError(new Exception("Переменная параллельного цикла должна быть определена в заголовке цикла"), new location(_for_node.source_context.begin_position.line_num, _for_node.source_context.begin_position.column_num, _for_node.source_context.end_position.line_num, _for_node.source_context.end_position.column_num, new document(_for_node.source_context.FileName)))); } else //уже генерируем одну из веток //если это параллельная ветка - последовательную генерировать не будем if (CurrentParallelPosition == ParallelPosition.InsideParallel) { isGenerateParallel = true; isGenerateSequential = false; } //else //а если последовательная - то флаг isGenerateParallel не установлен, сгенерируется только последовательная } } #endregion location loc1 = get_location(_for_node.loop_variable); var_definition_node vdn = null; expression_node left, right, res; expression_node initv = convert_strong(_for_node.initial_value); expression_node tmp = initv; if (initv is typed_expression) initv = convert_typed_expression_to_function_call(initv as typed_expression); if (initv.type == null) initv = tmp; statements_list head_stmts = new statements_list(loc1); convertion_data_and_alghoritms.statement_list_stack_push(head_stmts); if (_for_node.type_name == null && !_for_node.create_loop_variable) { definition_node dn = context.check_name_node_type(_for_node.loop_variable.name, loc1, general_node_type.variable_node); vdn = (var_definition_node)dn; if (context.is_loop_variable(vdn)) AddError(get_location(_for_node.loop_variable), "CANNOT_ASSIGN_TO_LOOP_VARIABLE"); if (!check_name_in_current_scope(_for_node.loop_variable.name)) AddError(new ForLoopControlMustBeSimpleLocalVariable(loc1)); } else { //В разработке DS //throw new NotSupportedError(get_location(_for_node.type_name)); type_node tn; if (_for_node.type_name != null) tn = convert_strong(_for_node.type_name); else tn = initv.type; //if (tn == SystemLibrary.SystemLibrary.void_type && _for_node.type_name != null) // AddError(new VoidNotValid(get_location(_for_node.type_name))) if (_for_node.type_name != null) check_for_type_allowed(tn,get_location(_for_node.type_name)); vdn = context.add_var_definition(_for_node.loop_variable.name, get_location(_for_node.loop_variable), tn, SemanticTree.polymorphic_state.ps_common); } internal_interface ii = vdn.type.get_internal_interface(internal_interface_kind.ordinal_interface); if (ii == null) { AddError(new OrdinalTypeExpected(loc1)); } ordinal_type_interface oti = (ordinal_type_interface)ii; location loc2 = get_location(_for_node.finish_value); var_definition_node vdn_finish = context.create_for_temp_variable(vdn.type, loc2); //Это должно стаять первее! left = create_variable_reference(vdn_finish, loc1); expression_node finishValue = convert_strong(_for_node.finish_value); right = finishValue; if (right is typed_expression) right = convert_typed_expression_to_function_call(right as typed_expression); res = find_operator(compiler_string_consts.assign_name, left, right, loc2); head_stmts.statements.AddElement(res); left = create_variable_reference(vdn, loc1); right = initv; res = find_operator(compiler_string_consts.assign_name, left, right, loc1); head_stmts.statements.AddElement(res); //for_node fn=new for_node(sl,; //fn.initialization_statement=sl; location loc3 = get_location(_for_node.initial_value); statement_node sn_inc = null; expression_node sn_while = null; expression_node sn_init_while = null; left = create_variable_reference(vdn, loc3); right = create_variable_reference(vdn, loc2); expression_node right_border = create_variable_reference(vdn_finish, loc2); switch (_for_node.cycle_type) { case SyntaxTree.for_cycle_type.to: { sn_inc = convertion_data_and_alghoritms.create_simple_function_call(oti.inc_method, loc1, left); //if (vdn.type != SystemLibrary.SystemLibrary.bool_type) sn_while = convertion_data_and_alghoritms.create_simple_function_call(oti.lower_method, loc2, right, right_border); sn_init_while = convertion_data_and_alghoritms.create_simple_function_call(oti.lower_eq_method, loc2, right, right_border); // else // sn_while = convertion_data_and_alghoritms.create_simple_function_call(SystemLibrary.SystemLibrary.bool_noteq, loc2, right, right_border); break; } case SyntaxTree.for_cycle_type.downto: { sn_inc = convertion_data_and_alghoritms.create_simple_function_call(oti.dec_method, loc1, left); //if (vdn.type != SystemLibrary.SystemLibrary.bool_type) sn_while = convertion_data_and_alghoritms.create_simple_function_call(oti.greater_method, loc2, right, right_border); sn_init_while = convertion_data_and_alghoritms.create_simple_function_call(oti.greater_eq_method, loc2, right, right_border); // else // sn_while = convertion_data_and_alghoritms.create_simple_function_call(SystemLibrary.SystemLibrary.bool_noteq, loc2, right, right_border); break; } } //fn.increment_statement=sn_inc; //fn.while_expr=sn_while; CheckToEmbeddedStatementCannotBeADeclaration(_for_node.statements); //DarkStar Modifed //исправил ошибку: не работали break в циклах for_node fn = new for_node(null, sn_while, sn_init_while, sn_inc, null, get_location(_for_node)); if (vdn.type == SystemLibrary.SystemLibrary.bool_type) fn.bool_cycle = true; context.cycle_stack.push(fn); context.loop_var_stack.Push(vdn); statements_list slst = new statements_list(get_location(_for_node.statements)); convertion_data_and_alghoritms.statement_list_stack_push(slst); context.enter_code_block_with_bind(); fn.body = convert_strong(_for_node.statements); context.leave_code_block(); slst = convertion_data_and_alghoritms.statement_list_stack.pop(); if (slst.statements.Count > 0 || slst.local_variables.Count > 0) { slst.statements.AddElement(fn.body); fn.body = slst; } context.cycle_stack.pop(); context.loop_var_stack.Pop(); head_stmts = convertion_data_and_alghoritms.statement_list_stack.pop(); head_stmts.statements.AddElement(fn); #region MikhailoMMX, обработка omp parallel for //флаг был установлен только если это самый внешний parallel for и нужно сгенерировать обе ветки //или если это вложенный parallel for, нужно сгенерировать обе ветки, но без проверки на OMP_Available //Последовательная ветка только что сгенерирована, теперь меняем состояние и генерируем параллельную if (isGenerateParallel) { CurrentParallelPosition = ParallelPosition.InsideParallel; statements_list stl = OpenMP.TryConvertFor(head_stmts, _for_node, fn, vdn, initv, finishValue, this); CurrentParallelPosition = ParallelPosition.Outside; if (stl != null) { OpenMP.LoopVariables.Pop(); return_value(stl); return; } } if (OpenMP.ForsFound) { OpenMP.LoopVariables.Pop(); } #endregion return_value(head_stmts); }