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 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 __call__(self, forms, var_env, func_env, macro_env): """Behavior of FletSystemMacro. """ from clispy.expander import Expander bindings, body = forms.car, forms.cdr # Expands body recursively. body = Expander.expand(body, var_env, macro_env, macro_env) # The body of flet has an implicit progn. forms = Cons(Symbol('FLET'), Cons(bindings, Cons(Cons(Symbol('PROGN'), body), Null()))) return forms
def __call__(self, forms, var_env, func_env, macro_env): """Behavior of BlockSystemMacro. """ from clispy.expander import Expander name, body = forms.car, forms.cdr # Expands body recursively. body = Expander.expand(body, var_env, func_env, macro_env) # The body of a block has an implicit progn. forms = Cons(Symbol('BLOCK'), Cons(name, Cons(Cons(Symbol('PROGN'), body), Null()))) return forms
def __call__(self, forms, var_env, func_env, macro_env): """Behavior of LambdaSystemMacro. """ from clispy.expander import Expander params, body = forms.car, forms.cdr # Expands body recursively. body = Expander.expand(body, var_env, func_env, macro_env) # The body of a lambda has an implicit progn. forms = Cons(Symbol('LAMBDA'), Cons(params, Cons(Cons(Symbol('PROGN'), body), Null()))) return forms
def __call__(self, forms, var_env, func_env, macro_env): """Behavior of IfSystemMacro. """ from clispy.expander import Expander # If else_form is Null, then else_form is set to Null. test_form, then_form, else_form = forms.car, forms.cdr.car, forms.cdr.cdr.car # Expands body recursively. test_form = Expander.expand(test_form, var_env, func_env, macro_env) then_form = Expander.expand(then_form, var_env, func_env, macro_env) else_form = Expander.expand(else_form, var_env, func_env, macro_env) forms = Cons(Symbol('IF'), Cons(test_form, Cons(then_form, Cons(else_form, Null())))) return forms
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 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 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 __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 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 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 DefmacroSystemMacro. """ from clispy.expander import Expander name, params, body = forms.car, forms.cdr.car, forms.cdr.cdr # Expands body, recursively. body = Expander.expand(body, var_env, func_env, macro_env) # The value of the last form executed is returned as the expansion of the macro. body = Cons(Cons(Symbol('PROGN'), body), Null()) # The body of a defmacro has an implicit block. forms = Cons(Symbol('DEFMACRO'), Cons(name, Cons(params, Cons(Cons(Symbol('BLOCK'), Cons(name, body)), Null())))) return forms
def __call__(self, forms, var_env, func_env, macro_env): """Behavior of ConsSytemFunction. """ args = self.eval_forms(forms, var_env, func_env, macro_env) return Cons(args.car, args.cdr.car)
def __call__(self, forms, var_env, func_env, macro_env): """Behavior of QuoteSystemMacro. """ # Retruns itself. return Cons(Symbol('QUOTE'), forms)