Пример #1
0
 public CalcValue(VarRun v)
 {
     Type   = CalcValueType.Var;
     VarRun = v;
 }
Пример #2
0
        //Вычисляет значение выражения
        public void Calculate()
        {
            var stack   = new Stack <CalcValue>(); //Стек для расчетов
            var stackif = new Stack <FilterIf>();  //Стек для фильтров по if

            stackif.Push(new FilterIf());
            int i = 0, n = CalcParam.Exprs.Length;

            while (i < n)
            {
                var expr = CalcParam.Exprs[i];
                if (!(expr is ExprOp) || !((ExprOp)expr).IsFilterIf)
                {
                    expr.ProcessCalcValue(stack, this);
                }
                else //Обработка операторов If, While и присваиваний
                {
                    var par = new CalcValue[expr.ParamsCount];
                    for (int j = expr.ParamsCount - 1; j >= 0; j--)
                    {
                        par[j] = stack.Pop();
                    }
                    var f   = ((ExprOp)expr).Code;
                    int adr = ((ExprOp)expr).LinkAddress;
                    switch (f)
                    {
                    case "assign":
                    case "assignr":
                    case "assignv":
                    case "assigni":
                    case "assigns":
                        CalcValue z  = null;
                        VarRun    vr = null;
                        switch (f)
                        {
                        case "assign":
                            vr = par[0].VarRun;
                            z  = par[1];
                            break;

                        case "assignr":
                            vr = par[1].VarRun;
                            z  = par[0];
                            break;

                        case "assignv":
                            vr = par[0].VarRun;
                            z  = new CalcValue();
                            break;

                        case "assigni":
                            z = par[2];
                            int ii = par[1].SingleValue.LastMoment.Integer;
                            vr = par[0].VarRun;
                            if (vr.CalcValue == null)
                            {
                                vr.CalcValue = new CalcValue(new SortedDictionary <int, VarRun>());
                            }
                            var ia = vr.CalcValue.IntArray;
                            if (ia.ContainsKey(ii))
                            {
                                vr = ia[ii];
                            }
                            else
                            {
                                vr = new VarRun();
                                ia.Add(ii, vr);
                            }
                            break;

                        case "assigns":
                            z = par[2];
                            string ss = par[1].SingleValue.LastMoment.String;
                            vr = par[0].VarRun;
                            if (vr.CalcValue == null)
                            {
                                vr.CalcValue = new CalcValue(new SortedDictionary <string, VarRun>());
                            }
                            var sa = vr.CalcValue.StringArray;
                            if (sa.ContainsKey(ss))
                            {
                                vr = sa[ss];
                            }
                            else
                            {
                                vr = new VarRun();
                                sa.Add(ss, vr);
                            }
                            break;
                        }
                        if (z.Type == CalcValueType.Void || vr.CalcValue == null)
                        {
                            vr.CalcValue = z;
                        }
                        else
                        {
                            var ppar = new CalcValue[3];
                            ppar[0]      = vr.CalcValue;
                            ppar[1]      = z;
                            ppar[2]      = stackif.Peek().True;
                            vr.CalcValue = stackif.Peek().IsPoints ? ThreadCalc.Funs.GeneralFunction(ppar, vr.DataType, this, null, ThreadCalc.Funs.assignp)
                                                                                                                : ThreadCalc.Funs.GeneralFunction(ppar, vr.DataType, this, ThreadCalc.Funs.assign, null);
                        }
                        vr.CalcValue.ParentParam = z.ParentParam;
                        break;

                    case "begin":
                        stackif.Push(stackif.Peek());
                        break;

                    case "if":
                    case "ifp":
                    case "ifv":
                    case "ifpv":
                        stackif.Push(new FilterIf(stackif.Peek(), par[0], this, f == "ifp" || f == "ifpv"));
                        if (f == "ifv" || f == "ifpv")
                        {
                            stack.Push(stackif.Peek().True);
                        }
                        if (IsFalse(stackif.Peek().True))
                        {
                            if (f == "ifv" || f == "ifpv")
                            {
                                stack.Push(new CalcValue(new SingleValue(new Moment(false))));
                            }
                            i = adr - 1;
                        }
                        break;

                    case "while":
                    case "whilep":
                        stackif.Push(new FilterIf(stackif.Pop(), par[0], this, f == "whilep"));
                        if (IsFalse(stackif.Peek().True))
                        {
                            i = adr - 1;
                        }
                        break;

                    case "else":
                    case "elsev":
                        stackif.Peek().ChangeToElse();
                        if (f == "elsev")
                        {
                            stack.Push(stackif.Peek().True);
                        }
                        if (IsFalse(stackif.Peek().True))
                        {
                            if (f == "elsev")
                            {
                                stack.Push(new CalcValue(new SingleValue(new Moment(false))));
                            }
                            i = adr - 1;
                        }
                        break;

                    case "ret":
                        i = adr - 1;
                        break;

                    case "end":
                        bool ep = stackif.Pop().IsPoints;
                        if (par.Length == 2)
                        {
                            stack.Push(par[1]);
                        }
                        if (par.Length == 4)
                        {
                            var dt = ((ExprOp)expr).DataType;
                            if (IsFalse(par[0]))
                            {
                                stack.Push(par[3].ChangeDataType(dt));
                            }
                            else if (IsFalse(par[2]))
                            {
                                stack.Push(par[1].ChangeDataType(dt));
                            }
                            else
                            {
                                stack.Push(ep ? ThreadCalc.Funs.GeneralFunction(par, dt, this, null, ThreadCalc.Funs.endifp)
                                                         : ThreadCalc.Funs.GeneralFunction(par, dt, this, ThreadCalc.Funs.endif, null));
                            }
                        }
                        break;

                    case "for":
                        var ef = ((ExprOp)expr);
                        if (par[1].Type == CalcValueType.IntArray)
                        {
                            if (ef.Num == 0)
                            {
                                ef.IntInd = new List <int>();
                                foreach (var k in par[1].IntArray.Keys)
                                {
                                    ef.IntInd.Add(k);
                                }
                            }
                            if (ef.Num == ef.IntInd.Count)
                            {
                                ef.Num = 0;
                                i      = adr - 1;
                            }
                            else
                            {
                                par[0].VarRun.CalcValue = new CalcValue(new SingleValue(new Moment(ef.IntInd[ef.Num])))
                                {
                                    Error = par[1].Error
                                }
                            };
                        }
                        else
                        {
                            if (ef.Num == 0)
                            {
                                ef.StringInd = new List <string>();
                                foreach (var k in par[1].StringArray.Keys)
                                {
                                    ef.StringInd.Add(k);
                                }
                            }
                            if (ef.Num == ef.StringInd.Count)
                            {
                                ef.Num = 0;
                                i      = adr - 1;
                            }
                            else
                            {
                                par[0].VarRun.CalcValue = new CalcValue(new SingleValue(new Moment(ef.StringInd[ef.Num])))
                                {
                                    Error = par[1].Error
                                }
                            };
                        }
                        break;
                    }
                }
                i++;
            }
            CalcValue = stack.Count > 0 ? stack.Pop() : new CalcValue();
        }
Пример #3
0
        //Сохранение одного параметра или одной переменной, возвращает словарь ключи - коды переменных, значения - величичны
        //code - полный код для для записи в DebugParams
        //debugType - Параметр, Подпараметр, Объект, Переменная, Сигнал, paramId - id параметра или подпараметра, для остальных 0
        //c - расчетный параметр, v - переменная, всегда одно из двух, level - уровень вложенности,
        //saveToRec - сохранять в рекордсет и переменные, если false, то сам параметр не сохраняется но могут сохраняться его подпараметры и переменные
        public Dictionary <string, string> SaveValues(string code, string debugType, int paramId, CalcParamRun c, VarRun v, int level, bool saveToRec = true)
        {
            if (level > 3)
            {
                return(null);
            }
            var       dic = new Dictionary <string, string>();
            CalcValue cv;
            string    adderr = "";

            if (v != null)
            {
                cv = v.CalcValue;
            }
            else
            {
                if (c == null || c.CalcValue == null)
                {
                    return(null);
                }
                if (_thread.IsSaveProperties)
                {
                    foreach (var met in c.Methods.Values)
                    {
                        bool e = met.CalcParam.IsNotObject;
                        AddDic(dic, SaveValues(code + "." + met.CalcParam.Code, e ? "Подпараметр" : "Порождаемый", e ? met.CalcParam.Id : 0, met, null, level + 1), met.CalcParam.Code);
                        if (met.CalcValue.Error != null && adderr.IsEmpty())
                        {
                            adderr = "Ошибки в " + (e ? "" : "порожденных ") + "подпараметрах";
                        }
                    }
                }
                if (_thread.IsSaveVariables)
                {
                    foreach (var vr in c.Vars.Dic)
                    {
                        if (vr.Key != "calc" || (c.CalcValue.Type == CalcValueType.Single && c.CalcValue.SingleValue != vr.Value.CalcValue.SingleValue))
                        {
                            AddDic(dic, SaveValues(code + "." + vr.Key, "Переменная", 0, null, vr.Value, level + 1), vr.Key);
                        }
                    }
                }
                cv = c.CalcValue;
            }

            if (cv != null)
            {
                switch (cv.Type)
                {
                case CalcValueType.Void:
                case CalcValueType.Single:
                    if ((saveToRec && cv.SingleValue != null) || !adderr.IsEmpty())
                    {
                        ValuesToRec(code, debugType, paramId, dic, cv.SingleValue ?? new SingleValue(), adderr);
                        dic.Add("", SvToStr(cv.SingleValue));
                    }
                    break;

                case CalcValueType.IntArray:
                    foreach (var a in cv.IntArray)
                    {
                        AddDic(dic, SaveValues(code + "[" + a.Key + "]", "Переменная", 0, null, a.Value, level + 1), null);
                    }
                    break;

                case CalcValueType.StringArray:
                    foreach (var a in cv.StringArray)
                    {
                        AddDic(dic, SaveValues(code + "[" + a.Key + "]", "Переменная", 0, null, a.Value, level + 1), null);
                    }
                    break;
                }
                if (cv.ParentParam != null && cv.ParentParam.Inputs.Count != 0)
                {
                    if (c == cv.ParentParam)
                    {
                        ValuesToRec(code, debugType, paramId, dic, new SingleValue());
                    }
                    else
                    {
                        AddDic(dic, SaveValues(code + ":" + cv.ParentParam.CalcParam.Code, debugType, paramId, cv.ParentParam, null, level, false), null);
                    }
                }
            }
            return(dic);
        }
Пример #4
0
        //calc - CalcParam с формулой для расчета, inputs - список входных значений
        //owner - владелец, caller - параметр, из которого вызывается
        public CalcParamRun(CalcParam calc, CalcValue[] inputs, CalcParamRun owner, CalcParamRun caller)
        {
            CalcParam = calc;
            Owner     = owner;
            Caller    = caller;
            if (inputs == null || inputs.Length == 0)
            {
                Owner.Methods.Add(calc.Code, this);
                if (calc.IsNotObject)
                {
                    calc.RunParam = this;
                }
            }

            StackDepth = caller == null ? 1 : caller.StackDepth + 1;
            if (StackDepth > 500)
            {
                CalcValue = new CalcValue(new SingleValue(new Moment(DataType.Value, new ErrorCalc("Переполнение стека", CalcParam.FullCode))));
                return;
            }

            foreach (var k in calc.Vars.Keys)
            {
                Vars.Add(k, new VarRun(calc.Vars[k]));
            }

            if (inputs != null)
            {
                for (int i = 0; i < inputs.Length; i++)
                {
                    VarRun v = Vars[calc.Inputs[i]];
                    v.CalcValue = inputs[i];
                    Inputs.Add(v);
                }
            }

            ThreadCalc = CalcParam.Project.ThreadCalc;
            //Сразу производится расчет
            Calculate();

            //Добавление ошибок расчета в проект
            if (CalcParam.Inputs.Count == 0)
            {
                var errors = CalcParam.Project.CalcErrors;
                if (CalcValue.Type != CalcValueType.Single)
                {
                    if (CalcValue.Error != null)
                    {
                        errors.Add(CalcValue.Error);
                    }
                }
                else
                {
                    var sv = CalcValue.SingleValue;
                    if (sv.Moment != null && sv.Moment.Error != null)
                    {
                        errors.Add(sv.Moment.Error);
                    }
                    if (sv.Moments != null)
                    {
                        foreach (var m in sv.Moments)
                        {
                            if (m.Error != null)
                            {
                                errors.Add(m.Error);
                                break;
                            }
                        }
                    }
                    if (sv.Segments != null)
                    {
                        foreach (var seg in sv.Segments)
                        {
                            if (seg.Error != null)
                            {
                                errors.Add(seg.Error);
                                break;
                            }
                        }
                    }
                }
            }
        }