# 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
        )


def eval_expr(expr, env):
    typ = expr[0]
    if typ == "number":
        return ("number", float(expr[1]))
    elif typ == "string":
        return ("string", expr[1])
    elif typ == "none":
        return ("none",)
    elif typ == "operation":
        return _operation(expr, env)
    elif typ == "symbol":
        name = expr[1]
        ret = env.get(name)
        if ret is None:
            raise Exception("Unknown symbol '%s'." % name)
        else:
            return ret
    elif typ == "assignment":
        var_name = expr[1][1]
        if var_name in env.items:
            raise Exception("Not allowed to re-assign symbol '%s'." % var_name)
        val = eval_expr(expr[2], env)
        env.set(var_name, val)
        return val
    elif typ == "call":
        return _function_call(expr, env)
    elif typ == "function":

# 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

        )


def eval_expr(expr, env):
    typ = expr[0]
    if typ == "number":
        return ("number", float(expr[1]))
    elif typ == "string":
        return ("string", expr[1])
    elif typ == "none":
        return ("none",)
    elif typ == "operation":
        return _operation(expr, env)
    elif typ == "symbol":
        name = expr[1]
        ret = env.get(name)
        if ret is None:
            raise Exception("Unknown symbol '%s'." % name)
        else:
            return ret
    elif typ == "assignment":
        var_name = expr[1][1]
        if var_name in env.items:
            raise Exception("Not allowed to re-assign symbol '%s'." % var_name)
        val = eval_expr(expr[2], env)
        env.set(var_name, val)
        return val
    elif typ == "call":
        return _function_call(expr, env)
    elif typ == "function":

        return ("function", expr[1], expr[2], Env(env))