private void VisitFor(for_node stmt) { if(CanWriteObject(stmt.initialization_statement)) VisitStatement(stmt.initialization_statement); VisitExpression(stmt.while_expr); if (CanWriteObject(stmt.init_while_expr)) VisitExpression(stmt.init_while_expr); VisitStatement(stmt.increment_statement); VisitStatement(stmt.body); bw.Write(stmt.bool_cycle); }
private void VisitFor(for_node stmt) { if (extended_mode) { if (stmt.init_while_expr is basic_function_call) { basic_function_call bfc = stmt.init_while_expr as basic_function_call; if (!(bfc.real_parameters[0] is local_block_variable_reference)) AddHint("USE_LOCAL_BLOCK_VARIABLES_FOR_CYCLE_COUNTER", stmt.location); else { local_block_variable lbv = (bfc.real_parameters[0] as local_block_variable_reference).var; if (lbv.loc.begin_line_num < stmt.location.begin_line_num || lbv.loc.begin_column_num < stmt.location.end_column_num) AddHint("USE_LOCAL_BLOCK_VARIABLES_CYCLE_COUNTER", stmt.location); } } } VisitStatement(stmt.init_while_expr); VisitStatement(stmt.initialization_statement); VisitStatement(stmt.increment_statement); VisitExpression(stmt.while_expr); VisitStatement(stmt.body); }
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); }
public override void visit(SyntaxTree.c_for_cycle node) { //throw new NotSupportedError(get_location(node)); location loc1 = get_location(node.expr1); statements_list head_stmts = new statements_list(loc1); convertion_data_and_alghoritms.statement_list_stack_push(head_stmts); //statement_node sn_init = convert_weak((SyntaxTree.statement)node.expr1); // SSM 12/06/15 - всё равно c-узлы никому не нужны statement_node sn_init = convert_weak(node.expr1); // SSM 12/06/15 expression_node sn_cond = convert_weak(node.expr2); //statement_node sn_next = convert_weak((SyntaxTree.statement)node.expr3); // SSM 12/06/15 statement_node sn_next = convert_weak(node.expr3); // SSM 12/06/15 CheckToEmbeddedStatementCannotBeADeclaration(node.stmt); for_node fn = new for_node(sn_init, sn_cond, null, sn_next, null, get_location(node)); context.cycle_stack.push(fn); statements_list slst = new statements_list(get_location(node.stmt)); convertion_data_and_alghoritms.statement_list_stack_push(slst); context.enter_code_block_with_bind(); fn.body = convert_strong(node.stmt); 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(); head_stmts = convertion_data_and_alghoritms.statement_list_stack.pop(); head_stmts.statements.AddElement(fn); return_value(head_stmts); /*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();*/ //ret.return_value(slst); }
private void VisitFor(for_node stmt) { VisitStatement(stmt.initialization_statement); VisitStatement(stmt.increment_statement); VisitExpression(stmt.while_expr); VisitStatement(stmt.body); }
public override void visit(PascalABCCompiler.SyntaxTree.for_node _for_node) { var loc1 = _visitor.get_location(_for_node.loop_variable); var loopIdentName = _for_node.loop_variable.name.ToLower(); var nodesToProcess = new List <syntax_tree_node>(); var_definition_node vdn; var initv = _visitor.convert_strong(_for_node.initial_value); var tmp = initv; if (initv is typed_expression) { initv = _visitor.convert_typed_expression_to_function_call(initv as typed_expression); } if (initv.type == null) { initv = tmp; } var headStmts = new statements_list(loc1); _visitor.convertion_data_and_alghoritms.statement_list_stack_push(headStmts); var newTreeNode = new CapturedVariablesTreeNodeForScope(_currentTreeNode, headStmts.Scope.ScopeNum, _for_node); if (_currentTreeNode != null) { _currentTreeNode.ChildNodes.Add(newTreeNode); } _currentTreeNode = newTreeNode; _scopesCapturedVarsNodesDictionary.Add(headStmts.Scope.ScopeNum, _currentTreeNode); if (_for_node.type_name == null && !_for_node.create_loop_variable) { var dn = _visitor.context.check_name_node_type(loopIdentName, loc1, general_node_type.variable_node); vdn = (var_definition_node)dn; nodesToProcess.Add(_for_node.loop_variable); } else { var tn = _for_node.type_name != null?_visitor.convert_strong(_for_node.type_name) : initv.type; vdn = _visitor.context.add_var_definition(loopIdentName, _visitor.get_location(_for_node.loop_variable), tn, polymorphic_state.ps_common); _currentTreeNode.VariablesDefinedInScope.Add(new CapturedVariablesTreeNode.CapturedSymbolInfo(_for_node, _visitor.context.find(loopIdentName))); } newTreeNode.SymbolInfoLoopVar = _visitor.context.find(loopIdentName); var fn = new PascalABCCompiler.TreeRealization.for_node(null, null, null, null, null, _visitor.get_location(_for_node)); if (vdn.type == SystemLibrary.bool_type) { fn.bool_cycle = true; } _visitor.context.cycle_stack.push(fn); _visitor.context.loop_var_stack.Push(vdn); nodesToProcess.Add(_for_node.initial_value); nodesToProcess.Add(_for_node.finish_value); nodesToProcess.Add(_for_node.increment_value); foreach (var n in nodesToProcess) { ProcessNode(n); } if (!(_for_node.statements is statement_list)) { var stmtList = new statement_list(_for_node.statements, _for_node.statements.source_context); _for_node.statements = stmtList; } ProcessNode(_for_node.statements); _visitor.context.cycle_stack.pop(); _visitor.context.loop_var_stack.Pop(); _visitor.convertion_data_and_alghoritms.statement_list_stack.pop(); _currentTreeNode = _currentTreeNode.ParentNode; }
/// <summary> /// Конструктор класса. /// </summary> /// <param name="fn"></param> /// <param name="loc">Расположение узла.</param> public for_continue_node(for_node fn, location loc) : base(null, loc) { _frnd = fn; }
/// <summary> /// Конструктор класса. /// </summary> /// <param name="fn">Цикл for внутри которого расположен этот break.</param> /// <param name="loc">Расположение узла.</param> public for_break_node(for_node fn, location loc) : base(null, loc) { _frnd = fn; }
private statement_node CreateFor() { statement_node init_stmt=null; if (CanReadObject()) init_stmt = CreateStatement(); expression_node while_expr = CreateExpression(); expression_node init_while_expr = null; if (CanReadObject()) init_while_expr = CreateExpression(); for_node stmt = new for_node(init_stmt,while_expr,init_while_expr,CreateStatement(),CreateStatement(),null); stmt.bool_cycle = br.ReadBoolean(); return stmt; }
public override void visit(PascalABCCompiler.SyntaxTree.for_node _for_node) { var loc1 = _visitor.get_location(_for_node.loop_variable); var loopIdentName = _for_node.loop_variable.name.ToLower(); var nodesToProcess = new List<syntax_tree_node>(); var_definition_node vdn; var initv = _visitor.convert_strong(_for_node.initial_value); var tmp = initv; if (initv is typed_expression) { initv = _visitor.convert_typed_expression_to_function_call(initv as typed_expression); } if (initv.type == null) { initv = tmp; } var headStmts = new statements_list(loc1); _visitor.convertion_data_and_alghoritms.statement_list_stack_push(headStmts); var newTreeNode = new CapturedVariablesTreeNodeForScope(_currentTreeNode, headStmts.Scope.ScopeNum, _for_node); if (_currentTreeNode != null) { _currentTreeNode.ChildNodes.Add(newTreeNode); } _currentTreeNode = newTreeNode; _scopesCapturedVarsNodesDictionary.Add(headStmts.Scope.ScopeNum, _currentTreeNode); if (_for_node.type_name == null && !_for_node.create_loop_variable) { var dn = _visitor.context.check_name_node_type(loopIdentName, loc1, general_node_type.variable_node); vdn = (var_definition_node)dn; nodesToProcess.Add(_for_node.loop_variable); } else { var tn = _for_node.type_name != null ? _visitor.convert_strong(_for_node.type_name) : initv.type; vdn = _visitor.context.add_var_definition(loopIdentName, _visitor.get_location(_for_node.loop_variable), tn, polymorphic_state.ps_common); _currentTreeNode.VariablesDefinedInScope.Add(new CapturedVariablesTreeNode.CapturedSymbolInfo(_for_node, _visitor.context.find(loopIdentName))); } newTreeNode.SymbolInfoLoopVar = _visitor.context.find(loopIdentName); var fn = new PascalABCCompiler.TreeRealization.for_node(null, null, null, null, null, _visitor.get_location(_for_node)); if (vdn.type == SystemLibrary.bool_type) { fn.bool_cycle = true; } _visitor.context.cycle_stack.push(fn); _visitor.context.loop_var_stack.Push(vdn); nodesToProcess.Add(_for_node.initial_value); nodesToProcess.Add(_for_node.finish_value); nodesToProcess.Add(_for_node.increment_value); foreach (var n in nodesToProcess) { ProcessNode(n); } if (!(_for_node.statements is statement_list)) { var stmtList = new statement_list(_for_node.statements, _for_node.statements.source_context); _for_node.statements = stmtList; } ProcessNode(_for_node.statements); _visitor.context.cycle_stack.pop(); _visitor.context.loop_var_stack.Pop(); _visitor.convertion_data_and_alghoritms.statement_list_stack.pop(); _currentTreeNode = _currentTreeNode.ParentNode; }
//Проверки на доступность 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; }
/// <summary> /// Конструктор класса. /// </summary> /// <param name="fn"></param> /// <param name="loc">Расположение узла.</param> public for_continue_node(for_node fn,location loc): base(null,loc) { _frnd=fn; }
/// <summary> /// Конструктор класса. /// </summary> /// <param name="fn">Цикл for внутри которого расположен этот break.</param> /// <param name="loc">Расположение узла.</param> public for_break_node(for_node fn,location loc) : base(null,loc) { _frnd=fn; }