/// <summary>
        /// Runs all the operations in main or else list. Return value indicates success.
        /// </summary>
        /// <param name="opData">Stack to use</param>
        /// <param name="error">Error message (null if sucessful, otherwise will contain information about the failure)</param>
        /// <returns>True if operation was successful, false if otherwise</returns>
        public override bool Run(IOpData opData, out string error)
        {
            if (opData.ItemCount < 1)
            {
                error = Err.OpNotEnoughItems;
                return(false);
            }

            // Remove top stack item and convert it to bool
            // OP_IF: runs if True
            // OP_NOTIF: runs if false
            byte[] topItem = opData.Pop();

            if (!opData.CheckConditionalOpBool(topItem))
            {
                error = "True/False item popped by conditional OPs must be strict.";
                return(false);
            }

            if (IsNotZero(topItem) == runWithTrue)
            {
                foreach (var op in mainOps)
                {
                    if (!op.Run(opData, out error))
                    {
                        return(false);
                    }
                }
            }
            else if (elseOps != null)
            {
                foreach (var op in elseOps)
                {
                    if (!op.Run(opData, out error))
                    {
                        return(false);
                    }
                }
            }

            error = null;
            return(true);
        }