예제 #1
0
        // подготавливает (если можно) узел к обработке "брата"
        private void FinalOperations(TBStack current)
        {
            if (inputStack.Count < 2)
            {
                if (!ToDrop()) output.V(current.tvalue);
                return;
            }
            TBStack previous = inputStack.ElementAt(1);
            int ic = inputStack.Count;
            // Вариантов использования значения три: 1) сбросить; 2) сбросить предыдущие и сбросить;
            // 3) вставить в родительское значение.
            // Если этот уровень последний, в котором можно формировать объектное значение,
            // или он следующий за тем, который породил последнюю скобку
            // то надо значение "сбросить"
            bool drop = ToDrop() || previous.dropped; // ic <= slevel + 1 || ic <= currentTreeDepth + 1;
            if (!drop)
            {
                // Проверка на невозможность принять значение в оперативную память
                if (previous.volume + 8 + current.volume > maxElementVolume
                    //|| totalVolume + 8 > maxTotalVolume // эту возможность пока не будем использовать, чтобы не порождать новых ошибок
                    )
                {
                    drop = true;
                    // Сбросить предыдущее
                    // Цикл по элементам стека
                    for (int s_at = ic - currentTreeDepth - 1; s_at > 0; s_at--) // currentTreeDepth - 1
                    {
                        TBStack ste = inputStack.ElementAt(s_at);
                        long index = inputStack.ElementAt(s_at - 1).index;
                        var tp = ste.nodeType;
                        if (tp.Vid == PTypeEnumeration.record)
                        {
                            output.R();
                            if (ste.tvalue != null)
                            {
                                object[] values = (object[])ste.tvalue;
                                for (int i = 0; i < index; i++) output.V(values[i]);
                            }
                        }
                        else if (tp.Vid == PTypeEnumeration.sequence)
                        {
                            output.S();
                            if (ste.tvalue != null)
                            {
                                object[] values = (object[])ste.tvalue;
                                for (int i = 0; i < index; i++) output.V(values[i]);
                            }
                        }
                        else if (tp.Vid == PTypeEnumeration.union)
                        {
                            object[] values = (object[])ste.tvalue;
                            output.U((int)values[0]); // подэлемент ТОЧНО не сформирован
                        }
                        ste.tvalue = null;
                        ste.dropped = true;
                        totalVolume -= ste.volume;
                    }
                    // Установим новое значение currentTreeDepth
                    currentTreeDepth = ic - 1;
                }
                else
                { // Случай, если нет ограничения - записываем значение в позицию индекса
                    if (previous.tvalue == null) previous.tvalue = new object[initialseqsize];
                    previous.tvalue = Set((object[])previous.tvalue, current.tvalue, current.index);
                    previous.volume += 8 + current.volume;
                    totalVolume += 8;
                    current.tvalue = null;
                }
            }
            if ( drop )
            {
                //object value = zstack[current.zposition].value;
                object value = current.tvalue;
                //long volume = zstack[current.zposition].volume;
                long volume = current.volume;
                //output.V(value, current.nodeType);
                output.V(value);
                totalVolume -= volume;
                current.volume = 0;
            }

            PrepareForBrothers(current);
        }
예제 #2
0
 private void PrepareForBrothers(TBStack current)
 {
     if (inputStack.Count == 1) return; // младших братьев не будет
     // Фаза 2: Подготовка к приему "младших братьев"
     TBStack previous = inputStack.ElementAt(1);
     current.volume = 0;
     current.tvalue = null;
     if (previous.nodeType.Vid == PTypeEnumeration.record)
     {
         PTypeRecord mtr = (PTypeRecord)previous.nodeType;
         if (current.index < mtr.Fields.Length - 1)
         {
             current.index += 1;
             current.nodeType = mtr.Fields[current.index].Type;
         }
         //else throw new Exception("Err in serial flow: too many fileds"); // это не нужно
     }
     else if (previous.nodeType.Vid == PTypeEnumeration.sequence)
     {
         current.index += 1;
     }
     else if (previous.nodeType.Vid == PTypeEnumeration.union)
     {
         if (current.index == 1) { } // все в порядке
         else throw new Exception("Err in serial flow: more than 1 subvalue in union");
     }
 }
예제 #3
0
        public void U(int tag)
        {
            TBStack uni = inputStack.Peek();
            if (uni.nodeType.Vid != PTypeEnumeration.union) throw new Exception("unexpected type");
            PTypeUnion mtu = (PTypeUnion)uni.nodeType;
            PType tel = mtu.Variants[tag].Type;
            TBStack uni_el = new TBStack(tel);

            if (ToDrop()) { output.U(tag); uni.dropped = true; }
            else
            { // Надо породить массив и записать в него тег
                uni.dropped = false;
                uni.tvalue = new object[] { tag, null };
                long v = 16 + 16;
                totalVolume += v;
                // Еще надо, чтобы индекс был 1, поскольку тег уже записан
                uni_el.index = 1;
            }

            inputStack.Push(uni_el);
        }