Пример #1
0
def equal(op1, op2):
    if is_iterable(op1) and is_iterable(
            op2):  # list and vector are equal in tests =(
        if count(op1) != count(op2):
            return False
        return all(equal(el1, el2) for (el1, el2) in zip(op1, op2))
    if is_hashmap(op1) and is_hashmap(op2):
        if set(keys(op1)) != set(keys(op2)):
            return False
        return all(equal(op1[key], op2[key]) for key in keys(op1))
    return type(op1) == type(op2) and op1 == op2
Пример #2
0
def eval_ast(ast, env):
    if is_vector(ast):
        return make_vector(EVAL(elem, env) for elem in ast)
    if is_hashmap(ast):
        return make_hashmap_from_pydict(
            {key: EVAL(value, env) for key, value in items(ast)}
        )
    if is_symbol(ast):
        return env.get(ast)
    elif is_list(ast):
        return make_list(EVAL(elem, env) for elem in ast)
    else:
        return ast
Пример #3
0
def quasiquote(ast):
    if is_list(ast):
        if is_empty(ast):
            return ast
        if ast[0] == make_symbol('unquote'):
            return ast[1]
        else:
            processed = []
            for elt in ast[::-1]:
                if is_list(elt) and not is_empty(elt) and elt[0] == make_symbol('splice-unquote'):
                    processed = make_list([make_symbol('concat'), elt[1], processed])
                else:
                    processed = make_list([make_symbol('cons'), quasiquote(elt), processed])
            return make_list(processed)
    elif is_vector(ast):
        return make_list([make_symbol('vec'), *ast])
    elif is_symbol(ast) or is_hashmap(ast):
        return make_list([make_symbol('quote'), ast])
    return ast
Пример #4
0
def pr_str(entity, print_readably=True):
    if isinstance(entity, MalException):
        return f'{pr_str(entity.value)}'
    if isinstance(entity, Exception):
        return entity.args[0]
    elif is_function(entity):
        return '#function'
    elif is_nil(entity):
        return 'nil'
    elif is_bool(entity):
        return {
            TRUE: 'true',
            FALSE: 'false',
        }[entity]
    elif is_number(entity):
        return str(entity)
    elif is_symbol(entity):
        return str(entity, 'utf-8')
    elif is_keyword(entity):
        return ':' + entity[1:]
    elif is_string(entity):
        if print_readably:
            return '"' + entity.replace('\\', '\\\\').replace('"', '\\"').replace('\n', '\\n') + '"'
        return entity
    elif is_atom(entity):
        return f'(atom {deref(entity)})'
    elif is_list(entity):
        return '(' + ' '.join(pr_str(inner, print_readably) for inner in entity) + ')'
    elif is_vector(entity):
        return '[' + ' '.join(pr_str(inner, print_readably) for inner in entity) + ']'
    elif is_hashmap(entity):
        return (
            '{'
            + ' '.join(f'{pr_str(k, print_readably)} {pr_str(v, print_readably)}' for k, v in entity.items())
            + '}'
        )
    raise RuntimeError(f'pr_str: unknown type {type(entity)}')