Example #1
0
def read_atom(reader):
    token = reader.peek()
    try:
        val = int(token)
        return mal_types.MalNumber(val)
    except ValueError:
        pass
    if token in _quote_mapping:
        reader.next()
        return mal_types.MalList(
            [mal_types.MalSymbol(_quote_mapping[token]),
             read_form(reader)])
    elif token == '^':
        reader.next()
        meta_data = read_form(reader)
        reader.next()
        lst = read_form(reader)
        return mal_types.MalList(
            [mal_types.MalSymbol("with-meta"), lst, meta_data])
    elif token.startswith('"') and token.endswith('"'):
        return mal_types.MalString(
            bytes(token[1:-1], "utf-8").decode("unicode_escape"))
    elif token.startswith(":"):
        return mal_types.MalKeyword(token)
    elif token in ('true', 'false'):
        if token == 'true':
            return mal_types.MalBool(True)
        return mal_types.MalBool(False)
    elif token == 'nil':
        return mal_types.MalNil()
    return mal_types.MalSymbol(token)  # symbol?
Example #2
0
def seq(x):
    if not x.data:
        return mal_types.MalNil()
    elif isinstance(x, mal_types.MalList):
        return x
    elif isinstance(x, mal_types.MalVector):
        return mal_types.MalList(x.data)
    elif isinstance(x, mal_types.MalString):
        return mal_types.MalList([mal_types.MalString(i) for i in x.data])
def quasiquote(ast):
    if not is_pair(ast):
        return mal_types.MalList([mal_types.MalSymbol('quote'), ast])
    elif ast[0].data == 'unquote':
        return ast[1]
    elif isinstance(ast[0], mal_types.list_types) and \
            isinstance(ast[0][0], mal_types.MalSymbol) and \
            ast[0][0].data == 'splice-unquote':
        return mal_types.MalList([mal_types.MalSymbol('concat'), ast[0][1], quasiquote(ast[1:])])
    else:
        return mal_types.MalList([mal_types.MalSymbol('cons'), quasiquote(ast[0]), quasiquote(ast[1:])])
Example #4
0
def cons(obj, lst):
    rv = mal_types.MalList([obj])
    if isinstance(lst, list):  #fixme
        rv.data.extend(lst)
    else:  #
        rv.data.extend(lst.data)
    return rv
Example #5
0
def conj(collection, *elements):
    if isinstance(collection, mal_types.MalList):
        lst = collection.data
        for i in elements:
            lst.insert(0, i)
        return mal_types.MalList(lst)
    if isinstance(collection, mal_types.MalVector):
        lst = collection.data
        for i in elements:
            lst.append(i)
        return mal_types.MalVector(lst)
Example #6
0
def read_atom(reader: Reader):
    atom = reader.peek()
    special_chars = {
        "'": "quote",
        "`": "quasiquote",
        "~": "unquote",
        "~@": "splice-unquote",
        "@": "deref"
    }

    if atom[0] == '"':
        if not is_proper_quote(atom):
            return "EOF"
        return '"' + escape(atom[1:-1]) + '"'
    if is_integer(atom):
        return int(atom)
    if atom in special_chars:
        reader.next()
        res_lst = mal_types.MalList("(")
        res_lst.append(special_chars[atom])
        res_lst.append(read_form(reader))
        return res_lst
    if atom == "^":
        res_lst = mal_types.MalList("(")
        res_lst.append("with-meta")
        reader.next()
        second = read_form(reader)
        reader.next()
        first = read_form(reader)
        res_lst.append(first)
        res_lst.append(second)
        return res_lst
    if atom == "true":
        return True
    if atom == "false":
        return False
    if atom == "nil":
        return None
    else:
        return atom
def main():
    rep("(def! not (fn* (a) (if a false true)))")
    rep('(def! load-file (fn* (f) (eval (read-string (str "(do " (slurp f) ")")))))')
    rep("""(defmacro! cond (fn* (& xs) (if (> (count xs) 0) (list'if (first xs) (if (> (count xs) 1) (nth xs 1) (throw "odd number of forms to cond")) (cons'cond (rest (rest xs)))))))""")
    rep("""(defmacro! or (fn* (& xs) (if (empty? xs) nil (if (= 1 (count xs)) (first xs) `(let* (or_FIXME ~(first xs)) (if or_FIXME or_FIXME (or ~@(rest xs))))))))""")
    repl_env.set("*ARGV*", mal_types.MalList([mal_types.MalString(i) for i in sys.argv[2:]]))
    if sys.argv[1:]:
        rep('(load-file "{}")'.format(sys.argv[1]))
        exit()
    while True:
        try:
            print(rep(input("user> ")))
        except mal_types.MalException as e:
            # raise e
            print(e)
        except Exception as e:
            # raise e
            print(e)
def main():
    rep("(def! not (fn* (a) (if a false true)))")
    rep('(def! load-file (fn* (f) (eval (read-string (str "(do " (slurp f) ")")))))'
        )
    repl_env.set(
        "*ARGV*",
        mal_types.MalList([mal_types.MalString(i) for i in sys.argv[2:]]))
    if sys.argv[1:]:
        rep('(load-file "{}")'.format(sys.argv[1]))
        exit()
    while True:
        try:
            print(rep(input("user> ")))
        except mal_types.MalException as e:
            # raise e
            print(e)
        except Exception as e:
            # raise e
            print(e)
Example #9
0
def read_list(reader: Reader, opener):
    res = mal_types.MalList(opener)
    try:
        for i in reader:
            next_atom = read_form(reader)
            if next_atom == res.closer:
                break
            res.append(next_atom)

        if opener == "{":
            for i in range(0, len(res), 2):
                res.dict[res[i]] = res[i + 1]
            res.clear()
            for x in sorted(res.dict):
                res.append(x)
                res.append(res.dict[x])

    except IndexError:
        raise EOFError
    return res
Example #10
0
def concat(*lsts):
    rv = mal_types.MalList()
    for l in lsts:
        rv.data.extend(l)
    return rv
Example #11
0
def map_(f, lst):
    #print('**MAP', type(f), f, lst)
    return mal_types.MalList([f(i) for i in lst])
Example #12
0
def rest(lst):
    if isinstance(lst, mal_types.MalNil):
        return mal_types.MalList()
    return mal_types.MalList(lst[1:])
Example #13
0
        return mal_types.MalBool(True)
    return mal_types.MalBool(False)


ns = {
    '+':
    lambda a, b: mal_types.MalNumber(
        a.data + b.data),  # fixme: operate and return maltypes directly
    '-':
    lambda a, b: mal_types.MalNumber(a.data - b.data),
    '*':
    lambda a, b: mal_types.MalNumber(a.data * b.data),
    '/':
    lambda a, b: mal_types.MalNumber((a.data / b.data)),
    "list":
    lambda *x: mal_types.MalList(list(x)),
    "list?":
    is_list,
    "vector":
    vector,
    "vector?":
    is_vector,
    "hash-map":
    hash_map,
    "map?":
    is_hash_map,
    "assoc":
    assoc,
    "dissoc":
    dissoc,
    "get":