Пример #1
0
Файл: env.py Проект: davemus/mal
 def get(self, name):
     env = self.find(name)
     if env is None:
         if is_symbol(name):
             name = str(name, encoding='utf-8')
         raise RuntimeError(f"\"'{name}' not found\"")
     return env._scope[name]
Пример #2
0
def is_macro_call(ast, env):
    try:
        return (
            is_list(ast)
            and is_symbol(ast[0])
            and env.get(ast[0]).is_macro
        )  # function, that is macros
    except (AttributeError, RuntimeError):
        return False
Пример #3
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
Пример #4
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
Пример #5
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)}')