Example #1
0
static Expr* eqv(Expr* args) {
	assert(args);

	if(scm_list_len(args) != 2) return scm_mk_error("eqv? expects 2 args");
	
	Expr* fst = scm_car(args);
	Expr* snd = scm_cadr(args);

	if(fst == snd) return TRUE;
	if(scm_is_pair(fst) || scm_is_pair(snd)) return FALSE;
	if(scm_is_closure(fst) || scm_is_closure(snd)) return FALSE;
	if(scm_is_num(fst) && scm_is_num(snd)) return num_eq(args);
	if(scm_is_string(fst) && scm_is_string(snd) && strcmp(scm_sval(fst), scm_sval(snd)) == 0) return TRUE;

	return FALSE;
}
Example #2
0
static void conv_highlight_keywords(struct conv *conv)
{
    int key_index = 0;
    scheme *sc = conv->proc->sc;
    pointer sym = conv->proc->code;
    
    assert(sc);
    assert(sym);

    if (sym == sc->NIL) {
        warn("%s: conv proc not a symbol", __FUNCTION__);
        return;
    }

    pointer ifc = sc->vptr->find_slot_in_env(sc, sc->envir, sym, 1);
    if (! scm_is_pair(sc, ifc)) {
        warn("%s: conv '%s' has no value", __FUNCTION__, scm_sym_val(sc, sym));
        return;
    }

    pointer clos = scm_cdr(sc, ifc);
    if (! scm_is_closure(sc, clos)) {
        warn("%s: conv '%s' not a closure", __FUNCTION__, scm_sym_val(sc, sym));
        return;
    }

    pointer env = scm_cdr(sc, clos);
    pointer vtable = scm_cdr(sc, scm_car(sc, scm_car(sc, env)));

    conv->n_keywords = scm_len(sc, vtable);

    if (!(conv->keywords = (char**)calloc(conv->n_keywords, sizeof(char*)))) {
        warn("%s: failed to allocate keyword array size %d", __FUNCTION__, conv->n_keywords);
        return;
    }

    if (!(conv->marked = bitset_alloc(conv->n_keywords))) {
        warn("%s: failed to allocate bitset array size %d", __FUNCTION__, conv->n_keywords);
        return;
    }

    while (scm_is_pair(sc, vtable)) {
        pointer binding = scm_car(sc, vtable);
        vtable = scm_cdr(sc, vtable);
        pointer var = scm_car(sc, binding);
        if (conv_add_keyword(conv, scm_sym_val(sc, var), key_index)) {
            return;
        }
        key_index++;
    }

    conv_sort_keywords(conv);
}
Example #3
0
/**
 * Evaluate a Scheme procedure with Scheme args. This is an internal helper
 * function.
 *
 * @param closure The closure to invoke.
 * @param args A scheme list of parameters.
 * @returns The result of evaluating the closure.
 */
static pointer closure_exec_with_scheme_args(closure_t *closure, pointer args)
{
        pointer result;

        /* Lock the closure against deletion while it is being called. */
        closure_ref(closure);

        /* Straight procedure call? */
        if (scm_is_closure(closure->sc, closure->code)) {
                result = scheme_call(closure->sc, closure->code, args);
        }

        /* Need to lookup it up first? */
        else if (scm_is_sym(closure->sc, closure->code)) {

                pointer pair;
                pointer proc;

                /* The 'code' pointer is a pointer to a scheme symbol. Looking
                 * it up in the scheme environment will return a (symbol,
                 * value) pair. We then take the cdr of the pair to get the
                 * actual procedure we want to call. */
                pair = closure->sc->vptr->find_slot_in_env(closure->sc, 
                                                           closure->sc->envir, 
                                                           closure->code, 
                                                           1);
                assert(scm_is_pair(closure->sc, pair));
                proc = closure->sc->vptr->pair_cdr(pair);
                result = scheme_call(closure->sc, proc, args);

        }

        /* Invalid or garbage-collected closure? */
        else {
                /* There's a bug somewhere. Happy hunting. */
                assert(false);
        }

        closure_unref(closure);
        return result;
}