private Value Division(DivisionNode exp)
        {
            try
            {
                Constant      left      = Eval(exp.Left).GetRValue();
                Constant      right     = Eval(exp.Right).GetRValue();
                Constant.Type leftType  = left.ConstantType;
                Constant.Type rightType = right.ConstantType;
                Constant.Type bt        = Max(leftType, rightType);
                switch (bt)
                {
                case Constant.Type.Complex:
                {
                    ComplexValue l = (ComplexValue)Convert(left, bt);
                    ComplexValue r = (ComplexValue)Convert(right, bt);
                    return(ComplexValue.OpDiv(l, r));
                }

                case Constant.Type.Int:
                {
                    IntValue l = (IntValue)Convert(left, bt);
                    IntValue r = (IntValue)Convert(right, bt);
                    return(IntValue.OpDiv(l, r));
                }

                case Constant.Type.Float:
                {
                    FloatValue l = (FloatValue)Convert(left, bt);
                    FloatValue r = (FloatValue)Convert(right, bt);
                    return(FloatValue.OpDiv(l, r));
                }
                }
                throw new ModelInterpreterException("Деление не определено для типа \"" + bt.ToString() + "\".")
                      {
                          Line     = exp.Line,
                          Position = exp.Position
                      };
            }
            catch (TypeConversionError exc)
            {
                throw new ModelInterpreterException($"Не удалось преобразование из \"{exc.Src}\" в \"{exc.Dst}\"")
                      {
                          Line     = exp.Line,
                          Position = exp.Position
                      };
            }
            catch (Exception exc)
            {
                throw new ModelInterpreterException(exc.Message)
                      {
                          Line     = exp.Line,
                          Position = exp.Position
                      };
            }
        }
        static public Constant Convert(Constant constant, Constant.Type newType)
        {
            if (newType == constant.ConstantType)
            {
                return(constant);
            }
            switch (newType)
            {
            case Constant.Type.Complex:
                if (constant.ConstantType == Constant.Type.Float)
                {
                    return(new ComplexValue((constant as FloatValue).Value, 0.0));
                }
                else if (constant.ConstantType == Constant.Type.Int)
                {
                    return(new ComplexValue((constant as IntValue).Value, 0.0));
                }
                break;

            case Constant.Type.Float:
                if (constant.ConstantType == Constant.Type.Int)
                {
                    return(new FloatValue((constant as IntValue).Value));
                }
                if (constant.ConstantType == Constant.Type.Bool)
                {
                    return(new FloatValue((constant as BoolValue).Value ? 1.0 : 0.0));
                }
                break;

            case Constant.Type.String:
                return(constant.CastToString());

            case Constant.Type.Int:
                if (constant.ConstantType == Constant.Type.Bool)
                {
                    return(new IntValue((constant as BoolValue).Value ? 1 : 0));
                }
                break;

            case Constant.Type.Bool:
                if (constant.ConstantType == Constant.Type.Int)
                {
                    return(new BoolValue((constant as IntValue).Value == 0 ? true : false));
                }
                break;
            }
            throw new TypeConversionError(constant.ConstantType.ToString(), newType.ToString());
        }
 public ArgumentDescription(Constant.Type type, Constant defaultType = null)
 {
     Type         = type;
     DefaultValue = defaultType;
 }
        static public Constant.Type Max(Constant.Type a, Constant.Type b)
        {
            if (a == b)
            {
                return(a);
            }
            if (a == Constant.Type.Object || a == Constant.Type.Array)
            {
                if (b == Constant.Type.String)
                {
                    return(b);
                }
                return(a);
                //throw new Exception("Invalid type conversion.");
            }
            else if (b == Constant.Type.Object || b == Constant.Type.Array)
            {
                if (a == Constant.Type.String)
                {
                    return(a);
                }
                return(b);
                //throw new Exception("Invalid type conversion.");
            }
            switch (a)
            {
            case Constant.Type.Complex:
                if (b == Constant.Type.Float || b == Constant.Type.Int || b == Constant.Type.Bool)
                {
                    return(a);
                }
                else if (b == Constant.Type.String)
                {
                    return(b);
                }
                break;

            case Constant.Type.Float:
                if (b == Constant.Type.Complex || b == Constant.Type.String)
                {
                    return(b);
                }
                else if (b == Constant.Type.Int || b == Constant.Type.Bool)
                {
                    return(a);
                }
                break;

            case Constant.Type.Int:
                if (b == Constant.Type.Complex || b == Constant.Type.Float || b == Constant.Type.String)
                {
                    return(b);
                }
                else if (b == Constant.Type.Bool)
                {
                    return(a);
                }
                break;

            case Constant.Type.String:
                return(a);

            case Constant.Type.Bool:
                return(b);
            }
            return(a);
            //throw new Exception("Invalid type conversion.");
        }