private void SaveVariable(var_definition_node cfn) { if (!string.IsNullOrEmpty(cfn.documentation)) { if (!cfn.documentation.Trim(' ', '\t').StartsWith("<summary>")) { xtw.WriteStartElement("member"); xtw.WriteStartAttribute("name"); if (!is_assembly) { xtw.WriteString("V:" + cfn.name); } else { xtw.WriteString("F:" + unit_name + "." + unit_name + "." + cfn.name); } xtw.WriteEndAttribute(); xtw.WriteStartElement("summary"); xtw.WriteString(cfn.documentation); xtw.WriteEndElement(); xtw.WriteEndElement(); } else { string doc = string.Concat("<member name=\"" + (is_assembly?"F:" + unit_name + "." + unit_name + ".":"V:") + cfn.name + "\">", cfn.documentation, "</member>"); StringReader sr = new StringReader(doc); XmlReader xr = XmlTextReader.Create(sr); xr.Read(); xtw.WriteNode(xr.ReadSubtree(), false); sr.Close(); xr.Close(); } } }
private void ForeachCheckAndConvert(foreach_stmt _foreach_stmt, out expression_node foreachCollection, out var_definition_node foreachVariable) { var lambdaSearcher = new LambdaSearcher(_foreach_stmt.in_what); if (lambdaSearcher.CheckIfContainsLambdas()) { AddError(new LambdasNotAllowedInForeachInWhatSatetement(get_location(lambdaSearcher.FoundLambda))); } foreachCollection = convert_strong(_foreach_stmt.in_what); expression_node tmp = convert_if_typed_expression_to_function_call(foreachCollection); if (tmp.type != null) { foreachCollection = tmp; } bool sys_coll_ienum; // true означает, что мы нашли тип object у интерфейса System.Collections.IEnumerable type_node elem_type = null; if (!FindIEnumerableElementType(foreachCollection.type, ref elem_type, out sys_coll_ienum)) { AddError(foreachCollection.location, "CAN_NOT_EXECUTE_FOREACH_BY_EXPR_OF_TYPE_{0}", foreachCollection.type.name); } CheckToEmbeddedStatementCannotBeADeclaration(_foreach_stmt.stmt); foreachVariable = FindForeachVariable(_foreach_stmt, elem_type, sys_coll_ienum); }
public void AddVariable(var_definition_node vdn) { VarInfo vi = new VarInfo(); if (ht[vdn] == null) { ht[vdn] = vi; } }
private void IncreaseNumUseVar(var_definition_node lvr) { VarInfo vi = helper.GetVariable(lvr); vi.num_use++; vi.act_num_use++; vi.cur_use++; //if (vi.cur_ass == 0 && !lvr.var.name.Contains("$")) helper.AddTempWarning(lvr.var,new UseWithoutAssign(lvr.var.name, lvr.location)); }
public void AddTempWarning(var_definition_node vdn, CompilerWarningWithLocation cw) { List <CompilerWarningWithLocation> lst = (List <CompilerWarningWithLocation>)warns[vdn]; if (lst == null) { lst = new List <CompilerWarningWithLocation>(); warns[vdn] = lst; } lst.Add(cw); }
private var_definition_node FindForeachVariable(foreach_stmt _foreach_stmt, type_node elem_type, bool sys_coll_ienum) { var_definition_node foreachVariable = null; if (_foreach_stmt.type_name == null) // значит, переменная определена в другом месте { location loc1 = get_location(_foreach_stmt.identifier); definition_node dn = context.check_name_node_type(_foreach_stmt.identifier.name, loc1, general_node_type.variable_node); foreachVariable = (var_definition_node)dn; if (!check_name_in_current_scope(_foreach_stmt.identifier.name)) { AddError(loc1, "FOREACH_LOOP_CONTROL_MUST_BE_SIMPLE_LOCAL_VARIABLE"); } } else { foreachVariable = context.add_var_definition(_foreach_stmt.identifier.name, get_location(_foreach_stmt.identifier)); type_node tn; if (_foreach_stmt.type_name is no_type_foreach) // значит, это for var x in a { tn = elem_type; } else // значит, это for var x: T in a { tn = convert_strong(_foreach_stmt.type_name); check_for_type_allowed(tn, get_location(_foreach_stmt.type_name)); check_using_static_class(tn, get_location(_foreach_stmt.type_name)); } if (tn.is_value_type && !tn.is_standard_type) { context.close_var_definition_list(tn, new default_operator_node(tn, foreachVariable.location)); } else { context.close_var_definition_list(tn, null); } } if (/*!(foreachVariable.type is compiled_generic_instance_type_node) &&*/ !sys_coll_ienum) // SSM 16.09.18 - закомментировал это ограничение для фиксации бага #1184 { convertion_data_and_alghoritms.check_convert_type_with_inheritance(elem_type, foreachVariable.type, get_location(_foreach_stmt.identifier)); } return(foreachVariable); }
private var_definition_node FindForeachVariable(foreach_stmt _foreach_stmt, type_node elem_type, bool sys_coll_ienum) { var_definition_node foreachVariable = null; if (_foreach_stmt.type_name == null) // значит, переменная определена в другом месте { location loc1 = get_location(_foreach_stmt.identifier); definition_node dn = context.check_name_node_type(_foreach_stmt.identifier.name, loc1, general_node_type.variable_node); foreachVariable = (var_definition_node)dn; if (!check_name_in_current_scope(_foreach_stmt.identifier.name)) { AddError(loc1, "FOREACH_LOOP_CONTROL_MUST_BE_SIMPLE_LOCAL_VARIABLE"); } } else { foreachVariable = context.add_var_definition(_foreach_stmt.identifier.name, get_location(_foreach_stmt.identifier)); type_node tn; if (_foreach_stmt.type_name is no_type_foreach) // значит, это for var x in a { tn = elem_type; } else // значит, это for var x: T in a { tn = convert_strong(_foreach_stmt.type_name); check_for_type_allowed(tn, get_location(_foreach_stmt.type_name)); } context.close_var_definition_list(tn, null); } if (!(foreachVariable.type is compiled_generic_instance_type_node) && !sys_coll_ienum) { convertion_data_and_alghoritms.check_convert_type_with_inheritance(elem_type, foreachVariable.type, get_location(_foreach_stmt.identifier)); } return(foreachVariable); }
public override void visit(foreach_stmt _foreach_stmt) { var loopIdentName = _foreach_stmt.identifier.name.ToLower(); definition_node dn = null; var_definition_node vdn = null; var sl2 = new statements_list(_visitor.get_location(_foreach_stmt)); _visitor.convertion_data_and_alghoritms.statement_list_stack_push(sl2); var newTreeNode = new CapturedVariablesTreeNodeForEachScope(_currentTreeNode, sl2.Scope.ScopeNum, _foreach_stmt); if (_currentTreeNode != null) { _currentTreeNode.ChildNodes.Add(newTreeNode); } _currentTreeNode = newTreeNode; _scopesCapturedVarsNodesDictionary.Add(sl2.Scope.ScopeNum, _currentTreeNode); var inWhat = _visitor.convert_strong(_foreach_stmt.in_what); var tmp = inWhat; if (inWhat is typed_expression) { inWhat = _visitor.convert_typed_expression_to_function_call(inWhat as typed_expression); } type_node elemType = null; if (inWhat.type == null) { inWhat = tmp; } _visitor.FindIEnumerableElementType(/*_foreach_stmt, */ inWhat.type, ref elemType); if (_foreach_stmt.type_name == null) { var loc1 = _visitor.get_location(_foreach_stmt.identifier); dn = _visitor.context.check_name_node_type(loopIdentName, loc1, general_node_type.variable_node); vdn = (var_definition_node)dn; } else { vdn = _visitor.context.add_var_definition(loopIdentName, _visitor.get_location(_foreach_stmt.identifier)); type_node tn; if (_foreach_stmt.type_name is no_type_foreach) { tn = elemType; } else { tn = _visitor.convert_strong(_foreach_stmt.type_name); _visitor.check_for_type_allowed(tn, _visitor.get_location(_foreach_stmt.type_name)); } _visitor.context.close_var_definition_list(tn, null); _currentTreeNode.VariablesDefinedInScope.Add(new CapturedVariablesTreeNode.CapturedSymbolInfo(_foreach_stmt, _visitor.context.find(loopIdentName))); } newTreeNode.SymbolInfoLoopVar = _visitor.context.find(loopIdentName); if (!(vdn.type is compiled_generic_instance_type_node)) { _visitor.convertion_data_and_alghoritms.check_convert_type_with_inheritance(vdn.type, elemType, _visitor.get_location(_foreach_stmt.identifier)); } var fn = new foreach_node(vdn, inWhat, null, _visitor.get_location(_foreach_stmt)); _visitor.context.cycle_stack.push(fn); _visitor.context.loop_var_stack.Push(vdn); ProcessNode(_foreach_stmt.in_what); if (!(_foreach_stmt.stmt is statement_list)) { var stmtList = new statement_list(_foreach_stmt.stmt, _foreach_stmt.stmt.source_context); _foreach_stmt.stmt = stmtList; } ProcessNode(_foreach_stmt.stmt); _visitor.context.loop_var_stack.Pop(); _visitor.convertion_data_and_alghoritms.statement_list_stack.pop(); _visitor.context.cycle_stack.pop(); _currentTreeNode = _currentTreeNode.ParentNode; }
/// <summary> /// Преобразует в семантическое представление поля to и from, проводя семантические проверки. /// </summary> private void AssignCheckAndConvert(assign _assign, out addressed_expression to, out expression_node from) { internal_is_assign = true; to = convert_address_strong(_assign.to); internal_is_assign = false; if (to == null) { AddError(get_location(_assign.to), "CAN_NOT_ASSIGN_TO_LEFT_PART"); } //(ssyy) Вставляю проверки прямо сюда, т.к. запарился вылавливать другие случаи. bool flag; general_node_type node_type; if (convertion_data_and_alghoritms.check_for_constant_or_readonly(to, out flag, out node_type)) { if (flag) { AddError(to.location, "CAN_NOT_ASSIGN_TO_CONSTANT_OBJECT"); } else { AddError(new CanNotAssignToReadOnlyElement(to.location, node_type)); } } // SSM исправление Саушкина 10.03.16 var fromAsLambda = _assign.from as function_lambda_definition; if (fromAsLambda != null) { #region Вывод параметров лямбда-выражения LambdaHelper.InferTypesFromVarStmt(to.type, fromAsLambda, this); //lroman// #endregion var lambdaVisitMode = fromAsLambda.lambda_visit_mode; fromAsLambda.lambda_visit_mode = LambdaVisitMode.VisitForAdvancedMethodCallProcessing; from = convert_strong(_assign.from); fromAsLambda.lambda_visit_mode = lambdaVisitMode; } else { from = convert_strong(_assign.from); ProcessAssigntToAutoType(to, ref from); } // end //SSM 4.04.16 if (to.type is undefined_type) { to.type = from.type; } location loc = get_location(_assign); if (to is class_field_reference) { var classFieldRef = to as class_field_reference; if (classFieldRef.obj.type.type_special_kind == type_special_kind.record && classFieldRef.obj is base_function_call) { //исключим ситуацию обращения к массиву if (!(classFieldRef.obj is common_method_call && (classFieldRef.obj as common_method_call).obj.type.type_special_kind == type_special_kind.array_wrapper)) { AddError(loc, "LEFT_SIDE_CANNOT_BE_ASSIGNED_TO"); } } //else check_field_reference_for_assign(to as class_field_reference,loc); } if (context.is_in_cycle() && !SemanticRules.AllowChangeLoopVariable) { var_definition_node toAsVariable = GetLocalVariableFromAdressExpressionIfPossible(to); if (toAsVariable != null && context.is_loop_variable(toAsVariable)) { AddError(to.location, "CANNOT_ASSIGN_TO_LOOP_VARIABLE"); } } { var classFieldRef = (to as simple_array_indexing)?.simple_arr_expr as class_field_reference; if (classFieldRef?.obj is constant_node) { AddError(loc, "LEFT_SIDE_CANNOT_BE_ASSIGNED_TO"); } } }
public void AddRealWarning(var_definition_node vdn, List <CompilerWarningWithLocation> cw) { List <CompilerWarningWithLocation> lst = (List <CompilerWarningWithLocation>)warns[vdn]; cw.AddRange(lst); }
public VarInfo GetVariable(var_definition_node vdn) { return((VarInfo)ht[vdn]); }
public override void visit(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 loopVariableLocation = get_location(_for_node.loop_variable); var_definition_node vdn = null; expression_node left, right, res; expression_node initialValue = convert_strong(_for_node.initial_value); expression_node tmp = initialValue; if (initialValue is typed_expression) { initialValue = convert_typed_expression_to_function_call(initialValue as typed_expression); } if (initialValue.type == null) { initialValue = tmp; } statements_list head_stmts = new statements_list(loopVariableLocation); convertion_data_and_alghoritms.statement_list_stack_push(head_stmts); var early_init_loop_variable = false; // SSM 25/05/16 if (_for_node.type_name == null && !_for_node.create_loop_variable) { definition_node dn = context.check_name_node_type(_for_node.loop_variable.name, loopVariableLocation, 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(loopVariableLocation)); } } 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 = initialValue.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, initialValue /*, polymorphic_state.ps_common*/); vdn.polymorphic_state = polymorphic_state.ps_common; early_init_loop_variable = true; // SSM 25/05/16 } internal_interface ii = vdn.type.get_internal_interface(internal_interface_kind.ordinal_interface); if (ii == null) { AddError(new OrdinalTypeExpected(loopVariableLocation)); } ordinal_type_interface oti = (ordinal_type_interface)ii; location finishValueLocation = get_location(_for_node.finish_value); var_definition_node vdn_finish = context.create_for_temp_variable(vdn.type, finishValueLocation); //Это должно стоять раньше!! left = create_variable_reference(vdn_finish, loopVariableLocation); 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, finishValueLocation); head_stmts.statements.AddElement(res); if (!early_init_loop_variable) // SSM 25/05/16 - for var i := f1() to f2() do без этой правки дважды вызывал f1() { left = create_variable_reference(vdn, loopVariableLocation); right = initialValue; res = find_operator(compiler_string_consts.assign_name, left, right, loopVariableLocation); head_stmts.statements.AddElement(res); } location initialValueLocation = 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, initialValueLocation); right = create_variable_reference(vdn, finishValueLocation); expression_node right_border = create_variable_reference(vdn_finish, finishValueLocation); switch (_for_node.cycle_type) { case for_cycle_type.to: { sn_inc = convertion_data_and_alghoritms.create_simple_function_call(oti.inc_method, loopVariableLocation, left); sn_while = convertion_data_and_alghoritms.create_simple_function_call(oti.lower_method, finishValueLocation, right, right_border); sn_init_while = convertion_data_and_alghoritms.create_simple_function_call(oti.lower_eq_method, finishValueLocation, right, right_border); break; } case for_cycle_type.downto: { sn_inc = convertion_data_and_alghoritms.create_simple_function_call(oti.dec_method, loopVariableLocation, left); sn_while = convertion_data_and_alghoritms.create_simple_function_call(oti.greater_method, finishValueLocation, right, right_border); sn_init_while = convertion_data_and_alghoritms.create_simple_function_call(oti.greater_eq_method, finishValueLocation, right, right_border); break; } } CheckToEmbeddedStatementCannotBeADeclaration(_for_node.statements); //DarkStar Modifed //исправил ошибку: не работали break в циклах TreeRealization.for_node forNode = new TreeRealization.for_node(null, sn_while, sn_init_while, sn_inc, null, get_location(_for_node)); if (vdn.type == SystemLibrary.SystemLibrary.bool_type) { forNode.bool_cycle = true; } context.cycle_stack.push(forNode); 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(); forNode.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(forNode.body); forNode.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(forNode); #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, forNode, vdn, initialValue, finishValue, this); CurrentParallelPosition = ParallelPosition.Outside; if (stl != null) { var f = _for_node.DescendantNodes().OfType <function_lambda_definition>().FirstOrDefault(); if (f != null) { AddError(get_location(f), "OPENMP_CONTROLLED_CONSTRUCTIONS_CANNOT_CONTAIN_LAMBDAS"); } OpenMP.LoopVariables.Pop(); return_value(stl); return; } } if (OpenMP.ForsFound) { OpenMP.LoopVariables.Pop(); } #endregion return_value(head_stmts); }