public override void visit(slice_expr sl) { expression_list el = null; if (sl.slices == null) { el = construct_expression_list_for_slice_expr(sl); } else { el = construct_expression_list_for_slice_expr_multi(sl); // то это многомерный массив } // надо как-то запретить многомерные слайсы в левой части присваивания if (sl.Parent is assign parent_assign && parent_assign.to == sl) { // если это многомерный слайс - кинуть ошибку if (sl.slices != null) { // запретим пока или вовсе throw new SyntaxVisitorError("MULTIDIMENSIONAL_SLICES_FORBIDDEN_IN_LEFT_SIDE_OF_ASSIGNMENT", sl.source_context); } el.Insert(0, parent_assign.from); var mc = method_call.NewP( dot_node.NewP( sl.v, new ident("SystemSliceAssignment", sl.v.source_context), sl.v.source_context), el, sl.source_context); var systemSliceAssignmentCall = new procedure_call(mc, sl.source_context); var typeCompatibilityCheck = GetAssignmentTypeCompatibilityCheck(sl, parent_assign.from, mc); var checkAndDesugaredSliceBlock = new statement_list(typeCompatibilityCheck, systemSliceAssignmentCall); checkAndDesugaredSliceBlock.source_context = sl.source_context; ReplaceUsingParent(parent_assign, checkAndDesugaredSliceBlock); visit(systemSliceAssignmentCall); // обойти заменённое на предмет наличия такого же синтаксического сахара }
expression_list construct_expression_list_for_slice_expr_multi(slice_expr sl) { if (sl.slices == null) { return(null); // упадёт - это ошибка компилятора } var el = new expression_list(); // будем наполнять кортежами - самое простое var sc = sl.source_context; foreach (var slice in sl.slices) { var tup = new dot_node(new dot_node(new ident("?System", sc), new ident("Tuple", sc), sc), new ident("Create", sc), sc); var eel = new expression_list(); // пытаемся разобраться с ^1 var sl1 = slice.Item1; eel.Add(sl1); IndexVisitor.New.ProcessNode(sl1); // индексный визитор сам не вызывается поскольку в многомерных срезах хранится List кортежей троек expression, который сам не обходится var sl2 = slice.Item2; eel.Add(sl2); IndexVisitor.New.ProcessNode(sl2); var sl3 = slice.Item3; // и step тоже надо обходить!!! eel.Add(sl3); IndexVisitor.New.ProcessNode(sl3); var mc = new method_call(tup, eel, sc); // sc - не очень хорошо - ошибка будет в общем месте el.Add(mc); // по идее все параметры готовы. Надо только проверить, что они целые } return(el); }
expression_list construct_expression_list_for_slice_expr(slice_expr sl) { // situation = 0 - ничего не пропущено // situation = 1 - пропущен from // situation = 2 - пропущен to // situation = 3 - пропущены from и to // Пропущенность кодируется тем, что в соответствующем поле - int.MaxValue // step может просто отсутствовать - это параметр по умолчанию в SystemSlice int situation = 0; if ((sl.from is int32_const) && (sl.from as int32_const).val == int.MaxValue) { situation += 1; } if ((sl.to is int32_const) && (sl.to as int32_const).val == int.MaxValue) { situation += 2; } var el = new expression_list(); el.Add(new int32_const(situation)); el.Add(sl.from); // Это плохо - считается 2 раза. Надо делать semantic_expr_node !!!? Нет!!! // Если там будет лямбда, то не будет работать - известно, что semantic_expr_node не работает с лямбдами // т.к. они несколько раз обходят код. el.Add(sl.to); if (sl.step != null) { el.Add(sl.step); } return(el); }
public addressed_value Into(addressed_value x, addressed_value v) // При возникновении новой конструкции в грамматике variable добавить обработку сюда { if (v.GetType() == typeof(dot_question_node)) { var vv = v as dot_question_node; var res = new dot_question_node(Into(x, vv.left), vv.right, x.source_context); return(res); } else if (v.GetType() == typeof(dot_node)) { var vv = v as dot_node; var res = new dot_node(Into(x, vv.left), vv.right, x.source_context); return(res); } else if (v.GetType() == typeof(indexer)) { var vv = v as indexer; var res = new indexer(Into(x, vv.dereferencing_value), vv.indexes, x.source_context); return(res); } else if (v.GetType() == typeof(slice_expr)) { var vv = v as slice_expr; var res = new slice_expr(Into(x, vv.dereferencing_value), vv.from, vv.to, vv.step, x.source_context); return(res); } else if (v.GetType() == typeof(slice_expr_question)) { var vv = v as slice_expr_question; var res = new slice_expr_question(Into(x, vv.dereferencing_value), vv.from, vv.to, vv.step, x.source_context); return(res); } else if (v.GetType() == typeof(method_call)) { var vv = v as method_call; var res = new method_call(Into(x, vv.dereferencing_value), vv.parameters, x.source_context); return(res); } else if (v.GetType() == typeof(roof_dereference)) { var vv = v as roof_dereference; var res = new roof_dereference(Into(x, vv.dereferencing_value), x.source_context); return(res); } else if (v.GetType() == typeof(ident_with_templateparams)) { var vv = v as ident_with_templateparams; var res = new ident_with_templateparams(Into(x, vv.name), vv.template_params, x.source_context); return(res); } else { var res = new dot_node(x, v, x.source_context); return(res); } }
public override void visit(slice_expr sl) { var el = construct_expression_list_for_slice_expr(sl); // Проблема в том, что тут тоже надо перепрошивать Parent! var mc = method_call.NewP(dot_node.NewP(sl.v, new ident("SystemSlice", sl.v.source_context), sl.v.source_context), el, sl.source_context); var sug = sugared_addressed_value.NewP(sl, mc, sl.source_context); ReplaceUsingParent(sl, sug); visit(mc); // обойти заменённое на предмет наличия такого же синтаксического сахара }
public override void visit(slice_expr sl) { var el = construct_expression_list_for_slice_expr(sl); if (sl.Parent is assign parent_assign && parent_assign.to == sl) { el.Insert(0, parent_assign.from); var mc = method_call.NewP( dot_node.NewP( sl.v, new ident("SystemSliceAssignment", sl.v.source_context), sl.v.source_context), el, sl.source_context); var systemSliceAssignmentCall = new procedure_call(mc, sl.source_context); var typeCompatibilityCheck = GetAssignmentTypeCompatibilityCheck(sl, parent_assign.from, mc); var checkAndDesugaredSliceBlock = new statement_list(typeCompatibilityCheck, systemSliceAssignmentCall); checkAndDesugaredSliceBlock.source_context = sl.source_context; ReplaceUsingParent(parent_assign, checkAndDesugaredSliceBlock); visit(systemSliceAssignmentCall); // обойти заменённое на предмет наличия такого же синтаксического сахара }
public virtual void visit(slice_expr _slice_expr) { DefaultVisit(_slice_expr); }
public override void visit(slice_expr _slice_expr) { DefaultVisit(_slice_expr); pre_do_visit(_slice_expr); visit(slice_expr.v); visit(slice_expr.from); visit(slice_expr.to); visit(slice_expr.step); post_do_visit(_slice_expr); }
public virtual void post_do_visit(slice_expr _slice_expr) { }