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);
        }
Beispiel #4
0
 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); // обойти заменённое на предмет наличия такого же синтаксического сахара
        }
Beispiel #6
0
        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 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);
		}
Beispiel #10
0
		public virtual void post_do_visit(slice_expr _slice_expr)
		{
		}