Exemple #1
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;
    }
}
Exemple #2
0
MalVal *read_atom(Reader *reader) {
    char *token;
    GRegex *regex;
    GMatchInfo *matchInfo;
    GError *err = NULL;
    gint pos;
    MalVal *atom;

    token = reader_next(reader);
    //g_print("read_atom token: %s\n", token);
    
    regex = g_regex_new ("(^-?[0-9]+$)|(^-?[0-9][0-9.]*$)|(^nil$)|(^true$)|(^false$)|^\"(.*)\"?$|:(.*)|(^[^\"]*$)", 0, 0, &err);
    g_regex_match (regex, token, 0, &matchInfo);

    if (g_match_info_fetch_pos(matchInfo, 1, &pos, NULL) && pos != -1) {
        //g_print("read_atom integer\n");
        atom = malval_new_integer(g_ascii_strtoll(token, NULL, 10));
    } else if (g_match_info_fetch_pos(matchInfo, 2, &pos, NULL) && pos != -1) {
        //g_print("read_atom float\n");
        atom = malval_new_float(g_ascii_strtod(token, NULL));
    } else if (g_match_info_fetch_pos(matchInfo, 3, &pos, NULL) && pos != -1) {
        //g_print("read_atom nil\n");
        atom = &mal_nil;
    } else if (g_match_info_fetch_pos(matchInfo, 4, &pos, NULL) && pos != -1) {
        //g_print("read_atom true\n");
        atom = &mal_true;
    } else if (g_match_info_fetch_pos(matchInfo, 5, &pos, NULL) && pos != -1) {
        //g_print("read_atom false\n");
        atom = &mal_false;
    } else if (g_match_info_fetch_pos(matchInfo, 6, &pos, NULL) && pos != -1) {
        //g_print("read_atom string: %s\n", token);
        int end = strlen(token)-1;
        if (token[end] != '"') { abort("expected '\"', got EOF"); }
        token[end] = '\0';
        atom = malval_new_string(g_strcompress(g_match_info_fetch(matchInfo, 6)));
    } else if (g_match_info_fetch_pos(matchInfo, 7, &pos, NULL) && pos != -1) {
        //g_print("read_atom keyword\n");
        atom = malval_new_keyword(MAL_GC_STRDUP(g_match_info_fetch(matchInfo, 7)));
    } else if (g_match_info_fetch_pos(matchInfo, 8, &pos, NULL) && pos != -1) {
        //g_print("read_atom symbol\n");
        atom = malval_new_symbol(MAL_GC_STRDUP(g_match_info_fetch(matchInfo, 8)));
    } else {
        malval_free(atom);
        atom = NULL;
    }

    return atom;
}