def find_symbol(cls, symbol_designator, package_designator=None): """find_symbol locates a symbol whose name is symbol_designator in a package. If a symbol named symbol_designator is found in package, directly or by inheritance, the symbol found is returned as the first value; the second value is as follows: :INTERNAL If the symbol is present in package as an internal symbol. :EXTERNAL If the symbol is present in package as an external symbol. :INHERITED If the symbol is inherited by package through use-package, but is not present in package. If no such symbol is accessible in package, both values are nil. Args: symbol_designator: String. a symbol name. package_designator: str. a package name. Returns: (Symbol, Keyword) """ # Get symbol_name and package_name. symbol_name = symbol_designator.value package_name = cls.get_package_name(package_designator) # Get package. The default is the current package. package = cls.get_package(package_name) # Extract symbol status included by package.symbol_container. if symbol_name in package.symbol_container.keys(): symbol, status, _ = package.symbol_container.find( symbol_name)[symbol_name] return symbol, status else: return Null(), Null()
def __call__(self, forms, var_env, func_env, macro_env): """Behavior of UsePackageSystemFunction. """ args = self.eval_forms(forms, var_env, func_env, macro_env) package_designator_to_use = args.car package_designator = args.cdr.car # Checks package_designator whether it is given or not. if package_designator is Null(): package_designator = None if isinstance(package_designator_to_use, Cons): # If package_designator_to_use is symbol list, exports all symbols. while package_designator_to_use.cdr is not Null(): PackageManager.use_package( package_designator_to_use=package_designator_to_use.car, package_designator=package_designator ) package_designator_to_use = package_designator_to_use.cdr # The last package_dexignator_to_use. return PackageManager.use_package( package_designator_to_use=package_designator_to_use.car, package_designator=package_designator ) else: return PackageManager.use_package( package_designator_to_use=package_designator_to_use, package_designator=package_designator )
def testPackageManager_find_symbol(self): # PackageManager.find_symbol returns symbol represented by symbol_designator and status. # The package_designator argument is omitted, # PackageManager.current_package.symbol_container is checked. # FIND-SYMBOL is interned to PackageManager.current_package in advance. PackageManager.intern(symbol_designator=String('FIND-SYMBOL')) symbol, status = PackageManager.find_symbol(symbol_designator=String('FIND-SYMBOL')) self.assertTrue(symbol is Symbol('FIND-SYMBOL')) self.assertTrue(status, Keyword(':INTERNAL')) # If symbol_designator dose not exist in PackageManager.current_package, # it must return Null object as symbol and status. symbol, status = PackageManager.find_symbol(symbol_designator=String('FIND-SYMBOL-NOT-EXIST')) self.assertTrue(symbol is Null()) self.assertTrue(status is Null()) # The package_designator argument is supplied to the specified package. # FIND-SYMBOL-WITH-PACKAGE is interned to COMMON-LISP-USER package in advance. PackageManager.intern(symbol_designator=String('FIND-SYMBOL-WITH-PACKAGE'), package_designator=String('COMMON-LISP-USER')) symbol, status = PackageManager.find_symbol(symbol_designator=String('FIND-SYMBOL-WITH-PACKAGE'), package_designator=String('COMMON-LISP-USER')) self.assertTrue(symbol is Symbol('FIND-SYMBOL-WITH-PACKAGE')) self.assertTrue(status is Keyword(':INTERNAL')) # If symbol_designator dose not exist in the specified package, # it must return Null object as symbol and status. symbol, status = PackageManager.find_symbol(symbol_designator=String('FIND-SYMBOL-WITH-PACKAGE-NOT-EXIST'), package_designator=String('COMMON-LISP-USER')) self.assertTrue(symbol is Null()) self.assertTrue(status is Null())
def __init__(self, proc): from clispy.python import PyObject self.ball = RuntimeWarning( "Sorry, can't continue this continuation any longer.") self.ball.retval = Null() self.proc = proc self.args = Cons(PyObject(Invoke(self)), Null())
def recusive_expand(cls, rest_forms, var_env, func_env, macro_env): """Expand forms recursively. """ expanded_forms = Null() while rest_forms is not Null(): expanded_forms = Cons( cls.expand(rest_forms.car, var_env, func_env, macro_env), expanded_forms) rest_forms = rest_forms.cdr return cls.reverse(expanded_forms, Null())
def __call__(self, forms, var_env, func_env, macro_env): """Behavior of AppendSystemFunction. """ args = self.eval_forms(forms, var_env, func_env, macro_env) retval = Null() while args.cdr is not Null(): retval = self.accumulate(args.car, retval) args = args.cdr last = args.car return self.reverse(retval, last)
def testFindSymbolFunction_call_not_existed_symbol(self): # Make an instance of FindSymbolSystemFunction. find_symbol = FindSymbolSystemFunction() # Calls find_symbol. forms = Parser.parse('("G0")') retval = find_symbol(forms, PackageManager.current_package.env['VARIABLE'], PackageManager.current_package.env['FUNCTION'], PackageManager.current_package.env['MACRO']) # Chesk return value. self.assertEqual(retval[0], Null()) self.assertEqual(retval[1], Null())
def __call__(self, forms, var_env, func_env, macro_env): """Behavior of NumericalEqualSystemFunction. """ args = self.eval_forms(forms, var_env, func_env, macro_env) # Sets initial value. val, args = args.car, args.cdr # Whether all numbers are the same or not. while args is not Null(): if args.car != val: return Null() args = args.cdr return T()
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 __call__(self, forms, var_env, func_env, macro_env): """Behavior of FletSpecialOperator. """ from clispy.evaluator import Evaluator bindings, body = forms.car, forms.cdr.car funcs = [] exps = [] while bindings is not Null(): func, exp = bindings.car.car, bindings.car.cdr # Interns symbol that represents function name into current package. PackageManager.intern(String(func.value)) funcs.append(func.value) exp = Cons(Symbol('LAMBDA'), exp) # The scope of the name bindings dose not encompasse the function definitions. exps.append(Evaluator.eval(exp, var_env, func_env, macro_env)) bindings = bindings.cdr # The bindings are in parallel. func_env = func_env.extend(params=funcs, args=exps) return Evaluator.eval(body, var_env, func_env, macro_env)
def __call__(self, forms, var_env, func_env, macro_env): """Behavior of FletSpecialOperator. """ from clispy.evaluator import Evaluator bindings, body = forms.car, forms.cdr.car funcs = [] exps = [] # For encompassing the function definitions themselves, # a function environment is extended in advance. local_func_env = func_env.extend() while bindings is not Null(): func, exp = bindings.car.car, bindings.car.cdr # Interns symbol that represents function name into current package. PackageManager.intern(String(func.value)) funcs.append(func.value) exp = Cons(Symbol('LAMBDA'), exp) # The scope of the name bindings encompasses the function definitions # themselves as well as the body. exps.append(Evaluator.eval(exp, var_env, local_func_env, macro_env)) bindings = bindings.cdr # The bindings are in parallel. local_func_env.update(zip(funcs, exps)) return Evaluator.eval(body, var_env, local_func_env, macro_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 GreaterThanSystemFunction. """ args = self.eval_forms(forms, var_env, func_env, macro_env) # Sets initial value. val, args = args.car, args.cdr # Whether the numbers are in monotonically decreasing order or not. while args is not Null(): if val < args.car: return Null() # Updates value and args. val, args = args.car, args.cdr return T()
def reverse(cls, args, last): """Reverses an element in args as Cons. """ while args is not Null(): last = Cons(args.car, last) args = args.cdr return last
def accumulate(cls, args, acc): """Accumulates an element in args as Cons to acc. """ while args is not Null(): acc = Cons(args.car, acc) args = args.cdr return acc
def __call__(self, forms, var_env, func_env, macro_env): """Behavior of DivSystemFunction. """ args = self.eval_forms(forms, var_env, func_env, macro_env) # Initializes retval. retval, args = args.car, args.cdr # If there is not an argument any more, returns ratio. if args is Null(): return Ratio('1/{}'.format(str(retval))) # Division. while args is not Null(): retval = retval / args.car args = args.cdr return retval
def testPackageManager_use_package(self): # PackageManager.use_package inherited symbol in package_designator_to_use. # The package_designator argument is omitted, # symbol is inherited, and interned to PackageManager.current_package.symbol_container. # USE-PACKAGE-INTERNAL and USE-PACKAGE-EXTERNAL are interned to COMMON-LISP-USER. PackageManager.intern(symbol_designator=String('USE-PACKAGE-INTERNAL'), package_designator=String('COMMON-LISP-USER')) PackageManager.intern(symbol_designator=String('USE-PACKAGE-EXTERNAL'), package_designator=String('COMMON-LISP-USER')) # Only status of USE-PACKAGE-EXTERNAL is changed to :EXTERNAL. PackageManager.export(symbol_designator=Symbol('USE-PACKAGE-EXTERNAL'), package_designator=Symbol('COMMON-LISP-USER')) PackageManager.use_package(package_designator_to_use=Symbol('COMMON-LISP-USER')) # When status is :EXTERNAL, the symbol is inherited. symbol, status = PackageManager.find_symbol(symbol_designator=String('USE-PACKAGE-EXTERNAL')) self.assertTrue(symbol is Symbol('USE-PACKAGE-EXTERNAL')) self.assertTrue(status is Keyword(':INHERITED')) # When statis is not :EXTERNAL, the symbol is not inherited. symbol, status = PackageManager.find_symbol(symbol_designator=String('USE-PACKAGE-INTERNAL')) self.assertTrue(symbol is Null()) self.assertTrue(status is Null()) # The package_designator argument is supplied to the specified package. # USE-PACKAGE-INTERNAL-WITH-PACKAGE and USE-PACKAGE-EXTERNAL-WITH-PACKAGE are interned to COMMON-LISP. PackageManager.intern(String('USE-PACKAGE-INTERNAL-WITH-PACKAGE')) PackageManager.intern(String('USE-PACKAGE-EXTERNAL-WITH-PACKAGE')) # Only status of USE-PACKAGE-EXTERNAL-WITH-PACKAGE is changed to :EXTERNAL. PackageManager.export(Symbol('USE-PACKAGE-EXTERNAL-WITH-PACKAGE')) PackageManager.use_package(package_designator_to_use=Symbol('COMMON-LISP'), package_designator=Symbol('COMMON-LISP-USER')) # When status is :EXTERNAL, the symbol is inherited. symbol, status = PackageManager.find_symbol(symbol_designator=String('USE-PACKAGE-EXTERNAL-WITH-PACKAGE'), package_designator=String('COMMON-LISP-USER')) self.assertTrue(symbol is Symbol('USE-PACKAGE-EXTERNAL-WITH-PACKAGE')) self.assertTrue(status is Keyword(':INHERITED')) # When statis is not :EXTERNAL, the symbol is not inherited. symbol, status = PackageManager.find_symbol(symbol_designator=String('USE-PACKAGE-INTERNAL-WITH-PACKAGE'), package_designator=String('COMMON-LISP-USER')) self.assertTrue(symbol is Null()) self.assertTrue(status is Null())
def __call__(self, forms, var_env, func_env, macro_env): """Behavior of EqSystemFunction. """ args = self.eval_forms(forms, var_env, func_env, macro_env) # Whether arguments are the same or not. if args.car is args.cdr.car: return T() else: return Null()
def exec_func(self, py_func_name, args): """Executes builtin function. """ # Sets args for function. py_args = [] while args is not Null(): py_args.append(args.car.value) args = args.cdr return __builtins__[py_func_name](*py_args)
def __call__(self, forms, var_env, func_env, macro_env): """Behavior of SortedBuiltinFunction. """ args = self.eval_forms(forms, var_env, func_env, macro_env) # If an argument is empty list. if args.car is Null(): return PyObject([]) return PyObject(self.exec_func(py_func_name='sorted', args=args))
def __call__(self, forms, var_env, func_env, macro_env): """Behavior of SliceBuiltinFunction. """ args = self.eval_forms(forms, var_env, func_env, macro_env) # Sets slice object for getting all elements. if args is Null(): return PyObject(slice(None, None, None)) return PyObject(self.exec_func(py_func_name='slice', args=args))
def testPackageManager_intern(self): # PackageManager.intern interns symbol_designator to Package.symbol_container. # The package_designator argument is omitted, # symbol_designator is interned to PackageManager.current_package.symbol_container. symbol, status = PackageManager.intern(symbol_designator=String('TEST-INTERN')) self.assertTrue(symbol is Symbol('TEST-INTERN')) self.assertTrue(status is Null()) self.assertTrue('TEST-INTERN' in PackageManager.current_package.symbol_container.keys()) self.assertEqual(PackageManager.current_package.symbol_container['TEST-INTERN'], [Symbol('TEST-INTERN'), Keyword(':INTERNAL'), None]) # The package_designator argument is supplied to the specified package. symbol, status = PackageManager.intern(symbol_designator=String('INTERN-WITH-PACKAGE'), package_designator=String('COMMON-LISP-USER')) self.assertTrue(symbol is Symbol('INTERN-WITH-PACKAGE')) self.assertTrue(status is Null()) self.assertTrue('INTERN-WITH-PACKAGE' in PackageManager.package_container['COMMON-LISP-USER'].symbol_container.keys()) self.assertEqual(PackageManager.package_container['COMMON-LISP-USER'].symbol_container['INTERN-WITH-PACKAGE'], [Symbol('INTERN-WITH-PACKAGE'), Keyword(':INTERNAL'), None])
def __call__(self, forms, var_env, func_env, macro_env): """Behavior of PrognSpecialOperator. """ from clispy.evaluator import Evaluator # The values of eatch form but the last are discarded. while forms is not Null(): last = Evaluator.eval(forms.car, var_env, func_env, macro_env) forms = forms.cdr return last
def __call__(self, forms, var_env, func_env, macro_env): """Behavior of NumericalNotEqualSystemFunction. """ args = self.eval_forms(forms, var_env, func_env, macro_env) # Sets initial value. val, args = args.car, args.cdr # Whether no two numbers are the same or not. while args is not Null(): rest_args = args while rest_args is not Null(): if rest_args.car == val: return Null() rest_args = rest_args.cdr # Updates value and args. val, args = args.car, args.cdr return T()
def __call__(self, forms, var_env, func_env, macro_env): """Behavior of BlockSpecialOperator. """ from clispy.evaluator import Evaluator # throw is a param of lambda in call/cc. lambda_forms = Cons(Cons(forms.car, Null()), forms.cdr) # call/cc is used to control. callcc = CallCC(Lambda(lambda_forms, var_env, func_env, macro_env)) return callcc(var_env, func_env, macro_env)
def expand_hepler(cls, forms): """Expand quotes recursively. """ if not isinstance(forms, Cons): # An argument is not an instance of Cons, it is quoted. return Cons(Symbol('QUOTE'), Cons(forms, Null())) if forms.car is Symbol('UNQUOTE'): # Unquote (,). return forms.cdr.car elif isinstance(forms.car, Cons) and forms.car.car is Symbol('UNQUOTE-SPLICING'): # Unquote-splicing (,@). return Cons(Symbol('APPEND'), Cons(forms.car.cdr.car, Cons(cls.expand_hepler(forms.cdr), Null()))) else: # Expands recursively and returns cons. return Cons(Symbol('CONS'), Cons(cls.expand_hepler(forms.car), Cons(cls.expand_hepler(forms.cdr), Null())))
def testEqSystemFunction_call_nil(self): # Make an instance of EqSystemFunction. eq = EqSystemFunction() # If args are not the same objects, eq return nil. forms = Parser.parse('(1 1.0)') retval = eq(forms, PackageManager.current_package.env['VARIABLE'], PackageManager.current_package.env['FUNCTION'], PackageManager.current_package.env['MACRO']) # Checks return value. self.assertEqual(retval, Null())
def testEqSystemFunction_call_cons(self): # Make an instance of EqSystemFunction. eq = EqSystemFunction() # If args are cons, eq return nil because cons returns a different object. forms = Parser.parse('((cons 1 1) (cons 1 1))') retval = eq(forms, PackageManager.current_package.env['VARIABLE'], PackageManager.current_package.env['FUNCTION'], PackageManager.current_package.env['MACRO']) # Checks return value self.assertEqual(retval, Null())
def __call__(self, forms, var_env, func_env, macro_env): """Behavior of FindSymbolSystemFunction. """ args = self.eval_forms(forms, var_env, func_env, macro_env) symbol_designator = args.car package_designator = args.cdr.car if package_designator is Null(): return PackageManager.find_symbol(symbol_designator=symbol_designator) else: return PackageManager.find_symbol(symbol_designator=symbol_designator, package_designator=package_designator)
def __call__(self, forms, var_env, func_env, macro_env): """Behavior of IfSpecialOperator. """ from clispy.evaluator import Evaluator # Sets test-form, then-form and else-form. test_form, then_form, else_form = forms.car, forms.cdr.car, forms.cdr.cdr.car # If-then-else if Evaluator.eval(test_form, var_env, func_env, macro_env) is Null(): return Evaluator.eval(else_form, var_env, func_env, macro_env) else: return Evaluator.eval(then_form, var_env, func_env, macro_env)