def rcl_l(self, symbols, cmd, cmds):
        # recalls a local variable (not overly useful, but avoids ambiguity)
        ret = 1
        ret, v = variables.next_cmd(ret, cmds)
        a = variables.get(v, symbols[SYM_LOCAL], None,
                          param_convs._any)  # as an integer
        variables.push(symbols, a)

        return ret
    def rcl(self, symbols, cmd, cmds):
        # recalls a variable.  Try local first, then global
        ret = 1
        ret, v = variables.next_cmd(ret, cmds)
        with symbols[SYM_GLOBAL][0]:  # lock the globals while we do this
            a = variables.get(v, symbols[SYM_LOCAL], symbols[SYM_GLOBAL][1],
                              param_convs._any)  # as an integer
        variables.push(symbols, a)

        return ret
    def rcl_g(self, symbols, cmd, cmds):
        # recalls a global variable (useful if you define an identical local var)
        ret = 1
        ret, v = variables.next_cmd(ret, cmds)
        with symbols[SYM_GLOBAL][0]:  # lock the globals while we do this
            a = variables.get(
                v, None, symbols[SYM_GLOBAL][1], param_convs._any
            )  # grab the value from the global vars as an integer
        variables.push(symbols, a)  # and push onto the stack

        return ret
    def chs(self, symbols, cmd, cmds):
        ret = 1
        a = variables.pop(symbols)

        try:
            variables.push(symbols, -a)
        except:
            raise Exception("Error in chs: " +
                            str(a))  # Errors are highly improbable here

        return ret
    def swap_x_y(self, symbols, cmd, cmds):
        # exchanges top two values on the stack
        ret = 1

        a = variables.pop(symbols)
        b = variables.pop(symbols)

        variables.push(symbols, a)
        variables.push(symbols, b)

        return ret
    def last_x(self, symbols, cmd, cmds):
        # resurrects the last value of x that was "consumed" by an operation
        ret = 1
        try:
            a = symbols[SYM_LOCAL]['last x']  # attempt to get the last-x value
        except:
            a = 0  # default is zero

        variables.push(symbols, a)  # and push it onto the stack

        return ret
    def one_on_x(self, symbols, cmd, cmds):
        ret = 1
        a = variables.pop(symbols)
        symbols[SYM_LOCAL]['last x'] = a

        try:
            variables.push(symbols, 1 / a)
        except:
            raise Exception("Error in 1/x: " +
                            str(a))  # Errors are highly possible here

        return ret
    def frac_x(self, symbols, cmd, cmds):
        # get the fractionasl part of x
        ret = 1
        a = variables.pop(symbols)
        symbols[SYM_LOCAL]['last x'] = a

        try:
            variables.push(symbols, a - int(a))
        except:
            raise Exception("Error in '" + cmd + "' " +
                            str(a))  # Errors are highly unlikely here

        return ret
    def sqr(self, symbols, cmd, cmds):
        # calculates the square
        ret = 1
        a = variables.pop(symbols)
        symbols[SYM_LOCAL]['last x'] = a

        try:
            c = a**2
        except:
            raise Exception("Error in squaring: " + str(a))

        variables.push(symbols, c)

        return ret
    def subtract(self, symbols, cmd, cmds):
        ret = 1
        a = variables.pop(symbols)
        b = variables.pop(symbols)
        symbols[SYM_LOCAL]['last x'] = a

        try:
            c = b - a
        except:
            raise Exception("Error in subtraction: " + str(b) + " - " + str(a))

        variables.push(symbols, c)

        return ret
    def mod(self, symbols, cmd, cmds):
        ret = 1
        a = variables.pop(symbols)
        b = variables.pop(symbols)
        symbols[SYM_LOCAL]['last x'] = a

        try:
            c = b % a
        except:
            raise Exception("Error in mod: " + str(b) + " % " +
                            str(a))  # Errors are highly possible here

        variables.push(symbols, c)

        return ret
    def multiply(self, symbols, cmd, cmds):
        ret = 1
        a = variables.pop(symbols)
        b = variables.pop(symbols)
        symbols[SYM_LOCAL]['last x'] = a

        try:
            c = b * a
        except:
            raise Exception("Error in multiplication: " + str(b) + " * " +
                            str(a))

        variables.push(symbols, c)

        return ret
    def y_to_x(self, symbols, cmd, cmds):
        # calculates the square
        ret = 1
        a = variables.pop(symbols)
        b = variables.pop(symbols)
        symbols[SYM_LOCAL]['last x'] = a

        try:
            c = b**a
        except:
            raise Exception("Error raising: " + str(b) + " to the " + str(a) +
                            "th power")  # Errors are highly possible here

        variables.push(symbols, c)

        return ret
    def add(
        self,
        symbols,  # the symbol table (stack, global vars, etc.)
        cmd,  # the current command
        cmds):  # the rest of the commands on the command line

        ret = 1  # always initialise ret to 1, because the default is to
        # step token by token along the expression

        a = variables.pop(
            symbols)  # add requires 2 params, pop them off the stack...
        b = variables.pop(symbols)  #
        symbols[SYM_LOCAL]['last x'] = a

        try:
            c = b + a  # RPN functions are defined as b (operator) a
        except:
            raise Exception("Error in addition: " + str(b) + " + " +
                            str(a))  # error message in case of problem

        variables.push(symbols, c)  # the result is pushed back on the stack

        return ret  # and we return the number of tokens to skip (normally 1)
    def stack_len(self, symbols, cmd, cmds):
        # returns stack length
        ret = 1
        variables.push(symbols, len(symbols[SYM_STACK]))

        return ret
    def dup(self, symbols, cmd, cmds):
        # duplicates the value on the top of the stack
        ret = 1
        variables.push(symbols, variables.top(symbols, 1))

        return ret