code: def _resolve_memory_references(self, expression: Expression) -> Union[float, int]:
          
          if isinstance(expression, BinaryExp):
              left = self._resolve_memory_references(expression.op1)
              right = self._resolve_memory_references(expression.op2)
              return expression.fn(left, right)
          elif isinstance(expression, Function):
              return expression.fn(self._resolve_memory_references(expression.expression))
          elif isinstance(expression, Parameter):
              raise ValueError(f"Unexpected Parameter in gate expression: {expression}")
          elif isinstance(expression, float) or isinstance(expression, int):
              return expression
          elif isinstance(expression, MemoryReference):
              return self._variables_shim.get(ParameterAref(name=expression.name, index=expression.offset), 0)
          else:
              raise ValueError(f"Unexpected expression in gate parameter: {expression}")
docs: Traverse the given Expression, and replace any Memory References with whatever values
          have been so far provided by the user for those memory spaces. Declared memory defaults
          to zero.
  
          :param expression: an Expression