def macro(self, scope, args): sig = list(args[0]) body = types.mklist(args[1]) for arg in sig: if not types.is_symbol(arg): raise LispException("argument 1 of lambda must be a list of symbols, found %s" % types.type_name(arg)) return types.mkmacro(sig, body, scope)
def invoke(self, scope, func, args, tailrec = False): args = list(args) if types.is_primitive(func): return func.invoke(scope, args) try: rest = list((i.value for i in func.sig)).index("&") except ValueError: rest = -1 if len(args) != len(func.sig): raise LispException("%s takes %d arguments, %d given" % (types.type_name(func), len(func.sig), len(args))) else: if len(args) < rest: raise LispException("%s takes at least %d arguments, %d given" % (types.type_name(func), rest, len(args))) closure = scope if tailrec else Scope(func, func.scope) for i in xrange(len(args)): if func.sig[i].value == "&": closure.define(func.sig[rest+1].value, types.mklist(args[rest:])) rest = -1 break else: closure.define(func.sig[i].value, args[i]) if rest >= 0: closure.define(func.sig[rest+1].value, types.nil) rv = types.nil for sexp in func.value: rv = self.execute(closure, sexp) return rv