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