def _process_quasiquote_list_item(obj): # TODO: could we invoke (list) directly? if is_list(obj) and first(obj) == Symbol('unquote'): return List([Symbol('list', ns='kaa.core'), first(rest(obj))]) if is_list(obj) and first(obj) == Symbol('unquote-splice'): return first(rest(obj)) return List([Symbol('list', ns='kaa.core'), _process_quasiquote(obj)])
def _read_unquote(self, stream): if stream.peek_char() == '@': stream.pop_char() return List([Symbol('unquote-splice', meta={'source': stream.source_meta()}), self.read_next(stream)]) return List([Symbol('unquote', meta={'source': stream.source_meta()}), self.read_next(stream)])
def _process_quasiquote(obj): # `a -> 'a if not is_list(obj) or not obj: return List([Symbol('quote'), obj]) # `~a -> a if first(obj) == Symbol('unquote'): return obj # `(a ~b ~@c) -> (concat (list 'a) (list b) c) # TODO: could we invoke (concat) directly? return List([Symbol('concat', ns='kaa.core')] + [_process_quasiquote_list_item(o) for o in obj])
def _read_list(self, stream): l = List(meta={'source': stream.source_meta()}) self.list_depth += 1 while True: form = self.read_next(stream) if form == EOLIST: break l.append(form) self.list_depth -= 1 return l
def bind_params(params, args): check_arity(params, args) bindings = dict(zip(params.required, args)) bindings.update( zip(params.optional, chain(args[len(params.required):], repeat(None)))) if params.rest: num_consumed = len(params.required) + len(params.optional) bindings[params.rest] = List(args[num_consumed:]) return bindings
def _read_quote(self, stream): return List([Symbol('quote', meta={'source': stream.source_meta()}), self.read_next(stream)])
def test_list_python_interop(): l = List((1, 2)) assert l[1] == 2 assert isinstance(l[1:], List)