# Path: pycell/env.py
# class Env:
#     def __init__(self, parent=None, stdin=None, stdout=None, stderr=None):
#         """
#         Supply _either_ std{in,out,err} _or_ parent, not both.
#         """
#         self.stdin = stdin
#         self.stdout = stdout
#         self.stderr = stderr
#         self.parent = parent
#         if parent is not None:
#             assert stdin is None
#             assert stdout is None
#             assert stderr is None
#             self.stdin = parent.stdin
#             self.stdout = parent.stdout
#             self.stderr = parent.stderr
#         self.items = {}
# 
#     def get(self, name):
#         if name in self.items:
#             return self.items[name]
#         elif self.parent is not None:
#             return self.parent.get(name)
#         else:
#             return None
# 
#     def set(self, name, value):
#         self.items[name] = value
# 
#     def contains(self, name):
#         return name in self.items
# 
#     def __str__(self):
#         ret = ""
#         for k, v in self.items.items():
#             ret += "%s=%s\n" % (k, v)
#         ret += ".\n" + str(self.parent)
#         return ret


import inspect
from pycell.env import Env
    arg1 = eval_expr(expr[2], env)
    arg2 = eval_expr(expr[3], env)
    if expr[1] == "+":
        return ("number", arg1[1] + arg2[1])
    elif expr[1] == "-":
        return ("number", arg1[1] - arg2[1])
    elif expr[1] == "*":
        return ("number", arg1[1] * arg2[1])
    elif expr[1] == "/":
        return ("number", arg1[1] / arg2[1])
    else:
        raise Exception("Unknown operation: " + expr[1])


def fail_if_wrong_number_of_args(fn_name, params, args):
    if len(params) != len(args):
        raise Exception((
            "%d arguments passed to function %s, but it "
            + "requires %d arguments."
        ) % (len(args), fn_name, len(params)))


def _function_call(expr, env):
    fn = eval_expr(expr[1], env)
    args = list((eval_expr(a, env) for a in expr[2]))
    if fn[0] == "function":
        params = fn[1]
        fail_if_wrong_number_of_args(expr[1], params, args)
        body = fn[2]
        fn_env = fn[3]

# Path: pycell/env.py
# class Env:
#     def __init__(self, parent=None, stdin=None, stdout=None, stderr=None):
#         """
#         Supply _either_ std{in,out,err} _or_ parent, not both.
#         """
#         self.stdin = stdin
#         self.stdout = stdout
#         self.stderr = stderr
#         self.parent = parent
#         if parent is not None:
#             assert stdin is None
#             assert stdout is None
#             assert stderr is None
#             self.stdin = parent.stdin
#             self.stdout = parent.stdout
#             self.stderr = parent.stderr
#         self.items = {}
# 
#     def get(self, name):
#         if name in self.items:
#             return self.items[name]
#         elif self.parent is not None:
#             return self.parent.get(name)
#         else:
#             return None
# 
#     def set(self, name, value):
#         self.items[name] = value
# 
#     def contains(self, name):
#         return name in self.items
# 
#     def __str__(self):
#         ret = ""
#         for k, v in self.items.items():
#             ret += "%s=%s\n" % (k, v)
#         ret += ".\n" + str(self.parent)
#         return ret


# Path: pycell/eval_.py
import inspect
from pycell.env import Env

    arg1 = eval_expr(expr[2], env)
    arg2 = eval_expr(expr[3], env)
    if expr[1] == "+":
        return ("number", arg1[1] + arg2[1])
    elif expr[1] == "-":
        return ("number", arg1[1] - arg2[1])
    elif expr[1] == "*":
        return ("number", arg1[1] * arg2[1])
    elif expr[1] == "/":
        return ("number", arg1[1] / arg2[1])
    else:
        raise Exception("Unknown operation: " + expr[1])


def fail_if_wrong_number_of_args(fn_name, params, args):
    if len(params) != len(args):
        raise Exception((
            "%d arguments passed to function %s, but it "
            + "requires %d arguments."
        ) % (len(args), fn_name, len(params)))


def _function_call(expr, env):
    fn = eval_expr(expr[1], env)
    args = list((eval_expr(a, env) for a in expr[2]))
    if fn[0] == "function":
        params = fn[1]
        fail_if_wrong_number_of_args(expr[1], params, args)
        body = fn[2]
        fn_env = fn[3]

        new_env = Env(fn_env)