int isvectordef (const char *type, relation rel) { definition *def; for (;;) { switch (rel) { case REL_VECTOR: return !streq (type, "string"); case REL_ARRAY: return 0; case REL_POINTER: return 0; case REL_ALIAS: def = findval (defined, type, typedefed); if (def == NULL) { return 0; } type = def->def.ty.old_type; rel = def->def.ty.rel; } } }
/* * 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); } }
static const char * fixit (const char *type, const char *orig) { definition *def; def = findval (defined, type, findit); if (def == NULL || def->def_kind != DEF_TYPEDEF) { return orig; } switch (def->def.ty.rel) { case REL_VECTOR: if (streq (def->def.ty.old_type, "opaque")) return ("char"); else return (def->def.ty.old_type); case REL_ALIAS: return (fixit (def->def.ty.old_type, orig)); default: return orig; } }
void BST<elemtype>::find(elemtype valu){ findval(root,valu); }
/* * We fetch a value through the pointer returned by * [[findval]], if any. * <env.c>= */ Value fetchval(Name name, Valenv env) { Value *vp = findval(name, env); assert(vp != NULL); return *vp; }
/* * A name is bound if the find function found it. * <env.c>= */ int isvalbound(Name name, Valenv env) { return findval(name, env) != NULL; }