apply.c
atom_t* apply(atom_t* expr, atom_t* proc, atom_t* args) {

    int argc = list_len(args);
    atom_t** argv = args->val.list->items;
    atom_t* env = active_env;

    // -------------------------------------
    // standard operator
    if (proc->type == STD_OP) {
        return apply_op(expr, proc, argc, argv);

    // -------------------------------------
    // function
    } else if (proc->type == FUNCTION) {
        if (argc != list_len(proc->val.func->params)) {
            errmsg("Syntax", "wrong number of arguments", NULL, NULL);
            list_print(expr, 0);
            return NULL;
        }

#ifdef DEBUG
printf("....  apply:                   Creating function environment\n");
#endif

        // Create function environment
        atom_t* fenv = dict(argc, proc->val.func->env);
        atom_t** par = proc->val.func->params->val.list->items;
        for (int i = 0; i < argc; ++i)
            dict_add(fenv, par[i]->val.sym, argv[i]);

#ifdef DEBUG
char* dbg_s = atom_tostr(fenv);
char* dbg_s2 = atom_tostr(proc->val.func->body);
printf("....  apply:                   --> eval %s in %s\n", dbg_s2, dbg_s);
safe_free(dbg_s);
safe_free(dbg_s2);
#endif

        // Evaluate body in the environment
        atom_t* v = eval(proc->val.func->body, fenv, NULL);
        active_env = env;

#ifdef DEBUG
dbg_s = atom_tostr(v);
printf("....  apply:                   %s <-- eval\n", dbg_s);
printf("....  apply:                   Deallocating function environment\n");
safe_free(dbg_s);
#endif

        if (v)
            atom_bind(v, env);  // protect returned value
        atom_del(fenv);
        if (v)
            atom_unbind(v, env);
        return v;
    }

    char* o = atom_tostr(proc);
    errmsg("Semantic", "object is not callable", o, o);
    safe_free(o);
    return NULL;
}
/*
--------------------------------------
apply

    Apply a procedure to arguments.
--------------------------------------
*/
apply
Apply a procedure to arguments.
apply Apply a procedure to arguments .
atom_t* apply(atom_t* expr, atom_t* proc, atom_t* args) {
    int argc = list_len(args);
    atom_t** argv = args->val.list->items;
    atom_t* env = active_env;
    if (proc->type == STD_OP) {
        return apply_op(expr, proc, argc, argv);
    } else if (proc->type == FUNCTION) {
        if (argc != list_len(proc->val.func->params)) {
            errmsg("Syntax", "wrong number of arguments", NULL, NULL);
            list_print(expr, 0);
            return NULL;
        }
#ifdef DEBUG
printf("....  apply:                   Creating function environment\n");
#endif
        atom_t* fenv = dict(argc, proc->val.func->env);
        atom_t** par = proc->val.func->params->val.list->items;
        for (int i = 0; i < argc; ++i)
            dict_add(fenv, par[i]->val.sym, argv[i]);
#ifdef DEBUG
char* dbg_s = atom_tostr(fenv);
char* dbg_s2 = atom_tostr(proc->val.func->body);
printf("....  apply:                   --> eval %s in %s\n", dbg_s2, dbg_s);
safe_free(dbg_s);
safe_free(dbg_s2);
#endif
        atom_t* v = eval(proc->val.func->body, fenv, NULL);
        active_env = env;
#ifdef DEBUG
dbg_s = atom_tostr(v);
printf("....  apply:                   %s <-- eval\n", dbg_s);
printf("....  apply:                   Deallocating function environment\n");
safe_free(dbg_s);
#endif
        if (v)
            atom_bind(v, env);  
        atom_del(fenv);
        if (v)
            atom_unbind(v, env);
        return v;
    }
    char* o = atom_tostr(proc);
    errmsg("Semantic", "object is not callable", o, o);
    safe_free(o);
    return NULL;
}
atom_t * apply ( atom_t * expr , atom_t * proc , atom_t * args ) { int argc = list_len ( args ) ; atom_t * * argv = args -> val . list -> items ; atom_t * env = active_env ; if ( proc -> type == STD_OP ) { return apply_op ( expr , proc , argc , argv ) ; } else if ( proc -> type == FUNCTION ) { if ( argc != list_len ( proc -> val . func -> params ) ) { errmsg ( " " , " " , NULL , NULL ) ; list_print ( expr , 0 ) ; return NULL ; } #ifdef DEBUG printf ( " \n " ) ; #endif atom_t * fenv = dict ( argc , proc -> val . func -> env ) ; atom_t * * par = proc -> val . func -> params -> val . list -> items ; for ( int i = 0 ; i < argc ; ++ i ) dict_add ( fenv , par [ i ] -> val . sym , argv [ i ] ) ; #ifdef DEBUG char * dbg_s = atom_tostr ( fenv ) ; char * dbg_s2 = atom_tostr ( proc -> val . func -> body ) ; printf ( " \n " , dbg_s2 , dbg_s ) ; safe_free ( dbg_s ) ; safe_free ( dbg_s2 ) ; #endif atom_t * v = eval ( proc -> val . func -> body , fenv , NULL ) ; active_env = env ; #ifdef DEBUG dbg_s = atom_tostr ( v ) ; printf ( " \n " , dbg_s ) ; printf ( " \n " ) ; safe_free ( dbg_s ) ; #endif if ( v ) atom_bind ( v , env ) ; atom_del ( fenv ) ; if ( v ) atom_unbind ( v , env ) ; return v ; } char * o = atom_tostr ( proc ) ; errmsg ( " " , " " , o , o ) ; safe_free ( o ) ; return NULL ; }
apply
Apply a procedure to arguments.
apply Apply a procedure to arguments .
// ------------------------------------- // standard operator // ------------------------------------- // function // Create function environment // Evaluate body in the environment // protect returned value