def _is_atom(x): """Asks if atom, checks for primitives and non-primitives as well.""" if is_atom(x): return True if is_null(x): return False if is_eq(car(x), quote("primitive")): return True if is_eq(car(x), quote("non-primitive")): return True return False
def apply_primitive(name, vals): """Applies the primitive function `name`, with args=`vals`.""" if is_eq(name, quote("cons")): return cons(first(vals), second(vals)) if is_eq(name, quote("car")): return car(first(vals)) if is_eq(name, quote("cdr")): return cdr(first(vals)) if is_eq(name, quote("null?")): return is_null(first(vals)) if is_eq(name, quote("eq?")): return is_eq(first(vals), second(vals)) if is_eq(name, quote("atom?")): return _is_atom(first(vals)) if is_eq(name, quote("zero?")): return is_zero(first(vals)) if is_eq(name, quote("add1")): return add1(first(vals)) if is_eq(name, quote("sub1")): return sub1(first(vals)) if is_eq(name, quote("number?")): return is_number(first(vals))
def t_const(exp, table): """`t_const` type function: `*const` in schmeme.""" if is_number(exp): return exp if is_eq(exp, quote("True")): return True if is_eq(exp, quote("False")): return False return build(quote("primitive", exp))
def multiinsertLR_starred_and_co(new, oldL, oldR, l, col): """Inserts new to the left of `oldL` and to the right of `oldR`. NB: Uses a collector func to gather new list and count L, R inserts """ if is_null(l): return col(quote(), 0, 0) if is_atom(car(l)): if is_eq(car(l), oldL): return multiinsertLR_starred_and_co( new, oldL, oldR, cdr(l), lambda newl, L, R: col( cons(new, cons(oldL, newl)), add1(L), R)) if is_eq(car(l), oldR): return multiinsertLR_starred_and_co( new, oldL, oldR, cdr(l), lambda newl, L, R: col( cons(oldR, cons(new, newl)), L, add1(R))) return multiinsertLR_starred_and_co( new, oldL, oldR, cdr(l), lambda newl, L, R: col(cons(car(l), newl), L, R)) return multiinsertLR_starred_and_co( new, oldL, oldR, car(l), lambda carnl, carL, carR: multiinsertLR_starred_and_co( new, oldL, oldR, cdr(l), lambda cdrnl, cdrL, cdrR: col( cons(carnl, cdrnl), add(carL, cdrL), add(carR, cdrR))))
def evlis(args, table): """This returns a list composed of the meaning of each argument.""" if is_null(args): return quote() return cons(exp=meaning(car(args), table=table), evlis(args=cdr(args), table=table))
def t_lambda(exp, table): """`t_lambda` type function: `*lambda` in schmeme. Since for non-primitive functions, the args & func body need to be remembered, this is simply `cdr(exp)` """ return build(quote("non-primitive"), cons(table, cdr(exp)))
def make_set(lat): """Makes `lat` into `set`.""" if is_null(lat): return quote() if is_member(car(lat), cdr(lat)): return make_set(cdr(lat)) return cons(car(lat), make_set(cdr(lat)))
def intersect(set1, set2): """Gathers the intersect between `set1` and `set2`.""" if is_null(set1): return quote() if is_member(car(set1), set2): return cons(car(set1), intersect(cdr(set1), set2)) return intersect(cdr(set1))
def rember(a, lat): """Removes `a` from `lat` if it exists in `lat`.""" if is_null(lat): return quote() if is_eq(car(lat), a): return cdr(lat) return cons(car(lat), rember(a, cdr(lat)))
def pick(a, lat): """Pick function, returns the atom at position `a` for list `lat`.""" if is_null(lat): return quote() elif is_zero(sub1(a)): return car(lat) else: return pick(sub1(a), cdr(lat))
def rempick(a, lat): """Remove the atom at position `a` from the list, `l`.""" if is_null(lat): return quote() elif is_zero(sub1(a)): return (cdr(lat)) else: return cons(car(lat), rempick(sub1(a), cdr(lat)))
def leftmost(l): """Returns the leftmost atom from the list `l`.""" if is_null(l): return quote() elif is_atom(car(l)): return car(l) else: return leftmost(car(l))
def no_nums(l): """Remove all the numbers in the list `l`.""" if is_null(l): return quote() elif is_atom(car(l)): if is_number(car(l)): return no_nums(cdr(l)) else: return cons(car(l), (no_nums(cdr(l)))) else: return cons(no_nums(car(l)), no_nums(cdr(l)))
def rember_starred(a, l): """Removes all occurences of `a` in `l`. NB: `l` is not guaranteed to be a lat """ if is_null(l): return quote() if is_atom(l): if is_eq(car(l), a): return cdr(l) return cons(car(l), rember_starred(a, cdr(l))) return cons(rember_starred(a, cons(l)), rember_starred(a, cdr(l)))
def all_nums(l): """Return all numbers from list `l`.""" if is_null(l): return quote() elif is_atom(car(l)): if is_number(car(l)): return cons(car(l), all_nums(cdr(l))) else: return all_nums(cdr(l)) else: return cons(all_nums(car(l)), all_nums(cdr(l)))
def insertR_starred(new, old, l): """Inserts `new` to the left of `old`, if `old` found in `l` for every occurrence.""" if is_null(l): return quote() elif is_atom(car(l)): if is_eq(car(l), old): return cons(new, cons(old, insertR_starred(new, old, cdr(l)))) else: return cons(car(l), insertR_starred(new, old, cdr(l))) else: return cons(insertR_starred(new, old, car(l)), insertR_starred(new, old, cdr(l)))
def evens_only_and_co(l, col): """Collects, evens, the multiplication of evens and addition of odds.""" if is_null(l): return col(quote(), 1, 0) if is_atom(car(l)): if is_even(car(l)): return evens_only_and_co( cdr(l), lambda evens, p, s: col(cons(car(l), evens), multiply(car(l), p), s)) return evens_only_and_co( cdr(l), lambda evens, p, s: col(evens, p, add(car(l), s))) return evens_only_and_co( car(l), lambda car_evens, carp, cars: evens_only_and_co( cdr(l), lambda cdr_evens, cdrp, cdrs: col( cons(car_evens, cdr_evens), multiply(carp, cdrp), add(cars, cdrs))))
def cond_lines_of(lines): """Retrieves only the `cond` lines in exp.""" if is_eq(car(car(lines)), quote("cond")): return cdr(lines) return cond_lines_of(cdr(lines))
def is_else(x): """Asks if `x` is an else statement.""" if is_atom(x): return is_eq(x, quote("else")) return False
def initial_table(name): """Initial table helper func. NOTE: Should never get used. """ return car(quote())
def is_non_primitive(l): """Asks the question if `l` is a primitive.""" return is_eq(first(l), quote("non-primitive"))
def list_to_action(exp): """Converts `exp` to `action, assuming `exp` is `list`.""" if is_atom(car(e)): if is_eq(car(e), quote("quote")):
def build(s1, s2): """Builds a `pair` from two S-expressions: `s1`, `s2`.""" return cons(s1, cons(s2, quote()))