# Path: esc/commands.py
# BINOP = 'binop'
# UNOP = 'unop'
# MAIN_DOC = """
#     The main menu. All other esc functions and menus are eventually accessible
#     from this menu.
# """
# class EscCommand:
# class EscMenu(EscCommand):
# class EscOperation(EscCommand):
# class EscBuiltin(EscCommand):
#     def __init__(self, key, description):
#     def help_title(self):
#     def signature_info(self):
#     def execute(self, access_key, ss, registry):
#     def register_child(self, child):
#     def simulated_result(self, ss, registry):  # pylint: disable=no-self-use, unused-argument
#     def test(self):
#     def __init__(self, key, description, doc, mode_display=None):
#     def __repr__(self):
#     def signature_info(self):
#     def is_main_menu(self):
#     def anonymous_children(self):
#     def named_children(self):
#     def child(self, access_key):
#     def execute(self, access_key, ss, registry):
#     def test(self):
#     def __init__(self, key, func, pop, push, description, menu, retain=False,
#                  log_as=None, simulate=True):
#     def __repr__(self):
#     def __doc__(self):
#     def signature_info(self):
#     def _describe_operation(self, args, retvals, registry):
#     def _insufficient_items_on_stack(self, pops_requested=None):
#     def _retrieve_arguments(self, ss):
#     def _simulated_description(self, args, log, results):
#     def _store_results(self, ss, args, return_values, registry):
#     def execute(self, access_key, ss, registry):  # pylint: disable=useless-return
#     def simulated_result(self, ss, registry):
#     def test(self):
#     def __init__(self):
#     def execute(self, access_key, ss, registry):  # pylint: disable=useless-return
#     def simulated_result(self, ss, registry):
#     def test(self):
#     def signature_info(self):
# def Menu(key, description, parent, doc, mode_display=None):  # pylint: disable=invalid-name
# def Constant(value, key, description, menu):  # pylint: disable=invalid-name
#     def func():
# def Operation(key, menu, push, description=None, retain=False, log_as=None, simulate=True):  # pylint: disable=invalid-name
#     def function_decorator(func):
#         def _bind_stack_parm(stack_item, parm):
#         def wrapper(stack, registry):
#         def ensure(before, after=None, raises=None, close=False):
# def Mode(name, default_value, allowable_values=None):  # pylint: disable=invalid-name
# def ModeChange(key, description, menu, mode_name, to_value):  # pylint: disable=invalid-name
# 
# Path: esc/consts.py
# CONSTANT_MENU_CHARACTER = 'i'
# 
# Path: esc/oops.py
# class InsufficientItemsError(FunctionExecutionError):
#     """
#     Raised directly by operations functions that request the entire stack to
#     indicate not enough items are on the stack to finish their work, or by
#     the menu logic when an operation requests more parameters than items on
#     the stack.
# 
#     Functions may use the simplified form of the exception, providing an int
#     describing the number of items that should have been on the stack for the
#     ``number_required`` constructor parameter. esc will then reraise the
#     exception with a more useful message; a fallback message is provided in
#     case this doesn't happen for some reason.
#     """
#     def __init__(self, number_required, msg=None):
#         super().__init__()
#         self.number_required = number_required
#         self.msg = msg
# 
#     def __str__(self):
#         if self.msg:
#             return self.msg
#         else:
#             return f"Insufficient items: needs at least {self.number_required}"
# 
# Path: esc/status.py
# class StatusState:
#     class Modality(Enum):
#     class SuccessCode(Enum):
#         READY = (' ', "Ready (<F1> for help)")
#         ENTERING_NUMBER = ('i', "Insert")
#         IN_MENU = ('m', "Expecting menu selection")
#         EXPECTING_REGISTER = ('r', "Expecting register identifier (any letter)")
#         EXPECTING_HELP = ('h', "Browsing help (select a command or menu)")
#         OK = auto()  # pylint: disable=invalid-name
#         ADVISORY = auto()
#         ERROR = auto()
#         def __init__(self, status_char, status_message):
#     def __init__(self):
#     def __repr__(self):
#     def status_char(self):
#     def status_message(self):
#     def _clear_errors(self):
#     def ready(self):
#     def entering_number(self):
#     def in_menu(self):
#     def expecting_register(self):
#     def expecting_help(self):
#     def advisory(self, msg):
#     def error(self, msg):
#     def mark_seen(self):
#     def push_state(self):
#     def pop_state(self):
#     def save_state(self):


from decimal import Decimal, InvalidOperation
from subprocess import Popen, PIPE
from .commands import BINOP, Constant, Operation, Menu, main_menu
from .consts import CONSTANT_MENU_CHARACTER
from .oops import InsufficientItemsError
from .status import status
import math
import platform
roll.ensure(before=[1, 2], after=[2, 1])
roll.ensure(before=[1], raises=InsufficientItemsError)
roll.ensure(before=[], raises=InsufficientItemsError)


@Operation('c', menu=main_menu, push=0, description='clear stack')
def clear(*stack):  #pylint: disable=useless-return
    """
    Clear all items from the stack, giving you a clean slate but maintaining
    your calculation history.
    """
    if not stack:
        raise InsufficientItemsError(number_required=1)
    return None

clear.ensure(before=[6, 8, 2], after=[])
clear.ensure(before=[1], after=[])
clear.ensure(before=[], raises=InsufficientItemsError)


#############
# CONSTANTS #
#############

log_doc = """Insert common mathematical constants from this menu."""
constants_menu = Menu(CONSTANT_MENU_CHARACTER,
                      'insert constant',
                      main_menu,
                      doc=log_doc)
Constant(math.pi, 'p', description='pi', menu=constants_menu)

# Path: esc/commands.py
# BINOP = 'binop'
# UNOP = 'unop'
# MAIN_DOC = """
#     The main menu. All other esc functions and menus are eventually accessible
#     from this menu.
# """
# class EscCommand:
# class EscMenu(EscCommand):
# class EscOperation(EscCommand):
# class EscBuiltin(EscCommand):
#     def __init__(self, key, description):
#     def help_title(self):
#     def signature_info(self):
#     def execute(self, access_key, ss, registry):
#     def register_child(self, child):
#     def simulated_result(self, ss, registry):  # pylint: disable=no-self-use, unused-argument
#     def test(self):
#     def __init__(self, key, description, doc, mode_display=None):
#     def __repr__(self):
#     def signature_info(self):
#     def is_main_menu(self):
#     def anonymous_children(self):
#     def named_children(self):
#     def child(self, access_key):
#     def execute(self, access_key, ss, registry):
#     def test(self):
#     def __init__(self, key, func, pop, push, description, menu, retain=False,
#                  log_as=None, simulate=True):
#     def __repr__(self):
#     def __doc__(self):
#     def signature_info(self):
#     def _describe_operation(self, args, retvals, registry):
#     def _insufficient_items_on_stack(self, pops_requested=None):
#     def _retrieve_arguments(self, ss):
#     def _simulated_description(self, args, log, results):
#     def _store_results(self, ss, args, return_values, registry):
#     def execute(self, access_key, ss, registry):  # pylint: disable=useless-return
#     def simulated_result(self, ss, registry):
#     def test(self):
#     def __init__(self):
#     def execute(self, access_key, ss, registry):  # pylint: disable=useless-return
#     def simulated_result(self, ss, registry):
#     def test(self):
#     def signature_info(self):
# def Menu(key, description, parent, doc, mode_display=None):  # pylint: disable=invalid-name
# def Constant(value, key, description, menu):  # pylint: disable=invalid-name
#     def func():
# def Operation(key, menu, push, description=None, retain=False, log_as=None, simulate=True):  # pylint: disable=invalid-name
#     def function_decorator(func):
#         def _bind_stack_parm(stack_item, parm):
#         def wrapper(stack, registry):
#         def ensure(before, after=None, raises=None, close=False):
# def Mode(name, default_value, allowable_values=None):  # pylint: disable=invalid-name
# def ModeChange(key, description, menu, mode_name, to_value):  # pylint: disable=invalid-name
# 
# Path: esc/consts.py
# CONSTANT_MENU_CHARACTER = 'i'
# 
# Path: esc/oops.py
# class InsufficientItemsError(FunctionExecutionError):
#     """
#     Raised directly by operations functions that request the entire stack to
#     indicate not enough items are on the stack to finish their work, or by
#     the menu logic when an operation requests more parameters than items on
#     the stack.
# 
#     Functions may use the simplified form of the exception, providing an int
#     describing the number of items that should have been on the stack for the
#     ``number_required`` constructor parameter. esc will then reraise the
#     exception with a more useful message; a fallback message is provided in
#     case this doesn't happen for some reason.
#     """
#     def __init__(self, number_required, msg=None):
#         super().__init__()
#         self.number_required = number_required
#         self.msg = msg
# 
#     def __str__(self):
#         if self.msg:
#             return self.msg
#         else:
#             return f"Insufficient items: needs at least {self.number_required}"
# 
# Path: esc/status.py
# class StatusState:
#     class Modality(Enum):
#     class SuccessCode(Enum):
#         READY = (' ', "Ready (<F1> for help)")
#         ENTERING_NUMBER = ('i', "Insert")
#         IN_MENU = ('m', "Expecting menu selection")
#         EXPECTING_REGISTER = ('r', "Expecting register identifier (any letter)")
#         EXPECTING_HELP = ('h', "Browsing help (select a command or menu)")
#         OK = auto()  # pylint: disable=invalid-name
#         ADVISORY = auto()
#         ERROR = auto()
#         def __init__(self, status_char, status_message):
#     def __init__(self):
#     def __repr__(self):
#     def status_char(self):
#     def status_message(self):
#     def _clear_errors(self):
#     def ready(self):
#     def entering_number(self):
#     def in_menu(self):
#     def expecting_register(self):
#     def expecting_help(self):
#     def advisory(self, msg):
#     def error(self, msg):
#     def mark_seen(self):
#     def push_state(self):
#     def pop_state(self):
#     def save_state(self):


# Path: esc/functions.py
from decimal import Decimal, InvalidOperation
from subprocess import Popen, PIPE
from .commands import BINOP, Constant, Operation, Menu, main_menu
from .consts import CONSTANT_MENU_CHARACTER
from .oops import InsufficientItemsError
from .status import status
import math
import platform

roll.ensure(before=[1, 2], after=[2, 1])
roll.ensure(before=[1], raises=InsufficientItemsError)
roll.ensure(before=[], raises=InsufficientItemsError)


@Operation('c', menu=main_menu, push=0, description='clear stack')
def clear(*stack):  #pylint: disable=useless-return
    """
    Clear all items from the stack, giving you a clean slate but maintaining
    your calculation history.
    """
    if not stack:
        raise InsufficientItemsError(number_required=1)
    return None

clear.ensure(before=[6, 8, 2], after=[])
clear.ensure(before=[1], after=[])
clear.ensure(before=[], raises=InsufficientItemsError)


#############
# CONSTANTS #
#############

log_doc = """Insert common mathematical constants from this menu."""
constants_menu = Menu(CONSTANT_MENU_CHARACTER,
                      'insert constant',
                      main_menu,
                      doc=log_doc)
Constant(math.pi, 'p', description='pi', menu=constants_menu)

Constant(math.e, 'e', description='e', menu=constants_menu)