<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def eval(self, expr):
 """Evaluate an expression. This does **not** add its argument (or its result) as an element of me! That is the responsibility of the code that created the object. This means that you need to :meth:`Environment.rec_new` any expression you get from user input before evaluating it. This, and any wrappers around it, are the **only** entry points to expression evaluation you should call from ordinary code (i.e., code that isn't part of a extension). Args: expr (LispVal):
 The expression to evaluate. Returns: LispVal: The result of evaluating the expression. Raises: ~parthial.errs.LimitationError: If evaluating the expression would require more nesting, more time, or the allocation of more values than is permissible. """

        if self.depth >= self.max_depth:
            raise LimitationError('too much nesting')
        if self.steps >= self.max_steps:
            raise LimitationError('too many steps')
        self.depth += 1
        self.steps += 1
        res = expr.eval(self)
        self.depth -= 1
        return res