/* parse.c 720b */
Namelist getnamelist(Par p, Parlist pl) {
    if (pl == NULL)
        return NULL;
    if (pl->hd->alt != ATOM)
        error("%p: formal parameter list contains %p, which is not a name", p,
                                                                        pl->hd);
    return mkNL(pl->hd->u.atom, getnamelist(p, pl->tl));
}
/*
 * <parse.c>=
 */
static Namelist getnamelist(Name f, Par p, Parlist pl) {
    if (pl == NULL)
        return NULL;
    if (pl->hd->alt != ATOM)
        error("%p: formal-parameter list of function %n contains "
              "something that is not a name", p, f);
    return mkNL(pl->hd->u.atom, getnamelist(f, p, pl->tl));
}
/*
 * You might think that to add a new binding to an
 * environment, we would always have to insert a new
 * binding at the beginning of the lists. But we can get
 * away with an optimization. If x in dom rho, instead
 * of extending rho by making rho{x |->v}, we can
 * overwrite the old binding of x. This optimization is
 * safe only because no program written in Impcore can
 * tell the difference. We can prove this by examining
 * the rules of the operational semantics, which show
 * that in any context where rho{x |->v} appears, there
 * is no way to get to the old rho(x). (See Exercise 
 * [->].) [*]
 * <env.c>=
 */
void bindval(Name name, Value val, Valenv env) {
    Value *vp = findval(name, env);
    if (vp != NULL)
        *vp = val;              /* safe optimization */
    else {
        env->nl = mkNL(name, env->nl);
        env->vl = mkVL(val,  env->vl);
    }
}
/*
 * <env.c>=
 */
void bindfun(Name name, Fun fun, Funenv env) {
    Fun *fp = findfun(name, env);
    if (fp != NULL)
        *fp = fun;              /* safe optimization */
    else {
        env->nl = mkNL(name, env->nl);
        env->fl = mkFL(fun,  env->fl);
    }
}
/* parse.c 723c */
static void parseletbindings(Par p, Parlist bindings, Exp letexp) {
    if (bindings) {
        Par t = bindings->hd;
        Name n;  /* name bound in t (if t is well formed) */
        Exp e;   /* expression on RHS of t (if t is well formed) */
        parseletbindings(p, bindings->tl, letexp);
        if (t->alt != LIST || lengthPL(t->u.list) != 2 
        ||  nthPL(t->u.list, 0)->alt != ATOM)
            error("%p: usage: (letX (letlist) exp)", p);
        n = nthPL(t->u.list, 0)->u.atom;
        e = parseexp(nthPL(t->u.list, 1));
        letexp->u.letx.nl = mkNL(n, letexp->u.letx.nl);
        letexp->u.letx.el = mkEL(e, letexp->u.letx.el);
    }
}