Пример #1
0
MalVal *read_list(Reader *reader, MalType type, char start, char end) {
    MalVal *ast, *form;
    char *token = reader_next(reader);
    //g_print("read_list start token: %s\n", token);
    if (token[0] != start) { abort("expected '(' or '['"); }

    ast = malval_new_list(type, g_array_new(TRUE, TRUE, sizeof(MalVal*)));

    while ((token = reader_peek(reader)) &&
           token[0] != end) {
        //g_print("read_list internal token %s\n", token);
        form = read_form(reader);
        if (!form) {
            if (!mal_error) { abort("unknown read_list failure"); }
            g_array_free(ast->val.array, TRUE);
            malval_free(ast);
            return NULL;
        }
        g_array_append_val(ast->val.array, form);
    }
    if (!token) { abort("expected ')' or ']', got EOF"); }
    reader_next(reader);
    //g_print("read_list end token: %s\n", token);
    return ast;
}
Пример #2
0
// eval
MalVal *eval_ast(MalVal *ast, GHashTable *env) {
    if (!ast || mal_error) return NULL;
    if (ast->type == MAL_SYMBOL) {
        //g_print("EVAL symbol: %s\n", ast->val.string);
        // TODO: check if not found
        return g_hash_table_lookup(env, ast->val.string);
    } else if ((ast->type == MAL_LIST) || (ast->type == MAL_VECTOR)) {
        //g_print("EVAL sequential: %s\n", _pr_str(ast,1));
        MalVal *el = _map2((MalVal *(*)(void*, void*))EVAL, ast, env);
        if (!el || mal_error) return NULL;
        el->type = ast->type;
        return el;
    } else if (ast->type == MAL_HASH_MAP) {
        //g_print("EVAL hash_map: %s\n", _pr_str(ast,1));
        GHashTableIter iter;
        gpointer key, value;
        MalVal *seq = malval_new_list(MAL_LIST,
                                    g_array_sized_new(TRUE, TRUE, sizeof(MalVal*),
                                                        _count(ast)));
        g_hash_table_iter_init (&iter, ast->val.hash_table);
        while (g_hash_table_iter_next (&iter, &key, &value)) {
            MalVal *kname = malval_new_string((char *)key);
            g_array_append_val(seq->val.array, kname);
            MalVal *new_val = EVAL((MalVal *)value, env);
            g_array_append_val(seq->val.array, new_val);
        }
        return _hash_map(seq);
    } else {
        //g_print("EVAL scalar: %s\n", _pr_str(ast,1));
        return ast;
    }
}