public override void visit(assign_tuple asstup) { var sl = new statement_list(); sl.Add(new semantic_check_sugared_statement_node(asstup)); // Это нужно для проверок на этапе преобразования в семантику var tname = "#temp_var" + UniqueNumStr(); var tt = new var_statement(new ident(tname), asstup.expr); sl.Add(tt); var n = asstup.vars.variables.Count(); for (var i = 0; i < n; i++) { var a = new assign(asstup.vars.variables[i], new dot_node(new ident(tname), new ident("Item" + (i + 1).ToString())), Operators.Assignment, asstup.vars.variables[i].source_context); sl.Add(a); } // Замена 1 оператор на 1 оператор - всё OK ReplaceUsingParent(asstup, sl); visit(asstup.expr); }
public override void visit(assign _assign) { var loc = get_location(_assign); addressed_expression to; expression_node from; AssignCheckAndConvert(_assign, out to, out from); InferLambdaResultTypeFromAssignment(_assign, from, to); if (ProcessAssignToPropertyIfPossible(_assign, to, loc, from)) { return; } if (ProcessAssignmentToEventIfPossible(_assign, to, from, loc)) { return; } if (ProcessAssignmentToShortStringIfPossible(_assign, to, from, loc)) { return; } assign_is_converting = true; statement_node en = find_operator(_assign.operator_type, to, from, get_location(_assign)); assign_is_converting = false; return_value(en); }
public statement_list NewLambdaBody(expression expr_l1, LexLocation loc) { var sl = new statement_list(); sl.expr_lambda_body = true; var id = new ident("result"); var op = new op_type_node(Operators.Assignment); //_op_type_node.source_context = parsertools.GetTokenSourceContext(); var ass = new assign(id, expr_l1, op.type); parsertools.create_source_context(ass, id, expr_l1); // дурацкая функция - если хотя бы у одного sc=null, то возвращает null if (ass.source_context == null) { if (expr_l1.source_context != null) { ass.source_context = expr_l1.source_context; } else if (id.source_context != null) { ass.source_context = id.source_context; } } sl.subnodes.Add(ass); sl.source_context = loc; return(sl); }
public statement MyStmt(expression ex, statement st) { // Проверить, что в ex - целый тип // Сделать специальный узел для проверки new semantic_check("Тип проверки",params syntax_node[] ob) // Включать этот узел первым для "сахарных" узлов синтаксического дерева var sc = new semantic_check("ExprIsInteger", ex); var id = new ident("#my"); var idlist = new ident_list(id); var typ = new named_type_reference("integer"); var one = new int32_const(1); var vdef = new var_def_statement(idlist, typ, one, definition_attribute.None, false, null); var vstat = new var_statement(vdef, null); var ass = new assign(new ident("#my"), one, Operators.AssignmentAddition); var stlistwhile = new statement_list(st); stlistwhile.Add(ass); var bin = new bin_expr(id, ex, Operators.LessEqual); var wh = new while_node(bin, stlistwhile, WhileCycleType.While); var stlist = new statement_list(sc); stlist.Add(vstat); stlist.Add(wh); return(stlist); }
// !Patterns public override void visit(assign assignment) { var to = assignment.to as ident; var from = assignment.from; if (to != null && assignment.operator_type == Operators.Assignment && to.name.ToLower() == RESULT_KEY_WORD) { var converted = syntaxTreeVisitor.convert_strong(from); if (converted is typed_expression) { delegated_methods dm = converted.type as delegated_methods; if (dm.empty_param_method != null) { converted = syntaxTreeVisitor.convert_typed_expression_to_function_call(converted as typed_expression); } } resultExpressionsTypes.Add(new Tuple <type_node, expression, expression_node>(converted.type, from, converted)); var si_list = syntaxTreeVisitor.context.find(RESULT_KEY_WORD); if (si_list != null && si_list.Count > 0 && si_list[0].sym_info == null) { si_list[0].sym_info = new local_variable(RESULT_KEY_WORD, converted.type, syntaxTreeVisitor.context.top_function, null); } } }
public static procedure_definition BuildToStringFuncForAutoClass(List <ident> names) { var pal = new procedure_attributes_list(proc_attribute.attr_override); var fp = new formal_parameters(); var ff = new function_header("ToString", "string", fp, pal); var cleft = new char_const('('); var cright = new char_const(')'); var ccomma = new char_const(','); bin_expr ex = new bin_expr(cleft, cright, Operators.Plus); for (var i = 0; i < names.Count; i++) { var dn = new dot_node(names[i], new ident("ToString")); var asnode = new typecast_node(names[i], new named_type_reference("object"), op_typecast.as_op); var eqnode = new bin_expr(asnode, new nil_const(), Operators.Equal); var expr = new question_colon_expression(eqnode, new string_const("nil"), dn); ex.left = new bin_expr(ex.left, expr, Operators.Plus); if (i < names.Count - 1) { ex.left = new bin_expr(ex.left, ccomma, Operators.Plus); } } var ass = new assign("Result", ex); return(BuildShortProcFuncDefinitionNoSC(ff, ass)); }
public override void visit(assign_tuple asstup) { // тут возможно ошибка более глубокая - в semantic_check_sugared_statement_node(asstup) возможно остаются во вложенных лямбдах другие assign_tuple var sl = new statement_list(); sl.Add(new semantic_check_sugared_statement_node(typeof(assign_tuple), new List <syntax_tree_node> { asstup.vars, asstup.expr }, asstup.source_context)); // Это нужно для проверок на этапе преобразования в семантику var tname = "#temp_var" + UniqueNumStr(); var tt = new var_statement(new ident(tname), asstup.expr); sl.Add(tt); var n = asstup.vars.variables.Count(); for (var i = 0; i < n; i++) { var a = new assign(asstup.vars.variables[i], new dot_node(new ident(tname), new ident("Item" + (i + 1).ToString())), Operators.Assignment, asstup.vars.variables[i].source_context); sl.Add(a); } // Замена 1 оператор на 1 оператор - всё OK ReplaceUsingParent(asstup, sl); visit(asstup.expr); }
public override void visit(assign an) { if (an.operator_type == Operators.AssignmentAddition || an.operator_type == Operators.AssignmentMultiplication || an.operator_type == Operators.AssignmentDivision) { ExtAssignCount++; } base.visit(an); }
public ActionResult Assign(int id) { theId = id; assign assign = new assign(); ViewBag.reviewer_id = new SelectList(db.AspNetUsers.Where(x => x.AspNetUserRoles.Select(y => y.RoleId).Contains("3")), "Id", "UserName"); return(View(assign)); }
public override void visit(assign value) { var to = value.to as ident; if (to != null && value.operator_type == Operators.Assignment && to.name.ToLower() == "result") { exprList.Add(value.from); } }
public override void visit(assign _assign) { executer.visit(_assign); if (_assign.to != null) this.visit((dynamic)_assign.to); if (_assign.from != null) this.visit((dynamic)_assign.from); if (_assign.attributes != null) this.visit((dynamic)_assign.attributes); }
public override void visit(assign assignment) { var to = assignment.to as ident; var from = assignment.from; if (to != null && assignment.operator_type == Operators.Assignment && to.name.ToLower() == RESULT_KEY_WORD) { var converted = syntaxTreeVisitor.convert_strong(from); resultExpressionsTypes.Add(new Tuple <type_node, expression, expression_node>(converted.type, from, converted)); } }
/// <summary> /// Выводит тип результата лямбды по первому присваиванию переменной Result. /// </summary> private void InferLambdaResultTypeFromAssignment(assign _assign, expression_node from, addressed_expression to) { if (stflambda.Count > 0) // мы находимся внутри лямбды - возможно, вложенной { var fld = stflambda.Peek(); if (_assign.to is ident && (_assign.to as ident).name.ToLower() == "result" && fld.RealSemTypeOfResExpr == null) // если это - первое присваивание Result { fld.RealSemTypeOfResExpr = from.type; fld.RealSemTypeOfResult = to.type; } } }
public statement_list NewLambdaBody(expression expr_l1, LexLocation loc) { var sl = new statement_list(); sl.expr_lambda_body = true; var id = new ident("result"); var op = new op_type_node(Operators.Assignment); //_op_type_node.source_context = parsertools.GetTokenSourceContext(); var ass = new assign(id, expr_l1, op.type); parsertools.create_source_context(ass, id, expr_l1); sl.subnodes.Add(ass); sl.source_context = loc; return(sl); }
public ActionResult Assign([Bind(Include = "paper_id, reviewer_id, aaa")] assign assign) { assign.paper_id = theId; ViewBag.reviewer_id = new SelectList(db.AspNetUsers, "Id", "UserName", assign.reviewer_id); if (ModelState.IsValid) { db.assign.Add(assign); db.SaveChanges(); if (User.IsInRole("Chair")) { return(RedirectToAction("IndexChair")); } if (User.IsInRole("Admin")) { return(RedirectToAction("IndexAdmin")); } return(RedirectToAction("Index")); } return(View(assign)); }
public override void visit(assign _assign) { var loc = get_location(_assign); addressed_expression to; expression_node from; AssignCheckAndConvert(_assign, out to, out from); InferLambdaResultTypeFromAssignment(_assign, from, to); if (ProcessAssignToPropertyIfPossible(_assign, to, loc, from)) { return; } if (ProcessAssignmentToEventIfPossible(_assign, to, from, loc)) { return; } if (ProcessAssignmentToShortStringIfPossible(_assign, to, from, loc)) { return; } assign_is_converting = true; if (to.type.type_special_kind == type_special_kind.set_type && from.type.type_special_kind == type_special_kind.set_type && // SSM 12/07/19 fix #1795 convertion_data_and_alghoritms.is_value_int_type(to.type.element_type) && convertion_data_and_alghoritms.is_value_real_type(from.type.element_type)) { AddError(new CanNotConvertTypes(from, from.type, to.type, from.location)); } statement_node en = find_operator(_assign.operator_type, to, from, get_location(_assign)); assign_is_converting = false; return_value(en); }
/// <summary> /// Сопоставляет составному присваиванию его аналог. /// Оператору '+=' возвращает '+', для '-=' возвращает '-', и т.д. /// </summary> /// <returns>Возвращает оператор. Если было передано не присваивание возвращает Operators.Undefined</returns> private static Operators MapCompositeAssignmentOperatorToSameBinaryOperator(assign _assign) { switch (_assign.operator_type) { case Operators.AssignmentAddition: return(Operators.Plus); case Operators.AssignmentBitwiseAND: return(Operators.BitwiseAND); case Operators.AssignmentBitwiseLeftShift: return(Operators.BitwiseLeftShift); case Operators.AssignmentBitwiseOR: return(Operators.BitwiseOR); case Operators.AssignmentBitwiseRightShift: return(Operators.BitwiseRightShift); case Operators.AssignmentBitwiseXOR: return(Operators.BitwiseXOR); case Operators.AssignmentDivision: return(Operators.Division); case Operators.AssignmentModulus: return(Operators.ModulusRemainder); case Operators.AssignmentMultiplication: return(Operators.Multiplication); case Operators.AssignmentSubtraction: return(Operators.Minus); default: return(Operators.Undefined); } }
/// <summary> /// Обрабатывает случай, когда левая часть присваивания short string. /// </summary> /// <returns>True - обработка прошла, иначе False.</returns> private bool ProcessAssignmentToShortStringIfPossible(assign _assign, addressed_expression to, expression_node from, location loc) { if (_assign.operator_type == Operators.Assignment) { if (to is simple_array_indexing && (to as simple_array_indexing).simple_arr_expr.type.type_special_kind == type_special_kind.short_string) { expression_node expr = (to as simple_array_indexing).simple_arr_expr; expression_node ind_expr = (to as simple_array_indexing).ind_expr; from = convertion_data_and_alghoritms.convert_type(from, SystemLibrary.SystemLibrary.char_type); ind_expr = convertion_data_and_alghoritms.create_simple_function_call( SystemLibInitializer.SetCharInShortStringProcedure.sym_info as function_node, loc, expr, ind_expr, new int_const_node((expr.type as short_string_type_node).Length, null), from); return_value(find_operator(compiler_string_consts.assign_name, expr, ind_expr, get_location(_assign))); return(true); } if (to.type.type_special_kind == type_special_kind.short_string) { if (from.type is null_type_node) { AddError(get_location(_assign), "NIL_WITH_VALUE_TYPES_NOT_ALLOWED"); } expression_node clip_expr = convertion_data_and_alghoritms.create_simple_function_call( SystemLibInitializer.ClipShortStringProcedure.sym_info as function_node, loc, convertion_data_and_alghoritms.convert_type(from, SystemLibrary.SystemLibrary.string_type), new int_const_node((to.type as short_string_type_node).Length, null)); statement_node en = find_operator(compiler_string_consts.assign_name, to, clip_expr, get_location(_assign)); return_value(en); return(true); } } return(false); }
/// <summary> /// Обрабатывает случай, когда левая часть присваивания имеет тип event. /// </summary> /// <returns>True - обработка прошла, иначе False.</returns> private bool ProcessAssignmentToEventIfPossible(assign _assign, addressed_expression to, expression_node from, location loc) { if ((to.semantic_node_type == semantic_node_type.static_event_reference) || (to.semantic_node_type == semantic_node_type.nonstatic_event_reference)) { statement_node event_assign = null; static_event_reference ser = (static_event_reference)to; expression_node right_del = convertion_data_and_alghoritms.convert_type(from, ser.en.delegate_type); switch (_assign.operator_type) { case Operators.AssignmentAddition: { if (to.semantic_node_type == semantic_node_type.static_event_reference) { event_assign = convertion_data_and_alghoritms.create_simple_function_call( ser.en.add_method, loc, right_del); } else { if (ser.en.semantic_node_type == semantic_node_type.compiled_event) { nonstatic_event_reference nser = (nonstatic_event_reference)ser; compiled_function_node cfn = (compiled_function_node)ser.en.add_method; compiled_function_call tmp_event_assign = new compiled_function_call(cfn, nser.obj, loc); tmp_event_assign.parameters.AddElement(right_del); event_assign = tmp_event_assign; } else if (ser.en.semantic_node_type == semantic_node_type.common_event) { nonstatic_event_reference nser = (nonstatic_event_reference)ser; common_method_node cfn = (common_method_node)ser.en.add_method; common_method_call tmp_event_assign = new common_method_call(cfn, nser.obj, loc); tmp_event_assign.parameters.AddElement(right_del); event_assign = tmp_event_assign; } } break; } case Operators.AssignmentSubtraction: { if (to.semantic_node_type == semantic_node_type.static_event_reference) { event_assign = convertion_data_and_alghoritms.create_simple_function_call( ser.en.remove_method, loc, right_del); } else { if (ser.en.semantic_node_type == semantic_node_type.compiled_event) { nonstatic_event_reference nser = (nonstatic_event_reference)ser; compiled_function_node cfn = (compiled_function_node)ser.en.remove_method; compiled_function_call tmp_event_assign = new compiled_function_call(cfn, nser.obj, loc); tmp_event_assign.parameters.AddElement(right_del); event_assign = tmp_event_assign; } else if (ser.en.semantic_node_type == semantic_node_type.common_event) { nonstatic_event_reference nser = (nonstatic_event_reference)ser; common_method_node cfn = (common_method_node)ser.en.remove_method; common_method_call tmp_event_assign = new common_method_call(cfn, nser.obj, loc); tmp_event_assign.parameters.AddElement(right_del); event_assign = tmp_event_assign; } } break; } default: { AddError(loc, "ASSIGN_TO_EVENT"); //throw new CanNotApplyThisOperationToEvent break; } } return_value(event_assign); return(true); } return(false); }
/// <summary> /// Обрабатывает случай, когда левая часть присваивания свойство. /// </summary> /// <returns>True - обработка прошла, иначе False.</returns> private bool ProcessAssignToPropertyIfPossible(assign _assign, addressed_expression to, location loc, expression_node from) { //проверка на обращение к полю записи возвращенной из функции с целью присваивания //нужно чтобы пользователь не мог менять временный обьект if (to.semantic_node_type == semantic_node_type.static_property_reference || to.semantic_node_type == semantic_node_type.non_static_property_reference) { property_node pn; if (to.semantic_node_type == semantic_node_type.static_property_reference) { pn = (to as static_property_reference).property; } else { pn = (to as non_static_property_reference).property; } var ot = MapCompositeAssignmentOperatorToSameBinaryOperator(_assign); var oper_ass_in_prop = ot != Operators.Undefined; if (_assign.operator_type == Operators.Assignment || oper_ass_in_prop) { if (oper_ass_in_prop) { if (pn.get_function == null) { AddError(loc, "THIS_PROPERTY_{0}_CAN_NOT_BE_READED", pn.name); } base_function_call prop_expr; if (to.semantic_node_type == semantic_node_type.non_static_property_reference) { prop_expr = create_not_static_method_call(pn.get_function, (to as non_static_property_reference).expression, loc, false); prop_expr.parameters.AddRange((to as non_static_property_reference).fact_parametres); } else { prop_expr = create_static_method_call(pn.get_function, loc, pn.comprehensive_type, false); prop_expr.parameters.AddRange((to as static_property_reference).fact_parametres); } from = find_operator(ot, prop_expr, from, loc); } if (to.semantic_node_type == semantic_node_type.static_property_reference) { static_property_reference spr = (static_property_reference)to; if (spr.property.set_function == null) { AddError(loc, "THIS_PROPERTY_{0}_CAN_NOT_BE_WRITED", spr.property.name); } check_property_params(spr, loc); function_node set_func = spr.property.set_function; from = convertion_data_and_alghoritms.convert_type(from, spr.property.property_type); spr.fact_parametres.AddElement(from); base_function_call bfc = create_static_method_call(set_func, loc, spr.property.comprehensive_type, true); bfc.parameters.AddRange(spr.fact_parametres); return_value((statement_node)bfc); } else if (to.semantic_node_type == semantic_node_type.non_static_property_reference) { non_static_property_reference nspr = (non_static_property_reference)to; check_property_params(nspr, loc); from = convertion_data_and_alghoritms.convert_type(from, nspr.property.property_type); nspr.fact_parametres.AddElement(from); //Обработка s[i]:='c' if (SystemUnitAssigned) { if (nspr.property.comprehensive_type == SystemLibrary.SystemLibrary.string_type) { if (nspr.property == SystemLibrary.SystemLibrary.string_type.default_property_node) { if (SystemLibInitializer.StringDefaultPropertySetProcedure != null) { expressions_list exl = new expressions_list(); exl.AddElement(nspr.expression); exl.AddElement(nspr.fact_parametres[0]); exl.AddElement(from); function_node fn = convertion_data_and_alghoritms.select_function(exl, SystemLibInitializer.StringDefaultPropertySetProcedure .SymbolInfo, loc); expression_node ret = convertion_data_and_alghoritms.create_simple_function_call(fn, loc, exl.ToArray()); return_value((statement_node)ret); return(true); } } } } if (nspr.property.set_function == null) { AddError(loc, "THIS_PROPERTY_{0}_CAN_NOT_BE_WRITED", nspr.property.name); } function_node set_func = nspr.property.set_function; base_function_call bfc = create_not_static_method_call(set_func, nspr.expression, loc, true); bfc.parameters.AddRange(nspr.fact_parametres); return_value((statement_node)bfc); } return(true); } } return(false); }
public virtual void visit(assign _assign) { }
public override void visit(assign _assign) { prepare_node(_assign.to, "to"); prepare_node(_assign.from, "from"); }
public override void visit(assign _assign) { var loc = _visitor.get_location(_assign); _visitor.internal_is_assign = true; var to = _visitor.convert_address_strong(_assign.to); _visitor.internal_is_assign = false; if (to == null) { _visitor.AddError(_visitor.get_location(_assign.to), "CAN_NOT_ASSIGN_TO_LEFT_PART"); } bool flag; var node_type = general_node_type.constant_definition; if (convertion_data_and_alghoritms.check_for_constant_or_readonly(to, out flag, out node_type)) { if (flag) { _visitor.AddError(to.location, "CAN_NOT_ASSIGN_TO_CONSTANT_OBJECT"); } else { _visitor.AddError(new CanNotAssignToReadOnlyElement(to.location, node_type)); } } if (to is class_field_reference) { if ((to as class_field_reference).obj.type.type_special_kind == type_special_kind.record && (to as class_field_reference).obj is base_function_call) { //исключим ситуацию обращения к массиву if (!(((to as class_field_reference).obj is common_method_call) && ((to as class_field_reference).obj as common_method_call).obj.type.type_special_kind == type_special_kind.array_wrapper)) { _visitor.AddError(loc, "LEFT_SIDE_CANNOT_BE_ASSIGNED_TO"); } } } else if (_visitor.context.is_in_cycle() && !SemanticRules.AllowChangeLoopVariable && to.semantic_node_type == semantic_node_type.namespace_variable_reference) { if (_visitor.context.is_loop_variable((to as namespace_variable_reference).var)) { _visitor.AddError(to.location, "CANNOT_ASSIGN_TO_LOOP_VARIABLE"); } } else if (_visitor.context.is_in_cycle() && !SemanticRules.AllowChangeLoopVariable && to.semantic_node_type == semantic_node_type.local_variable_reference) { if (_visitor.context.is_loop_variable((to as local_variable_reference).var)) { _visitor.AddError(to.location, "CANNOT_ASSIGN_TO_LOOP_VARIABLE"); } } else if (_visitor.context.is_in_cycle() && !SemanticRules.AllowChangeLoopVariable && to.semantic_node_type == semantic_node_type.local_block_variable_reference) { if (_visitor.context.is_loop_variable((to as local_block_variable_reference).var)) { _visitor.AddError(to.location, "CANNOT_ASSIGN_TO_LOOP_VARIABLE"); } } else if (to is simple_array_indexing) { if ((to as simple_array_indexing).simple_arr_expr is class_field_reference && ((to as simple_array_indexing).simple_arr_expr as class_field_reference).obj != null && ((to as simple_array_indexing).simple_arr_expr as class_field_reference).obj is constant_node) { _visitor.AddError(loc, "LEFT_SIDE_CANNOT_BE_ASSIGNED_TO"); } } ProcessNode(_assign.to); ProcessNode(_assign.from); }
public virtual void visit(assign _assign) { DefaultVisit(_assign); }
/* * public override void Exit(syntax_tree_node st) * { * if (st is slice_expr_question) * { * ProceedSliceQuestionExpr(st as slice_expr_question); * } else if (st is slice_expr) * { * ProceedSliceExpr(st as slice_expr); * } * }*/ public override void visit(assign _assign) { _assign.from.visit(this); _assign.to.visit(this); }
public virtual void post_do_visit(assign _assign) { }
// frninja 21/05/16 public override void visit(foreach_stmt frch) { // Полный код Loweringа c yield_unknown_foreach_type = integer // var a: System.Collections.Generic.IEnumerable<integer>; // a := l; // var en := a.GetEnumerator(); // while en.MoveNext do // begin // var curr := en.Current; // var не нужно ставить если curr была описана раньше // Print(curr); // end; /// // var a: System.Collections.Generic.IEnumerable<yield_unknown_foreach_type> := l; var foreachCollIdent = this.NewForeachCollectionName(); var foreachCollType = new template_type_reference(new named_type_reference("System.Collections.Generic.IEnumerable"), new template_param_list(new yield_unknown_foreach_type(frch))); var foreachCollVarDef = new var_statement(foreachCollIdent, foreachCollType); var ass = new assign(foreachCollIdent, frch.in_what); // var en := a.GetEnumerator(); var enumeratorIdent = this.NewEnumeratorName(); var enumeratorVarDef = new var_statement(enumeratorIdent, new method_call(new dot_node(foreachCollIdent, new ident("GetEnumerator")), new expression_list())); //var curr := en.Current; // Переменная цикла foreach. Есть три варианта: // 1. foreach x in l do -> curr := en.Current; // 2. foreach var x in l do -> var curr := en.Current; // 3. foreach var x: T in l do -> var curr: T := en.Current; var currentIdent = frch.identifier; statement st = null; var curExpr = new dot_node(enumeratorIdent, "Current"); // С типом if (frch.type_name == null) // 1. foreach x in l do -> curr := en.Current; { st = new assign(currentIdent, curExpr); } else if (frch.type_name is no_type_foreach) // 2. foreach var x in l do -> var curr := en.Current; { // Получаем служебное имя с $ и заменяем его в теле цикла currentIdent = this.NewVarNames(frch.identifier).VarName; var replacerVis = new ReplaceVariableNameVisitor(frch.identifier, currentIdent); frch.visit(replacerVis); st = new var_statement(currentIdent, curExpr); } else // 3. foreach var x: T in l do -> var curr: T := en.Current; { // Получаем служебное имя с $ и заменяем его в теле цикла currentIdent = this.NewVarNames(frch.identifier).VarName; var replacerVis = new ReplaceVariableNameVisitor(frch.identifier, currentIdent); frch.visit(replacerVis); st = new var_statement(currentIdent, frch.type_name, curExpr); } // Добавляем тело цикла в stl var stl = new statement_list(st); ProcessNode(frch.stmt); // для обработки вложенных конструкций stl.Add(frch.stmt); var whileNode = new while_node(new method_call(new dot_node(enumeratorIdent, "MoveNext"), new expression_list()), stl, WhileCycleType.While); var sq = SeqStatements(foreachCollVarDef, ass, enumeratorVarDef, whileNode); ReplaceStatement(frch, sq); visit(whileNode); // Lowering оставшегося whileNode }
public override void visit(assign _assign) { _assign.to.visit(this); _assign.from.visit(this); AddPossibleComments(_assign); }
public override void visit(assign _assign) { text = "operator_type: " + _assign.operator_type.ToString(); }
/// <summary> /// Преобразует foreach в for, если коллекция это одномерный массив. /// </summary> /// <param name="_foreach_stmt"></param> /// <param name="in_what"></param> /// <returns>True - если преобразование удалось, иначе False</returns> private bool OptimizeForeachInCase1DArray(foreach_stmt _foreach_stmt, expression_node in_what) { var is1dimdynarr = false; var comptn = in_what.type as compiled_type_node; if (comptn != null && comptn.type_special_kind == type_special_kind.array_kind && comptn.rank == 1) { is1dimdynarr = true; } if (!is1dimdynarr) { var comtn = in_what.type as common_type_node; if (comtn != null && comtn.internal_type_special_kind == type_special_kind.array_kind && comtn.rank == 1) { is1dimdynarr = true; } } // SSM 23.08.16 Закомментировал оптимизацию. Не работает с лямбдами. Лямбды обходят старое дерево. А заменить foreach на for на этом этапе пока не получается - не развита инфраструктура if (is1dimdynarr) // Замена foreach на for для массива { // сгенерировать код для for и вызвать соответствующий visit var arrid = GenIdentName(); //var vdarr = new var_statement(arrid, new semantic_addr_value(in_what)); // semantic_addr_value - перевод в синтаксис для мгновенного вычисления семантического выражения, которое уже вычислено в in_what var vdarr = new var_statement(arrid, _foreach_stmt.in_what); var i = GenIdentName(); var x = _foreach_stmt.identifier; // Возможны 3 случая: // 1. _foreach_stmt.type_name = null - значит, переменная определена в другом месте // 2. _foreach_stmt.type_name = no_type_foreach - значит, это for var x in a // 3. _foreach_stmt.type_name = T - значит, это for var x: T in a statement vd; if (_foreach_stmt.type_name == null) // 1. { vd = new assign(x, arrid.indexer(i)); } else if (_foreach_stmt.type_name is no_type_foreach) // 2. { vd = new var_statement(x, arrid.indexer(i)); } else // 3. { vd = new var_statement(x, _foreach_stmt.type_name, arrid.indexer(i)); } // Превратить старое тело в statement_list и добавить к нему в начало x := a[i] или var x := a[i] var newbody = _foreach_stmt.stmt.ToStatementList(); newbody.AddFirst(vd); var high = arrid.dot_node("Length").Minus(1); var fornode = new for_node(i, 0, high, newbody, for_cycle_type.to, null, null, true); var stl = new statement_list(vdarr, fornode); // Замена 1 оператора на 1 оператор. Всё хорошо даже если оператор помечен меткой ReplaceUsingParent(_foreach_stmt, stl); visit(stl); //visit(vdarr); //visit(fornode); return(true); } /// SSM 29.07.16 return(false); }
/// <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 override void visit(assign _assign) { DefaultVisit(_assign); pre_do_visit(_assign); visit(assign.to); visit(assign.from); post_do_visit(_assign); }
bool VisitTypeclassDeclaration(type_declaration typeclassDeclaration) { var typeclassDefinition = typeclassDeclaration.type_def as typeclass_definition; if (typeclassDefinition == null) { return(false); } var typeclassName = typeclassDeclaration.type_name as typeclass_restriction; // TODO: typeclassDefinition.additional_restrictions - translate to usual classes // Creating interface // Get members for typeclass interface var interfaceMembers = new List <class_members>(); foreach (var cm in typeclassDefinition.body.class_def_blocks) { var cmNew = (class_members)cm.Clone(); for (int i = 0; i < cmNew.members.Count; i++) { var member = cmNew.members[i]; if (member is function_header || member is procedure_header) { cmNew.members[i] = member; } else if (member is procedure_definition procDef) { cmNew.members[i] = procDef.proc_header; } AddAttribute(cmNew.members[i], "__TypeclassMemberAttribute"); if (cmNew.members[i] is procedure_header ph) { ConvertOperatorNameIdent(ph); } } interfaceMembers.Add(cmNew); } var interfaceInheritance = (named_type_reference_list)typeclassDefinition.additional_restrictions?.Clone(); if (interfaceInheritance != null) { interfaceInheritance.source_context = null; for (int i = 0; i < interfaceInheritance.types.Count; i++) { if (interfaceInheritance.types[i] is typeclass_reference tr) { interfaceInheritance.types[i] = TypeclassReferenceToInterfaceName(tr.names[0].name, tr.restriction_args); } else { throw new NotImplementedException("Syntactic Error"); } } } var typeclassInterfaceDef = SyntaxTreeBuilder.BuildClassDefinition( interfaceInheritance, null, interfaceMembers.ToArray()); typeclassInterfaceDef.keyword = class_keyword.Interface; var typeclassInterfaceName = new template_type_name("I" + typeclassName.name, RestrictionsToIdentList(typeclassName.restriction_args)); var typeclassInterfaceDecl = new type_declaration(typeclassInterfaceName, typeclassInterfaceDef); typeclassInterfaceDecl.attributes = typeclassDeclaration.attributes; AddAttribute( typeclassInterfaceDecl, "__TypeclassAttribute", new expression_list(new string_const(TypeclassRestrictionToString(typeclassName)))); // Creating class var typeclassDefTranslated = SyntaxTreeBuilder.BuildClassDefinition( new named_type_reference_list(new template_type_reference(typeclassInterfaceName.name, typeclassName.restriction_args)), null, typeclassDefinition.body.class_def_blocks.ToArray()); typeclassDefTranslated.attribute = class_attribute.Abstract; for (int i = 0; i < typeclassDefTranslated.body.class_def_blocks.Count; i++) { var cm = typeclassDefTranslated.body.class_def_blocks[i].members; for (int j = 0; j < cm.Count; j++) { procedure_header header = null; if (cm[j] is procedure_header ph) { header = ph; header.proc_attributes.Add(new procedure_attribute("abstract", proc_attribute.attr_abstract)); } else if (cm[j] is procedure_definition pd) { header = pd.proc_header; header.proc_attributes.Add(new procedure_attribute("virtual", proc_attribute.attr_virtual)); } ConvertOperatorNameIdent(header); } } /* * { * // Add constructor * var cm = typeclassDefTranslated.body.class_def_blocks[0]; * var def = new procedure_definition( * new constructor(), * new statement_list(new empty_statement())); * def.proc_body.Parent = def; * def.proc_header.proc_attributes = new procedure_attributes_list(); * * cm.Add(def); * } */ // Add template parameters for typeclass class(derived typeclasses) ident_list templates = RestrictionsToIdentList(typeclassName.restriction_args); if (typeclassDefinition.additional_restrictions != null) { for (int i = 0; i < typeclassDefinition.additional_restrictions.types.Count; i++) { string name; string templateName; if (typeclassDefinition.additional_restrictions.types[i] is typeclass_reference tr) { name = tr.names[0].name; templateName = TypeclassRestrctionToTemplateName(name, tr.restriction_args).name; } else { throw new NotImplementedException("SyntaxError"); } // Add template parameter templates.Add(templateName); // Add where restriction if (typeclassDefTranslated.where_section == null) { typeclassDefTranslated.where_section = new where_definition_list(); } typeclassDefTranslated.where_section.Add(GetWhereRestriction( interfaceInheritance.types[i], templateName)); // Add methods from derived typeclasses var body = (instancesAndRestrictedFunctions.typeclasses[name].type_def as typeclass_definition).body; foreach (var cdb in body.class_def_blocks) { var cdbNew = new class_members(cdb.access_mod == null ? access_modifer.none : cdb.access_mod.access_level); foreach (var member in cdb.members) { procedure_header memberHeaderNew; if (member is procedure_header || member is function_header) { memberHeaderNew = (procedure_header)member.Clone(); memberHeaderNew.source_context = null; } else if (member is procedure_definition procDefinition) { memberHeaderNew = (procedure_header)procDefinition.proc_header.Clone(); memberHeaderNew.Parent = null; memberHeaderNew.source_context = null; } else { continue; } var variableName = templateName + "Instance"; var parameters = memberHeaderNew.parameters.params_list.Aggregate(new expression_list(), (x, y) => new expression_list(x.expressions.Concat(y.idents.idents).ToList())); expression methodCall = null; if (memberHeaderNew.name.meth_name is operator_name_ident oni) { ConvertOperatorNameIdent(memberHeaderNew); Debug.Assert(parameters.expressions.Count == 2, "Parameters count for operation should be equal to 2"); //methodCall = new bin_expr(parameters.expressions[0], parameters.expressions[1], oni.operator_type); } var callName = new dot_node(variableName, memberHeaderNew.name.meth_name.name); methodCall = new method_call(callName, parameters); statement exec = null; if (memberHeaderNew is function_header) { exec = new assign("Result", methodCall); } else if (memberHeaderNew is procedure_header) { exec = new procedure_call(methodCall as method_call); } var procDef = new procedure_definition( memberHeaderNew, new statement_list( GetInstanceSingletonVarStatement(templateName), exec)); cdbNew.Add(procDef); } typeclassDefTranslated.body.class_def_blocks.Add(cdbNew); } } } var typeclassNameTanslated = new template_type_name(typeclassName.name, templates, typeclassName.source_context); var typeclassDeclTranslated = new type_declaration(typeclassNameTanslated, typeclassDefTranslated, typeclassDeclaration.source_context); typeclassDeclTranslated.attributes = typeclassDeclaration.attributes; AddAttribute( typeclassDeclTranslated, "__TypeclassAttribute", new expression_list(new string_const(TypeclassRestrictionToString(typeclassName)))); Replace(typeclassDeclaration, typeclassDeclTranslated); UpperNodeAs <type_declarations>().InsertBefore(typeclassDeclTranslated, typeclassInterfaceDecl); visit(typeclassInterfaceDecl); visit(typeclassDeclTranslated); return(true); }