def toscheme(self, val, shallow=False): "Convert a Python value to a Scheme value." if callable(val): val = self._wrap_python_callable(val, shallow) return expressions.makePrimitiveProcedure(val) if val is True: return symbol.true if val is False: return symbol.false if type(val) is schemepy.types.Symbol: return symbol.Symbol(val.name) if type(val) is schemepy.types.Cons: car = val.car cdr = val.cdr if not shallow: car = self.toscheme(car) cdr = self.toscheme(cdr) return pair.cons(car, cdr) if isinstance(val, list): lst = pair.NIL for el in reversed(val): if not shallow: el = self.toscheme(el) lst = pair.cons(el, lst) return lst if isinstance(val, dict): lst = pair.NIL for key, value in val.items(): key = self.toscheme(key) if not shallow: value = self.toscheme(value) lst = pair.cons(pair.cons(key, value), lst) return lst return val
def make_each(ms): def find_next_arity(this, arities): arities = [x for x in arities if x > this] if not arities: return MEC return max(MEC, min(arities)) if ms is nil: return nil meth = ms.car() rest = make_each(ms.cdr()) names = None if fixed_arityp(meth): names = (meth_name(meth, meth_arity(meth)),) else: names = nil base = meth_base_name(meth) this_arity = meth_arity(meth) next_arity = find_next_arity(this_arity, variable_arities[base]) for i in range(this_arity, next_arity): if i not in fixed_arities.get(base, ()): names = cons(meth_name(meth, i), names) if this_arity == max(variable_arities[base]): names = cons(meth_name(meth, '+'), names) return cons((meth, names), rest)
def collect_elifs(seq): if seq.nullp(): return false_s, seq next = seq.car() if tagged_list(next, else_s): return cons(do_s, next.cdr()), seq.cdr() if not tagged_list(next, elif_s): return false_s, seq alt, tail = collect_elifs(seq.cdr()) return plist(do_s, cons(if_s, next.cdr()), plist(else_s, alt)), tail
def expand_for(exp): param = exp.cadr() in_word = exp.caddr() seq_exp = exp.cadddr() body_seq = exp.cddddr() if in_word is not in_s: raise CompileError(exp, 'should be "for <expr> in <expr>"') f = cons(fn_s, cons(plist(param), body_seq)) return plist(map_s, f, seq_exp)
def set_merge(l1, l2): if l1.nullp(): return l2 if l2.nullp(): return l1 l1a = l1.car() l2a = l2.car() if l1a is l2a: return cons(l1a, set_merge(l1.cdr(), l2.cdr())) if l1a < l2a: return cons(l1a, set_merge(l1.cdr(), l2)) if l1a > l2a: return cons(l2a, set_merge(l1, l2.cdr())) raise RuntimeError("can't happen")
def expandQuasiquotation(exp, depth=1): """Takes a quasiquoted expression and constructs a new quoted expression. FIXME: this function is SO evil. *grin* Must clean this up. """ if not pair.isList(exp): return makeQuoted(exp) if isUnquoted(exp): if depth == 1: return textOfUnquotation(exp) else: return pair.list( Symbol("list"), makeQuoted(Symbol("unquote")), expandQuasiquotation(textOfUnquotation(exp), depth - 1)) if isQuasiquoted(exp): return pair.list( Symbol("list"), makeQuoted(Symbol("quasiquote")), expandQuasiquotation(textOfUnquotation(exp), depth + 1)) else: return pair.cons( Symbol("list"), pair.listMap(lambda subexp: expandQuasiquotation(subexp, depth), exp))
def scan_out_defines(body, cenv): def scan(body): if body.nullp(): return nil, nil, nil exp = body.car() vars, exps, voids = scan(body.cdr()) if tagged_list(exp, def_s): var = definition_variable(exp) val = definition_value(exp) set = plist(set__s, var, val) return cons(var, vars), cons(set, exps), cons(q_unassigned_s, voids) if tagged_list2(exp, assign_s): var = exp.car() addr, tail = find_variable(var, cenv) if addr is not_found_s: exp = assign2prefix(exp, def_s) val = definition_value(exp) set = plist(set__s, var, val) return cons(var, vars), cons(set, exps), cons(q_unassigned_s, voids) else: set = assign2prefix(exp, set__s) return vars, cons(set, exps), voids else: return vars, cons(exp, exps), voids vars, exps, voids = scan(body) if vars.nullp(): return exps binding = make_fn(vars, exps) return plist(cons(binding, voids)) # apply the fn to the void values
def expand_if(seq): def help(stmt, alt): test = stmt.cadr() consequent = cons(do_s, stmt.cddr()) return plist(qmark_s, test, consequent, alt) if seq.nullp(): return seq alternative, tail = collect_elifs(seq.cdr()) return cons(help(seq.car(), alternative), tail)
def testSetCarCdr(self): self.pe("(define x '(hello world))") self.pe("(define y x)") self.pe("(define z (cons 'hi 'earth))") self.pe("(set-car! x 'hi)") self.pe("(set-cdr! y 'earth)") self.assertEquals(pair.cons(Symbol("hi"), Symbol("earth")), self.pe("x")) self.assert_(self.pe("(eq? x y)")) self.assert_(self.pe("(not (eq? x z))")) self.assert_(self.pe("(equal? x z)"))
def expand_import(stmt): def old_name(term): if symbolp(term): return term return term.car() def new_name(term): if symbolp(term): return term return term.caddr() def import_term2def(term): return make_def(new_name(term), make_call(new_name(stmt.cadr()), old_name(term))) def module2def(name): return make_def(new_name(name), make_load_module(old_name(name))) terms = stmt.cddr() return cons(module2def(stmt.cadr()), terms.map(import_term2def))
def compile_meth_body(meth, meth_entry, cenv): pop_all_symbol = make_label('pop-all') if is_inline_meth(meth): return compile_inline_meth_body(meth, meth_entry, cenv) if is_asm_meth(meth): return compile_asm_meth_body(meth, meth_entry, cenv) formals = meth_params(meth) body = meth_body(meth) cenv = cons(formals, cenv) return append_ir_seqs( make_ir_seq((proc_r,), (env_r,), backptr(), meth_entry, closure_env(env_r, proc_r)), compile_literal(formals, tmp_r, next_s, cenv, pop_all_symbol), make_ir_seq((env_r, tmp_r, argl_r), (env_r,), extend_environment(env_r, env_r, argl_r, tmp_r)), compile_sequence(body, val_r, return_s, cenv, pop_all_symbol))
def scan(body): if body.nullp(): return nil, nil, nil exp = body.car() vars, exps, voids = scan(body.cdr()) if tagged_list(exp, def_s): var = definition_variable(exp) val = definition_value(exp) set = plist(set__s, var, val) return cons(var, vars), cons(set, exps), cons(q_unassigned_s, voids) if tagged_list2(exp, assign_s): var = exp.car() addr, tail = find_variable(var, cenv) if addr is not_found_s: exp = assign2prefix(exp, def_s) val = definition_value(exp) set = plist(set__s, var, val) return cons(var, vars), cons(set, exps), cons(q_unassigned_s, voids) else: set = assign2prefix(exp, set__s) return vars, cons(set, exps), voids else: return vars, cons(exp, exps), voids
def makeAnd(clauses): return pair.cons(symbol.Symbol("AND"), clauses)
def make_fn(parameters, body): return cons(fn_s, cons(parameters, body))
def make_obj(tos): return cons(obj_s, tos)
def letBindingValues(bindings): if pair.isNull(bindings): return pair.list() return pair.cons(pair.cadr(pair.car(bindings)), letBindingValues(pair.cdr(bindings)))
def makeApplication(operators, operands): return pair.cons(operators, operands)
def help(stmt, alt): test = stmt.cadr() consequent = cons(do_s, stmt.cddr()) return plist(qmark_s, test, consequent, alt)
def c_rest_eaten(restVal): return pogo.bounce(cont, pair.cons(firstVal, restVal))
def c2(tail_val): return pogo.bounce(cont, pair.cons(head_val, tail_val))
def makeBegin(seq): return pair.cons(Symbol("begin"), seq)
def set_minus1(l, x): if l.nullp(): return nil a = l.car() d = set_minus1(l.cdr(), x) return d if a is x else cons(a, d)
def letToApplication(exp): bindings = letBindings(exp) return pair.cons(makeLambda(letBindingVariables(bindings), letBody(exp)), letBindingValues(bindings))
def export_term2to(term): if symbolp(term): return cons(plist(term), plist(term)) return cons(plist(term.caddr()), plist(term.car()))
def eval_rest_cont(tailVal): return pogo.bounce(cont, pair.cons(headVal, tailVal))
def if_macro_alternative(seq): if seq.nullp(): return false_s next = seq.car() if tagged_list(next, else_s): return cons(do_s, next.cdr()) return false_s
def makeOr(clauses): return pair.cons(symbol.Symbol("OR"), clauses)
def testRecursiveExpressionsDontKillUs(self): ## Makes sure that circular structures do not kill us. loopyList = pair.cons(1, 1) pair.setCdrBang(loopyList, loopyList) self.assertEquals("(1 . [...])", toString(loopyList))
def exp_operands(exp): if not message_send(exp): return exp.cdr() if call_app(exp): return exp.cddr() msg = plist(quote_s, extract_message(exp.cadr())) argl = cons(S('list'), exp.cddr()) if send_app(exp): return plist(exp.car(), msg, argl)
def testDottedPairs(self): self.assertEquals("(1 . 2)", toString(pair.cons(1, 2)))
def fn2obj(exp): sig = cons(run_s, fn_params(exp)) body = fn_body(exp) return make_obj(plist(cons(sig, body)))
def match_loop(self, parse, *sentinels): if self.peek in sentinels: return nil first = parse() return cons(first, self.match_loop(parse, *sentinels))