示例#1
0
        // Использует итерационный алгоритм для задачи распространения констант OUT[B] = fB(IN[B])
        // На вход получает _in Stream из которого создается DataStreamValue - Поток данных(реализация на множествах для ITA)
        // Выход новый Stream после изменения значений для присваиваний из tACodeLines
        // где SemilatticeStreamValue - обёртка над именем переменной и её значением из полурешётки констант SemilatticeValue
        // где DataStreamTable - Поток данных(реализация на словаре для реализации алгоритма и более удобной работы)
        public HashSet <SemilatticeStreamValue> Calculate(HashSet <SemilatticeStreamValue> _in, ThreeAddressCode tACodeLines)
        {
            basicBlock = tACodeLines;
            var result           = new HashSet <SemilatticeStreamValue>();
            var dataStreamValue1 = new DataStreamValue(_in);
            var dataStreamValue2 = new DataStreamValue();

            foreach (TacNode node in tACodeLines)
            {
                if (node is TacAssignmentNode assign)
                {
                    var idVar     = assign.LeftPartIdentifier;
                    var value1    = assign.FirstOperand;
                    var operation = assign.Operation;
                    var value2    = assign.SecondOperand;
                    var table     = new DataStreamTable(dataStreamValue1.Stream, dataStreamValue2.Stream);
                    if (IsSimpleAssignNode(assign))
                    {
                        dataStreamValue2.ChangeStreamValue(idVar, table.GetValue(value1));
                    }
                    else
                    {
                        var semVal1 = table.GetValue(value1);
                        var semVal2 = table.GetValue(value2);
                        if (semVal1.TypeValue == SemilatticeValueEnum.CONST && semVal2.TypeValue == SemilatticeValueEnum.CONST)
                        {
                            double val1 = double.Parse(semVal1.ConstValue);
                            double val2 = double.Parse(semVal2.ConstValue);
                            double val3 = 0;
                            switch (operation)
                            {
                            case "+":
                                val3 = val1 + val2;
                                break;

                            case "-":
                                val3 = val1 - val2;
                                break;

                            case "/":
                                val3 = val1 / val2;
                                break;

                            case "*":
                                val3 = val1 * val2;
                                break;
                            }
                            dataStreamValue2.ChangeStreamValue(idVar, new SemilatticeValue(SemilatticeValueEnum.CONST, val3.ToString()));
                        }
                        else if (semVal1.TypeValue == SemilatticeValueEnum.NAC || semVal2.TypeValue == SemilatticeValueEnum.NAC)
                        {
                            dataStreamValue2.ChangeStreamValue(idVar, new SemilatticeValue(SemilatticeValueEnum.NAC));
                        }
                        else
                        {
                            dataStreamValue2.ChangeStreamValue(idVar, new SemilatticeValue(SemilatticeValueEnum.UNDEF));
                        }
                    }
                }
            }
            var dataStreamValue3 = dataStreamValue1 ^ dataStreamValue2;

            return(dataStreamValue3.Stream);
        }