LakeVal *apply(LakeCtx *ctx, LakeVal *fnVal, LakeList *args) { LakeVal *result = NULL; if (lake_is_type(TYPE_PRIM, fnVal)) { LakePrimitive *prim = PRIM(fnVal); int arity = prim->arity; if (arity == ARITY_VARARGS || LIST_N(args) == arity) { result = prim->fn(ctx, args); } else { ERR("%s expects %d params but got %zu", prim->name, arity, LIST_N(args)); result = NULL; } } else if (lake_is_type(TYPE_FN, fnVal)) { LakeFn *fn = FN(fnVal); /* Check # of params */ size_t nparams = LIST_N(fn->params); if (!fn->varargs && LIST_N(args) != nparams) { ERR("expected %zu params but got %zu", nparams, LIST_N(args)); return NULL; } else if (fn->varargs && LIST_N(args) < nparams) { ERR("expected at least %zu params but got %zu", nparams, LIST_N(args)); return NULL; } Env *env = env_make(fn->closure); /* bind each (param,arg) pair in env */ size_t i; for (i = 0; i < nparams; ++i) { env_define(env, SYM(LIST_VAL(fn->params, i)), LIST_VAL(args, i)); } /* bind varargs */ if (fn->varargs) { LakeList *remainingArgs = list_make_with_capacity(LIST_N(args) - nparams); for (; i < LIST_N(args); ++i) { list_append(remainingArgs, LIST_VAL(args, i)); } env_define(env, fn->varargs, VAL(remainingArgs)); } /* evaluate body */ result = eval_exprs1(ctx, env, fn->body); } else { ERR("not a function: %s", lake_repr(fnVal)); } return result; }
void el_substandrun_str (stralloc *src, unsigned int srcbase, char const *const *envp, exlsn_t const *info) { stralloc dst = STRALLOC_ZERO ; register int r = el_substitute(&dst, src->s + srcbase, src->len, info->vars.s, info->values.s, genalloc_s(elsubst_t const, &info->data), genalloc_len(elsubst_t const, &info->data)) ; if (r < 0) strerr_diefu1sys(111, "el_substitute") ; if (!r) _exit(0) ; stralloc_free(src) ; { char const *v[r + 1] ; if (!env_make(v, r, dst.s, dst.len)) strerr_diefu1sys(111, "env_make") ; v[r] = 0 ; pathexec_r(v, envp, env_len(envp), info->modifs.s, info->modifs.len) ; } strerr_dieexec(111, dst.s) ; }
int env_init() { int len, i; struct env *env; char *res[PACKAGE_ENV_LISTLEN]; char *env_value = getenv(env_name); INIT_LIST_HEAD(&env_list); if (!env_value) return 0; len = strsplit(env_value, ";", res, PACKAGE_ENV_LISTLEN); for (i = 0; i < len; i++) { env = malloc(sizeof(*env)); if (!env) continue; env_make(env, res[i]); INIT_LIST_HEAD(&env->allpackages); list_add(&env->alllink, &env_list); free(res[i]); pkg_makeroot(env); } return 0; }
env *prepare_env() { env *e = env_make(NULL, 8); load_core(e); return e; }
status_e initenv(void) { std_env = env_make( environ ) ; return( ( std_env == NULL ) ? FAILED : OK ) ; }