Ejemplo n.º 1
0
    def eval(cls, forms, var_env, func_env, macro_env):
        if isinstance(forms, Null):
            # Returns nil.
            return forms

        elif isinstance(forms, Symbol):
            # Gets symbol_name, package_name, and status_check.
            symbol_name, package_name, status_check = PackageManager.split_symbol_name(
                forms.value)

            # Gets the value binded by the symbol.
            # When package_name is None, the package becomes PackageManager.current_package.
            try:
                # Tries to get the value from lexical environment in current package.
                return var_env.find(symbol_name)[symbol_name]
            except LookupError:
                # Tries to get the value from another package.
                return PackageManager.find(symbol_name,
                                           package_name,
                                           status_check,
                                           env='VARIABLE')[symbol_name]
            finally:
                # If package_name is 'KEYWORD', sets keyword represented by symbol_name.
                if package_name == 'KEYWORD':
                    assign_helper(symbol_name, Keyword(symbol_name),
                                  package_name, 'VARIABLE', ':EXTERNAL')
                    return PackageManager.find(symbol_name,
                                               package_name,
                                               status_check,
                                               env='VARIABLE')[symbol_name]

        elif not isinstance(forms, Cons):
            # If an atom is given, returns itself.
            return forms

        else:
            # Binds function object.
            if isinstance(forms.car, Cons):
                # If lambda expression is given, it is bound as an anonymous function.
                # Other than that, it is bound from predefined functions involving special
                func = cls.eval(forms.car, var_env, func_env, macro_env)

            else:
                # Gets symbol_name, package_name, and status_check.
                func_name, package_name, status_check = PackageManager.split_symbol_name(
                    forms.car.value)

                # Gets the function binded by the symbol.
                # When package_name is None, the package becomes PackageManager.current_package.
                try:
                    # Tries to get the function from lexical environment in current package.
                    func = func_env.find(func_name)[func_name]
                except LookupError:
                    # Tries to get the function from another package.
                    func = PackageManager.find(func_name,
                                               package_name,
                                               status_check,
                                               env='FUNCTION')[func_name]

            return func(forms.cdr, var_env, func_env, macro_env)
Ejemplo n.º 2
0
    def testPackageManager_find(self):
        # PackageManger.find results an environment that have value assigned by symbol.
        # The package that have the environment is shown by package_name.

        # symbol_name, package_name, status_check is given by PackageManger.split_symbol.

        # Checks an environment using *PACKAGE* in current package.

        symbol_name, package_name, status_check = PackageManager.split_symbol_name('COMMON-LISP::*PACKAGE*')
        env = PackageManager.find(symbol_name, package_name, status_check)
        self.assertIsInstance(env, Environment)
        self.assertTrue('*PACKAGE*' in env)

        symbol_name, package_name, status_check = PackageManager.split_symbol_name('COMMON-LISP:*PACKAGE*')
        env = PackageManager.find(symbol_name, package_name, status_check)
        self.assertIsInstance(env, Environment)
        self.assertTrue('*PACKAGE*' in env)

        symbol_name, package_name, status_check = PackageManager.split_symbol_name('*PACKAGE*')
        env = PackageManager.find(symbol_name, package_name, status_check)
        self.assertIsInstance(env, Environment)
        self.assertTrue('*PACKAGE*' in env)

        # Checks an environment using *PACKAGE* in another package.

        symbol_name, package_name, status_check = PackageManager.split_symbol_name('COMMON-LISP-USER::*PACKAGE*')
        env = PackageManager.find(symbol_name, package_name, status_check)
        self.assertIsInstance(env, Environment)
        self.assertTrue('*PACKAGE*' in env)

        symbol_name, package_name, status_check = PackageManager.split_symbol_name('COMMON-LISP-USER:*PACKAGE*')
        env = PackageManager.find(symbol_name, package_name, status_check)
        self.assertIsInstance(env, Environment)
        self.assertTrue('*PACKAGE*' in env)
Ejemplo n.º 3
0
    def __call__(self, forms, var_env, func_env, macro_env):
        """Behavior of SetqSpecialOperator.
        """
        from clispy.evaluator import Evaluator

        while forms is not Null():
            symbol, value, forms = forms.car, forms.cdr.car, forms.cdr.cdr

            symbol_name = symbol.value
            value = Evaluator.eval(value, var_env, func_env, macro_env)

            # Interns symbol that represents function name into current package.
            PackageManager.intern(String(symbol_name))

            # setq may be used for assignment of both lexical and dynamic variables.
            try:
                var_env.find(symbol_name)[symbol_name] = value
            except LookupError:
                try:
                    # package_name=None means finding an environment from current package.
                    PackageManager.find(
                        symbol_name, package_name=None,
                        status_check=False)[symbol_name] = value
                except LookupError:
                    PackageManager.current_package.env['VARIABLE'][
                        symbol_name] = value

        # the primary value of the last form
        return value
Ejemplo n.º 4
0
    def __call__(self, forms, var_env, func_env, macro_env):
        """Behavior of ImportModuleObjectManipulation.
        """
        while forms is not Null():
            symbol, module_name, forms = forms.car, forms.cdr.car, forms.cdr.cdr

            symbol_name = symbol.value
            module = PyObject(import_module(module_name.value))

            # Interns symbol that represents module name into current package.
            PackageManager.intern(String(symbol_name))

            # import-moduel may be used for assignment of both lexical and dynamic variables.
            try:
                var_env.find(symbol_name)[symbol_name] = module
            except LookupError:
                try:
                    # package_name=None means finding an environment from current package.
                    PackageManager.find(
                        symbol_name, package_name=None,
                        status_check=False)[symbol_name] = module
                except LookupError:
                    PackageManager.current_package.env['VARIABLE'][
                        symbol_name] = module

        # the primary value of the last form
        return symbol
Ejemplo n.º 5
0
    def expand(cls, forms, var_env, func_env, macro_env):
        if not isinstance(forms, Cons):
            # If an atom is given, returns itself.
            return forms

        elif isinstance(forms.car,
                        Symbol):  # and forms.car.value in macro_env:
            # Gets symbol_name, package_name, and status_check.
            macro_name, package_name, status_check = PackageManager.split_symbol_name(
                forms.car.value)

            # Gets the macro binded by the symbol.
            # When package_name is None, the package becomes PackageManager.current_package.
            try:
                # Tries to get the function from lexical environment in current package.
                macro = macro_env.find(macro_name)[macro_name]
            except LookupError:
                try:
                    macro = PackageManager.find(macro_name,
                                                package_name,
                                                status_check,
                                                env='MACRO')[macro_name]
                except LookupError:
                    return Cons(
                        forms.car,
                        cls.recusive_expand(forms.cdr, var_env, func_env,
                                            macro_env))

            return macro(forms.cdr, var_env, func_env, macro_env)

        else:
            return Cons(cls.expand(forms.car, var_env, func_env, macro_env),
                        cls.expand(forms.cdr, var_env, func_env, macro_env))
Ejemplo n.º 6
0
    def __call__(self, forms, var_env, func_env, macro_env):
        """Behavior of FunctionSpecialOperator.
        """
        if isinstance(forms.car, Cons) and forms.car.car is Symbol('LAMBDA'):
            return Lambda(forms.car.cdr, var_env, func_env, macro_env)
        else:
            # Gets symbol_name, package_name, and status_check.
            func_name, package_name, status_check = PackageManager.split_symbol_name(
                forms.car.value)

            # Gets the function binded by the symbol.
            try:
                # First, tries to get the value from lexical environment.
                return func_env.find(func_name)[func_name]
            except LookupError:
                # If LookupError is raised, tries to get from another package.
                return PackageManager.find(func_name,
                                           package_name,
                                           status_check,
                                           env='FUNCTION')[func_name]
Ejemplo n.º 7
0
    def testDefunSytemFunction_call(self):
        # Makes an instance of DefunSystemFunction.
        defun = DefunSystemFunction()

        # Calls defun.
        forms = Parser.parse('(func (x) (* x x x))')
        retval = defun(forms, PackageManager.current_package.env['VARIABLE'],
                       PackageManager.current_package.env['FUNCTION'],
                       PackageManager.current_package.env['MACRO'])

        # Checks retval.
        self.assertEqual(retval, Symbol('FUNC'))

        # Gets function object.
        func = PackageManager.find('FUNC',
                                   package_name=None,
                                   status_check=False,
                                   env='FUNCTION')['FUNC']

        # Checks type.
        self.assertIsInstance(func, Lambda)
Ejemplo n.º 8
0
    def __call__(self, forms, var_env, func_env, macro_env):
        """Behavior of DefunSystemFunction.
        """
        func_symbol = forms.car
        func_name = func_symbol.value

        lambda_forms = forms

        # Lambda function.
        func = Lambda(lambda_forms.cdr, var_env, func_env, macro_env)

        # Interns symbol that represents function name into current package.
        PackageManager.intern(String(func_name))

        # Binds value to symbol into the global environment.
        try:
            # package_name=None means finding an environment from current package.
            PackageManager.find(func_name, package_name=None, status_check=False, env='FUNCTION')[func_name] = func
        except LookupError:
            PackageManager.current_package.env['FUNCTION'][func_name] = func

        return func_symbol
Ejemplo n.º 9
0
    def __call__(self, forms, var_env, func_env, macro_env):
        """Behavior of DefmacroSystemFunction.
        """
        macro_symbol = forms.car
        macro_name = macro_symbol.value

        lambda_forms = forms

        # Lambda function.
        macro = Lambda(lambda_forms.cdr, var_env, func_env, macro_env)

        # Interns symbol that represents macro name into current package.
        PackageManager.intern(String(macro_name))

        # Binds value to symbol into the global environment.
        try:
            # package_name=None means finding an environment from current package.
            PackageManager.find(macro_name, package_name=None, status_check=False, env='MACRO')[macro_name] = macro
        except LookupError:
            PackageManager.current_package.env['MACRO'][macro_name] = macro

        return macro_symbol
Ejemplo n.º 10
0
    def testDefmacroSystemFunction_call(self):
        # Makes an instance of DefmacroSystemFunction.
        defmacro = DefmacroSystemFunction()

        # Calls defmacro.
        forms = Parser.parse('(mac (x) `(* ,x ,x ,x))')
        retval = defmacro(forms,
                          PackageManager.current_package.env['VARIABLE'],
                          PackageManager.current_package.env['FUNCTION'],
                          PackageManager.current_package.env['MACRO'])

        # Checks retval.
        self.assertTrue(retval, Symbol('MACRO'))

        # Gets macro object.
        mac = PackageManager.find('MAC',
                                  package_name=None,
                                  status_check=False,
                                  env='MACRO')['MAC']

        # Checks type.
        self.assertIsInstance(mac, Lambda)